add initial drm_fb framebuffer
So far I can load fbcon, once I use my miniglx to add a framebuffer. fbcon doesn't show anything on screen but baby steps and all that.main
parent
add7a928ad
commit
32f6a58db2
|
@ -14,7 +14,7 @@ drm-objs := drm_auth.o drm_bufs.o drm_context.o drm_dma.o drm_drawable.o \
|
|||
drm_memory_debug.o ati_pcigart.o drm_sman.o \
|
||||
drm_hashtab.o drm_mm.o drm_object.o drm_compat.o \
|
||||
drm_fence.o drm_ttm.o drm_bo.o drm_bo_move.o drm_crtc.o \
|
||||
drm_edid.o drm_modes.o
|
||||
drm_edid.o drm_modes.o drm_fb.o
|
||||
tdfx-objs := tdfx_drv.o
|
||||
r128-objs := r128_drv.o r128_cce.o r128_state.o r128_irq.o
|
||||
mga-objs := mga_drv.o mga_dma.o mga_state.o mga_warp.o mga_irq.o
|
||||
|
|
|
@ -1022,6 +1022,7 @@ int drm_mode_addfb(struct inode *inode, struct file *filp,
|
|||
if (copy_to_user(argp, &r, sizeof(r)))
|
||||
return -EFAULT;
|
||||
|
||||
drmfb_probe(dev, fb);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1040,6 +1041,7 @@ int drm_mode_rmfb(struct inode *inode, struct file *filp,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
drmfb_remove(dev, fb);
|
||||
/* TODO check if we own the buffer */
|
||||
/* TODO release all crtc connected to the framebuffer */
|
||||
/* bind the fb to the crtc for now */
|
||||
|
|
|
@ -11,6 +11,8 @@
|
|||
#include <linux/types.h>
|
||||
#include <linux/idr.h>
|
||||
|
||||
#include <linux/fb.h>
|
||||
|
||||
struct drm_device;
|
||||
|
||||
/*
|
||||
|
@ -179,6 +181,9 @@ struct drm_framebuffer {
|
|||
int bits_per_pixel;
|
||||
int flags;
|
||||
struct drm_buffer_object *bo;
|
||||
void *fbdev;
|
||||
u32 pseudo_palette[17];
|
||||
void *virtual_base;
|
||||
};
|
||||
struct drm_crtc;
|
||||
struct drm_output;
|
||||
|
@ -412,6 +417,7 @@ struct drm_mode_config {
|
|||
/* DamagePtr rotationDamage? */
|
||||
/* DGA stuff? */
|
||||
struct drm_mode_config_funcs *funcs;
|
||||
int fb_base;
|
||||
};
|
||||
|
||||
struct drm_output *drm_output_create(struct drm_device *dev,
|
||||
|
|
|
@ -0,0 +1,160 @@
|
|||
/*
|
||||
* Modularization
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/tty.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/fb.h>
|
||||
#include <linux/init.h>
|
||||
|
||||
#include "drmP.h"
|
||||
struct drmfb_par {
|
||||
struct drm_device *dev;
|
||||
struct drm_framebuffer *fb;
|
||||
};
|
||||
|
||||
static int drmfb_setcolreg(unsigned regno, unsigned red, unsigned green,
|
||||
unsigned blue, unsigned transp,
|
||||
struct fb_info *info)
|
||||
{
|
||||
struct drmfb_par *par = info->par;
|
||||
struct drm_framebuffer *fb = par->fb;
|
||||
if (regno > 17)
|
||||
return 1;
|
||||
|
||||
printk(KERN_INFO "Got set col reg %d %d %d %d\n", red, green, blue, regno);
|
||||
|
||||
if (regno < 16) {
|
||||
switch (fb->depth) {
|
||||
case 15:
|
||||
fb->pseudo_palette[regno] = ((red & 0xf800) >> 1) |
|
||||
((green & 0xf800) >> 6) |
|
||||
((blue & 0xf800) >> 11);
|
||||
break;
|
||||
case 16:
|
||||
fb->pseudo_palette[regno] = (red & 0xf800) |
|
||||
((green & 0xfc00) >> 5) |
|
||||
((blue & 0xf800) >> 11);
|
||||
break;
|
||||
case 24:
|
||||
fb->pseudo_palette[regno] = ((red & 0xff00) << 8) |
|
||||
(green & 0xff00) |
|
||||
((blue & 0xff00) >> 8);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct fb_ops drmfb_ops = {
|
||||
.owner = THIS_MODULE,
|
||||
// .fb_open = drmfb_open,
|
||||
// .fb_read = drmfb_read,
|
||||
// .fb_write = drmfb_write,
|
||||
// .fb_release = drmfb_release,
|
||||
// .fb_ioctl = drmfb_ioctl,
|
||||
.fb_setcolreg = drmfb_setcolreg,
|
||||
.fb_fillrect = cfb_fillrect,
|
||||
.fb_copyarea = cfb_copyarea,
|
||||
.fb_imageblit = cfb_imageblit,
|
||||
};
|
||||
|
||||
int drmfb_probe(struct drm_device *dev, struct drm_framebuffer *fb)
|
||||
{
|
||||
struct fb_info *info;
|
||||
struct drmfb_par *par;
|
||||
struct device *device = &dev->pdev->dev;
|
||||
struct fb_var_screeninfo *var_info;
|
||||
unsigned long base, size;
|
||||
|
||||
info = framebuffer_alloc(sizeof(struct drmfb_par), device);
|
||||
if (!info){
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
fb->fbdev = info;
|
||||
|
||||
par = info->par;
|
||||
|
||||
par->dev = dev;
|
||||
par->fb = fb;
|
||||
|
||||
info->fbops = &drmfb_ops;
|
||||
|
||||
strcpy(info->fix.id, "drmfb");
|
||||
info->fix.smem_start = fb->offset + dev->mode_config.fb_base;
|
||||
info->fix.smem_len = (8*1024*1024);
|
||||
info->fix.type = FB_TYPE_PACKED_PIXELS;
|
||||
info->fix.visual = FB_VISUAL_DIRECTCOLOR;
|
||||
info->fix.type_aux = 0;
|
||||
info->fix.mmio_start = 0;
|
||||
info->fix.mmio_len = 0;
|
||||
info->fix.line_length = fb->pitch;
|
||||
|
||||
info->flags = FBINFO_DEFAULT;
|
||||
|
||||
base = fb->bo->offset + dev->mode_config.fb_base;
|
||||
size = (fb->bo->mem.num_pages * PAGE_SIZE);
|
||||
|
||||
DRM_DEBUG("remapping %08X %d\n", base, size);
|
||||
fb->virtual_base = ioremap_nocache(base, size);
|
||||
|
||||
info->screen_base = fb->virtual_base;
|
||||
info->screen_size = size;
|
||||
info->pseudo_palette = fb->pseudo_palette;
|
||||
info->var.xres = fb->width;
|
||||
info->var.xres_virtual = fb->pitch;
|
||||
info->var.yres = fb->height;
|
||||
info->var.yres_virtual = fb->height;
|
||||
info->var.bits_per_pixel = fb->bits_per_pixel;
|
||||
info->var.xoffset = 0;
|
||||
info->var.yoffset = 0;
|
||||
|
||||
switch(fb->depth) {
|
||||
case 8:
|
||||
case 15:
|
||||
case 16:
|
||||
break;
|
||||
case 24:
|
||||
case 32:
|
||||
info->var.red.offset = 16;
|
||||
info->var.green.offset = 8;
|
||||
info->var.blue.offset = 0;
|
||||
info->var.red.length = info->var.green.length =
|
||||
info->var.blue.length = 8;
|
||||
if (fb->depth == 32) {
|
||||
info->var.transp.offset = 24;
|
||||
info->var.transp.length = 8;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (register_framebuffer(info) < 0)
|
||||
return -EINVAL;
|
||||
|
||||
printk(KERN_INFO "fb%d: %s frame buffer device\n", info->node,
|
||||
info->fix.id);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(drmfb_probe);
|
||||
|
||||
int drmfb_remove(struct drm_device *dev, struct drm_framebuffer *fb)
|
||||
{
|
||||
struct fb_info *info = fb->fbdev;
|
||||
|
||||
if (info) {
|
||||
iounmap(fb->virtual_base);
|
||||
unregister_framebuffer(info);
|
||||
framebuffer_release(info);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(drmfb_remove);
|
||||
MODULE_LICENSE("GPL");
|
|
@ -28,11 +28,11 @@ int i915_driver_load(drm_device_t *dev, unsigned long flags)
|
|||
if (IS_I9XX(dev)) {
|
||||
dev_priv->mmiobase = drm_get_resource_start(dev, 0);
|
||||
dev_priv->mmiolen = drm_get_resource_len(dev, 0);
|
||||
dev_priv->baseaddr = drm_get_resource_start(dev, 2) & 0xff000000;
|
||||
dev->mode_config.fb_base = dev_priv->baseaddr = drm_get_resource_start(dev, 2) & 0xff000000;
|
||||
} else if (drm_get_resource_start(dev, 1)) {
|
||||
dev_priv->mmiobase = drm_get_resource_start(dev, 1);
|
||||
dev_priv->mmiolen = drm_get_resource_len(dev, 1);
|
||||
dev_priv->baseaddr = drm_get_resource_start(dev, 0) & 0xff000000;
|
||||
dev->mode_config.fb_base = dev_priv->baseaddr = drm_get_resource_start(dev, 0) & 0xff000000;
|
||||
} else {
|
||||
DRM_ERROR("Unable to find MMIO registers\n");
|
||||
return -ENODEV;
|
||||
|
|
Loading…
Reference in New Issue