Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 307384
b: refs/heads/master
c: f9aa76a
h: refs/heads/master
v: v3
  • Loading branch information
Dave Airlie committed May 17, 2012
1 parent 4dc9ef1 commit fc474bf
Show file tree
Hide file tree
Showing 11 changed files with 2,096 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 414c453106255b11df77ed6b08eedb6d2369c338
refs/heads/master: f9aa76a85248565ff13dc0e10633c4343a059f71
2 changes: 2 additions & 0 deletions trunk/drivers/gpu/drm/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -190,3 +190,5 @@ source "drivers/gpu/drm/udl/Kconfig"
source "drivers/gpu/drm/ast/Kconfig"

source "drivers/gpu/drm/mgag200/Kconfig"

source "drivers/gpu/drm/cirrus/Kconfig"
1 change: 1 addition & 0 deletions trunk/drivers/gpu/drm/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ obj-$(CONFIG_DRM_MGA) += mga/
obj-$(CONFIG_DRM_I810) += i810/
obj-$(CONFIG_DRM_I915) += i915/
obj-$(CONFIG_DRM_MGAG200) += mgag200/
obj-$(CONFIG_DRM_CIRRUS_QEMU) += cirrus/
obj-$(CONFIG_DRM_SIS) += sis/
obj-$(CONFIG_DRM_SAVAGE)+= savage/
obj-$(CONFIG_DRM_VMWGFX)+= vmwgfx/
Expand Down
11 changes: 11 additions & 0 deletions trunk/drivers/gpu/drm/cirrus/Kconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
config DRM_CIRRUS_QEMU
tristate "Cirrus driver for QEMU emulated device"
depends on DRM && PCI && EXPERIMENTAL
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
select DRM_KMS_HELPER
help
This is a KMS driver for emulated cirrus device in qemu.
It is *NOT* intended for real cirrus devices. This requires
the modesetting userspace X.org driver.
5 changes: 5 additions & 0 deletions trunk/drivers/gpu/drm/cirrus/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
ccflags-y := -Iinclude/drm
cirrus-y := cirrus_main.o cirrus_mode.o \
cirrus_drv.o cirrus_fbdev.o cirrus_ttm.o

obj-$(CONFIG_DRM_CIRRUS_QEMU) += cirrus.o
106 changes: 106 additions & 0 deletions trunk/drivers/gpu/drm/cirrus/cirrus_drv.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
/*
* Copyright 2012 Red Hat <mjg@redhat.com>
*
* This file is subject to the terms and conditions of the GNU General
* Public License version 2. See the file COPYING in the main
* directory of this archive for more details.
*
* Authors: Matthew Garrett
* Dave Airlie
*/
#include <linux/module.h>
#include <linux/console.h>
#include "drmP.h"
#include "drm.h"

#include "cirrus_drv.h"

int cirrus_modeset = -1;

MODULE_PARM_DESC(modeset, "Disable/Enable modesetting");
module_param_named(modeset, cirrus_modeset, int, 0400);

/*
* This is the generic driver code. This binds the driver to the drm core,
* which then performs further device association and calls our graphics init
* functions
*/

static struct drm_driver driver;

/* only bind to the cirrus chip in qemu */
static DEFINE_PCI_DEVICE_TABLE(pciidlist) = {
{ PCI_VENDOR_ID_CIRRUS, PCI_DEVICE_ID_CIRRUS_5446, 0x1af4, 0x1100, 0,
0, 0 },
{0,}
};

static int __devinit
cirrus_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
{
return drm_get_pci_dev(pdev, ent, &driver);
}

static void cirrus_pci_remove(struct pci_dev *pdev)
{
struct drm_device *dev = pci_get_drvdata(pdev);

drm_put_dev(dev);
}

static const struct file_operations cirrus_driver_fops = {
.owner = THIS_MODULE,
.open = drm_open,
.release = drm_release,
.unlocked_ioctl = drm_ioctl,
.mmap = cirrus_mmap,
.poll = drm_poll,
.fasync = drm_fasync,
};
static struct drm_driver driver = {
.driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_USE_MTRR,
.load = cirrus_driver_load,
.unload = cirrus_driver_unload,
.fops = &cirrus_driver_fops,
.name = DRIVER_NAME,
.desc = DRIVER_DESC,
.date = DRIVER_DATE,
.major = DRIVER_MAJOR,
.minor = DRIVER_MINOR,
.patchlevel = DRIVER_PATCHLEVEL,
.gem_init_object = cirrus_gem_init_object,
.gem_free_object = cirrus_gem_free_object,
.dumb_create = cirrus_dumb_create,
.dumb_map_offset = cirrus_dumb_mmap_offset,
.dumb_destroy = cirrus_dumb_destroy,
};

static struct pci_driver cirrus_pci_driver = {
.name = DRIVER_NAME,
.id_table = pciidlist,
.probe = cirrus_pci_probe,
.remove = cirrus_pci_remove,
};

static int __init cirrus_init(void)
{
if (vgacon_text_force() && cirrus_modeset == -1)
return -EINVAL;

if (cirrus_modeset == 0)
return -EINVAL;
return drm_pci_init(&driver, &cirrus_pci_driver);
}

static void __exit cirrus_exit(void)
{
drm_pci_exit(&driver, &cirrus_pci_driver);
}

module_init(cirrus_init);
module_exit(cirrus_exit);

MODULE_DEVICE_TABLE(pci, pciidlist);
MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");
246 changes: 246 additions & 0 deletions trunk/drivers/gpu/drm/cirrus/cirrus_drv.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,246 @@
/*
* Copyright 2012 Red Hat
*
* This file is subject to the terms and conditions of the GNU General
* Public License version 2. See the file COPYING in the main
* directory of this archive for more details.
*
* Authors: Matthew Garrett
* Dave Airlie
*/
#ifndef __CIRRUS_DRV_H__
#define __CIRRUS_DRV_H__

#include <video/vga.h>

#include <drm/drm_fb_helper.h>

#include "ttm/ttm_bo_api.h"
#include "ttm/ttm_bo_driver.h"
#include "ttm/ttm_placement.h"
#include "ttm/ttm_memory.h"
#include "ttm/ttm_module.h"

#define DRIVER_AUTHOR "Matthew Garrett"

#define DRIVER_NAME "cirrus"
#define DRIVER_DESC "qemu Cirrus emulation"
#define DRIVER_DATE "20110418"

#define DRIVER_MAJOR 1
#define DRIVER_MINOR 0
#define DRIVER_PATCHLEVEL 0

#define CIRRUSFB_CONN_LIMIT 1

#define RREG8(reg) ioread8(((void __iomem *)cdev->rmmio) + (reg))
#define WREG8(reg, v) iowrite8(v, ((void __iomem *)cdev->rmmio) + (reg))
#define RREG32(reg) ioread32(((void __iomem *)cdev->rmmio) + (reg))
#define WREG32(reg, v) iowrite32(v, ((void __iomem *)cdev->rmmio) + (reg))

#define SEQ_INDEX 4
#define SEQ_DATA 5

#define WREG_SEQ(reg, v) \
do { \
WREG8(SEQ_INDEX, reg); \
WREG8(SEQ_DATA, v); \
} while (0) \

#define CRT_INDEX 0x14
#define CRT_DATA 0x15

#define WREG_CRT(reg, v) \
do { \
WREG8(CRT_INDEX, reg); \
WREG8(CRT_DATA, v); \
} while (0) \

#define GFX_INDEX 0xe
#define GFX_DATA 0xf

#define WREG_GFX(reg, v) \
do { \
WREG8(GFX_INDEX, reg); \
WREG8(GFX_DATA, v); \
} while (0) \

/*
* Cirrus has a "hidden" DAC register that can be accessed by writing to
* the pixel mask register to reset the state, then reading from the register
* four times. The next write will then pass to the DAC
*/
#define VGA_DAC_MASK 0x6

#define WREG_HDR(v) \
do { \
RREG8(VGA_DAC_MASK); \
RREG8(VGA_DAC_MASK); \
RREG8(VGA_DAC_MASK); \
RREG8(VGA_DAC_MASK); \
WREG8(VGA_DAC_MASK, v); \
} while (0) \


#define CIRRUS_MAX_FB_HEIGHT 4096
#define CIRRUS_MAX_FB_WIDTH 4096

#define CIRRUS_DPMS_CLEARED (-1)

#define to_cirrus_crtc(x) container_of(x, struct cirrus_crtc, base)
#define to_cirrus_encoder(x) container_of(x, struct cirrus_encoder, base)
#define to_cirrus_framebuffer(x) container_of(x, struct cirrus_framebuffer, base)

struct cirrus_crtc {
struct drm_crtc base;
u8 lut_r[256], lut_g[256], lut_b[256];
int last_dpms;
bool enabled;
};

struct cirrus_fbdev;
struct cirrus_mode_info {
bool mode_config_initialized;
struct cirrus_crtc *crtc;
/* pointer to fbdev info structure */
struct cirrus_fbdev *gfbdev;
};

struct cirrus_encoder {
struct drm_encoder base;
int last_dpms;
};

struct cirrus_connector {
struct drm_connector base;
};

struct cirrus_framebuffer {
struct drm_framebuffer base;
struct drm_gem_object *obj;
};

struct cirrus_mc {
resource_size_t vram_size;
resource_size_t vram_base;
};

struct cirrus_device {
struct drm_device *dev;
unsigned long flags;

resource_size_t rmmio_base;
resource_size_t rmmio_size;
void __iomem *rmmio;

struct cirrus_mc mc;
struct cirrus_mode_info mode_info;

int num_crtc;
int fb_mtrr;

struct {
struct drm_global_reference mem_global_ref;
struct ttm_bo_global_ref bo_global_ref;
struct ttm_bo_device bdev;
atomic_t validate_sequence;
} ttm;

};


struct cirrus_fbdev {
struct drm_fb_helper helper;
struct cirrus_framebuffer gfb;
struct list_head fbdev_list;
void *sysram;
int size;
};

struct cirrus_bo {
struct ttm_buffer_object bo;
struct ttm_placement placement;
struct ttm_bo_kmap_obj kmap;
struct drm_gem_object gem;
u32 placements[3];
int pin_count;
};
#define gem_to_cirrus_bo(gobj) container_of((gobj), struct cirrus_bo, gem)

static inline struct cirrus_bo *
cirrus_bo(struct ttm_buffer_object *bo)
{
return container_of(bo, struct cirrus_bo, bo);
}


#define to_cirrus_obj(x) container_of(x, struct cirrus_gem_object, base)
#define DRM_FILE_PAGE_OFFSET (0x100000000ULL >> PAGE_SHIFT)

/* cirrus_mode.c */
void cirrus_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
u16 blue, int regno);
void cirrus_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green,
u16 *blue, int regno);


/* cirrus_main.c */
int cirrus_device_init(struct cirrus_device *cdev,
struct drm_device *ddev,
struct pci_dev *pdev,
uint32_t flags);
void cirrus_device_fini(struct cirrus_device *cdev);
int cirrus_gem_init_object(struct drm_gem_object *obj);
void cirrus_gem_free_object(struct drm_gem_object *obj);
int cirrus_dumb_mmap_offset(struct drm_file *file,
struct drm_device *dev,
uint32_t handle,
uint64_t *offset);
int cirrus_gem_create(struct drm_device *dev,
u32 size, bool iskernel,
struct drm_gem_object **obj);
int cirrus_dumb_create(struct drm_file *file,
struct drm_device *dev,
struct drm_mode_create_dumb *args);
int cirrus_dumb_destroy(struct drm_file *file,
struct drm_device *dev,
uint32_t handle);

int cirrus_framebuffer_init(struct drm_device *dev,
struct cirrus_framebuffer *gfb,
struct drm_mode_fb_cmd2 *mode_cmd,
struct drm_gem_object *obj);

/* cirrus_display.c */
int cirrus_modeset_init(struct cirrus_device *cdev);
void cirrus_modeset_fini(struct cirrus_device *cdev);

/* cirrus_fbdev.c */
int cirrus_fbdev_init(struct cirrus_device *cdev);
void cirrus_fbdev_fini(struct cirrus_device *cdev);



/* cirrus_irq.c */
void cirrus_driver_irq_preinstall(struct drm_device *dev);
int cirrus_driver_irq_postinstall(struct drm_device *dev);
void cirrus_driver_irq_uninstall(struct drm_device *dev);
irqreturn_t cirrus_driver_irq_handler(DRM_IRQ_ARGS);

/* cirrus_kms.c */
int cirrus_driver_load(struct drm_device *dev, unsigned long flags);
int cirrus_driver_unload(struct drm_device *dev);
extern struct drm_ioctl_desc cirrus_ioctls[];
extern int cirrus_max_ioctl;

int cirrus_mm_init(struct cirrus_device *cirrus);
void cirrus_mm_fini(struct cirrus_device *cirrus);
void cirrus_ttm_placement(struct cirrus_bo *bo, int domain);
int cirrus_bo_create(struct drm_device *dev, int size, int align,
uint32_t flags, struct cirrus_bo **pcirrusbo);
int cirrus_mmap(struct file *filp, struct vm_area_struct *vma);
int cirrus_bo_reserve(struct cirrus_bo *bo, bool no_wait);
void cirrus_bo_unreserve(struct cirrus_bo *bo);
int cirrus_bo_push_sysram(struct cirrus_bo *bo);
int cirrus_bo_pin(struct cirrus_bo *bo, u32 pl_flag, u64 *gpu_addr);
#endif /* __CIRRUS_DRV_H__ */
Loading

0 comments on commit fc474bf

Please sign in to comment.