summaryrefslogtreecommitdiffstats
path: root/sys/dev/drm2
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2014-03-06 18:30:56 +0000
committerjhb <jhb@FreeBSD.org>2014-03-06 18:30:56 +0000
commit59b6242e909c7e020d7903a27847e2a465486a45 (patch)
tree2c015c503188a6a75426ca67e8433237f3533f97 /sys/dev/drm2
parentfe643776c1c5732c2d5d8354a64b520b7007e15c (diff)
downloadFreeBSD-src-59b6242e909c7e020d7903a27847e2a465486a45.zip
FreeBSD-src-59b6242e909c7e020d7903a27847e2a465486a45.tar.gz
MFC 259016,259019,259049,259071,259102,259110,259129,259130,259178,259179,
259203,259221,259261,259532,259615,259650,259651,259667,259680,259727, 259761,259772,259776,259777,259830,259882,259915,260160,260449,260450, 260688,260888,260953,261269,261547,261551,261552,261553,261585: Merge the vt(4) driver (newcons) to stable/10. Approved by: ray
Diffstat (limited to 'sys/dev/drm2')
-rw-r--r--sys/dev/drm2/drmP.h1
-rw-r--r--sys/dev/drm2/drm_fb_helper.c79
-rw-r--r--sys/dev/drm2/drm_os_freebsd.h2
-rw-r--r--sys/dev/drm2/i915/i915_drv.c25
-rw-r--r--sys/dev/drm2/i915/intel_fb.c19
-rw-r--r--sys/dev/drm2/radeon/radeon.h3
-rw-r--r--sys/dev/drm2/radeon/radeon_drv.c7
-rw-r--r--sys/dev/drm2/radeon/radeon_fb.c105
-rw-r--r--sys/dev/drm2/radeon/radeon_pm.c6
9 files changed, 164 insertions, 83 deletions
diff --git a/sys/dev/drm2/drmP.h b/sys/dev/drm2/drmP.h
index fe2ee86..c724a2dc 100644
--- a/sys/dev/drm2/drmP.h
+++ b/sys/dev/drm2/drmP.h
@@ -113,6 +113,7 @@ struct drm_device;
#include "opt_compat.h"
#include "opt_drm.h"
+#include "opt_syscons.h"
#ifdef DRM_DEBUG
#undef DRM_DEBUG
#define DRM_DEBUG_DEFAULT_ON 1
diff --git a/sys/dev/drm2/drm_fb_helper.c b/sys/dev/drm2/drm_fb_helper.c
index 37b50cf..d797502 100644
--- a/sys/dev/drm2/drm_fb_helper.c
+++ b/sys/dev/drm2/drm_fb_helper.c
@@ -36,6 +36,41 @@ __FBSDID("$FreeBSD$");
#include <dev/drm2/drm_fb_helper.h>
#include <dev/drm2/drm_crtc_helper.h>
+#if defined(__FreeBSD__)
+struct vt_kms_softc {
+ struct drm_fb_helper *fb_helper;
+ struct task fb_mode_task;
+};
+
+static fb_enter_t vt_kms_postswitch;
+static void vt_restore_fbdev_mode(void *, int);
+
+/* Call restore out of vt(9) locks. */
+static void
+vt_restore_fbdev_mode(void *arg, int pending)
+{
+ struct drm_fb_helper *fb_helper;
+ struct vt_kms_softc *sc;
+
+ sc = (struct vt_kms_softc *)arg;
+ fb_helper = sc->fb_helper;
+ sx_xlock(&fb_helper->dev->mode_config.mutex);
+ drm_fb_helper_restore_fbdev_mode(fb_helper);
+ sx_xunlock(&fb_helper->dev->mode_config.mutex);
+}
+
+static int
+vt_kms_postswitch(void *arg)
+{
+ struct vt_kms_softc *sc;
+
+ sc = (struct vt_kms_softc *)arg;
+ taskqueue_enqueue_fast(taskqueue_thread, &sc->fb_mode_task);
+
+ return (0);
+}
+#endif
+
static DRM_LIST_HEAD(kernel_fb_helper_list);
/* simple single crtc case helper function */
@@ -216,6 +251,10 @@ static int
fb_get_options(const char *connector_name, char **option)
{
+ /*
+ * TODO: store mode options pointer in ${option} for connector with
+ * name ${connector_name}
+ */
return (1);
}
@@ -892,11 +931,13 @@ int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper,
int new_fb = 0;
int crtc_count = 0;
int i;
-#if 0
struct fb_info *info;
-#endif
struct drm_fb_helper_surface_size sizes;
int gamma_size = 0;
+#if defined(__FreeBSD__)
+ struct vt_kms_softc *sc;
+ device_t kdev;
+#endif
memset(&sizes, 0, sizeof(struct drm_fb_helper_surface_size));
sizes.surface_depth = 24;
@@ -973,8 +1014,21 @@ int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper,
if (new_fb < 0)
return new_fb;
-#if 0
+#if defined(__FreeBSD__)
+ sc = malloc(sizeof(struct vt_kms_softc), DRM_MEM_KMS,
+ M_WAITOK | M_ZERO);
+ sc->fb_helper = fb_helper;
+ TASK_INIT(&sc->fb_mode_task, 0, vt_restore_fbdev_mode, sc);
+
info = fb_helper->fbdev;
+
+ info->fb_name = device_get_nameunit(fb_helper->dev->device);
+ info->fb_depth = fb_helper->fb->bits_per_pixel;
+ info->fb_height = fb_helper->fb->height;
+ info->fb_width = fb_helper->fb->width;
+ info->fb_stride = fb_helper->fb->pitches[0];
+ info->fb_priv = sc;
+ info->enter = &vt_kms_postswitch;
#endif
/* set the fb pointer */
@@ -982,7 +1036,23 @@ int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper,
fb_helper->crtc_info[i].mode_set.fb = fb_helper->fb;
}
-#if 0
+#if defined(__FreeBSD__)
+ if (new_fb) {
+ device_t fbd;
+ int ret;
+
+ kdev = fb_helper->dev->device;
+ fbd = device_add_child(kdev, "fbd", device_get_unit(kdev));
+ if (fbd != NULL)
+ ret = device_probe_and_attach(fbd);
+ else
+ ret = ENODEV;
+#ifdef DEV_VT
+ if (ret != 0)
+ DRM_ERROR("Failed to attach fbd device: %d\n", ret);
+#endif
+ }
+#else
if (new_fb) {
info->var.pixclock = 0;
if (register_framebuffer(info) < 0) {
@@ -1006,7 +1076,6 @@ int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper,
if (new_fb)
list_add(&fb_helper->kernel_fb_list, &kernel_fb_helper_list);
#endif
-
return 0;
}
diff --git a/sys/dev/drm2/drm_os_freebsd.h b/sys/dev/drm2/drm_os_freebsd.h
index d3d987a..af03f8d 100644
--- a/sys/dev/drm2/drm_os_freebsd.h
+++ b/sys/dev/drm2/drm_os_freebsd.h
@@ -6,6 +6,8 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
+#include <sys/fbio.h>
+
#if _BYTE_ORDER == _BIG_ENDIAN
#define __BIG_ENDIAN 4321
#else
diff --git a/sys/dev/drm2/i915/i915_drv.c b/sys/dev/drm2/i915/i915_drv.c
index a6bbb7d..85ac10e 100644
--- a/sys/dev/drm2/i915/i915_drv.c
+++ b/sys/dev/drm2/i915/i915_drv.c
@@ -40,6 +40,8 @@ __FBSDID("$FreeBSD$");
#include <dev/drm2/drm_pciids.h>
#include <dev/drm2/i915/intel_drv.h>
+#include "fb_if.h"
+
/* drv_PCI_IDs comes from drm_pciids.h, generated from drm_pciids.txt. */
static drm_pci_id_list_t i915_pciidlist[] = {
i915_PCI_IDS
@@ -380,6 +382,25 @@ i915_attach(device_t kdev)
return (drm_attach(kdev, i915_pciidlist));
}
+static struct fb_info *
+i915_fb_helper_getinfo(device_t kdev)
+{
+ struct intel_fbdev *ifbdev;
+ drm_i915_private_t *dev_priv;
+ struct drm_device *dev;
+ struct fb_info *info;
+
+ dev = device_get_softc(kdev);
+ dev_priv = dev->dev_private;
+ ifbdev = dev_priv->fbdev;
+ if (ifbdev == NULL)
+ return (NULL);
+
+ info = ifbdev->helper.fbdev;
+
+ return (info);
+}
+
const struct intel_device_info *
i915_get_device_id(int device)
{
@@ -400,6 +421,10 @@ static device_method_t i915_methods[] = {
DEVMETHOD(device_suspend, i915_suspend),
DEVMETHOD(device_resume, i915_resume),
DEVMETHOD(device_detach, drm_detach),
+
+ /* Framebuffer service methods */
+ DEVMETHOD(fb_getinfo, i915_fb_helper_getinfo),
+
DEVMETHOD_END
};
diff --git a/sys/dev/drm2/i915/intel_fb.c b/sys/dev/drm2/i915/intel_fb.c
index e41a49f..2957920 100644
--- a/sys/dev/drm2/i915/intel_fb.c
+++ b/sys/dev/drm2/i915/intel_fb.c
@@ -41,8 +41,8 @@ static int intelfb_create(struct intel_fbdev *ifbdev,
struct drm_device *dev = ifbdev->helper.dev;
#if 0
struct drm_i915_private *dev_priv = dev->dev_private;
- struct fb_info *info;
#endif
+ struct fb_info *info;
struct drm_framebuffer *fb;
struct drm_mode_fb_cmd2 mode_cmd;
struct drm_i915_gem_object *obj;
@@ -86,6 +86,16 @@ static int intelfb_create(struct intel_fbdev *ifbdev,
}
info->par = ifbdev;
+#else
+ info = malloc(sizeof(struct fb_info), DRM_MEM_KMS, M_WAITOK | M_ZERO);
+ info->fb_size = size;
+ info->fb_bpp = sizes->surface_bpp;
+ info->fb_width = sizes->fb_width;
+ info->fb_height = sizes->fb_height;
+ info->fb_pbase = dev->agp->base + obj->gtt_offset;
+ info->fb_vbase = (vm_offset_t)pmap_mapdev_attr(info->fb_pbase, size,
+ PAT_WRITE_COMBINING);
+
#endif
ret = intel_framebuffer_init(dev, &ifbdev->ifb, &mode_cmd, obj);
@@ -95,8 +105,8 @@ static int intelfb_create(struct intel_fbdev *ifbdev,
fb = &ifbdev->ifb.base;
ifbdev->helper.fb = fb;
-#if 0
ifbdev->helper.fbdev = info;
+#if 0
strcpy(info->fix.id, "inteldrmfb");
@@ -135,9 +145,8 @@ static int intelfb_create(struct intel_fbdev *ifbdev,
/* Use default scratch pixmap (info->pixmap.flags = FB_PIXMAP_SYSTEM) */
#endif
-
- DRM_DEBUG_KMS("allocated %dx%d fb: 0x%08x, bo %p\n",
- fb->width, fb->height,
+ DRM_DEBUG_KMS("allocated %dx%d (s %dbits) fb: 0x%08x, bo %p\n",
+ fb->width, fb->height, fb->depth,
obj->gtt_offset, obj);
DRM_UNLOCK(dev);
diff --git a/sys/dev/drm2/radeon/radeon.h b/sys/dev/drm2/radeon/radeon.h
index 88a5c5a..aabe9aa 100644
--- a/sys/dev/drm2/radeon/radeon.h
+++ b/sys/dev/drm2/radeon/radeon.h
@@ -2041,6 +2041,9 @@ void radeon_pm_acpi_event_handler(struct radeon_device *rdev);
int radeon_ttm_init(struct radeon_device *rdev);
void radeon_ttm_fini(struct radeon_device *rdev);
+/* radeon_fb.c */
+struct fb_info * radeon_fb_helper_getinfo(device_t kdev);
+
/* r600.c */
int r600_ih_ring_alloc(struct radeon_device *rdev);
void r600_ih_ring_fini(struct radeon_device *rdev);
diff --git a/sys/dev/drm2/radeon/radeon_drv.c b/sys/dev/drm2/radeon/radeon_drv.c
index 3156e38..0cf96d2 100644
--- a/sys/dev/drm2/radeon/radeon_drv.c
+++ b/sys/dev/drm2/radeon/radeon_drv.c
@@ -41,6 +41,7 @@ __FBSDID("$FreeBSD$");
#include <dev/drm2/drm_pciids.h>
+#include "fb_if.h"
/*
* KMS wrapper.
@@ -495,6 +496,8 @@ radeon_resume(device_t kdev)
return (-ret);
}
+extern struct fb_info * radeon_fb_helper_getinfo(device_t kdev);
+
static device_method_t radeon_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, radeon_probe),
@@ -502,6 +505,10 @@ static device_method_t radeon_methods[] = {
DEVMETHOD(device_suspend, radeon_suspend),
DEVMETHOD(device_resume, radeon_resume),
DEVMETHOD(device_detach, drm_detach),
+
+ /* Framebuffer service methods */
+ DEVMETHOD(fb_getinfo, radeon_fb_helper_getinfo),
+
DEVMETHOD_END
};
diff --git a/sys/dev/drm2/radeon/radeon_fb.c b/sys/dev/drm2/radeon/radeon_fb.c
index fc247e2..ec5b2e8 100644
--- a/sys/dev/drm2/radeon/radeon_fb.c
+++ b/sys/dev/drm2/radeon/radeon_fb.c
@@ -27,6 +27,8 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
+#include <machine/_inttypes.h>
+
#include <dev/drm2/drmP.h>
#include <dev/drm2/drm_crtc.h>
#include <dev/drm2/drm_crtc_helper.h>
@@ -46,7 +48,7 @@ struct radeon_fbdev {
struct radeon_device *rdev;
};
-#ifdef DUMBBELL_WIP
+#if defined(__linux__)
static struct fb_ops radeonfb_ops = {
.owner = THIS_MODULE,
.fb_check_var = drm_fb_helper_check_var,
@@ -60,7 +62,7 @@ static struct fb_ops radeonfb_ops = {
.fb_debug_enter = drm_fb_helper_debug_enter,
.fb_debug_leave = drm_fb_helper_debug_leave,
};
-#endif /* DUMBBELL_WIP */
+#endif
int radeon_align_pitch(struct radeon_device *rdev, int width, int bpp, bool tiled)
@@ -191,20 +193,13 @@ static int radeonfb_create(struct radeon_fbdev *rfbdev,
struct drm_fb_helper_surface_size *sizes)
{
struct radeon_device *rdev = rfbdev->rdev;
-#ifdef DUMBBELL_WIP
struct fb_info *info;
-#endif /* DUMBBELL_WIP */
struct drm_framebuffer *fb = NULL;
struct drm_mode_fb_cmd2 mode_cmd;
struct drm_gem_object *gobj = NULL;
struct radeon_bo *rbo = NULL;
-#ifdef DUMBBELL_WIP
- device_t device = rdev->dev;
-#endif /* DUMBBELL_WIP */
int ret;
-#ifdef DUMBBELL_WIP
unsigned long tmp;
-#endif /* DUMBBELL_WIP */
mode_cmd.width = sizes->surface_width;
mode_cmd.height = sizes->surface_height;
@@ -224,16 +219,7 @@ static int radeonfb_create(struct radeon_fbdev *rfbdev,
rbo = gem_to_radeon_bo(gobj);
-#ifdef DUMBBELL_WIP
- /* okay we have an object now allocate the framebuffer */
- info = framebuffer_alloc(0, device);
- if (info == NULL) {
- ret = -ENOMEM;
- goto out_unref;
- }
-
- info->par = rfbdev;
-#endif /* DUMBBELL_WIP */
+ info = malloc(sizeof(*info), DRM_MEM_KMS, M_WAITOK | M_ZERO);
ret = radeon_framebuffer_init(rdev->ddev, &rfbdev->rfb, &mode_cmd, gobj);
if (ret) {
@@ -245,61 +231,29 @@ static int radeonfb_create(struct radeon_fbdev *rfbdev,
/* setup helper */
rfbdev->helper.fb = fb;
-#ifdef DUMBBELL_WIP
rfbdev->helper.fbdev = info;
- memset_io(rbo->kptr, 0x0, radeon_bo_size(rbo));
-
- strcpy(info->fix.id, "radeondrmfb");
-
- drm_fb_helper_fill_fix(info, fb->pitches[0], fb->depth);
-
- info->flags = FBINFO_DEFAULT | FBINFO_CAN_FORCE_OUTPUT;
- info->fbops = &radeonfb_ops;
+ memset(rbo->kptr, 0x0, radeon_bo_size(rbo));
tmp = radeon_bo_gpu_offset(rbo) - rdev->mc.vram_start;
- info->fix.smem_start = rdev->mc.aper_base + tmp;
- info->fix.smem_len = radeon_bo_size(rbo);
- info->screen_base = rbo->kptr;
- info->screen_size = radeon_bo_size(rbo);
-
- 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 = rdev->ddev->mode_config.fb_base;
- info->apertures->ranges[0].size = rdev->mc.aper_size;
-
- /* Use default scratch pixmap (info->pixmap.flags = FB_PIXMAP_SYSTEM) */
-
- 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;
- }
-
- DRM_INFO("fb mappable at 0x%lX\n", info->fix.smem_start);
+ info->fb_size = radeon_bo_size(rbo);
+ info->fb_bpp = sizes->surface_bpp;
+ info->fb_width = sizes->surface_width;
+ info->fb_height = sizes->surface_height;
+ info->fb_pbase = rdev->mc.aper_base + tmp;
+ info->fb_vbase = (vm_offset_t)rbo->kptr;
+
+ DRM_INFO("fb mappable at 0x%" PRIXPTR "\n", info->fb_pbase);
DRM_INFO("vram apper at 0x%lX\n", (unsigned long)rdev->mc.aper_base);
DRM_INFO("size %lu\n", (unsigned long)radeon_bo_size(rbo));
DRM_INFO("fb depth is %d\n", fb->depth);
DRM_INFO(" pitch is %d\n", fb->pitches[0]);
- vga_switcheroo_client_fb_set(rdev->ddev->pdev, info);
-#endif /* DUMBBELL_WIP */
return 0;
out_unref:
if (rbo) {
-
+ /* TODO? dumbbell@ */
}
if (fb && ret) {
drm_gem_object_unreference(gobj);
@@ -332,21 +286,13 @@ void radeon_fb_output_poll_changed(struct radeon_device *rdev)
static int radeon_fbdev_destroy(struct drm_device *dev, struct radeon_fbdev *rfbdev)
{
-#ifdef DUMBBELL_WIP
struct fb_info *info;
-#endif /* DUMBBELL_WIP */
struct radeon_framebuffer *rfb = &rfbdev->rfb;
-#ifdef DUMBBELL_WIP
if (rfbdev->helper.fbdev) {
info = rfbdev->helper.fbdev;
-
- unregister_framebuffer(info);
- if (info->cmap.len)
- fb_dealloc_cmap(&info->cmap);
- framebuffer_release(info);
+ free(info, DRM_MEM_KMS);
}
-#endif /* DUMBBELL_WIP */
if (rfb->obj) {
DRM_UNLOCK(dev); /* Work around lock recursion. dumbbell@ */
@@ -431,3 +377,22 @@ bool radeon_fbdev_robj_is_fb(struct radeon_device *rdev, struct radeon_bo *robj)
return true;
return false;
}
+
+struct fb_info *
+radeon_fb_helper_getinfo(device_t kdev)
+{
+ struct drm_device *dev;
+ struct radeon_device *rdev;
+ struct radeon_fbdev *rfbdev;
+ struct fb_info *info;
+
+ dev = device_get_softc(kdev);
+ rdev = dev->dev_private;
+ rfbdev = rdev->mode_info.rfbdev;
+ if (rfbdev == NULL)
+ return (NULL);
+
+ info = rfbdev->helper.fbdev;
+
+ return (info);
+}
diff --git a/sys/dev/drm2/radeon/radeon_pm.c b/sys/dev/drm2/radeon/radeon_pm.c
index 47042db..0caa1b7 100644
--- a/sys/dev/drm2/radeon/radeon_pm.c
+++ b/sys/dev/drm2/radeon/radeon_pm.c
@@ -248,7 +248,7 @@ static void radeon_pm_set_clocks(struct radeon_device *rdev)
(rdev->pm.requested_power_state_index == rdev->pm.current_power_state_index))
return;
- DRM_LOCK(rdev->ddev);
+ //DRM_LOCK(rdev->ddev); XXX Recursion, already locked in drm_attach/drm_load -- dumbbell@
sx_xlock(&rdev->pm.mclk_lock);
sx_xlock(&rdev->ring_lock);
@@ -263,7 +263,7 @@ static void radeon_pm_set_clocks(struct radeon_device *rdev)
/* needs a GPU reset dont reset here */
sx_xunlock(&rdev->ring_lock);
sx_xunlock(&rdev->pm.mclk_lock);
- DRM_UNLOCK(rdev->ddev);
+ //DRM_UNLOCK(rdev->ddev); XXX Recursion, already locked in drm_attach/drm_load -- dumbbell@
return;
}
}
@@ -299,7 +299,7 @@ static void radeon_pm_set_clocks(struct radeon_device *rdev)
sx_xunlock(&rdev->ring_lock);
sx_xunlock(&rdev->pm.mclk_lock);
- DRM_UNLOCK(rdev->ddev);
+ //DRM_UNLOCK(rdev->ddev); XXX Recursion, already locked in drm_attach/drm_load -- dumbbell@
}
static void radeon_pm_print_states(struct radeon_device *rdev)
OpenPOWER on IntegriCloud