diff options
Diffstat (limited to 'drivers/gpu/drm/mgag200')
-rw-r--r-- | drivers/gpu/drm/mgag200/Kconfig | 10 | ||||
-rw-r--r-- | drivers/gpu/drm/mgag200/Makefile | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/mgag200/mgag200_cursor.c | 329 | ||||
-rw-r--r-- | drivers/gpu/drm/mgag200/mgag200_drv.c | 109 | ||||
-rw-r--r-- | drivers/gpu/drm/mgag200/mgag200_drv.h | 81 | ||||
-rw-r--r-- | drivers/gpu/drm/mgag200/mgag200_fb.c | 315 | ||||
-rw-r--r-- | drivers/gpu/drm/mgag200/mgag200_i2c.c | 5 | ||||
-rw-r--r-- | drivers/gpu/drm/mgag200/mgag200_main.c | 123 | ||||
-rw-r--r-- | drivers/gpu/drm/mgag200/mgag200_mode.c | 76 | ||||
-rw-r--r-- | drivers/gpu/drm/mgag200/mgag200_ttm.c | 10 |
10 files changed, 378 insertions, 682 deletions
diff --git a/drivers/gpu/drm/mgag200/Kconfig b/drivers/gpu/drm/mgag200/Kconfig index 76fee0fbdcae..d60aa4b9ccd4 100644 --- a/drivers/gpu/drm/mgag200/Kconfig +++ b/drivers/gpu/drm/mgag200/Kconfig @@ -4,10 +4,12 @@ config DRM_MGAG200 depends on DRM && PCI && MMU select DRM_KMS_HELPER select DRM_VRAM_HELPER + select DRM_TTM + select DRM_TTM_HELPER help This is a KMS driver for the MGA G200 server chips, it - does not support the original MGA G200 or any of the desktop - chips. It requires 0.3.0 of the modesetting userspace driver, - and a version of mga driver that will fail on KMS enabled - devices. + does not support the original MGA G200 or any of the desktop + chips. It requires 0.3.0 of the modesetting userspace driver, + and a version of mga driver that will fail on KMS enabled + devices. diff --git a/drivers/gpu/drm/mgag200/Makefile b/drivers/gpu/drm/mgag200/Makefile index 98d204408bd0..04b281bcf655 100644 --- a/drivers/gpu/drm/mgag200/Makefile +++ b/drivers/gpu/drm/mgag200/Makefile @@ -1,5 +1,5 @@ # SPDX-License-Identifier: GPL-2.0-only mgag200-y := mgag200_main.o mgag200_mode.o mgag200_cursor.o \ - mgag200_drv.o mgag200_fb.o mgag200_i2c.o mgag200_ttm.o + mgag200_drv.o mgag200_i2c.o mgag200_ttm.o obj-$(CONFIG_DRM_MGAG200) += mgag200.o diff --git a/drivers/gpu/drm/mgag200/mgag200_cursor.c b/drivers/gpu/drm/mgag200/mgag200_cursor.c index f0c61a92351c..d491edd317ff 100644 --- a/drivers/gpu/drm/mgag200/mgag200_cursor.c +++ b/drivers/gpu/drm/mgag200/mgag200_cursor.c @@ -5,41 +5,17 @@ * Author: Christopher Harvey <charvey@matrox.com> */ -#include <drm/drmP.h> +#include <linux/pci.h> + #include "mgag200_drv.h" static bool warn_transparent = true; static bool warn_palette = true; -/* - Hide the cursor off screen. We can't disable the cursor hardware because it - takes too long to re-activate and causes momentary corruption -*/ -static void mga_hide_cursor(struct mga_device *mdev) -{ - WREG8(MGA_CURPOSXL, 0); - WREG8(MGA_CURPOSXH, 0); - if (mdev->cursor.pixels_current) - drm_gem_vram_unpin(mdev->cursor.pixels_current); - mdev->cursor.pixels_current = NULL; -} - -int mga_crtc_cursor_set(struct drm_crtc *crtc, - struct drm_file *file_priv, - uint32_t handle, - uint32_t width, - uint32_t height) +static int mgag200_cursor_update(struct mga_device *mdev, void *dst, void *src, + unsigned int width, unsigned int height) { - struct drm_device *dev = crtc->dev; - struct mga_device *mdev = (struct mga_device *)dev->dev_private; - struct drm_gem_vram_object *pixels_1 = mdev->cursor.pixels_1; - struct drm_gem_vram_object *pixels_2 = mdev->cursor.pixels_2; - struct drm_gem_vram_object *pixels_current = mdev->cursor.pixels_current; - struct drm_gem_vram_object *pixels_next; - struct drm_gem_object *obj; - struct drm_gem_vram_object *gbo = NULL; - int ret = 0; - u8 *src, *dst; + struct drm_device *dev = mdev->dev; unsigned int i, row, col; uint32_t colour_set[16]; uint32_t *next_space = &colour_set[0]; @@ -47,78 +23,9 @@ int mga_crtc_cursor_set(struct drm_crtc *crtc, uint32_t this_colour; bool found = false; int colour_count = 0; - s64 gpu_addr; - u64 dst_gpu; u8 reg_index; u8 this_row[48]; - if (!pixels_1 || !pixels_2) { - WREG8(MGA_CURPOSXL, 0); - WREG8(MGA_CURPOSXH, 0); - return -ENOTSUPP; /* Didn't allocate space for cursors */ - } - - if (WARN_ON(pixels_current && - pixels_1 != pixels_current && - pixels_2 != pixels_current)) { - return -ENOTSUPP; /* inconsistent state */ - } - - if (!handle || !file_priv) { - mga_hide_cursor(mdev); - return 0; - } - - if (width != 64 || height != 64) { - WREG8(MGA_CURPOSXL, 0); - WREG8(MGA_CURPOSXH, 0); - return -EINVAL; - } - - if (pixels_current == pixels_1) - pixels_next = pixels_2; - else - pixels_next = pixels_1; - - obj = drm_gem_object_lookup(file_priv, handle); - if (!obj) - return -ENOENT; - gbo = drm_gem_vram_of_gem(obj); - ret = drm_gem_vram_pin(gbo, 0); - if (ret) { - dev_err(&dev->pdev->dev, "failed to lock user bo\n"); - goto err_drm_gem_object_put_unlocked; - } - src = drm_gem_vram_kmap(gbo, true, NULL); - if (IS_ERR(src)) { - ret = PTR_ERR(src); - dev_err(&dev->pdev->dev, - "failed to kmap user buffer updates\n"); - goto err_drm_gem_vram_unpin_src; - } - - /* Pin and map up-coming buffer to write colour indices */ - ret = drm_gem_vram_pin(pixels_next, 0); - if (ret) - dev_err(&dev->pdev->dev, - "failed to pin cursor buffer: %d\n", ret); - goto err_drm_gem_vram_kunmap_src; - dst = drm_gem_vram_kmap(pixels_next, true, NULL); - if (IS_ERR(dst)) { - ret = PTR_ERR(dst); - dev_err(&dev->pdev->dev, - "failed to kmap cursor updates: %d\n", ret); - goto err_drm_gem_vram_unpin_dst; - } - gpu_addr = drm_gem_vram_offset(pixels_2); - if (gpu_addr < 0) { - ret = (int)gpu_addr; - dev_err(&dev->pdev->dev, - "failed to get cursor scanout address: %d\n", ret); - goto err_drm_gem_vram_kunmap_dst; - } - dst_gpu = (u64)gpu_addr; - memset(&colour_set[0], 0, sizeof(uint32_t)*16); /* width*height*4 = 16384 */ for (i = 0; i < 16384; i += 4) { @@ -131,8 +38,7 @@ int mga_crtc_cursor_set(struct drm_crtc *crtc, dev_info(&dev->pdev->dev, "Not enabling hardware cursor.\n"); warn_transparent = false; /* Only tell the user once. */ } - ret = -EINVAL; - goto err_drm_gem_vram_kunmap_dst; + return -EINVAL; } /* Don't need to store transparent pixels as colours */ if (this_colour>>24 == 0x0) @@ -153,8 +59,7 @@ int mga_crtc_cursor_set(struct drm_crtc *crtc, dev_info(&dev->pdev->dev, "Not enabling hardware cursor.\n"); warn_palette = false; /* Only tell the user once. */ } - ret = -EINVAL; - goto err_drm_gem_vram_kunmap_dst; + return -EINVAL; } *next_space = this_colour; next_space++; @@ -198,55 +103,217 @@ int mga_crtc_cursor_set(struct drm_crtc *crtc, memcpy_toio(dst + row*48, &this_row[0], 48); } + return 0; +} + +static void mgag200_cursor_set_base(struct mga_device *mdev, u64 address) +{ + u8 addrl = (address >> 10) & 0xff; + u8 addrh = (address >> 18) & 0x3f; + /* Program gpu address of cursor buffer */ - WREG_DAC(MGA1064_CURSOR_BASE_ADR_LOW, (u8)((dst_gpu>>10) & 0xff)); - WREG_DAC(MGA1064_CURSOR_BASE_ADR_HI, (u8)((dst_gpu>>18) & 0x3f)); + WREG_DAC(MGA1064_CURSOR_BASE_ADR_LOW, addrl); + WREG_DAC(MGA1064_CURSOR_BASE_ADR_HI, addrh); +} + +static int mgag200_show_cursor(struct mga_device *mdev, void *src, + unsigned int width, unsigned int height) +{ + struct drm_device *dev = mdev->dev; + struct drm_gem_vram_object *gbo; + void *dst; + s64 off; + int ret; + + gbo = mdev->cursor.gbo[mdev->cursor.next_index]; + if (!gbo) { + WREG8(MGA_CURPOSXL, 0); + WREG8(MGA_CURPOSXH, 0); + return -ENOTSUPP; /* Didn't allocate space for cursors */ + } + dst = drm_gem_vram_vmap(gbo); + if (IS_ERR(dst)) { + ret = PTR_ERR(dst); + dev_err(&dev->pdev->dev, + "failed to map cursor updates: %d\n", ret); + return ret; + } + off = drm_gem_vram_offset(gbo); + if (off < 0) { + ret = (int)off; + dev_err(&dev->pdev->dev, + "failed to get cursor scanout address: %d\n", ret); + goto err_drm_gem_vram_vunmap; + } + + ret = mgag200_cursor_update(mdev, dst, src, width, height); + if (ret) + goto err_drm_gem_vram_vunmap; + mgag200_cursor_set_base(mdev, off); /* Adjust cursor control register to turn on the cursor */ WREG_DAC(MGA1064_CURSOR_CTL, 4); /* 16-colour palletized cursor mode */ + drm_gem_vram_vunmap(gbo, dst); + + ++mdev->cursor.next_index; + mdev->cursor.next_index %= ARRAY_SIZE(mdev->cursor.gbo); + + return 0; + +err_drm_gem_vram_vunmap: + drm_gem_vram_vunmap(gbo, dst); + return ret; +} + +/* + * Hide the cursor off screen. We can't disable the cursor hardware because + * it takes too long to re-activate and causes momentary corruption. + */ +static void mgag200_hide_cursor(struct mga_device *mdev) +{ + WREG8(MGA_CURPOSXL, 0); + WREG8(MGA_CURPOSXH, 0); +} + +static void mgag200_move_cursor(struct mga_device *mdev, int x, int y) +{ + if (WARN_ON(x <= 0)) + return; + if (WARN_ON(y <= 0)) + return; + if (WARN_ON(x & ~0xffff)) + return; + if (WARN_ON(y & ~0xffff)) + return; + + WREG8(MGA_CURPOSXL, x & 0xff); + WREG8(MGA_CURPOSXH, (x>>8) & 0xff); + + WREG8(MGA_CURPOSYL, y & 0xff); + WREG8(MGA_CURPOSYH, (y>>8) & 0xff); +} + +int mgag200_cursor_init(struct mga_device *mdev) +{ + struct drm_device *dev = mdev->dev; + size_t ncursors = ARRAY_SIZE(mdev->cursor.gbo); + size_t size; + int ret; + size_t i; + struct drm_gem_vram_object *gbo; + + size = roundup(64 * 48, PAGE_SIZE); + if (size * ncursors > mdev->vram_fb_available) + return -ENOMEM; + + for (i = 0; i < ncursors; ++i) { + gbo = drm_gem_vram_create(dev, size, 0); + if (IS_ERR(gbo)) { + ret = PTR_ERR(gbo); + goto err_drm_gem_vram_put; + } + ret = drm_gem_vram_pin(gbo, DRM_GEM_VRAM_PL_FLAG_VRAM | + DRM_GEM_VRAM_PL_FLAG_TOPDOWN); + if (ret) { + drm_gem_vram_put(gbo); + goto err_drm_gem_vram_put; + } + + mdev->cursor.gbo[i] = gbo; + } + + /* + * At the high end of video memory, we reserve space for + * buffer objects. The cursor plane uses this memory to store + * a double-buffered image of the current cursor. Hence, it's + * not available for framebuffers. + */ + mdev->vram_fb_available -= ncursors * size; + + return 0; + +err_drm_gem_vram_put: + while (i) { + --i; + gbo = mdev->cursor.gbo[i]; + drm_gem_vram_unpin(gbo); + drm_gem_vram_put(gbo); + mdev->cursor.gbo[i] = NULL; + } + return ret; +} + +void mgag200_cursor_fini(struct mga_device *mdev) +{ + size_t i; + struct drm_gem_vram_object *gbo; + + for (i = 0; i < ARRAY_SIZE(mdev->cursor.gbo); ++i) { + gbo = mdev->cursor.gbo[i]; + drm_gem_vram_unpin(gbo); + drm_gem_vram_put(gbo); + } +} + +int mgag200_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv, + uint32_t handle, uint32_t width, uint32_t height) +{ + struct drm_device *dev = crtc->dev; + struct mga_device *mdev = (struct mga_device *)dev->dev_private; + struct drm_gem_object *obj; + struct drm_gem_vram_object *gbo = NULL; + int ret; + u8 *src; + + if (!handle || !file_priv) { + mgag200_hide_cursor(mdev); + return 0; + } + + if (width != 64 || height != 64) { + WREG8(MGA_CURPOSXL, 0); + WREG8(MGA_CURPOSXH, 0); + return -EINVAL; + } + + obj = drm_gem_object_lookup(file_priv, handle); + if (!obj) + return -ENOENT; + gbo = drm_gem_vram_of_gem(obj); + src = drm_gem_vram_vmap(gbo); + if (IS_ERR(src)) { + ret = PTR_ERR(src); + dev_err(&dev->pdev->dev, + "failed to map user buffer updates\n"); + goto err_drm_gem_object_put_unlocked; + } + + ret = mgag200_show_cursor(mdev, src, width, height); + if (ret) + goto err_drm_gem_vram_vunmap; + /* Now update internal buffer pointers */ - if (pixels_current) - drm_gem_vram_unpin(pixels_current); - mdev->cursor.pixels_current = pixels_next; - - drm_gem_vram_kunmap(pixels_next); - drm_gem_vram_unpin(pixels_next); - drm_gem_vram_kunmap(gbo); - drm_gem_vram_unpin(gbo); + drm_gem_vram_vunmap(gbo, src); drm_gem_object_put_unlocked(obj); return 0; - -err_drm_gem_vram_kunmap_dst: - drm_gem_vram_kunmap(pixels_next); -err_drm_gem_vram_unpin_dst: - drm_gem_vram_unpin(pixels_next); -err_drm_gem_vram_kunmap_src: - drm_gem_vram_kunmap(gbo); -err_drm_gem_vram_unpin_src: - drm_gem_vram_unpin(gbo); +err_drm_gem_vram_vunmap: + drm_gem_vram_vunmap(gbo, src); err_drm_gem_object_put_unlocked: drm_gem_object_put_unlocked(obj); return ret; } -int mga_crtc_cursor_move(struct drm_crtc *crtc, int x, int y) +int mgag200_crtc_cursor_move(struct drm_crtc *crtc, int x, int y) { struct mga_device *mdev = (struct mga_device *)crtc->dev->dev_private; + /* Our origin is at (64,64) */ x += 64; y += 64; - BUG_ON(x <= 0); - BUG_ON(y <= 0); - BUG_ON(x & ~0xffff); - BUG_ON(y & ~0xffff); + mgag200_move_cursor(mdev, x, y); - WREG8(MGA_CURPOSXL, x & 0xff); - WREG8(MGA_CURPOSXH, (x>>8) & 0xff); - - WREG8(MGA_CURPOSYL, y & 0xff); - WREG8(MGA_CURPOSYH, (y>>8) & 0xff); return 0; } diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.c b/drivers/gpu/drm/mgag200/mgag200_drv.c index aafa1cb31f50..7a5bad2f57d7 100644 --- a/drivers/gpu/drm/mgag200/mgag200_drv.c +++ b/drivers/gpu/drm/mgag200/mgag200_drv.c @@ -5,14 +5,18 @@ * Authors: Matthew Garrett * Dave Airlie */ -#include <linux/module.h> -#include <linux/console.h> -#include <drm/drmP.h> -#include "mgag200_drv.h" +#include <linux/console.h> +#include <linux/module.h> +#include <linux/pci.h> +#include <drm/drm_drv.h> +#include <drm/drm_file.h> +#include <drm/drm_ioctl.h> #include <drm/drm_pciids.h> +#include "mgag200_drv.h" + /* * This is the generic driver code. This binds the driver to the drm core, * which then performs further device association and calls our graphics init @@ -23,10 +27,15 @@ int mgag200_modeset = -1; MODULE_PARM_DESC(modeset, "Disable/Enable modesetting"); module_param_named(modeset, mgag200_modeset, int, 0400); +int mgag200_hw_bug_no_startadd = -1; +MODULE_PARM_DESC(modeset, "HW does not interpret scanout-buffer start address correctly"); +module_param_named(hw_bug_no_startadd, mgag200_hw_bug_no_startadd, int, 0400); + static struct drm_driver driver; static const struct pci_device_id pciidlist[] = { - { PCI_VENDOR_ID_MATROX, 0x522, PCI_ANY_ID, PCI_ANY_ID, 0, 0, G200_SE_A }, + { PCI_VENDOR_ID_MATROX, 0x522, PCI_ANY_ID, PCI_ANY_ID, 0, 0, + G200_SE_A | MGAG200_FLAG_HW_BUG_NO_STARTADD}, { PCI_VENDOR_ID_MATROX, 0x524, PCI_ANY_ID, PCI_ANY_ID, 0, 0, G200_SE_B }, { PCI_VENDOR_ID_MATROX, 0x530, PCI_ANY_ID, PCI_ANY_ID, 0, 0, G200_EV }, { PCI_VENDOR_ID_MATROX, 0x532, PCI_ANY_ID, PCI_ANY_ID, 0, 0, G200_WB }, @@ -42,27 +51,94 @@ MODULE_DEVICE_TABLE(pci, pciidlist); static int mga_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { - drm_fb_helper_remove_conflicting_pci_framebuffers(pdev, 0, "mgag200drmfb"); + struct drm_device *dev; + int ret; + + drm_fb_helper_remove_conflicting_pci_framebuffers(pdev, "mgag200drmfb"); + + ret = pci_enable_device(pdev); + if (ret) + return ret; + + dev = drm_dev_alloc(&driver, &pdev->dev); + if (IS_ERR(dev)) { + ret = PTR_ERR(dev); + goto err_pci_disable_device; + } + + dev->pdev = pdev; + pci_set_drvdata(pdev, dev); + + ret = mgag200_driver_load(dev, ent->driver_data); + if (ret) + goto err_drm_dev_put; + + ret = drm_dev_register(dev, ent->driver_data); + if (ret) + goto err_mgag200_driver_unload; - return drm_get_pci_dev(pdev, ent, &driver); + return 0; + +err_mgag200_driver_unload: + mgag200_driver_unload(dev); +err_drm_dev_put: + drm_dev_put(dev); +err_pci_disable_device: + pci_disable_device(pdev); + return ret; } static void mga_pci_remove(struct pci_dev *pdev) { struct drm_device *dev = pci_get_drvdata(pdev); - drm_put_dev(dev); + drm_dev_unregister(dev); + mgag200_driver_unload(dev); + drm_dev_put(dev); } -static const struct file_operations mgag200_driver_fops = { - .owner = THIS_MODULE, - DRM_VRAM_MM_FILE_OPERATIONS -}; +DEFINE_DRM_GEM_FOPS(mgag200_driver_fops); + +static bool mgag200_pin_bo_at_0(const struct mga_device *mdev) +{ + if (mgag200_hw_bug_no_startadd > 0) { + DRM_WARN_ONCE("Option hw_bug_no_startradd is enabled. Please " + "report the output of 'lspci -vvnn' to " + "<dri-devel@lists.freedesktop.org> if this " + "option is required to make mgag200 work " + "correctly on your system.\n"); + return true; + } else if (!mgag200_hw_bug_no_startadd) { + return false; + } + return mdev->flags & MGAG200_FLAG_HW_BUG_NO_STARTADD; +} + +int mgag200_driver_dumb_create(struct drm_file *file, + struct drm_device *dev, + struct drm_mode_create_dumb *args) +{ + struct mga_device *mdev = dev->dev_private; + unsigned long pg_align; + + if (WARN_ONCE(!dev->vram_mm, "VRAM MM not initialized")) + return -EINVAL; + + pg_align = 0ul; + + /* + * Aligning scanout buffers to the size of the video ram forces + * placement at offset 0. Works around a bug where HW does not + * respect 'startadd' field. + */ + if (mgag200_pin_bo_at_0(mdev)) + pg_align = PFN_UP(mdev->mc.vram_size); + + return drm_gem_vram_fill_create_dumb(file, dev, pg_align, 0, args); +} static struct drm_driver driver = { .driver_features = DRIVER_GEM | DRIVER_MODESET, - .load = mgag200_driver_load, - .unload = mgag200_driver_unload, .fops = &mgag200_driver_fops, .name = DRIVER_NAME, .desc = DRIVER_DESC, @@ -70,7 +146,10 @@ static struct drm_driver driver = { .major = DRIVER_MAJOR, .minor = DRIVER_MINOR, .patchlevel = DRIVER_PATCHLEVEL, - DRM_GEM_VRAM_DRIVER + .debugfs_init = drm_vram_mm_debugfs_init, + .dumb_create = mgag200_driver_dumb_create, + .dumb_map_offset = drm_gem_vram_driver_dumb_mmap_offset, + .gem_prime_mmap = drm_gem_prime_mmap, }; static struct pci_driver mgag200_pci_driver = { diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.h b/drivers/gpu/drm/mgag200/mgag200_drv.h index c47671ce6c48..aa32aad222c2 100644 --- a/drivers/gpu/drm/mgag200/mgag200_drv.h +++ b/drivers/gpu/drm/mgag200/mgag200_drv.h @@ -10,19 +10,16 @@ #ifndef __MGAG200_DRV_H__ #define __MGAG200_DRV_H__ +#include <linux/i2c-algo-bit.h> +#include <linux/i2c.h> + #include <video/vga.h> #include <drm/drm_encoder.h> #include <drm/drm_fb_helper.h> - #include <drm/drm_gem.h> #include <drm/drm_gem_vram_helper.h> -#include <drm/drm_vram_mm_helper.h> - -#include <linux/i2c.h> -#include <linux/i2c-algo-bit.h> - #include "mgag200_reg.h" #define DRIVER_AUTHOR "Matthew Garrett" @@ -100,21 +97,6 @@ #define to_mga_crtc(x) container_of(x, struct mga_crtc, base) #define to_mga_encoder(x) container_of(x, struct mga_encoder, base) #define to_mga_connector(x) container_of(x, struct mga_connector, base) -#define to_mga_framebuffer(x) container_of(x, struct mga_framebuffer, base) - -struct mga_framebuffer { - struct drm_framebuffer base; - struct drm_gem_object *obj; -}; - -struct mga_fbdev { - struct drm_fb_helper helper; /* must be first */ - struct mga_framebuffer mfb; - void *sysram; - int size; - int x1, y1, x2, y2; /* dirty rect */ - spinlock_t dirty_lock; -}; struct mga_crtc { struct drm_crtc base; @@ -147,16 +129,8 @@ struct mga_connector { }; struct mga_cursor { - /* - We have to have 2 buffers for the cursor to avoid occasional - corruption while switching cursor icons. - If either of these is NULL, then don't do hardware cursors, and - fall back to software. - */ - struct drm_gem_vram_object *pixels_1; - struct drm_gem_vram_object *pixels_2; - /* The currently displayed icon, this points to one of pixels_1, or pixels_2 */ - struct drm_gem_vram_object *pixels_current; + struct drm_gem_vram_object *gbo[2]; + unsigned int next_index; }; struct mga_mc { @@ -176,6 +150,12 @@ enum mga_type { G200_EW3, }; +/* HW does not handle 'startadd' field correct. */ +#define MGAG200_FLAG_HW_BUG_NO_STARTADD (1ul << 8) + +#define MGAG200_TYPE_MASK (0x000000ff) +#define MGAG200_FLAG_MASK (0x00ffff00) + #define IS_G200_SE(mdev) (mdev->type == G200_SE_A || mdev->type == G200_SE_B) struct mga_device { @@ -189,9 +169,10 @@ struct mga_device { struct mga_mc mc; struct mga_mode_info mode_info; - struct mga_fbdev *mfbdev; struct mga_cursor cursor; + size_t vram_fb_available; + bool suspended; int num_crtc; enum mga_type type; @@ -206,29 +187,25 @@ struct mga_device { u32 unique_rev_id; }; +static inline enum mga_type +mgag200_type_from_driver_data(kernel_ulong_t driver_data) +{ + return (enum mga_type)(driver_data & MGAG200_TYPE_MASK); +} + +static inline unsigned long +mgag200_flags_from_driver_data(kernel_ulong_t driver_data) +{ + return driver_data & MGAG200_FLAG_MASK; +} + /* mgag200_mode.c */ int mgag200_modeset_init(struct mga_device *mdev); void mgag200_modeset_fini(struct mga_device *mdev); - /* mgag200_fb.c */ -int mgag200_fbdev_init(struct mga_device *mdev); -void mgag200_fbdev_fini(struct mga_device *mdev); - /* mgag200_main.c */ -int mgag200_framebuffer_init(struct drm_device *dev, - struct mga_framebuffer *mfb, - const struct drm_mode_fb_cmd2 *mode_cmd, - struct drm_gem_object *obj); - - int mgag200_driver_load(struct drm_device *dev, unsigned long flags); void mgag200_driver_unload(struct drm_device *dev); -int mgag200_gem_create(struct drm_device *dev, - u32 size, bool iskernel, - struct drm_gem_object **obj); -int mgag200_dumb_create(struct drm_file *file, - struct drm_device *dev, - struct drm_mode_create_dumb *args); /* mgag200_i2c.c */ struct mga_i2c_chan *mgag200_i2c_create(struct drm_device *dev); @@ -238,8 +215,10 @@ int mgag200_mm_init(struct mga_device *mdev); void mgag200_mm_fini(struct mga_device *mdev); int mgag200_mmap(struct file *filp, struct vm_area_struct *vma); -int mga_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv, - uint32_t handle, uint32_t width, uint32_t height); -int mga_crtc_cursor_move(struct drm_crtc *crtc, int x, int y); +int mgag200_cursor_init(struct mga_device *mdev); +void mgag200_cursor_fini(struct mga_device *mdev); +int mgag200_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv, + uint32_t handle, uint32_t width, uint32_t height); +int mgag200_crtc_cursor_move(struct drm_crtc *crtc, int x, int y); #endif /* __MGAG200_DRV_H__ */ diff --git a/drivers/gpu/drm/mgag200/mgag200_fb.c b/drivers/gpu/drm/mgag200/mgag200_fb.c deleted file mode 100644 index 8adb33228732..000000000000 --- a/drivers/gpu/drm/mgag200/mgag200_fb.c +++ /dev/null @@ -1,315 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright 2010 Matt Turner. - * Copyright 2012 Red Hat - * - * Authors: Matthew Garrett - * Matt Turner - * Dave Airlie - */ -#include <linux/module.h> -#include <drm/drmP.h> -#include <drm/drm_util.h> -#include <drm/drm_fb_helper.h> -#include <drm/drm_crtc_helper.h> - -#include "mgag200_drv.h" - -static void mga_dirty_update(struct mga_fbdev *mfbdev, - int x, int y, int width, int height) -{ - int i; - struct drm_gem_object *obj; - struct drm_gem_vram_object *gbo; - int src_offset, dst_offset; - int bpp = mfbdev->mfb.base.format->cpp[0]; - int ret; - u8 *dst; - bool unmap = false; - bool store_for_later = false; - int x2, y2; - unsigned long flags; - - obj = mfbdev->mfb.obj; - gbo = drm_gem_vram_of_gem(obj); - - if (drm_can_sleep()) { - /* We pin the BO so it won't be moved during the - * update. The actual location, video RAM or system - * memory, is not important. - */ - ret = drm_gem_vram_pin(gbo, 0); - if (ret) { - if (ret != -EBUSY) - return; - store_for_later = true; - } - } else { - store_for_later = true; - } - - x2 = x + width - 1; - y2 = y + height - 1; - spin_lock_irqsave(&mfbdev->dirty_lock, flags); - - if (mfbdev->y1 < y) - y = mfbdev->y1; - if (mfbdev->y2 > y2) - y2 = mfbdev->y2; - if (mfbdev->x1 < x) - x = mfbdev->x1; - if (mfbdev->x2 > x2) - x2 = mfbdev->x2; - - if (store_for_later) { - mfbdev->x1 = x; - mfbdev->x2 = x2; - mfbdev->y1 = y; - mfbdev->y2 = y2; - spin_unlock_irqrestore(&mfbdev->dirty_lock, flags); - return; - } - - mfbdev->x1 = mfbdev->y1 = INT_MAX; - mfbdev->x2 = mfbdev->y2 = 0; - spin_unlock_irqrestore(&mfbdev->dirty_lock, flags); - - dst = drm_gem_vram_kmap(gbo, false, NULL); - if (IS_ERR(dst)) { - DRM_ERROR("failed to kmap fb updates\n"); - goto out; - } else if (!dst) { - dst = drm_gem_vram_kmap(gbo, true, NULL); - if (IS_ERR(dst)) { - DRM_ERROR("failed to kmap fb updates\n"); - goto out; - } - unmap = true; - } - - for (i = y; i <= y2; i++) { - /* assume equal stride for now */ - src_offset = dst_offset = - i * mfbdev->mfb.base.pitches[0] + (x * bpp); - memcpy_toio(dst + dst_offset, mfbdev->sysram + src_offset, - (x2 - x + 1) * bpp); - } - - if (unmap) - drm_gem_vram_kunmap(gbo); - -out: - drm_gem_vram_unpin(gbo); -} - -static void mga_fillrect(struct fb_info *info, - const struct fb_fillrect *rect) -{ - struct mga_fbdev *mfbdev = info->par; - drm_fb_helper_sys_fillrect(info, rect); - mga_dirty_update(mfbdev, rect->dx, rect->dy, rect->width, - rect->height); -} - -static void mga_copyarea(struct fb_info *info, - const struct fb_copyarea *area) -{ - struct mga_fbdev *mfbdev = info->par; - drm_fb_helper_sys_copyarea(info, area); - mga_dirty_update(mfbdev, area->dx, area->dy, area->width, - area->height); -} - -static void mga_imageblit(struct fb_info *info, - const struct fb_image *image) -{ - struct mga_fbdev *mfbdev = info->par; - drm_fb_helper_sys_imageblit(info, image); - mga_dirty_update(mfbdev, image->dx, image->dy, image->width, - image->height); -} - - -static struct fb_ops mgag200fb_ops = { - .owner = THIS_MODULE, - .fb_check_var = drm_fb_helper_check_var, - .fb_set_par = drm_fb_helper_set_par, - .fb_fillrect = mga_fillrect, - .fb_copyarea = mga_copyarea, - .fb_imageblit = mga_imageblit, - .fb_pan_display = drm_fb_helper_pan_display, - .fb_blank = drm_fb_helper_blank, - .fb_setcmap = drm_fb_helper_setcmap, -}; - -static int mgag200fb_create_object(struct mga_fbdev *afbdev, - const struct drm_mode_fb_cmd2 *mode_cmd, - struct drm_gem_object **gobj_p) -{ - struct drm_device *dev = afbdev->helper.dev; - u32 size; - struct drm_gem_object *gobj; - int ret = 0; - - size = mode_cmd->pitches[0] * mode_cmd->height; - ret = mgag200_gem_create(dev, size, true, &gobj); - if (ret) - return ret; - - *gobj_p = gobj; - return ret; -} - -static int mgag200fb_create(struct drm_fb_helper *helper, - struct drm_fb_helper_surface_size *sizes) -{ - struct mga_fbdev *mfbdev = - container_of(helper, struct mga_fbdev, helper); - struct drm_device *dev = mfbdev->helper.dev; - struct drm_mode_fb_cmd2 mode_cmd; - struct mga_device *mdev = dev->dev_private; - struct fb_info *info; - struct drm_framebuffer *fb; - struct drm_gem_object *gobj = NULL; - int ret; - void *sysram; - int size; - - mode_cmd.width = sizes->surface_width; - mode_cmd.height = sizes->surface_height; - mode_cmd.pitches[0] = mode_cmd.width * ((sizes->surface_bpp + 7) / 8); - - mode_cmd.pixel_format = drm_mode_legacy_fb_format(sizes->surface_bpp, - sizes->surface_depth); - size = mode_cmd.pitches[0] * mode_cmd.height; - - ret = mgag200fb_create_object(mfbdev, &mode_cmd, &gobj); - if (ret) { - DRM_ERROR("failed to create fbcon backing object %d\n", ret); - return ret; - } - - sysram = vmalloc(size); - if (!sysram) { - ret = -ENOMEM; - goto err_sysram; - } - - info = drm_fb_helper_alloc_fbi(helper); - if (IS_ERR(info)) { - ret = PTR_ERR(info); - goto err_alloc_fbi; - } - - ret = mgag200_framebuffer_init(dev, &mfbdev->mfb, &mode_cmd, gobj); - if (ret) - goto err_alloc_fbi; - - mfbdev->sysram = sysram; - mfbdev->size = size; - - fb = &mfbdev->mfb.base; - - /* setup helper */ - mfbdev->helper.fb = fb; - - info->fbops = &mgag200fb_ops; - - /* setup aperture base/size for vesafb takeover */ - info->apertures->ranges[0].base = mdev->dev->mode_config.fb_base; - info->apertures->ranges[0].size = mdev->mc.vram_size; - - drm_fb_helper_fill_info(info, &mfbdev->helper, sizes); - - info->screen_base = sysram; - info->screen_size = size; - info->pixmap.flags = FB_PIXMAP_SYSTEM; - - DRM_DEBUG_KMS("allocated %dx%d\n", - fb->width, fb->height); - - return 0; - -err_alloc_fbi: - vfree(sysram); -err_sysram: - drm_gem_object_put_unlocked(gobj); - - return ret; -} - -static int mga_fbdev_destroy(struct drm_device *dev, - struct mga_fbdev *mfbdev) -{ - struct mga_framebuffer *mfb = &mfbdev->mfb; - - drm_fb_helper_unregister_fbi(&mfbdev->helper); - - if (mfb->obj) { - drm_gem_object_put_unlocked(mfb->obj); - mfb->obj = NULL; - } - drm_fb_helper_fini(&mfbdev->helper); - vfree(mfbdev->sysram); - drm_framebuffer_unregister_private(&mfb->base); - drm_framebuffer_cleanup(&mfb->base); - - return 0; -} - -static const struct drm_fb_helper_funcs mga_fb_helper_funcs = { - .fb_probe = mgag200fb_create, -}; - -int mgag200_fbdev_init(struct mga_device *mdev) -{ - struct mga_fbdev *mfbdev; - int ret; - int bpp_sel = 32; - - /* prefer 16bpp on low end gpus with limited VRAM */ - if (IS_G200_SE(mdev) && mdev->mc.vram_size < (2048*1024)) - bpp_sel = 16; - - mfbdev = devm_kzalloc(mdev->dev->dev, sizeof(struct mga_fbdev), GFP_KERNEL); - if (!mfbdev) - return -ENOMEM; - - mdev->mfbdev = mfbdev; - spin_lock_init(&mfbdev->dirty_lock); - - drm_fb_helper_prepare(mdev->dev, &mfbdev->helper, &mga_fb_helper_funcs); - - ret = drm_fb_helper_init(mdev->dev, &mfbdev->helper, - MGAG200FB_CONN_LIMIT); - if (ret) - goto err_fb_helper; - - ret = drm_fb_helper_single_add_all_connectors(&mfbdev->helper); - if (ret) - goto err_fb_setup; - - /* disable all the possible outputs/crtcs before entering KMS mode */ - drm_helper_disable_unused_functions(mdev->dev); - - ret = drm_fb_helper_initial_config(&mfbdev->helper, bpp_sel); - if (ret) - goto err_fb_setup; - - return 0; - -err_fb_setup: - drm_fb_helper_fini(&mfbdev->helper); -err_fb_helper: - mdev->mfbdev = NULL; - - return ret; -} - -void mgag200_fbdev_fini(struct mga_device *mdev) -{ - if (!mdev->mfbdev) - return; - - mga_fbdev_destroy(mdev->dev, mdev->mfbdev); -} diff --git a/drivers/gpu/drm/mgag200/mgag200_i2c.c b/drivers/gpu/drm/mgag200/mgag200_i2c.c index 77d1c4771786..9f4635916d32 100644 --- a/drivers/gpu/drm/mgag200/mgag200_i2c.c +++ b/drivers/gpu/drm/mgag200/mgag200_i2c.c @@ -25,10 +25,11 @@ /* * Authors: Dave Airlie <airlied@redhat.com> */ + #include <linux/export.h> -#include <linux/i2c.h> #include <linux/i2c-algo-bit.h> -#include <drm/drmP.h> +#include <linux/i2c.h> +#include <linux/pci.h> #include "mgag200_drv.h" diff --git a/drivers/gpu/drm/mgag200/mgag200_main.c b/drivers/gpu/drm/mgag200/mgag200_main.c index dd61ccc5af5c..e278b6a547bd 100644 --- a/drivers/gpu/drm/mgag200/mgag200_main.c +++ b/drivers/gpu/drm/mgag200/mgag200_main.c @@ -7,70 +7,16 @@ * Matt Turner * Dave Airlie */ -#include <drm/drmP.h> -#include <drm/drm_crtc_helper.h> -#include "mgag200_drv.h" - -static void mga_user_framebuffer_destroy(struct drm_framebuffer *fb) -{ - struct mga_framebuffer *mga_fb = to_mga_framebuffer(fb); - - drm_gem_object_put_unlocked(mga_fb->obj); - drm_framebuffer_cleanup(fb); - kfree(fb); -} - -static const struct drm_framebuffer_funcs mga_fb_funcs = { - .destroy = mga_user_framebuffer_destroy, -}; - -int mgag200_framebuffer_init(struct drm_device *dev, - struct mga_framebuffer *gfb, - const struct drm_mode_fb_cmd2 *mode_cmd, - struct drm_gem_object *obj) -{ - int ret; - drm_helper_mode_fill_fb_struct(dev, &gfb->base, mode_cmd); - gfb->obj = obj; - ret = drm_framebuffer_init(dev, &gfb->base, &mga_fb_funcs); - if (ret) { - DRM_ERROR("drm_framebuffer_init failed: %d\n", ret); - return ret; - } - return 0; -} +#include <linux/pci.h> -static struct drm_framebuffer * -mgag200_user_framebuffer_create(struct drm_device *dev, - struct drm_file *filp, - const struct drm_mode_fb_cmd2 *mode_cmd) -{ - struct drm_gem_object *obj; - struct mga_framebuffer *mga_fb; - int ret; - - obj = drm_gem_object_lookup(filp, mode_cmd->handles[0]); - if (obj == NULL) - return ERR_PTR(-ENOENT); - - mga_fb = kzalloc(sizeof(*mga_fb), GFP_KERNEL); - if (!mga_fb) { - drm_gem_object_put_unlocked(obj); - return ERR_PTR(-ENOMEM); - } +#include <drm/drm_crtc_helper.h> +#include <drm/drm_gem_framebuffer_helper.h> - ret = mgag200_framebuffer_init(dev, mga_fb, mode_cmd, obj); - if (ret) { - drm_gem_object_put_unlocked(obj); - kfree(mga_fb); - return ERR_PTR(ret); - } - return &mga_fb->base; -} +#include "mgag200_drv.h" static const struct drm_mode_config_funcs mga_mode_funcs = { - .fb_create = mgag200_user_framebuffer_create, + .fb_create = drm_gem_fb_create }; static int mga_probe_vram(struct mga_device *mdev, void __iomem *mem) @@ -149,7 +95,8 @@ static int mgag200_device_init(struct drm_device *dev, struct mga_device *mdev = dev->dev_private; int ret, option; - mdev->type = flags; + mdev->flags = mgag200_flags_from_driver_data(flags); + mdev->type = mgag200_type_from_driver_data(flags); /* Hardcode the number of CRTCs to 1 */ mdev->num_crtc = 1; @@ -172,8 +119,11 @@ static int mgag200_device_init(struct drm_device *dev, return -ENOMEM; /* stash G200 SE model number for later use */ - if (IS_G200_SE(mdev)) + if (IS_G200_SE(mdev)) { mdev->unique_rev_id = RREG32(0x1e24); + DRM_DEBUG("G200 SE unique revision id is 0x%x\n", + mdev->unique_rev_id); + } ret = mga_vram_init(mdev); if (ret) @@ -214,10 +164,10 @@ int mgag200_driver_load(struct drm_device *dev, unsigned long flags) drm_mode_config_init(dev); dev->mode_config.funcs = (void *)&mga_mode_funcs; - if (IS_G200_SE(mdev) && mdev->mc.vram_size < (2048*1024)) + if (IS_G200_SE(mdev) && mdev->vram_fb_available < (2048*1024)) dev->mode_config.preferred_depth = 16; else - dev->mode_config.preferred_depth = 24; + dev->mode_config.preferred_depth = 32; dev->mode_config.prefer_shadow = 1; r = mgag200_modeset_init(mdev); @@ -226,25 +176,20 @@ int mgag200_driver_load(struct drm_device *dev, unsigned long flags) goto err_modeset; } - /* Make small buffers to store a hardware cursor (double buffered icon updates) */ - mdev->cursor.pixels_1 = drm_gem_vram_create(dev, &dev->vram_mm->bdev, - roundup(48*64, PAGE_SIZE), - 0, 0); - mdev->cursor.pixels_2 = drm_gem_vram_create(dev, &dev->vram_mm->bdev, - roundup(48*64, PAGE_SIZE), - 0, 0); - if (IS_ERR(mdev->cursor.pixels_2) || IS_ERR(mdev->cursor.pixels_1)) { - mdev->cursor.pixels_1 = NULL; - mdev->cursor.pixels_2 = NULL; + r = mgag200_cursor_init(mdev); + if (r) dev_warn(&dev->pdev->dev, - "Could not allocate space for cursors. Not doing hardware cursors.\n"); - } - mdev->cursor.pixels_current = NULL; + "Could not initialize cursors. Not doing hardware cursors.\n"); + + r = drm_fbdev_generic_setup(mdev->dev, 0); + if (r) + goto err_modeset; return 0; err_modeset: drm_mode_config_cleanup(dev); + mgag200_cursor_fini(mdev); mgag200_mm_fini(mdev); err_mm: dev->dev_private = NULL; @@ -259,32 +204,8 @@ void mgag200_driver_unload(struct drm_device *dev) if (mdev == NULL) return; mgag200_modeset_fini(mdev); - mgag200_fbdev_fini(mdev); drm_mode_config_cleanup(dev); + mgag200_cursor_fini(mdev); mgag200_mm_fini(mdev); dev->dev_private = NULL; } - -int mgag200_gem_create(struct drm_device *dev, - u32 size, bool iskernel, - struct drm_gem_object **obj) -{ - struct drm_gem_vram_object *gbo; - int ret; - - *obj = NULL; - - size = roundup(size, PAGE_SIZE); - if (size == 0) - return -EINVAL; - - gbo = drm_gem_vram_create(dev, &dev->vram_mm->bdev, size, 0, false); - if (IS_ERR(gbo)) { - ret = PTR_ERR(gbo); - if (ret != -ERESTARTSYS) - DRM_ERROR("failed to allocate GEM object\n"); - return ret; - } - *obj = &gbo->gem; - return 0; -} diff --git a/drivers/gpu/drm/mgag200/mgag200_mode.c b/drivers/gpu/drm/mgag200/mgag200_mode.c index a25054015e8c..62a8e9ccb16d 100644 --- a/drivers/gpu/drm/mgag200/mgag200_mode.c +++ b/drivers/gpu/drm/mgag200/mgag200_mode.c @@ -9,9 +9,10 @@ */ #include <linux/delay.h> +#include <linux/pci.h> -#include <drm/drmP.h> #include <drm/drm_crtc_helper.h> +#include <drm/drm_fourcc.h> #include <drm/drm_plane_helper.h> #include <drm/drm_probe_helper.h> @@ -859,28 +860,16 @@ static int mga_crtc_do_set_base(struct drm_crtc *crtc, struct drm_framebuffer *fb, int x, int y, int atomic) { - struct mga_device *mdev = crtc->dev->dev_private; - struct drm_gem_object *obj; - struct mga_framebuffer *mga_fb; struct drm_gem_vram_object *gbo; int ret; s64 gpu_addr; - void *base; if (!atomic && fb) { - mga_fb = to_mga_framebuffer(fb); - obj = mga_fb->obj; - gbo = drm_gem_vram_of_gem(obj); - - /* unmap if console */ - if (&mdev->mfbdev->mfb == mga_fb) - drm_gem_vram_kunmap(gbo); + gbo = drm_gem_vram_of_gem(fb->obj[0]); drm_gem_vram_unpin(gbo); } - mga_fb = to_mga_framebuffer(crtc->primary->fb); - obj = mga_fb->obj; - gbo = drm_gem_vram_of_gem(obj); + gbo = drm_gem_vram_of_gem(crtc->primary->fb->obj[0]); ret = drm_gem_vram_pin(gbo, DRM_GEM_VRAM_PL_FLAG_VRAM); if (ret) @@ -891,15 +880,6 @@ static int mga_crtc_do_set_base(struct drm_crtc *crtc, goto err_drm_gem_vram_unpin; } - if (&mdev->mfbdev->mfb == mga_fb) { - /* if pushing console in kmap it */ - base = drm_gem_vram_kmap(gbo, true, NULL); - if (IS_ERR(base)) { - ret = PTR_ERR(base); - DRM_ERROR("failed to kmap fbcon\n"); - } - } - mga_set_start_address(crtc, (u32)gpu_addr); return 0; @@ -1423,14 +1403,9 @@ static void mga_crtc_disable(struct drm_crtc *crtc) DRM_DEBUG_KMS("\n"); mga_crtc_dpms(crtc, DRM_MODE_DPMS_OFF); if (crtc->primary->fb) { - struct mga_device *mdev = crtc->dev->dev_private; - struct mga_framebuffer *mga_fb = to_mga_framebuffer(crtc->primary->fb); - struct drm_gem_object *obj = mga_fb->obj; - struct drm_gem_vram_object *gbo = drm_gem_vram_of_gem(obj); - - /* unmap if console */ - if (&mdev->mfbdev->mfb == mga_fb) - drm_gem_vram_kunmap(gbo); + struct drm_framebuffer *fb = crtc->primary->fb; + struct drm_gem_vram_object *gbo = + drm_gem_vram_of_gem(fb->obj[0]); drm_gem_vram_unpin(gbo); } crtc->primary->fb = NULL; @@ -1438,8 +1413,8 @@ static void mga_crtc_disable(struct drm_crtc *crtc) /* These provide the minimum set of functions required to handle a CRTC */ static const struct drm_crtc_funcs mga_crtc_funcs = { - .cursor_set = mga_crtc_cursor_set, - .cursor_move = mga_crtc_cursor_move, + .cursor_set = mgag200_crtc_cursor_set, + .cursor_move = mgag200_crtc_cursor_move, .gamma_set = mga_crtc_gamma_set, .set_config = drm_crtc_helper_set_config, .destroy = mga_crtc_destroy, @@ -1654,7 +1629,7 @@ static enum drm_mode_status mga_vga_mode_valid(struct drm_connector *connector, bpp = connector->cmdline_mode.bpp; } - if ((mode->hdisplay * mode->vdisplay * (bpp/8)) > mdev->mc.vram_size) { + if ((mode->hdisplay * mode->vdisplay * (bpp/8)) > mdev->vram_fb_available) { if (connector->cmdline_mode.specified) connector->cmdline_mode.specified = false; return MODE_BAD; @@ -1663,16 +1638,6 @@ static enum drm_mode_status mga_vga_mode_valid(struct drm_connector *connector, return MODE_OK; } -static struct drm_encoder *mga_connector_best_encoder(struct drm_connector - *connector) -{ - int enc_id = connector->encoder_ids[0]; - /* pick the encoder ids */ - if (enc_id) - return drm_encoder_find(connector->dev, NULL, enc_id); - return NULL; -} - static void mga_connector_destroy(struct drm_connector *connector) { struct mga_connector *mga_connector = to_mga_connector(connector); @@ -1684,7 +1649,6 @@ static void mga_connector_destroy(struct drm_connector *connector) static const struct drm_connector_helper_funcs mga_vga_connector_helper_funcs = { .get_modes = mga_vga_get_modes, .mode_valid = mga_vga_mode_valid, - .best_encoder = mga_connector_best_encoder, }; static const struct drm_connector_funcs mga_vga_connector_funcs = { @@ -1703,18 +1667,19 @@ static struct drm_connector *mga_vga_init(struct drm_device *dev) return NULL; connector = &mga_connector->base; + mga_connector->i2c = mgag200_i2c_create(dev); + if (!mga_connector->i2c) + DRM_ERROR("failed to add ddc bus\n"); - drm_connector_init(dev, connector, - &mga_vga_connector_funcs, DRM_MODE_CONNECTOR_VGA); + drm_connector_init_with_ddc(dev, connector, + &mga_vga_connector_funcs, + DRM_MODE_CONNECTOR_VGA, + &mga_connector->i2c->adapter); drm_connector_helper_add(connector, &mga_vga_connector_helper_funcs); drm_connector_register(connector); - mga_connector->i2c = mgag200_i2c_create(dev); - if (!mga_connector->i2c) - DRM_ERROR("failed to add ddc bus\n"); - return connector; } @@ -1723,7 +1688,6 @@ int mgag200_modeset_init(struct mga_device *mdev) { struct drm_encoder *encoder; struct drm_connector *connector; - int ret; mdev->mode_info.mode_config_initialized = true; @@ -1748,12 +1712,6 @@ int mgag200_modeset_init(struct mga_device *mdev) drm_connector_attach_encoder(connector, encoder); - ret = mgag200_fbdev_init(mdev); - if (ret) { - DRM_ERROR("mga_fbdev_init failed\n"); - return ret; - } - return 0; } diff --git a/drivers/gpu/drm/mgag200/mgag200_ttm.c b/drivers/gpu/drm/mgag200/mgag200_ttm.c index 59294c0fd24a..e89657630ea7 100644 --- a/drivers/gpu/drm/mgag200/mgag200_ttm.c +++ b/drivers/gpu/drm/mgag200/mgag200_ttm.c @@ -25,7 +25,8 @@ /* * Authors: Dave Airlie <airlied@redhat.com> */ -#include <drm/drmP.h> + +#include <linux/pci.h> #include "mgag200_drv.h" @@ -36,8 +37,7 @@ int mgag200_mm_init(struct mga_device *mdev) struct drm_device *dev = mdev->dev; vmm = drm_vram_helper_alloc_mm(dev, pci_resource_start(dev->pdev, 0), - mdev->mc.vram_size, - &drm_gem_vram_mm_funcs); + mdev->mc.vram_size); if (IS_ERR(vmm)) { ret = PTR_ERR(vmm); DRM_ERROR("Error initializing VRAM MM; %d\n", ret); @@ -50,6 +50,8 @@ int mgag200_mm_init(struct mga_device *mdev) mdev->fb_mtrr = arch_phys_wc_add(pci_resource_start(dev->pdev, 0), pci_resource_len(dev->pdev, 0)); + mdev->vram_fb_available = mdev->mc.vram_size; + return 0; } @@ -57,6 +59,8 @@ void mgag200_mm_fini(struct mga_device *mdev) { struct drm_device *dev = mdev->dev; + mdev->vram_fb_available = 0; + drm_vram_helper_release_mm(dev); arch_io_free_memtype_wc(pci_resource_start(dev->pdev, 0), |