drm/glint: add bare TTM memory manager and framebuffer
The TTM code uses the drm_addmap hack, so I can get something on the
screen sooner rather than later.
Signed-off-by: Matt Turner <mattst88@gmail.com>
diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index 87e33ea..8bafa45 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -131,6 +131,11 @@
config DRM_GLINT
tristate "Permedia (GLint) 3/4 driver"
depends on DRM && AGP
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ select DRM_KMS_HELPER
+ select DRM_TTM
config DRM_MGA
tristate "Matrox g200/g400"
diff --git a/drivers/gpu/drm/glint/Makefile b/drivers/gpu/drm/glint/Makefile
index 27f4c94..f65d255 100644
--- a/drivers/gpu/drm/glint/Makefile
+++ b/drivers/gpu/drm/glint/Makefile
@@ -4,6 +4,7 @@
ccflags-y := -Iinclude/drm
glint-y := glint_crtc.o glint_dac.o glint_device.o glint_display.o \
- glint_drv.o glint_irq.o glint_kms.o glint_vga.o
+ glint_drv.o glint_fbdev.o glint_framebuffer.o \
+ glint_irq.o glint_kms.o glint_ttm.o glint_vga.o init_ttm.o
obj-$(CONFIG_DRM_GLINT) += glint.o
diff --git a/drivers/gpu/drm/glint/glint.h b/drivers/gpu/drm/glint/glint.h
index 243043b..c4dc408 100644
--- a/drivers/gpu/drm/glint/glint.h
+++ b/drivers/gpu/drm/glint/glint.h
@@ -4,11 +4,22 @@
#include "glint_family.h"
#include "glint_mode.h"
+#include <ttm/ttm_bo_api.h>
+#include <ttm/ttm_bo_driver.h>
+#include <ttm/ttm_placement.h>
+#include <ttm/ttm_module.h>
+#include <ttm/ttm_page_alloc.h>
+
+#define DRM_FILE_PAGE_OFFSET (0x100000000ULL >> PAGE_SHIFT)
+struct glint_mman {
+ struct ttm_global_reference mem_global_ref;
+ struct ttm_bo_global_ref bo_global_ref;
+ struct ttm_bo_device bdev;
+};
+
struct glint_mc {
- resource_size_t aper_size;
- resource_size_t aper_base;
- char __iomem *vram;
- u32 vram_size;
+ resource_size_t vram_size;
+ resource_size_t vram_base;
};
struct glint_device {
@@ -22,8 +33,11 @@
resource_size_t rmmio_size;
void __iomem *rmmio;
+ drm_local_map_t *framebuffer;
+
struct glint_mc mc;
struct glint_mode_info mode_info;
+ struct glint_mman mman;
int num_crtc;
};
diff --git a/drivers/gpu/drm/glint/glint_crtc.c b/drivers/gpu/drm/glint/glint_crtc.c
index 01f5a5f..ea60d37 100644
--- a/drivers/gpu/drm/glint/glint_crtc.c
+++ b/drivers/gpu/drm/glint/glint_crtc.c
@@ -167,3 +167,25 @@
drm_crtc_helper_add(&glint_crtc->base, &glint_helper_funcs);
}
+
+/** Sets the color ramps on behalf of fbcon */
+void glint_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
+ u16 blue, int regno)
+{
+ struct glint_crtc *glint_crtc = to_glint_crtc(crtc);
+
+ glint_crtc->lut_r[regno] = red;
+ glint_crtc->lut_g[regno] = green;
+ glint_crtc->lut_b[regno] = blue;
+}
+
+/** Gets the color ramps on behalf of fbcon */
+void glint_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green,
+ u16 *blue, int regno)
+{
+ struct glint_crtc *glint_crtc = to_glint_crtc(crtc);
+
+ *red = glint_crtc->lut_r[regno];
+ *green = glint_crtc->lut_g[regno];
+ *blue = glint_crtc->lut_b[regno];
+}
diff --git a/drivers/gpu/drm/glint/glint_device.c b/drivers/gpu/drm/glint/glint_device.c
index de5a428..cb8ecc8 100644
--- a/drivers/gpu/drm/glint/glint_device.c
+++ b/drivers/gpu/drm/glint/glint_device.c
@@ -12,13 +12,26 @@
u32 temp1, temp2;
u32 memsize = 0;
unsigned i;
- char __iomem *vram = gdev->mc.vram;
+ char __iomem *vram;
+
+ vram = ioremap(gdev->mc.vram_base, gdev->mc.vram_size);
+ if (!vram) {
+ GLINT_ERROR("Unable to ioremap %lu MB of VRAM. Retrying...\n", (unsigned long)gdev->mc.vram_size / MB);
+ gdev->mc.vram_size /= 2;
+ ioremap(gdev->mc.vram_base, gdev->mc.vram_size);
+ if (!vram) {
+ GLINT_ERROR("Unable to ioremap %lu MB of VRAM. Bailing out.\n", (unsigned long)gdev->mc.vram_size / MB);
+ return -1;
+ }
+ GLINT_INFO("ioremapped %lu MB of VRAM.\n", (unsigned long)gdev->mc.vram_size / MB);
+ }
+ GLINT_INFO("vram base: 0x%08X\n", (uint32_t)gdev->mc.vram_base);
WREG32(PM3MemBypassWriteMask, 0xffffffff);
#define TEST_PATTERN 0x00345678
for (i = 0; i < 32; i++) {
- iowrite32(i * TEST_PATTERN, gdev->mc.vram + (i * MB));
+ iowrite32(i * TEST_PATTERN, vram + (i * MB));
mb();
temp1 = ioread32(vram + (i * MB));
@@ -54,28 +67,52 @@
WREG32(PM3MemBypassWriteMask, tempBypass);
+ iounmap(vram);
+
return (memsize + 1) * MB;
}
static int glint_vram_init(struct glint_device *gdev)
{
- /* work out accessible VRAM */
- gdev->mc.aper_base = pci_resource_start(gdev->ddev->pdev, 1);
- gdev->mc.aper_size = pci_resource_len(gdev->ddev->pdev, 1);
+ unsigned size;
+ int ret;
- gdev->mc.vram = ioremap(gdev->mc.aper_base, gdev->mc.aper_size);
- if (!gdev->mc.vram) {
- GLINT_ERROR("Unable to ioremap %lu MB of VRAM. Retrying...\n", (unsigned long)gdev->mc.aper_size / MB);
- gdev->mc.aper_size /= 2;
- ioremap(gdev->mc.aper_base, gdev->mc.aper_size);
- if (!gdev->mc.vram) {
- GLINT_ERROR("Unable to ioremap %lu MB of VRAM. Bailing out.\n", (unsigned long)gdev->mc.aper_size / MB);
- return -1;
- }
- GLINT_INFO("ioremapped %lu MB of VRAM.\n", (unsigned long)gdev->mc.aper_size / MB);
- }
+ /* work out accessible VRAM */
+ gdev->mc.vram_base = pci_resource_start(gdev->ddev->pdev, 1);
+ gdev->mc.vram_size = pci_resource_len(gdev->ddev->pdev, 1);
+
gdev->mc.vram_size = glint_vram_size(gdev);
+ if (!request_region(gdev->mc.vram_base, gdev->mc.vram_size, "glintfb_vram")) {
+ GLINT_ERROR("can't region_reserve VRAM\n");
+ return -ENXIO;
+ }
+
+ ret = generic_ttm_global_init(&gdev->mman);
+ if (ret) {
+ GLINT_ERROR("failed to set up ttm\n");
+ return -1;
+ }
+
+ ret = ttm_bo_device_init(&gdev->mman.bdev,
+ gdev->mman.bo_global_ref.ref.object,
+ &glint_bo_driver, DRM_FILE_PAGE_OFFSET,
+ false);
+ if (ret) {
+ GLINT_ERROR("failed to set up buffer object driver: %d\n", ret);
+ return -1;
+ }
+
+ size = size & (PAGE_MASK << 1);
+ ret = ttm_bo_init_mm(&gdev->mman.bdev, TTM_PL_VRAM, size >> PAGE_SHIFT);
+ if (ret) {
+ GLINT_ERROR("failed vram init: %d\n", ret);
+ return -1;
+ }
+
+ ret = drm_addmap(gdev->ddev, gdev->mc.vram_base, gdev->mc.vram_size,
+ _DRM_FRAME_BUFFER, _DRM_WRITE_COMBINING,
+ &gdev->framebuffer);
return 0;
}
@@ -83,8 +120,10 @@
{
iounmap(gdev->rmmio);
gdev->rmmio = NULL;
- iounmap(gdev->mc.vram);
- gdev->mc.vram = NULL;
+ if (gdev->framebuffer)
+ drm_rmmap(gdev->ddev, gdev->framebuffer);
+ if (gdev->mc.vram_base)
+ release_region(gdev->mc.vram_base, gdev->mc.vram_size);
}
int glint_device_init(struct glint_device *gdev,
@@ -98,7 +137,7 @@
gdev->ddev = ddev;
gdev->pdev = pdev;
gdev->flags = flags;
- gdev->num_crtc = 2;
+ gdev->num_crtc = 1;
/* Registers mapping */
/* TODO: block userspace mapping of io register */
diff --git a/drivers/gpu/drm/glint/glint_display.c b/drivers/gpu/drm/glint/glint_display.c
index 50da039..db0dae6 100644
--- a/drivers/gpu/drm/glint/glint_display.c
+++ b/drivers/gpu/drm/glint/glint_display.c
@@ -9,6 +9,7 @@
{
struct drm_encoder *encoder;
struct drm_connector *connector;
+ int ret;
int i;
drm_mode_config_init(gdev->ddev);
@@ -17,7 +18,7 @@
gdev->ddev->mode_config.max_width = GLINT_MAX_FB_WIDTH;
gdev->ddev->mode_config.max_height = GLINT_MAX_FB_HEIGHT;
- gdev->ddev->mode_config.fb_base = gdev->mc.aper_base;
+ gdev->ddev->mode_config.fb_base = gdev->mc.vram_base;
/* allocate crtcs */
for (i = 0; i < gdev->num_crtc; i++) {
@@ -38,11 +39,19 @@
drm_mode_connector_attach_encoder(connector, encoder);
+ ret = glint_fbdev_init(gdev);
+ if (ret) {
+ GLINT_ERROR("glint_fbdev_init failed\n");
+ return ret;
+ }
+
return 0;
}
void glint_modeset_fini(struct glint_device *gdev)
{
+ glint_fbdev_fini(gdev);
+
if (gdev->mode_info.mode_config_initialized) {
drm_mode_config_cleanup(gdev->ddev);
gdev->mode_info.mode_config_initialized = false;
diff --git a/drivers/gpu/drm/glint/glint_drv.h b/drivers/gpu/drm/glint/glint_drv.h
index c48518c..0b962c3 100644
--- a/drivers/gpu/drm/glint/glint_drv.h
+++ b/drivers/gpu/drm/glint/glint_drv.h
@@ -33,6 +33,10 @@
#include "glint.h"
/* glint_crtc.c */
+void glint_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
+ u16 blue, int regno);
+void glint_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green,
+ u16 *blue, int regno);
void glint_crtc_init(struct drm_device *dev, int index);
/* glint_dac.c */
@@ -49,6 +53,15 @@
int glint_modeset_init(struct glint_device *gdev);
void glint_modeset_fini(struct glint_device *gdev);
+ /* glint_fbdev.c */
+int glint_fbdev_init(struct glint_device *gdev);
+void glint_fbdev_fini(struct glint_device *gdev);
+
+ /* glint_framebuffer.c */
+int glint_framebuffer_init(struct drm_device *dev,
+ struct glint_framebuffer *gfb,
+ struct drm_mode_fb_cmd *mode_cmd);
+
/* glint_irq.c */
void glint_driver_irq_preinstall(struct drm_device *dev);
int glint_driver_irq_postinstall(struct drm_device *dev);
@@ -61,7 +74,14 @@
extern struct drm_ioctl_desc glint_ioctls[];
extern int glint_max_ioctl;
+ /* glint_ttm.c */
+extern struct ttm_bo_driver glint_bo_driver;
+
/* glint_vga.c */
struct drm_connector *glint_vga_init(struct drm_device *dev);
+ /* init_ttm.c */
+void generic_ttm_global_release(struct glint_mman *ttm);
+int generic_ttm_global_init(struct glint_mman *ttm);
+
#endif /* __GLINT_DRV_H__ */
diff --git a/drivers/gpu/drm/glint/glint_fbdev.c b/drivers/gpu/drm/glint/glint_fbdev.c
new file mode 100644
index 0000000..faec453
--- /dev/null
+++ b/drivers/gpu/drm/glint/glint_fbdev.c
@@ -0,0 +1,211 @@
+#include "drmP.h"
+#include "drm.h"
+#include "drm_fb_helper.h"
+
+#include <linux/fb.h>
+
+#include "glint.h"
+#include "glint_drv.h"
+
+struct glint_fbdev {
+ struct drm_fb_helper helper;
+ struct glint_framebuffer gfb;
+ struct list_head fbdev_list;
+ struct glint_device *gdev;
+};
+
+static struct fb_ops glintfb_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_pan_display = drm_fb_helper_pan_display,
+ .fb_blank = drm_fb_helper_blank,
+ .fb_setcmap = drm_fb_helper_setcmap,
+};
+
+static int glintfb_create(struct glint_fbdev *gfbdev,
+ struct drm_fb_helper_surface_size *sizes)
+{
+ struct glint_device *gdev = gfbdev->gdev;
+ struct fb_info *info;
+ struct drm_framebuffer *fb;
+ struct drm_map_list *r_list, *list_t;
+ struct drm_local_map *map = NULL;
+ struct drm_mode_fb_cmd mode_cmd;
+ struct device *device = &gdev->pdev->dev;
+ int ret;
+
+ mode_cmd.width = sizes->surface_width;
+ mode_cmd.height = sizes->surface_height;
+ mode_cmd.bpp = sizes->surface_bpp;
+ mode_cmd.depth = sizes->surface_depth;
+ mode_cmd.pitch = mode_cmd.width * ((mode_cmd.bpp + 7) / 8);
+
+ info = framebuffer_alloc(0, device);
+ if (info == NULL)
+ return -ENOMEM;
+
+ info->par = gfbdev;
+
+ ret = glint_framebuffer_init(gdev->ddev, &gfbdev->gfb, &mode_cmd);
+ if (ret)
+ return ret;
+
+ fb = &gfbdev->gfb.base;
+ if (!fb) {
+ GLINT_INFO("fb is NULL\n");
+ }
+
+ /* setup helper */
+ gfbdev->helper.fb = fb;
+ gfbdev->helper.fbdev = info;
+
+ strcpy(info->fix.id, "glintdrmfb");
+
+ drm_fb_helper_fill_fix(info, fb->pitch, fb->depth);
+
+ info->flags = FBINFO_DEFAULT;
+ info->fbops = &glintfb_ops;
+
+ drm_fb_helper_fill_var(info, &gfbdev->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_iounmap;
+ }
+ info->apertures->ranges[0].base = gdev->ddev->mode_config.fb_base;
+ info->apertures->ranges[0].size = gdev->mc.vram_size;
+
+ list_for_each_entry_safe(r_list, list_t, &gdev->ddev->maplist, head) {
+ map = r_list->map;
+ if (map->type == _DRM_FRAME_BUFFER) {
+ map->handle = ioremap_nocache(map->offset, map->size);
+ if (!map->handle) {
+ GLINT_ERROR("fb: can't remap framebuffer\n");
+ return -1;
+ }
+ break;
+ }
+ }
+
+ info->fix.smem_start = map->offset;
+ info->fix.smem_len = map->size;
+ if (!info->fix.smem_len) {
+ GLINT_ERROR("%s: can't count memory\n", info->fix.id);
+ goto out_iounmap;
+ }
+ info->screen_base = map->handle;
+ if (!info->screen_base) {
+ GLINT_ERROR("%s: can't remap framebuffer\n", info->fix.id);
+ goto out_iounmap;
+ }
+
+ info->fix.mmio_start = 0;
+ info->fix.mmio_len = 0;
+
+ ret = fb_alloc_cmap(&info->cmap, 256, 0);
+ if (ret) {
+ GLINT_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);
+ DRM_INFO("fb depth is %d\n", fb->depth);
+ DRM_INFO(" pitch is %d\n", fb->pitch);
+
+ return 0;
+out_iounmap:
+ iounmap(map->handle);
+ return ret;
+}
+
+static int glint_fb_find_or_create_single(struct drm_fb_helper *helper,
+ struct drm_fb_helper_surface_size *sizes)
+{
+ struct glint_fbdev *gfbdev = (struct glint_fbdev *)helper;
+ int new_fb = 0;
+ int ret;
+
+ if (!helper->fb) {
+ ret = glintfb_create(gfbdev, sizes);
+ if (ret)
+ return ret;
+ new_fb = 1;
+ }
+ return new_fb;
+}
+
+static int glint_fbdev_destroy(struct drm_device *dev, struct glint_fbdev *gfbdev)
+{
+ struct fb_info *info;
+ struct glint_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_fini(&gfbdev->helper);
+ drm_framebuffer_cleanup(&gfb->base);
+
+ return 0;
+}
+
+static struct drm_fb_helper_funcs glint_fb_helper_funcs = {
+ .gamma_set = glint_crtc_fb_gamma_set,
+ .gamma_get = glint_crtc_fb_gamma_get,
+ .fb_probe = glint_fb_find_or_create_single,
+};
+
+int glint_fbdev_init(struct glint_device *gdev)
+{
+ struct glint_fbdev *gfbdev;
+ int bpp_sel = 32;
+ int ret;
+
+ /* select 8 bpp console on <= 32 MB cards */
+ if (gdev->mc.vram_size <= (32 * MB))
+ bpp_sel = 8;
+
+ gfbdev = kzalloc(sizeof(struct glint_fbdev), GFP_KERNEL);
+ if (!gfbdev)
+ return -ENOMEM;
+
+ gfbdev->gdev = gdev;
+ gdev->mode_info.gfbdev = gfbdev;
+ gfbdev->helper.funcs = &glint_fb_helper_funcs;
+
+ ret = drm_fb_helper_init(gdev->ddev, &gfbdev->helper,
+ gdev->num_crtc,
+ GLINTFB_CONN_LIMIT);
+ if (ret) {
+ kfree(gfbdev);
+ return ret;
+ }
+ drm_fb_helper_single_add_all_connectors(&gfbdev->helper);
+ drm_fb_helper_initial_config(&gfbdev->helper, bpp_sel);
+
+ return 0;
+}
+
+void glint_fbdev_fini(struct glint_device *gdev)
+{
+ if (!gdev->mode_info.gfbdev)
+ return;
+
+ glint_fbdev_destroy(gdev->ddev, gdev->mode_info.gfbdev);
+ kfree(gdev->mode_info.gfbdev);
+ gdev->mode_info.gfbdev = NULL;
+}
diff --git a/drivers/gpu/drm/glint/glint_framebuffer.c b/drivers/gpu/drm/glint/glint_framebuffer.c
new file mode 100644
index 0000000..e6d58ca
--- /dev/null
+++ b/drivers/gpu/drm/glint/glint_framebuffer.c
@@ -0,0 +1,37 @@
+#include "drmP.h"
+#include "drm.h"
+#include "drm_crtc_helper.h"
+
+#include "glint.h"
+#include "glint_drv.h"
+
+static void glint_user_framebuffer_destroy(struct drm_framebuffer *fb)
+{
+ drm_framebuffer_cleanup(fb);
+}
+
+static int glint_user_framebuffer_create_handle(struct drm_framebuffer *fb,
+ struct drm_file *file_priv,
+ unsigned int *handle)
+{
+ return 0;
+}
+
+static const struct drm_framebuffer_funcs glint_fb_funcs = {
+ .destroy = glint_user_framebuffer_destroy,
+ .create_handle = glint_user_framebuffer_create_handle,
+};
+
+int glint_framebuffer_init(struct drm_device *dev,
+ struct glint_framebuffer *gfb,
+ struct drm_mode_fb_cmd *mode_cmd)
+{
+ int ret = drm_framebuffer_init(dev, &gfb->base, &glint_fb_funcs);
+ if (ret) {
+ GLINT_ERROR("drm_framebuffer_init failed: %d\n", ret);
+ return ret;
+ }
+ drm_helper_mode_fill_fb_struct(&gfb->base, mode_cmd);
+
+ return 0;
+}
diff --git a/drivers/gpu/drm/glint/glint_mode.h b/drivers/gpu/drm/glint/glint_mode.h
index d0a2cc6..c6cbf00 100644
--- a/drivers/gpu/drm/glint/glint_mode.h
+++ b/drivers/gpu/drm/glint/glint_mode.h
@@ -11,6 +11,7 @@
#define to_glint_crtc(x) container_of(x, struct glint_crtc, base)
#define to_glint_encoder(x) container_of(x, struct glint_encoder, base)
+#define to_glint_framebuffer(x) container_of(x, struct glint_framebuffer, base)
struct glint_crtc {
struct drm_crtc base;
@@ -22,7 +23,9 @@
struct glint_mode_info {
bool mode_config_initialized;
- struct glint_crtc *crtcs[2]; /* FIXME: how many CRTCs? */
+ struct glint_crtc *crtcs[1]; /* FIXME: how many CRTCs? */
+ /* pointer to fbdev info structure */
+ struct glint_fbdev *gfbdev;
};
struct glint_encoder {
@@ -34,4 +37,8 @@
struct drm_connector base;
};
+struct glint_framebuffer {
+ struct drm_framebuffer base;
+};
+
#endif /* __GLINT_MODE_H__ */
diff --git a/drivers/gpu/drm/glint/glint_ttm.c b/drivers/gpu/drm/glint/glint_ttm.c
new file mode 100644
index 0000000..96a0396
--- /dev/null
+++ b/drivers/gpu/drm/glint/glint_ttm.c
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2010 James Simmons
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sub license,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "drmP.h"
+
+#include <ttm/ttm_bo_api.h>
+#include <ttm/ttm_bo_driver.h>
+#include <ttm/ttm_placement.h>
+#include <ttm/ttm_module.h>
+#include <ttm/ttm_page_alloc.h>
+
+#include "glint.h"
+
+static struct glint_device *glint_get_gdev(struct ttm_bo_device *bdev)
+{
+ struct glint_mman *mman;
+ struct glint_device *gdev;
+
+ mman = container_of(bdev, struct glint_mman, bdev);
+ gdev = container_of(mman, struct glint_device, mman);
+ return gdev;
+}
+
+static struct ttm_backend *
+glint_bo_create_ttm_backend_entry(struct ttm_bo_device *bdev)
+{
+ return NULL;
+}
+
+static int
+glint_bo_invalidate_caches(struct ttm_bo_device *bdev, uint32_t flags)
+{
+ return 0;
+}
+
+static int
+glint_bo_init_mem_type(struct ttm_bo_device *bdev, uint32_t type,
+ struct ttm_mem_type_manager *man)
+{
+ struct glint_device *gdev = glint_get_gdev(bdev);
+
+ switch (type) {
+ case TTM_PL_SYSTEM:
+ /* System memory */
+ man->flags = TTM_MEMTYPE_FLAG_MAPPABLE;
+ man->available_caching = TTM_PL_MASK_CACHING;
+ man->default_caching = TTM_PL_FLAG_CACHED;
+ break;
+ case TTM_PL_VRAM:
+ man->flags = TTM_MEMTYPE_FLAG_FIXED |
+ TTM_MEMTYPE_FLAG_MAPPABLE;
+ man->available_caching = TTM_PL_FLAG_UNCACHED |
+ TTM_PL_FLAG_WC;
+ man->default_caching = TTM_PL_FLAG_WC;
+ man->gpu_offset = gdev->mc.vram_base;
+ break;
+ default:
+ DRM_ERROR("Unsupported memory type %u\n", (unsigned)type);
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static void
+glint_bo_evict_flags(struct ttm_buffer_object *bo, struct ttm_placement *pl)
+{
+}
+
+static int
+glint_bo_move(struct ttm_buffer_object *bo, bool evict, bool intr,
+ bool no_wait_reserve, bool no_wait_gpu,
+ struct ttm_mem_reg *new_mem)
+{
+ return 0;
+}
+
+static int
+glint_bo_verify_access(struct ttm_buffer_object *bo, struct file *filp)
+{
+ return 0;
+}
+
+static int
+glint_ttm_io_mem_reserve(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem)
+{
+ return 0;
+}
+
+static void
+glint_ttm_io_mem_free(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem)
+{
+}
+
+static int
+glint_ttm_fault_reserve_notify(struct ttm_buffer_object *bo)
+{
+ return 0;
+}
+
+struct ttm_bo_driver glint_bo_driver = {
+ .create_ttm_backend_entry = glint_bo_create_ttm_backend_entry,
+ .invalidate_caches = glint_bo_invalidate_caches,
+ .init_mem_type = glint_bo_init_mem_type,
+ .evict_flags = glint_bo_evict_flags,
+ .move = glint_bo_move,
+ .verify_access = glint_bo_verify_access,
+ .fault_reserve_notify = &glint_ttm_fault_reserve_notify,
+ .io_mem_reserve = &glint_ttm_io_mem_reserve,
+ .io_mem_free = &glint_ttm_io_mem_free,
+};
diff --git a/drivers/gpu/drm/glint/init_ttm.c b/drivers/gpu/drm/glint/init_ttm.c
new file mode 100644
index 0000000..0b35382
--- /dev/null
+++ b/drivers/gpu/drm/glint/init_ttm.c
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2010 James Simmons
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sub license,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "drmP.h"
+
+#include "glint.h"
+
+#include <ttm/ttm_bo_api.h>
+#include <ttm/ttm_bo_driver.h>
+#include <ttm/ttm_placement.h>
+#include <ttm/ttm_module.h>
+#include <ttm/ttm_page_alloc.h>
+
+static int
+generic_ttm_mem_global_init(struct ttm_global_reference *ref)
+{
+ return ttm_mem_global_init(ref->object);
+}
+
+static void
+generic_ttm_mem_global_release(struct ttm_global_reference *ref)
+{
+ ttm_mem_global_release(ref->object);
+}
+
+void
+generic_ttm_global_release(struct glint_mman *ttm)
+{
+ if (ttm->mem_global_ref.release == NULL)
+ return;
+
+ ttm_global_item_unref(&ttm->bo_global_ref.ref);
+ ttm_global_item_unref(&ttm->mem_global_ref);
+ ttm->mem_global_ref.release = NULL;
+}
+
+int
+generic_ttm_global_init(struct glint_mman *ttm)
+{
+ struct ttm_global_reference *global_ref;
+ int r;
+
+ global_ref = &ttm->mem_global_ref;
+ global_ref->global_type = TTM_GLOBAL_TTM_MEM;
+ global_ref->size = sizeof(struct ttm_mem_global);
+ global_ref->init = &generic_ttm_mem_global_init;
+ global_ref->release = &generic_ttm_mem_global_release;
+ r = ttm_global_item_ref(global_ref);
+ if (r != 0) {
+ DRM_ERROR("Failed setting up TTM memory accounting "
+ "subsystem.\n");
+ return r;
+ }
+
+ ttm->bo_global_ref.mem_glob = ttm->mem_global_ref.object;
+ global_ref = &ttm->bo_global_ref.ref;
+ global_ref->global_type = TTM_GLOBAL_TTM_BO;
+ global_ref->size = sizeof(struct ttm_bo_global);
+ global_ref->init = &ttm_bo_global_init;
+ global_ref->release = &ttm_bo_global_release;
+ r = ttm_global_item_ref(global_ref);
+ if (r != 0) {
+ DRM_ERROR("Failed setting up TTM BO subsystem.\n");
+ ttm_global_item_unref(&ttm->mem_global_ref);
+ return r;
+ }
+
+ return 0;
+}