aboutsummaryrefslogtreecommitdiff
path: root/drivers/mfd/glamo
diff options
context:
space:
mode:
authorThomas White <taw@bitwiz.org.uk>2009-06-18 00:00:30 +0100
committerThomas White <taw@bitwiz.org.uk>2009-06-18 00:00:30 +0100
commit9f1ef16f2c739da94261ecb32a8ce96a62a94eac (patch)
treed2d8e4be55aa18ffd5803563a8ebc5768c80b569 /drivers/mfd/glamo
parentef859741e8baf985777015207041860cc42a2939 (diff)
More KMS plumbing
Signed-off-by: Thomas White <taw@bitwiz.org.uk>
Diffstat (limited to 'drivers/mfd/glamo')
-rw-r--r--drivers/mfd/glamo/glamo-buffer.c54
-rw-r--r--drivers/mfd/glamo/glamo-buffer.h3
-rw-r--r--drivers/mfd/glamo/glamo-display.c59
-rw-r--r--drivers/mfd/glamo/glamo-drm-drv.c16
-rw-r--r--drivers/mfd/glamo/glamo-kms-fb.c47
5 files changed, 115 insertions, 64 deletions
diff --git a/drivers/mfd/glamo/glamo-buffer.c b/drivers/mfd/glamo/glamo-buffer.c
index 945824a1b15..9f19c454477 100644
--- a/drivers/mfd/glamo/glamo-buffer.c
+++ b/drivers/mfd/glamo/glamo-buffer.c
@@ -27,49 +27,70 @@
#include "glamo-drm-private.h"
-int glamo_ioctl_gem_create(struct drm_device *dev, void *data,
- struct drm_file *file_priv)
+struct drm_gem_object *glamo_gem_object_alloc(struct drm_device *dev, int size,
+ int alignment)
{
- struct drm_glamo_gem_create *args = data;
struct drm_gem_object *obj;
struct glamodrm_handle *gdrm;
struct drm_glamo_gem_object *gobj;
- int handle, ret;
gdrm = dev->dev_private;
- args->size = roundup(args->size, PAGE_SIZE);
+ size = roundup(size, PAGE_SIZE);
- obj = drm_gem_object_alloc(dev, args->size);
- if (obj == NULL) return -ENOMEM;
+ obj = drm_gem_object_alloc(dev, size);
+ if (obj == NULL) return NULL;
gobj = obj->driver_private;
/* Allocate memory for this object in VRAM */
- gobj->block = drm_mm_search_free(gdrm->mmgr, args->size,
- args->alignment, 1);
+ gobj->block = drm_mm_search_free(gdrm->mmgr, size, alignment, 1);
if (!gobj->block) {
- ret = -ENOMEM;
goto fail;
}
- gobj->block = drm_mm_get_block(gobj->block, args->size,
- args->alignment);
+ gobj->block = drm_mm_get_block(gobj->block, size, alignment);
if (!gobj->block) {
- ret = -ENOMEM;
goto fail;
}
+ return obj;
+
+fail:
+ mutex_lock(&dev->struct_mutex);
+ drm_gem_object_unreference(obj);
+ mutex_unlock(&dev->struct_mutex);
+ printk(KERN_INFO "[glamo-drm] Failed to allocate object\n");
+
+ return NULL;
+}
+
+
+int glamo_ioctl_gem_create(struct drm_device *dev, void *data,
+ struct drm_file *file_priv)
+{
+ struct drm_glamo_gem_create *args = data;
+ struct drm_gem_object *obj;
+ struct drm_glamo_gem_object *gobj;
+ int handle, ret;
+
+ /* Create an object */
+ obj = glamo_gem_object_alloc(dev, args->size, args->alignment);
+ if ( obj == NULL ) return -ENOMEM;
+
+ /* Create a handle for it */
ret = drm_gem_handle_create(file_priv, obj, &handle);
mutex_lock(&dev->struct_mutex);
drm_gem_object_handle_unreference(obj);
mutex_unlock(&dev->struct_mutex);
-
if (ret) goto fail;
-
+
+ /* Watchpoint */
+ gobj = obj->driver_private;
printk(KERN_INFO "[glamo-drm] GEM object %i: %li bytes at 0x%lx\n",
handle, gobj->block->size, gobj->block->start);
+
+ /* Return */
args->handle = handle;
-
return 0;
fail:
@@ -77,7 +98,6 @@ fail:
drm_gem_object_unreference(obj);
mutex_unlock(&dev->struct_mutex);
printk(KERN_INFO "[glamo-drm] Failed to allocate object\n");
-
return ret;
}
diff --git a/drivers/mfd/glamo/glamo-buffer.h b/drivers/mfd/glamo/glamo-buffer.h
index 7d87e428d79..41f18fd7989 100644
--- a/drivers/mfd/glamo/glamo-buffer.h
+++ b/drivers/mfd/glamo/glamo-buffer.h
@@ -36,6 +36,9 @@ extern int glamodrm_gem_init_object(struct drm_gem_object *obj);
extern void glamodrm_gem_free_object(struct drm_gem_object *obj);
+extern struct drm_gem_object *glamo_gem_object_alloc(struct drm_device *dev,
+ int size, int alignment);
+
extern int glamo_ioctl_gem_create(struct drm_device *dev, void *data,
struct drm_file *file_priv);
diff --git a/drivers/mfd/glamo/glamo-display.c b/drivers/mfd/glamo/glamo-display.c
index 1ced367c4af..bcea62b2ed5 100644
--- a/drivers/mfd/glamo/glamo-display.c
+++ b/drivers/mfd/glamo/glamo-display.c
@@ -531,6 +531,30 @@ static const struct drm_mode_config_funcs glamo_mode_funcs = {
};
+static struct drm_mode_set kernelfb_mode;
+
+
+/* Restore's the kernel's fbcon mode, used for panic path */
+void glamo_display_restore(void)
+{
+ drm_crtc_helper_set_config(&kernelfb_mode);
+}
+
+
+static int glamo_display_panic(struct notifier_block *n, unsigned long ununsed,
+ void *panic_str)
+{
+ DRM_ERROR("panic occurred, switching back to text console\n");
+
+ glamo_display_restore();
+ return 0;
+}
+
+static struct notifier_block paniced = {
+ .notifier_call = glamo_display_panic,
+};
+
+
int glamo_display_init(struct drm_device *dev)
{
struct glamodrm_handle *gdrm;
@@ -538,6 +562,9 @@ int glamo_display_init(struct drm_device *dev)
struct glamo_output *glamo_output;
struct drm_connector *connector;
struct glamo_framebuffer *glamo_fb;
+ struct fb_info *info;
+ struct glamofb_par *par;
+ struct drm_mode_set *modeset;
gdrm = dev->dev_private;
@@ -550,7 +577,8 @@ int glamo_display_init(struct drm_device *dev)
dev->mode_config.funcs = (void *)&glamo_mode_funcs;
- /* Initialise our CRTC object */
+ /* Initialise our CRTC object.
+ * Only one connector per CRTC. We know this: it's kind of soldered. */
glamo_crtc = kzalloc(sizeof(struct glamo_crtc)
+ sizeof(struct drm_connector *), GFP_KERNEL);
if (glamo_crtc == NULL) return 1;
@@ -565,7 +593,7 @@ int glamo_display_init(struct drm_device *dev)
connector = &glamo_output->base;
/* Initialise the connector */
- drm_connector_init(dev, &glamo_output->base, &glamo_connector_funcs,
+ drm_connector_init(dev, connector, &glamo_connector_funcs,
DRM_MODE_CONNECTOR_Unknown);
drm_sysfs_connector_add(connector);
connector->interlace_allowed = 0;
@@ -591,5 +619,32 @@ int glamo_display_init(struct drm_device *dev)
ret = glamofb_create(dev, 480, 640, 480, 640, &glamo_fb);
if (ret) return -EINVAL;
}
+
+ info = glamo_fb->base.fbdev;
+ par = info->par;
+
+ modeset = &glamo_crtc->mode_set;
+ modeset->fb = &glamo_fb->base;
+// modeset->connectors[0] = connector;
+
+ //par->crtc_ids[0] = glamo_crtc->base.id;
+
+ modeset->num_connectors = 1;
+// modeset->mode = modeset->crtc->desired_mode;
+
+ par->crtc_count = 1;
+
+ info->var.pixclock = -1;
+ if (register_framebuffer(info) < 0)
+ return -EINVAL;
+
+ printk(KERN_INFO "fb%d: %s frame buffer device\n", info->node,
+ info->fix.id);
+
+ /* Switch back to kernel console on panic */
+ kernelfb_mode = *modeset;
+ atomic_notifier_chain_register(&panic_notifier_list, &paniced);
+ printk(KERN_INFO "registered panic notifier\n");
+
return 0;
}
diff --git a/drivers/mfd/glamo/glamo-drm-drv.c b/drivers/mfd/glamo/glamo-drm-drv.c
index dbcb8eb4ab5..b389325235c 100644
--- a/drivers/mfd/glamo/glamo-drm-drv.c
+++ b/drivers/mfd/glamo/glamo-drm-drv.c
@@ -263,12 +263,12 @@ static int glamodrm_probe(struct platform_device *pdev)
rc = -ENOENT;
goto out_unmap_regs;
}
- gdrm->vram_base = ioremap(gdrm->vram->start, RESSIZE(gdrm->vram));
- if ( !gdrm->vram_base ) {
- dev_err(&pdev->dev, "failed to ioremap() VRAM\n");
- rc = -ENOENT;
- goto out_release_vram;
- }
+// gdrm->vram_base = ioremap(gdrm->vram->start, RESSIZE(gdrm->vram));
+// if ( !gdrm->vram_base ) {
+// dev_err(&pdev->dev, "failed to ioremap() VRAM\n");
+// rc = -ENOENT;
+// goto out_release_vram;
+// }
/* Find the LCD controller */
gdrm->lcd_regs = platform_get_resource(pdev, IORESOURCE_MEM, 3);
@@ -308,7 +308,7 @@ out_unmap_cmdq:
out_release_cmdq:
release_mem_region(gdrm->cmdq->start, RESSIZE(gdrm->cmdq));
out_unmap_vram:
- iounmap(gdrm->vram_base);
+// iounmap(gdrm->vram_base);
out_release_vram:
release_mem_region(gdrm->vram->start, RESSIZE(gdrm->vram));
out_unmap_regs:
@@ -335,7 +335,7 @@ static int glamodrm_remove(struct platform_device *pdev)
release_mem_region(gdrm->reg->start, RESSIZE(gdrm->reg));
/* Release VRAM */
- iounmap(gdrm->vram_base);
+// iounmap(gdrm->vram_base);
release_mem_region(gdrm->vram->start, RESSIZE(gdrm->vram));
/* Release command queue */
diff --git a/drivers/mfd/glamo/glamo-kms-fb.c b/drivers/mfd/glamo/glamo-kms-fb.c
index 4a7c551c37d..440863dc1b4 100644
--- a/drivers/mfd/glamo/glamo-kms-fb.c
+++ b/drivers/mfd/glamo/glamo-kms-fb.c
@@ -62,6 +62,7 @@
#include "glamo-drm-private.h"
#include "glamo-regs.h"
#include "glamo-display.h"
+#include "glamo-buffer.h"
struct glamofb_par {
@@ -85,19 +86,6 @@ static int reg_read(struct glamodrm_handle *gdrm, u_int16_t reg)
}
-static void reg_write(struct glamodrm_handle *gdrm,
- u_int16_t reg, u_int16_t val)
-{
- int i = 0;
-
- for (i = 0; i != 2; i++)
- nop();
-
- iowrite16(val, gdrm->lcd_base + reg);
-}
-
-
-
static int glamofb_setcolreg(unsigned regno, unsigned red, unsigned green,
unsigned blue, unsigned transp,
struct fb_info *info)
@@ -374,6 +362,9 @@ static struct fb_ops glamofb_ops = {
};
+#define RESSIZE(ressource) (((ressource)->end - (ressource)->start)+1)
+
+
/* Here, we create a GEM object of the correct size, and then turn it into
* /dev/fbX so that the kernel can put a console on it. */
int glamofb_create(struct drm_device *dev, uint32_t fb_width,
@@ -392,8 +383,6 @@ int glamofb_create(struct drm_device *dev, uint32_t fb_width,
struct glamodrm_handle *gdrm;
int size, ret;
- printk(KERN_ERR "1\n");
-
gdrm = dev->dev_private;
mode_cmd.width = surface_width;
@@ -403,43 +392,35 @@ int glamofb_create(struct drm_device *dev, uint32_t fb_width,
mode_cmd.pitch = ALIGN(mode_cmd.width * ((mode_cmd.bpp + 1) / 8), 64);
mode_cmd.depth = 16;
- printk(KERN_ERR "2\n");
size = mode_cmd.pitch * mode_cmd.height;
size = ALIGN(size, PAGE_SIZE);
- fbo = drm_gem_object_alloc(dev, size);
- printk(KERN_ERR "3\n");
+ fbo = glamo_gem_object_alloc(dev, size, 2);
if (!fbo) {
printk(KERN_ERR "failed to allocate framebuffer\n");
ret = -ENOMEM;
goto out;
}
obj_priv = fbo->driver_private;
- printk(KERN_ERR "4\n");
-
+
mutex_lock(&dev->struct_mutex);
ret = glamo_framebuffer_create(dev, &mode_cmd, &fb, fbo);
- printk(KERN_ERR "5\n");
if (ret) {
DRM_ERROR("failed to allocate fb.\n");
goto out_unref;
}
- printk(KERN_ERR "6\n");
-
+
list_add(&fb->filp_head, &dev->mode_config.fb_kernel_list);
glamo_fb = to_glamo_framebuffer(fb);
*glamo_fb_p = glamo_fb;
- printk(KERN_ERR "7\n");
info = framebuffer_alloc(sizeof(struct glamofb_par), device);
- printk(KERN_ERR "8\n");
if (!info) {
ret = -ENOMEM;
goto out_unref;
}
- printk(KERN_ERR "9\n");
-
+
par = info->par;
strcpy(info->fix.id, "glamodrmfb");
@@ -451,7 +432,6 @@ int glamofb_create(struct drm_device *dev, uint32_t fb_width,
info->fix.ywrapstep = 0;
info->fix.accel = FB_ACCEL_I830;
info->fix.type_aux = 0;
- printk(KERN_ERR "10\n");
info->flags = FBINFO_DEFAULT;
info->fbops = &glamofb_ops;
@@ -463,7 +443,7 @@ int glamofb_create(struct drm_device *dev, uint32_t fb_width,
info->flags = FBINFO_DEFAULT;
- info->screen_base = ioremap_wc(gdrm->vram->start, size);
+ info->screen_base = ioremap(gdrm->vram->start, RESSIZE(gdrm->vram));
if (!info->screen_base) {
printk(KERN_ERR "[glamo-drm] Couldn't map framebuffer!\n");
ret = -ENOSPC;
@@ -480,7 +460,6 @@ int glamofb_create(struct drm_device *dev, uint32_t fb_width,
info->var.activate = FB_ACTIVATE_NOW;
info->var.height = -1;
info->var.width = -1;
- printk(KERN_ERR "11\n");
info->var.xres = fb_width;
info->var.yres = fb_height;
@@ -495,7 +474,7 @@ int glamofb_create(struct drm_device *dev, uint32_t fb_width,
switch (fb->depth) {
case 16:
- switch (reg_read(gdrm, GLAMO_REG_LCD_MODE3) & 0xc000) {
+ switch (reg_read(gdrm, GLAMO_REG_LCD_MODE3) & 0xc000) { /* FIXME */
case GLAMO_LCD_SRC_RGB565:
info->var.red.offset = 11;
info->var.green.offset = 5;
@@ -537,25 +516,19 @@ int glamofb_create(struct drm_device *dev, uint32_t fb_width,
}
fb->fbdev = info;
-printk(KERN_ERR "12\n");
par->glamo_fb = glamo_fb;
par->dev = dev;
/* To allow resizeing without swapping buffers */
printk("allocated %dx%d fb: bo %p\n", glamo_fb->base.width,
glamo_fb->base.height, fbo);
-printk(KERN_ERR "13\n");
mutex_unlock(&dev->struct_mutex);
return 0;
out_unref:
- printk(KERN_ERR "14\n");
drm_gem_object_unreference(fbo);
- printk(KERN_ERR "15\n");
mutex_unlock(&dev->struct_mutex);
- printk(KERN_ERR "16\n");
out:
- printk(KERN_ERR "7\n");
return ret;
}