import mesa-drm git at change 04893aa99abfbed8eb6d7067a974fa1f31193c87.

This commit is contained in:
mrg 2008-07-19 22:05:02 +00:00
parent 103b767319
commit 60c992bef9
10 changed files with 170 additions and 103 deletions

View File

@ -394,7 +394,7 @@
0x8086 0x29C2 CHIP_I9XX|CHIP_I915 "Intel G33"
0x8086 0x29B2 CHIP_I9XX|CHIP_I915 "Intel Q35"
0x8086 0x29D2 CHIP_I9XX|CHIP_I915 "Intel Q33"
0x8086 0x2A42 CHIP_I9XX|CHIP_I965 "Intel Integrated Graphics Device"
0x8086 0x2A42 CHIP_I9XX|CHIP_I965 "Mobile Intel® GM45 Express Chipset"
0x8086 0x2E02 CHIP_I9XX|CHIP_I965 "Intel Integrated Graphics Device"
0x8086 0x2E12 CHIP_I9XX|CHIP_I965 "Intel Q45/Q43"
0x8086 0x2E22 CHIP_I9XX|CHIP_I965 "Intel G45/G43"

View File

@ -1038,6 +1038,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25)
intel_init_chipset_flush_compat(dev);
#endif
intel_opregion_init(dev);
#endif
return ret;
@ -1050,6 +1051,10 @@ int i915_driver_unload(struct drm_device *dev)
if (dev_priv->mmio_map)
drm_rmmap(dev, dev_priv->mmio_map);
#ifdef __linux__
intel_opregion_free(dev);
#endif
drm_free(dev->dev_private, sizeof(drm_i915_private_t),
DRM_MEM_DRIVER);
#ifdef __linux__

View File

@ -105,6 +105,22 @@ typedef struct _drm_i915_vbl_swap {
int flip;
} drm_i915_vbl_swap_t;
#ifdef __linux__
struct opregion_header;
struct opregion_acpi;
struct opregion_swsci;
struct opregion_asle;
struct intel_opregion {
struct opregion_header *header;
struct opregion_acpi *acpi;
struct opregion_swsci *swsci;
struct opregion_asle *asle;
int enabled;
};
#endif
typedef struct drm_i915_private {
drm_local_map_t *sarea;
drm_local_map_t *mmio_map;
@ -158,6 +174,11 @@ typedef struct drm_i915_private {
struct drm_buffer_object *sarea_bo;
struct drm_bo_kmap_obj sarea_kmap;
#endif
#ifdef __linux__
struct intel_opregion opregion;
#endif
/* Register state */
u8 saveLBB;
u32 saveDSPACNTR;
@ -342,6 +363,14 @@ int i915_execbuffer(struct drm_device *dev, void *data,
#endif
#ifdef __linux__
/* i915_opregion.c */
extern int intel_opregion_init(struct drm_device *dev);
extern void intel_opregion_free(struct drm_device *dev);
extern void opregion_asle_intr(struct drm_device *dev);
extern void opregion_enable_asle(struct drm_device *dev);
#endif
#ifdef __linux__
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25)
extern void intel_init_chipset_flush_compat(struct drm_device *dev);
@ -613,6 +642,7 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
#define I915_DISPLAY_PIPE_B_EVENT_INTERRUPT (1<<4)
#define I915_DEBUG_INTERRUPT (1<<2)
#define I915_USER_INTERRUPT (1<<1)
#define I915_ASLE_INTERRUPT (1<<0)
#define EIR 0x020b0
#define EMR 0x020b4
#define ESR 0x020b8
@ -1801,7 +1831,7 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
#define IS_I965GM(dev) ((dev)->pci_device == 0x2A02)
#define IS_IGD_GM(dev) ((dev)->pci_device == 0x2A42)
#define IS_GM45(dev) ((dev)->pci_device == 0x2A42)
#define IS_G4X(dev) ((dev)->pci_device == 0x2E02 || \
(dev)->pci_device == 0x2E12 || \
@ -1815,8 +1845,8 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
IS_I945GM(dev) || IS_I965G(dev) || IS_G33(dev))
#define IS_MOBILE(dev) (IS_I830(dev) || IS_I85X(dev) || IS_I915GM(dev) || \
IS_I945GM(dev) || IS_I965GM(dev) || IS_IGD_GM(dev))
IS_I945GM(dev) || IS_I965GM(dev) || IS_GM45(dev))
#define I915_NEED_GFX_HWS(dev) (IS_G33(dev) || IS_IGD_GM(dev) || IS_G4X(dev))
#define I915_NEED_GFX_HWS(dev) (IS_G33(dev) || IS_GM45(dev) || IS_G4X(dev))
#endif

View File

@ -162,11 +162,11 @@ static void i915_vblank_tasklet(struct drm_device *dev)
u32 ropcpp = (0xcc << 16) | ((cpp - 1) << 24);
RING_LOCALS;
if (sarea_priv->front_tiled) {
if (IS_I965G(dev) && sarea_priv->front_tiled) {
cmd |= XY_SRC_COPY_BLT_DST_TILED;
dst_pitch >>= 2;
}
if (sarea_priv->back_tiled) {
if (IS_I965G(dev) && sarea_priv->back_tiled) {
cmd |= XY_SRC_COPY_BLT_SRC_TILED;
src_pitch >>= 2;
}
@ -361,28 +361,7 @@ static void i915_vblank_tasklet(struct drm_device *dev)
drm_free(swap_hit, sizeof(*swap_hit), DRM_MEM_DRIVER);
}
}
#if 0
static int i915_in_vblank(struct drm_device *dev, int pipe)
{
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
unsigned long pipedsl, vblank, vtotal;
unsigned long vbl_start, vbl_end, cur_line;
pipedsl = pipe ? PIPEBDSL : PIPEADSL;
vblank = pipe ? VBLANK_B : VBLANK_A;
vtotal = pipe ? VTOTAL_B : VTOTAL_A;
vbl_start = I915_READ(vblank) & VBLANK_START_MASK;
vbl_end = (I915_READ(vblank) >> VBLANK_END_SHIFT) & VBLANK_END_MASK;
cur_line = I915_READ(pipedsl);
if (cur_line >= vbl_start)
return 1;
return 0;
}
#endif
u32 i915_get_vblank_counter(struct drm_device *dev, int plane)
{
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
@ -416,22 +395,6 @@ u32 i915_get_vblank_counter(struct drm_device *dev, int plane)
count = (high1 << 8) | low;
/*
* If we're in the middle of the vblank period, the
* above regs won't have been updated yet, so return
* an incremented count to stay accurate
*/
#if 0
if (i915_in_vblank(dev, pipe))
count++;
#endif
/* count may be reset by other driver(e.g. 2D driver),
we have no way to know if it is wrapped or resetted
when count is zero. do a rough guess.
*/
if (count == 0 && dev->last_vblank[pipe] < dev->max_vblank_count/2)
dev->last_vblank[pipe] = 0;
return count;
}
@ -444,18 +407,8 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
int vblank = 0;
iir = I915_READ(IIR);
#if 0
DRM_DEBUG("flag=%08x\n", iir);
#endif
if (iir == 0) {
DRM_DEBUG ("iir 0x%08x im 0x%08x ie 0x%08x pipea 0x%08x pipeb 0x%08x\n",
iir,
I915_READ(IMR),
I915_READ(IER),
I915_READ(PIPEASTAT),
I915_READ(PIPEBSTAT));
if (iir == 0)
return IRQ_NONE;
}
/*
* Clear the PIPE(A|B)STAT regs before the IIR otherwise
@ -474,15 +427,33 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
}
if (iir & I915_DISPLAY_PIPE_B_EVENT_INTERRUPT) {
pipeb_stats = I915_READ(PIPEBSTAT);
/* Ack the event */
I915_WRITE(PIPEBSTAT, pipeb_stats);
/* The vblank interrupt gets enabled even if we didn't ask for
it, so make sure it's shut down again */
if (!(dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_B))
pipeb_stats &= ~(I915_VBLANK_INTERRUPT_ENABLE);
if (pipeb_stats & (PIPE_START_VBLANK_INTERRUPT_STATUS|
PIPE_VBLANK_INTERRUPT_STATUS))
{
vblank++;
drm_handle_vblank(dev, i915_get_plane(dev, 1));
}
#ifdef __linux__
if (pipeb_stats & I915_LEGACY_BLC_EVENT_ENABLE)
opregion_asle_intr(dev);
#endif
I915_WRITE(PIPEBSTAT, pipeb_stats);
}
#ifdef __linux__
if (iir & I915_ASLE_INTERRUPT)
opregion_asle_intr(dev);
#endif
if (dev_priv->sarea_priv)
dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
@ -703,6 +674,10 @@ static void i915_enable_interrupt (struct drm_device *dev)
dev_priv->irq_enable_reg |= I915_USER_INTERRUPT;
#ifdef __linux__
opregion_enable_asle(dev);
#endif
I915_WRITE(IER, dev_priv->irq_enable_reg);
dev_priv->irq_enabled = 1;
}
@ -713,20 +688,12 @@ int i915_vblank_pipe_set(struct drm_device *dev, void *data,
struct drm_file *file_priv)
{
drm_i915_private_t *dev_priv = dev->dev_private;
drm_i915_vblank_pipe_t *pipe = data;
if (!dev_priv) {
DRM_ERROR("called with no initialization\n");
return -EINVAL;
}
if (pipe->pipe & ~(DRM_I915_VBLANK_PIPE_A|DRM_I915_VBLANK_PIPE_B)) {
DRM_ERROR("called with invalid pipe 0x%x\n", pipe->pipe);
return -EINVAL;
}
dev_priv->vblank_pipe = pipe->pipe;
return 0;
}
@ -735,20 +702,13 @@ int i915_vblank_pipe_get(struct drm_device *dev, void *data,
{
drm_i915_private_t *dev_priv = dev->dev_private;
drm_i915_vblank_pipe_t *pipe = data;
u16 flag;
if (!dev_priv) {
DRM_ERROR("called with no initialization\n");
return -EINVAL;
}
flag = I915_READ(IER);
pipe->pipe = 0;
if (flag & I915_DISPLAY_PIPE_A_EVENT_INTERRUPT)
pipe->pipe |= DRM_I915_VBLANK_PIPE_A;
if (flag & I915_DISPLAY_PIPE_B_EVENT_INTERRUPT)
pipe->pipe |= DRM_I915_VBLANK_PIPE_B;
pipe->pipe = DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B;
return 0;
}
@ -809,7 +769,13 @@ int i915_vblank_swap(struct drm_device *dev, void *data,
DRM_SPINUNLOCK_IRQRESTORE(&dev->drw_lock, irqflags);
drm_update_vblank_count(dev, pipe);
/*
* We take the ref here and put it when the swap actually completes
* in the tasklet.
*/
ret = drm_vblank_get(dev, pipe);
if (ret)
return ret;
curseq = drm_vblank_count(dev, pipe);
if (seqtype == _DRM_VBLANK_RELATIVE)
@ -820,6 +786,7 @@ int i915_vblank_swap(struct drm_device *dev, void *data,
swap->sequence = curseq + 1;
} else {
DRM_DEBUG("Missed target sequence\n");
drm_vblank_put(dev, pipe);
return -EINVAL;
}
}
@ -841,6 +808,7 @@ int i915_vblank_swap(struct drm_device *dev, void *data,
irqflags);
DRM_DEBUG("Invalid drawable ID %d\n",
swap->drawable);
drm_vblank_put(dev, pipe);
return -EINVAL;
}
@ -848,6 +816,7 @@ int i915_vblank_swap(struct drm_device *dev, void *data,
DRM_SPINUNLOCK_IRQRESTORE(&dev->drw_lock, irqflags);
drm_vblank_put(dev, pipe);
return 0;
}
}
@ -871,6 +840,7 @@ int i915_vblank_swap(struct drm_device *dev, void *data,
if (dev_priv->swaps_pending >= 100) {
DRM_DEBUG("Too many swaps queued\n");
drm_vblank_put(dev, pipe);
return -EBUSY;
}
@ -878,17 +848,12 @@ int i915_vblank_swap(struct drm_device *dev, void *data,
if (!vbl_swap) {
DRM_ERROR("Failed to allocate memory to queue swap\n");
drm_vblank_put(dev, pipe);
return -ENOMEM;
}
DRM_DEBUG("\n");
ret = drm_vblank_get(dev, pipe);
if (ret) {
drm_free(vbl_swap, sizeof(*vbl_swap), DRM_MEM_DRIVER);
return ret;
}
vbl_swap->drw_id = swap->drawable;
vbl_swap->plane = plane;
vbl_swap->sequence = swap->sequence;
@ -935,6 +900,7 @@ int i915_driver_irq_postinstall(struct drm_device * dev)
if (ret)
return ret;
dev_priv->vblank_pipe = DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B;
dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */
i915_enable_interrupt(dev);
@ -956,6 +922,8 @@ void i915_driver_irq_uninstall(struct drm_device * dev)
if (!dev_priv)
return;
dev_priv->vblank_pipe = 0;
dev_priv->irq_enabled = 0;
I915_WRITE(HWSTAM, 0xffffffff);
I915_WRITE(IMR, 0xffffffff);

View File

@ -25,7 +25,7 @@
#ifndef __NOUVEAU_DRM_H__
#define __NOUVEAU_DRM_H__
#define NOUVEAU_DRM_HEADER_PATCHLEVEL 10
#define NOUVEAU_DRM_HEADER_PATCHLEVEL 11
struct drm_nouveau_channel_alloc {
uint32_t fb_ctxdma_handle;
@ -85,10 +85,12 @@ struct drm_nouveau_gpuobj_free {
#define NOUVEAU_MEM_PINNED 0x00000040
#define NOUVEAU_MEM_USER_BACKED 0x00000080
#define NOUVEAU_MEM_MAPPED 0x00000100
#define NOUVEAU_MEM_INSTANCE 0x00000200 /* internal */
#define NOUVEAU_MEM_NOTIFIER 0x00000400 /* internal */
#define NOUVEAU_MEM_NOVM 0x00000800 /* internal */
#define NOUVEAU_MEM_USER 0x00001000 /* internal */
#define NOUVEAU_MEM_TILE 0x00000200
#define NOUVEAU_MEM_TILE_ZETA 0x00000400
#define NOUVEAU_MEM_INSTANCE 0x01000000 /* internal */
#define NOUVEAU_MEM_NOTIFIER 0x02000000 /* internal */
#define NOUVEAU_MEM_NOVM 0x04000000 /* internal */
#define NOUVEAU_MEM_USER 0x08000000 /* internal */
#define NOUVEAU_MEM_INTERNAL (NOUVEAU_MEM_INSTANCE | \
NOUVEAU_MEM_NOTIFIER | \
NOUVEAU_MEM_NOVM | \
@ -107,6 +109,13 @@ struct drm_nouveau_mem_free {
int flags;
};
struct drm_nouveau_mem_tile {
uint64_t offset;
uint64_t delta;
uint64_t size;
int flags;
};
/* FIXME : maybe unify {GET,SET}PARAMs */
#define NOUVEAU_GETPARAM_PCI_VENDOR 3
#define NOUVEAU_GETPARAM_PCI_DEVICE 4
@ -168,5 +177,6 @@ struct drm_nouveau_sarea {
#define DRM_NOUVEAU_GPUOBJ_FREE 0x07
#define DRM_NOUVEAU_MEM_ALLOC 0x08
#define DRM_NOUVEAU_MEM_FREE 0x09
#define DRM_NOUVEAU_MEM_TILE 0x0a
#endif /* __NOUVEAU_DRM_H__ */

View File

@ -34,7 +34,7 @@
#define DRIVER_MAJOR 0
#define DRIVER_MINOR 0
#define DRIVER_PATCHLEVEL 10
#define DRIVER_PATCHLEVEL 11
#define NOUVEAU_FAMILY 0x0000FFFF
#define NOUVEAU_FLAGS 0xFFFF0000
@ -359,6 +359,8 @@ extern int nouveau_ioctl_mem_alloc(struct drm_device *, void *data,
struct drm_file *);
extern int nouveau_ioctl_mem_free(struct drm_device *, void *data,
struct drm_file *);
extern int nouveau_ioctl_mem_tile(struct drm_device *, void *data,
struct drm_file *);
extern struct mem_block* nouveau_mem_alloc(struct drm_device *,
int alignment, uint64_t size,
int flags, struct drm_file *);

View File

@ -593,6 +593,7 @@ struct drm_ioctl_desc nouveau_ioctls[] = {
DRM_IOCTL_DEF(DRM_NOUVEAU_GPUOBJ_FREE, nouveau_ioctl_gpuobj_free, DRM_AUTH),
DRM_IOCTL_DEF(DRM_NOUVEAU_MEM_ALLOC, nouveau_ioctl_mem_alloc, DRM_AUTH),
DRM_IOCTL_DEF(DRM_NOUVEAU_MEM_FREE, nouveau_ioctl_mem_free, DRM_AUTH),
DRM_IOCTL_DEF(DRM_NOUVEAU_MEM_TILE, nouveau_ioctl_mem_tile, DRM_AUTH),
};
int nouveau_max_ioctl = DRM_ARRAY_SIZE(nouveau_ioctls);

View File

@ -594,7 +594,7 @@ nouveau_mem_alloc(struct drm_device *dev, int alignment, uint64_t size,
* page size in the GPU VM.
*/
if (flags & NOUVEAU_MEM_FB && dev_priv->card_type >= NV_50) {
size = (size + (64 * 1024)) & ~((64 * 1024) - 1);
size = (size + 65535) & ~65535;
if (alignment < 16)
alignment = 16;
}
@ -659,6 +659,7 @@ alloc_ok:
struct nouveau_gpuobj *pt = dev_priv->vm_vram_pt;
unsigned offset = block->start;
unsigned count = block->size / 65536;
unsigned tile = 0;
if (!pt) {
DRM_ERROR("vm alloc without vm pt\n");
@ -666,11 +667,22 @@ alloc_ok:
return NULL;
}
/* The tiling stuff is *not* what NVIDIA does - but both the
* 2D and 3D engines seem happy with this simpler method.
* Should look into why NVIDIA do what they do at some point.
*/
if (flags & NOUVEAU_MEM_TILE) {
if (flags & NOUVEAU_MEM_TILE_ZETA)
tile = 0x00002800;
else
tile = 0x00007000;
}
while (count--) {
unsigned pte = offset / 65536;
INSTANCE_WR(pt, (pte * 2) + 0, offset | 1);
INSTANCE_WR(pt, (pte * 2) + 1, 0x00000000);
INSTANCE_WR(pt, (pte * 2) + 1, 0x00000000 | tile);
offset += 65536;
}
} else {
@ -808,3 +820,53 @@ nouveau_ioctl_mem_free(struct drm_device *dev, void *data,
nouveau_mem_free(dev, block);
return 0;
}
int
nouveau_ioctl_mem_tile(struct drm_device *dev, void *data,
struct drm_file *file_priv)
{
struct drm_nouveau_private *dev_priv = dev->dev_private;
struct drm_nouveau_mem_tile *memtile = data;
struct mem_block *block = NULL;
NOUVEAU_CHECK_INITIALISED_WITH_RETURN;
if (dev_priv->card_type < NV_50)
return -EINVAL;
if (memtile->flags & NOUVEAU_MEM_FB) {
memtile->offset -= 512*1024*1024;
block = find_block(dev_priv->fb_heap, memtile->offset);
}
if (!block)
return -EINVAL;
if (block->file_priv != file_priv)
return -EPERM;
{
struct nouveau_gpuobj *pt = dev_priv->vm_vram_pt;
unsigned offset = block->start + memtile->delta;
unsigned count = memtile->size / 65536;
unsigned tile = 0;
if (memtile->flags & NOUVEAU_MEM_TILE) {
if (memtile->flags & NOUVEAU_MEM_TILE_ZETA)
tile = 0x00002800;
else
tile = 0x00007000;
}
while (count--) {
unsigned pte = offset / 65536;
INSTANCE_WR(pt, (pte * 2) + 0, offset | 1);
INSTANCE_WR(pt, (pte * 2) + 1, 0x00000000 | tile);
offset += 65536;
}
}
return 0;
}

View File

@ -893,17 +893,6 @@ static int radeon_do_init_cp(struct drm_device * dev, drm_radeon_init_t * init)
*/
dev_priv->vblank_crtc = DRM_RADEON_VBLANK_CRTC1;
switch(init->func) {
case RADEON_INIT_R200_CP:
dev_priv->microcode_version = UCODE_R200;
break;
case RADEON_INIT_R300_CP:
dev_priv->microcode_version = UCODE_R300;
break;
default:
dev_priv->microcode_version = UCODE_R100;
}
dev_priv->do_boxes = 0;
dev_priv->cp_mode = init->cp_mode;
@ -951,8 +940,7 @@ static int radeon_do_init_cp(struct drm_device * dev, drm_radeon_init_t * init)
*/
dev_priv->depth_clear.rb3d_cntl = (RADEON_PLANE_MASK_ENABLE |
(dev_priv->color_fmt << 10) |
(dev_priv->microcode_version ==
UCODE_R100 ? RADEON_ZBLOCK16 : 0));
(dev_priv->chip_family < CHIP_R200 ? RADEON_ZBLOCK16 : 0));
dev_priv->depth_clear.rb3d_zstencilcntl =
(dev_priv->depth_fmt |
@ -1158,7 +1146,7 @@ static int radeon_do_init_cp(struct drm_device * dev, drm_radeon_init_t * init)
dev_priv->gart_info.mapping.size =
dev_priv->gart_info.table_size;
drm_core_ioremap(&dev_priv->gart_info.mapping, dev);
drm_core_ioremap_wc(&dev_priv->gart_info.mapping, dev);
dev_priv->gart_info.addr =
dev_priv->gart_info.mapping.handle;
@ -1731,6 +1719,7 @@ int radeon_driver_load(struct drm_device *dev, unsigned long flags)
break;
}
dev_priv->chip_family = flags & RADEON_FAMILY_MASK;
if (drm_device_is_agp(dev))
dev_priv->flags |= RADEON_IS_AGP;
else if (drm_device_is_pcie(dev))

View File

@ -88,7 +88,7 @@ static struct mem_block *alloc_block(struct mem_block *heap, int size,
list_for_each(p, heap) {
int start = (p->start + mask) & ~mask;
if (p->file_priv == 0 && start + size <= p->start + p->size)
if (p->file_priv == NULL && start + size <= p->start + p->size)
return split_block(p, start, size, file_priv);
}
@ -113,7 +113,7 @@ static void free_block(struct mem_block *p)
/* Assumes a single contiguous range. Needs a special file_priv in
* 'heap' to stop it being subsumed.
*/
if (p->next->file_priv == 0) {
if (p->next->file_priv == NULL) {
struct mem_block *q = p->next;
p->size += q->size;
p->next = q->next;
@ -121,7 +121,7 @@ static void free_block(struct mem_block *p)
drm_free(q, sizeof(*q), DRM_MEM_BUFS);
}
if (p->prev->file_priv == 0) {
if (p->prev->file_priv == NULL) {
struct mem_block *q = p->prev;
q->size += p->size;
q->next = p->next;
@ -174,7 +174,7 @@ void radeon_mem_release(struct drm_file *file_priv, struct mem_block *heap)
* 'heap' to stop it being subsumed.
*/
list_for_each(p, heap) {
while (p->file_priv == 0 && p->next->file_priv == 0) {
while (p->file_priv == NULL && p->next->file_priv == NULL) {
struct mem_block *q = p->next;
p->size += q->size;
p->next = q->next;