From 9f1ef16f2c739da94261ecb32a8ce96a62a94eac Mon Sep 17 00:00:00 2001 From: Thomas White Date: Thu, 18 Jun 2009 00:00:30 +0100 Subject: More KMS plumbing Signed-off-by: Thomas White --- drivers/mfd/glamo/glamo-buffer.c | 54 ++++++++++++++++++++++++----------- drivers/mfd/glamo/glamo-buffer.h | 3 ++ drivers/mfd/glamo/glamo-display.c | 59 +++++++++++++++++++++++++++++++++++++-- drivers/mfd/glamo/glamo-drm-drv.c | 16 +++++------ drivers/mfd/glamo/glamo-kms-fb.c | 47 +++++++------------------------ 5 files changed, 115 insertions(+), 64 deletions(-) (limited to 'drivers/mfd/glamo') 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; } -- cgit v1.2.3