1/**************************************************************************
2
3Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
4Copyright © 2002 by David Dawes.
5
6All Rights Reserved.
7
8Permission is hereby granted, free of charge, to any person obtaining a
9copy of this software and associated documentation files (the
10"Software"), to deal in the Software without restriction, including
11without limitation the rights to use, copy, modify, merge, publish,
12distribute, sub license, and/or sell copies of the Software, and to
13permit persons to whom the Software is furnished to do so, subject to
14the following conditions:
15
16The above copyright notice and this permission notice (including the
17next paragraph) shall be included in all copies or substantial portions
18of the Software.
19
20THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
21OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
23IN NO EVENT SHALL THE COPYRIGHT HOLDERS AND/OR THEIR SUPPLIERS BE LIABLE FOR
24ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
25TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
26SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27
28**************************************************************************/
29
30/*
31 * Authors:
32 *   Keith Whitwell <keith@tungstengraphics.com>
33 *   David Dawes <dawes@xfree86.org>
34 *
35 * Updated for Dual Head capabilities:
36 *   Alan Hourihane <alanh@tungstengraphics.com>
37 */
38
39/**
40 * @file i830_memory.c
41 *
42 * This is the video memory allocator.  Our memory allocation is different from
43 * other graphics chips, where you have a fixed amount of graphics memory
44 * available that you want to put to the best use.  Instead, we have almost no
45 * memory pre-allocated, and we have to choose an appropriate amount of sytem
46 * memory to use.
47 *
48 * The allocations we might do:
49 *
50 * - Ring buffer
51 * - HW cursor block (either one block or four)
52 * - Overlay registers
53 * - Front buffer (screen 1)
54 * - Front buffer (screen 2, only in zaphod mode)
55 * - Back/depth buffer (3D only)
56 * - Compatibility texture pool (optional, more is always better)
57 * - New texture pool (optional, more is always better.  aperture allocation
58 *     only)
59 *
60 * The user may request a specific amount of memory to be used
61 * (pI830->pEnt->videoRam != 0), in which case allocations have to fit within
62 * that much aperture.  If not, the individual allocations will be
63 * automatically sized, and will be fit within the maximum aperture size.
64 * Only the actual memory used (not alignment padding) will get actual AGP
65 * memory allocated.
66 *
67 * Given that the allocations listed are generally a page or more than a page,
68 * our allocator will only return page-aligned offsets, simplifying the memory
69 * binding process.  For smaller allocations, the acceleration architecture's
70 * linear allocator is preferred.
71 */
72
73#ifdef HAVE_CONFIG_H
74#include "config.h"
75#endif
76
77#include <assert.h>
78#include <inttypes.h>
79#include <string.h>
80#include <errno.h>
81#include <sys/types.h>
82#include <sys/ioctl.h>
83
84#include "xf86.h"
85#include "xf86_OSproc.h"
86
87#include "i830.h"
88#include "i810_reg.h"
89#include "i915_drm.h"
90
91/* Our hardware status area is just a single page */
92#define HWSTATUS_PAGE_SIZE GTT_PAGE_SIZE
93#define PWRCTX_SIZE GTT_PAGE_SIZE
94
95static i830_memory *
96i830_allocate_aperture(ScrnInfoPtr pScrn, const char *name,
97		       unsigned long size, unsigned long pitch,
98		       unsigned long alignment, int flags,
99		       enum tile_format tile_format);
100
101static int i830_set_tiling(ScrnInfoPtr pScrn, unsigned int offset,
102			   unsigned int pitch, unsigned int size,
103			   enum tile_format tile_format);
104
105static void i830_clear_tiling(ScrnInfoPtr pScrn, unsigned int fence_nr);
106
107/**
108 * Returns the fence size for a tiled area of the given size.
109 */
110unsigned long
111i830_get_fence_size(I830Ptr pI830, unsigned long size)
112{
113    unsigned long i;
114    unsigned long start;
115
116    if (IS_I965G(pI830)) {
117	/* The 965 can have fences at any page boundary. */
118	return ALIGN(size, GTT_PAGE_SIZE);
119    } else {
120	/* Align the size to a power of two greater than the smallest fence
121	 * size.
122	 */
123	if (IS_I9XX(pI830))
124	    start = MB(1);
125	else
126	    start = KB(512);
127
128	for (i = start; i < size; i <<= 1)
129	    ;
130
131	return i;
132    }
133}
134
135/**
136 * On some chips, pitch width has to be a power of two tile width, so
137 * calculate that here.
138 */
139unsigned long
140i830_get_fence_pitch(I830Ptr pI830, unsigned long pitch, int format)
141{
142    unsigned long i;
143    unsigned long tile_width = (format == I915_TILING_Y) ? 128 : 512;
144
145    if (format == TILE_NONE)
146	return pitch;
147
148    /* 965 is flexible */
149    if (IS_I965G(pI830))
150	return ROUND_TO(pitch, tile_width);
151
152    /* Pre-965 needs power of two tile width */
153    for (i = tile_width; i < pitch; i <<= 1)
154	;
155
156    return i;
157}
158
159/**
160 * On some chips, pitch width has to be a power of two tile width, so
161 * calculate that here.
162 */
163static unsigned long
164i830_get_fence_alignment(I830Ptr pI830, unsigned long size)
165{
166    if (IS_I965G(pI830))
167	return 4096;
168    else
169	return i830_get_fence_size(pI830, size);
170}
171
172static Bool
173i830_check_display_stride(ScrnInfoPtr pScrn, int stride, Bool tiling)
174{
175    I830Ptr pI830 = I830PTR(pScrn);
176    int limit = KB(32);
177
178    /* 8xx spec has always 8K limit, but tests show larger limit in
179       non-tiling mode, which makes large monitor work. */
180    if ((IS_845G(pI830) || IS_I85X(pI830)) && tiling)
181	limit = KB(8);
182
183    if (IS_I915(pI830) && tiling)
184	limit = KB(8);
185
186    if (IS_I965G(pI830) && tiling)
187	limit = KB(16);
188
189    if (stride <= limit)
190	return TRUE;
191    else
192	return FALSE;
193}
194
195static Bool
196i830_bind_memory(ScrnInfoPtr pScrn, i830_memory *mem)
197{
198    I830Ptr pI830 = I830PTR(pScrn);
199
200    if (mem == NULL || mem->bound || pI830->use_drm_mode)
201	return TRUE;
202
203    if (pI830->have_gem && mem->bo != NULL) {
204
205	if (dri_bo_pin(mem->bo, mem->alignment) != 0) {
206	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
207		       "Failed to pin %s: %s\n",
208		       mem->name, strerror(errno));
209	    return FALSE;
210	}
211
212	mem->bound = TRUE;
213	mem->offset = mem->bo->offset;
214	mem->end = mem->offset + mem->size;
215    } else {
216	if (!pI830->gtt_acquired)
217	    return TRUE;
218
219	if (mem->key != -1 &&
220	    !xf86BindGARTMemory(pScrn->scrnIndex, mem->key, mem->agp_offset))
221	{
222	    return FALSE;
223	}
224
225	mem->bound = TRUE;
226    }
227
228    if (mem->tiling != TILE_NONE && !pI830->kernel_exec_fencing) {
229	mem->fence_nr = i830_set_tiling(pScrn, mem->offset, mem->pitch,
230					mem->allocated_size, mem->tiling);
231    }
232
233    return TRUE;
234}
235
236static Bool
237i830_unbind_memory(ScrnInfoPtr pScrn, i830_memory *mem)
238{
239    I830Ptr pI830 = I830PTR(pScrn);
240
241    if (mem == NULL || !mem->bound)
242	return TRUE;
243
244    if (mem->tiling != TILE_NONE && !pI830->use_drm_mode &&
245	!pI830->kernel_exec_fencing)
246	i830_clear_tiling(pScrn, mem->fence_nr);
247
248    if (mem->bo != NULL && !pI830->use_drm_mode) {
249	if (dri_bo_unpin(mem->bo) == 0) {
250	    mem->bound = FALSE;
251	    /* Give buffer obviously wrong offset/end until it's re-pinned. */
252	    mem->offset = -1;
253	    mem->end = -1;
254	    return TRUE;
255	} else {
256	    return FALSE;
257	}
258    }
259
260    if (mem->key == -1 || xf86UnbindGARTMemory(pScrn->scrnIndex, mem->key)) {
261	mem->bound = FALSE;
262	return TRUE;
263    } else {
264	return FALSE;
265    }
266}
267
268void
269i830_free_memory(ScrnInfoPtr pScrn, i830_memory *mem)
270{
271    if (mem == NULL)
272	return;
273
274    /* Free any AGP memory. */
275    i830_unbind_memory(pScrn, mem);
276
277    if (mem->bo != NULL) {
278	I830Ptr pI830 = I830PTR(pScrn);
279	dri_bo_unreference (mem->bo);
280	if (pI830->bo_list == mem) {
281	    pI830->bo_list = mem->next;
282	    if (mem->next)
283		mem->next->prev = NULL;
284	} else {
285	    if (mem->prev)
286		mem->prev->next = mem->next;
287	    if (mem->next)
288		mem->next->prev = mem->prev;
289	}
290	xfree(mem->name);
291	xfree(mem);
292	return;
293    }
294	    /* Disconnect from the list of allocations */
295    if (mem->prev != NULL)
296	mem->prev->next = mem->next;
297    if (mem->next != NULL)
298	mem->next->prev = mem->prev;
299
300    if (mem->key != -1) {
301	xf86DeallocateGARTMemory(pScrn->scrnIndex, mem->key);
302	mem->key = -1;
303    }
304
305    xfree(mem->name);
306    xfree(mem);
307}
308
309/* Resets the state of the aperture allocator, freeing all memory that had
310 * been allocated.
311 */
312void
313i830_reset_allocations(ScrnInfoPtr pScrn)
314{
315    I830Ptr pI830 = I830PTR(pScrn);
316    int	    p;
317
318    /* While there is any memory between the start and end markers, free it. */
319    while (pI830->memory_list->next->next != NULL) {
320	i830_memory *mem = pI830->memory_list->next;
321
322	/* Don't reset BO allocator, which we set up at init. */
323	if (pI830->memory_manager == mem) {
324	    mem = mem->next;
325	    if (mem->next == NULL)
326		break;
327	}
328
329	i830_free_memory(pScrn, mem);
330    }
331
332    /* Free any allocations in buffer objects */
333    while (pI830->bo_list != NULL)
334        i830_free_memory(pScrn, pI830->bo_list);
335
336    /* Null out the pointers for all the allocations we just freed.  This is
337     * kind of gross, but at least it's just one place now.
338     */
339    pI830->cursor_mem = NULL;
340    for (p = 0; p < 2; p++) {
341	pI830->cursor_mem_classic[p] = NULL;
342	pI830->cursor_mem_argb[p] = NULL;
343    }
344    pI830->front_buffer = NULL;
345    pI830->overlay_regs = NULL;
346    pI830->power_context = NULL;
347    pI830->ring.mem = NULL;
348    pI830->fake_bufmgr_mem = NULL;
349}
350
351/**
352 * Initialize's the driver's video memory allocator to allocate in the
353 * given range.
354 *
355 * This sets up the kernel memory manager to manage as much of the memory
356 * as we think it can, while leaving enough to us to fulfill our non-GEM
357 * static allocations.  Some of these exist because of the need for physical
358 * addresses to reference.
359 */
360Bool
361i830_allocator_init(ScrnInfoPtr pScrn, unsigned long size)
362{
363    I830Ptr pI830 = I830PTR(pScrn);
364    i830_memory *start, *end;
365    struct drm_i915_setparam sp;
366
367    start = xcalloc(1, sizeof(*start));
368    if (start == NULL)
369	return FALSE;
370    start->name = xstrdup("start marker");
371    if (start->name == NULL) {
372	xfree(start);
373	return FALSE;
374    }
375    end = xcalloc(1, sizeof(*end));
376    if (end == NULL) {
377	xfree(start->name);
378	xfree(start);
379	return FALSE;
380    }
381    end->name = xstrdup("end marker");
382    if (end->name == NULL) {
383	xfree(start->name);
384	xfree(start);
385	xfree(end);
386	return FALSE;
387    }
388
389    start->key = -1;
390    start->offset = 0;
391    start->end = start->offset;
392    start->size = 0;
393    start->next = end;
394    end->key = -1;
395    end->offset = size;
396    end->end = end->offset;
397    end->size = 0;
398    end->prev = start;
399
400    pI830->memory_list = start;
401
402    /* Now that we have our manager set up, give the kernel a piece of the
403     * aperture for GEM buffer object mapping. This is only needed for UXA
404     * and/or DRI2 when the kernel hasn't already managed this itself under
405     * KMS.  We need libdri interface5.4 or newer so we can rely on the lock
406     * being held after DRIScreenInit, rather than after DRIFinishScreenInit.
407     */
408
409    if (!pI830->use_drm_mode) {
410	int mmsize;
411
412	/* Take over all of the graphics aperture minus enough to for
413	 * physical-address allocations of cursor/overlay registers.
414	 */
415	mmsize = size;
416
417	/* Overlay and cursors, if physical, need to be allocated outside
418	 * of the kernel memory manager.
419	 */
420	if (!OVERLAY_NOPHYSICAL(pI830) && !OVERLAY_NOEXIST(pI830)) {
421	    mmsize -= ROUND_TO(OVERLAY_SIZE, GTT_PAGE_SIZE);
422	}
423	if (pI830->CursorNeedsPhysical) {
424	    mmsize -= 2 * (ROUND_TO(HWCURSOR_SIZE, GTT_PAGE_SIZE) +
425			   ROUND_TO(HWCURSOR_SIZE_ARGB, GTT_PAGE_SIZE));
426	}
427	if (pI830->fb_compression)
428	    mmsize -= MB(6) + ROUND_TO_PAGE(FBC_LL_SIZE + FBC_LL_PAD);
429
430	/* Can't do GEM on stolen memory */
431	mmsize -= pI830->stolen_size;
432
433	/* Create the aperture allocation */
434	pI830->memory_manager =
435		i830_allocate_aperture(pScrn, "DRI memory manager",
436				       mmsize, 0, GTT_PAGE_SIZE,
437				       ALIGN_BOTH_ENDS | NEED_NON_STOLEN,
438				       TILE_NONE);
439
440	if (pI830->memory_manager != NULL) {
441	    struct drm_i915_gem_init init;
442	    int ret;
443
444	    sp.param = I915_SETPARAM_NUM_USED_FENCES;
445	    sp.value = 0; /* kernel gets them all */
446
447	    ret = drmCommandWrite(pI830->drmSubFD, DRM_I915_SETPARAM,
448				  &sp, sizeof(sp));
449	    if (ret == 0)
450		pI830->kernel_exec_fencing = TRUE;
451	    init.gtt_start = pI830->memory_manager->offset;
452	    init.gtt_end = pI830->memory_manager->offset + pI830->memory_manager->size;
453
454	    /* Tell the kernel to manage it */
455	    ret = ioctl(pI830->drmSubFD, DRM_IOCTL_I915_GEM_INIT, &init);
456	    if (ret == 0) {
457		pI830->have_gem = TRUE;
458		i830_init_bufmgr(pScrn);
459	    } else {
460		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
461			   "Failed to initialize kernel memory manager\n");
462		i830_free_memory(pScrn, pI830->memory_manager);
463		pI830->memory_manager = NULL;
464	    }
465	} else {
466	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
467		       "Failed to allocate space for kernel memory manager\n");
468	}
469    }
470
471    return TRUE;
472}
473
474void
475i830_allocator_fini(ScrnInfoPtr pScrn)
476{
477    I830Ptr pI830 = I830PTR(pScrn);
478
479    /* Free most of the allocations */
480    i830_reset_allocations(pScrn);
481
482    /* The memory manager is more special */
483    if (pI830->memory_manager) {
484	 i830_free_memory(pScrn, pI830->memory_manager);
485	 pI830->memory_manager = NULL;
486    }
487
488    /* Free the start/end markers */
489    free(pI830->memory_list->next);
490    free(pI830->memory_list);
491    pI830->memory_list = NULL;
492}
493
494/**
495 * Reads a GTT entry for the memory at the given offset and returns the
496 * physical address.
497 *
498 * \return physical address if successful.
499 * \return (uint64_t)-1 if unsuccessful.
500 */
501static uint64_t
502i830_get_gtt_physical(ScrnInfoPtr pScrn, unsigned long offset)
503{
504    I830Ptr pI830 = I830PTR(pScrn);
505    uint32_t gttentry;
506
507    /* We don't have GTTBase set up on i830 yet. */
508    if (pI830->GTTBase == NULL)
509	return -1;
510
511    gttentry = INGTT(offset / 1024);
512
513    /* Mask out these reserved bits on this hardware. */
514    if (!IS_I9XX(pI830) || IS_I915G(pI830) || IS_I915GM(pI830) ||
515	IS_I945G(pI830) || IS_I945GM(pI830))
516    {
517	gttentry &= ~PTE_ADDRESS_MASK_HIGH;
518    }
519
520    /* If it's not a mapping type we know, then bail. */
521    if ((gttentry & PTE_MAPPING_TYPE_MASK) != PTE_MAPPING_TYPE_UNCACHED &&
522	(gttentry & PTE_MAPPING_TYPE_MASK) != PTE_MAPPING_TYPE_CACHED)
523    {
524	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
525		   "Unusable physical mapping type 0x%08x\n",
526		   (unsigned int)(gttentry & PTE_MAPPING_TYPE_MASK));
527	return -1;
528    }
529    assert((gttentry & PTE_VALID) != 0);
530
531    return (gttentry & PTE_ADDRESS_MASK) |
532	((uint64_t)(gttentry & PTE_ADDRESS_MASK_HIGH) << (32 - 4));
533}
534
535/**
536 * Reads the GTT entries for stolen memory at the given offset, returning the
537 * physical address.
538 *
539 * \return physical address if successful.
540 * \return (uint64_t)-1 if unsuccessful.
541 */
542static uint64_t
543i830_get_stolen_physical(ScrnInfoPtr pScrn, unsigned long offset,
544			 unsigned long size)
545{
546    I830Ptr pI830 = I830PTR(pScrn);
547    uint64_t physical;
548    unsigned long scan;
549
550    /* Check that the requested region is within stolen memory. */
551    if (offset + size >= pI830->stolen_size)
552	return -1;
553
554    physical = i830_get_gtt_physical(pScrn, offset);
555    if (physical == -1)
556	return -1;
557
558    /* Check that the following pages in our allocation follow the first page
559     * contiguously.
560     */
561    for (scan = offset + 4096; scan < offset + size; scan += 4096) {
562	uint64_t scan_physical = i830_get_gtt_physical(pScrn, scan);
563
564	if ((scan - offset) != (scan_physical - physical)) {
565	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
566		       "Non-contiguous GTT entries: (%ld,0x16%" PRIx64 ") vs "
567		       "(%ld,0x%" PRIx64 ")\n",
568		       scan, scan_physical, offset, physical);
569	    return -1;
570	}
571    }
572
573    return physical;
574}
575
576/* Allocate aperture space for the given size and alignment, and returns the
577 * memory allocation.
578 *
579 * Allocations are a minimum of a page, and will be at least page-aligned.
580 */
581static i830_memory *
582i830_allocate_aperture(ScrnInfoPtr pScrn, const char *name,
583		       unsigned long size, unsigned long pitch,
584		       unsigned long alignment, int flags,
585		       enum tile_format tile_format)
586{
587    I830Ptr pI830 = I830PTR(pScrn);
588    i830_memory *mem, *scan;
589
590    mem = xcalloc(1, sizeof(*mem));
591    if (mem == NULL)
592	return NULL;
593
594    /* No memory allocated to back the region */
595    mem->key = -1;
596
597    mem->name = xstrdup(name);
598    if (mem->name == NULL) {
599	xfree(mem);
600	return NULL;
601    }
602    /* Only allocate page-sized increments. */
603    size = ALIGN(size, GTT_PAGE_SIZE);
604    mem->size = size;
605    mem->allocated_size = size;
606    mem->alignment = alignment;
607    mem->tiling = tile_format;
608    mem->pitch = pitch;
609    mem->fence_nr = -1;
610
611    if (alignment < GTT_PAGE_SIZE)
612	alignment = GTT_PAGE_SIZE;
613
614    for (scan = pI830->memory_list; scan->next != NULL; scan = scan->next) {
615	mem->offset = ROUND_TO(scan->end, alignment);
616	if ((flags & NEED_PHYSICAL_ADDR) && mem->offset < pI830->stolen_size) {
617	    /* If the allocation is entirely within stolen memory, and we're
618	     * able to get the physical addresses out of the GTT and check that
619	     * it's contiguous (it ought to be), then we can do our physical
620	     * allocations there and not bother the kernel about it.  This
621	     * helps avoid aperture fragmentation from our physical
622	     * allocations.
623	     */
624	    mem->bus_addr = i830_get_stolen_physical(pScrn, mem->offset,
625						     mem->size);
626
627	    if (mem->bus_addr == ((uint64_t)-1)) {
628		/* Move the start of the allocation to just past the end of
629		 * stolen memory.
630		 */
631		mem->offset = ROUND_TO(pI830->stolen_size, alignment);
632	    }
633	}
634	if ((flags & NEED_NON_STOLEN) && mem->offset < pI830->stolen_size) {
635	    mem->offset = ROUND_TO(pI830->stolen_size, alignment);
636	}
637
638	mem->end = mem->offset + size;
639	if (flags & ALIGN_BOTH_ENDS)
640	    mem->end = ROUND_TO(mem->end, alignment);
641	if (mem->end <= scan->next->offset)
642	    break;
643    }
644    if (scan->next == NULL) {
645	/* Reached the end of the list, and didn't find space */
646	xfree(mem->name);
647	xfree(mem);
648	return NULL;
649    }
650    /* Insert new allocation into the list */
651    mem->prev = scan;
652    mem->next = scan->next;
653    scan->next = mem;
654    mem->next->prev = mem;
655
656    return mem;
657}
658
659/**
660 * Allocates the AGP memory necessary for the part of a memory allocation not
661 * already covered by the stolen memory.
662 *
663 * The memory is automatically bound if we have the VT.
664 */
665static Bool
666i830_allocate_agp_memory(ScrnInfoPtr pScrn, i830_memory *mem, int flags)
667{
668    I830Ptr pI830 = I830PTR(pScrn);
669    unsigned long size;
670
671    if (mem->key != -1)
672	return TRUE;
673
674    if (mem->offset + mem->size <= pI830->stolen_size)
675	return TRUE;
676
677    if (mem->offset < pI830->stolen_size)
678	mem->agp_offset = pI830->stolen_size;
679    else
680	mem->agp_offset = mem->offset;
681
682    size = mem->size - (mem->agp_offset - mem->offset);
683
684    if (flags & NEED_PHYSICAL_ADDR) {
685	unsigned long agp_bus_addr;
686
687	mem->key = xf86AllocateGARTMemory(pScrn->scrnIndex, size, 2,
688					  &agp_bus_addr);
689	mem->bus_addr = agp_bus_addr;
690    } else {
691	mem->key = xf86AllocateGARTMemory(pScrn->scrnIndex, size, 0, NULL);
692    }
693    if (mem->key == -1 || ((flags & NEED_PHYSICAL_ADDR) && mem->bus_addr == 0))
694    {
695	return FALSE;
696    }
697
698    return TRUE;
699}
700
701static i830_memory *
702i830_allocate_memory_bo(ScrnInfoPtr pScrn, const char *name,
703			unsigned long size, unsigned long pitch,
704			unsigned long align, int flags,
705			enum tile_format tile_format)
706{
707    I830Ptr pI830 = I830PTR(pScrn);
708    i830_memory *mem;
709    uint32_t bo_tiling_mode = I915_TILING_NONE;
710    int	    ret;
711
712    assert((flags & NEED_PHYSICAL_ADDR) == 0);
713
714    /* Only allocate page-sized increments. */
715    size = ALIGN(size, GTT_PAGE_SIZE);
716    align = i830_get_fence_alignment(pI830, size);
717
718    mem = xcalloc(1, sizeof(*mem));
719    if (mem == NULL)
720	return NULL;
721
722    mem->name = xstrdup(name);
723    if (mem->name == NULL) {
724	xfree(mem);
725	return NULL;
726    }
727
728    mem->bo = dri_bo_alloc (pI830->bufmgr, name, size, align);
729
730    if (!mem->bo) {
731	xfree(mem->name);
732	xfree(mem);
733	return NULL;
734    }
735
736    /* Give buffer obviously wrong offset/end until it's pinned. */
737    mem->offset = -1;
738    mem->end = -1;
739    mem->size = size;
740    mem->allocated_size = size;
741    mem->alignment = align;
742    mem->tiling = tile_format;
743    mem->pitch = pitch;
744    mem->fence_nr = -1;
745    if (flags & NEED_LIFETIME_FIXED)
746	mem->lifetime_fixed_offset = TRUE;
747
748    switch (tile_format) {
749    case TILE_XMAJOR:
750	bo_tiling_mode = I915_TILING_X;
751	break;
752    case TILE_YMAJOR:
753	bo_tiling_mode = I915_TILING_Y;
754	break;
755    case TILE_NONE:
756    default:
757	bo_tiling_mode = I915_TILING_NONE;
758	break;
759    }
760
761    ret = drm_intel_bo_set_tiling(mem->bo, &bo_tiling_mode, pitch);
762    if (ret != 0 || (bo_tiling_mode == I915_TILING_NONE && tile_format != TILE_NONE)) {
763	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
764		   "Failed to set tiling on %s: %s\n",
765		   mem->name,
766		   ret == 0 ? "rejected by kernel" : strerror(errno));
767	mem->tiling = TILE_NONE;
768    }
769    /* Bind it if we currently control the VT */
770    if (pScrn->vtSema || pI830->use_drm_mode) {
771	if (!i830_bind_memory(pScrn, mem)) {
772	    dri_bo_unreference (mem->bo);
773	    xfree(mem->name);
774	    xfree(mem);
775	    return NULL;
776	}
777    }
778
779    if (flags & DISABLE_REUSE)
780	drm_intel_bo_disable_reuse(mem->bo);
781
782    /* Insert new allocation into the list */
783    mem->prev = NULL;
784    mem->next = pI830->bo_list;
785    if (pI830->bo_list != NULL)
786	pI830->bo_list->prev = mem;
787    pI830->bo_list = mem;
788
789    return mem;
790}
791
792/* Allocates video memory at the given size, pitch, alignment and tile format.
793 *
794 * The memory will be bound automatically when the driver is in control of the
795 * VT.  When the kernel memory manager is available and compatible with flags
796 * (that is, flags doesn't say that the allocation must include a physical
797 * address), that will be used for the allocation.
798 *
799 * flags:
800 * - NEED_PHYSICAL_ADDR: Allocates the memory physically contiguous, and return
801 *   the bus address for that memory.
802 * - ALIGN_BOTH_ENDS: after choosing the alignment, align the end offset to
803 *   @alignment as well.
804 * - NEED_NON-STOLEN: don't allow any part of the memory allocation to lie
805 *   within stolen memory
806 * - NEED_LIFETIME_FIXED: don't allow the buffer object to move throughout
807 *   the entire Screen lifetime.  This means not using buffer objects, which
808 *   get their offsets chosen at each EnterVT time.
809 */
810i830_memory *
811i830_allocate_memory(ScrnInfoPtr pScrn, const char *name,
812		     unsigned long size, unsigned long pitch,
813		     unsigned long alignment, int flags,
814		     enum tile_format tile_format)
815{
816    i830_memory *mem;
817    I830Ptr pI830 = I830PTR(pScrn);
818
819    /* Manage tile alignment and size constraints */
820    if (tile_format != TILE_NONE) {
821	/* Only allocate page-sized increments. */
822	size = ALIGN(size, GTT_PAGE_SIZE);
823
824	/* Check for maximum tiled region size */
825	if (IS_I9XX(pI830)) {
826	    if (size > MB(128))
827		return NULL;
828	} else {
829	    if (size > MB(64))
830		return NULL;
831	}
832
833	/* round to size necessary for the fence register to work */
834	size = i830_get_fence_size(pI830, size);
835	alignment = i830_get_fence_alignment(pI830, size);
836    }
837    /*
838     * Create a kernel buffer object when suitable.
839     * Under KMS, all graphics memory must be managed by the
840     * kernel. Under UMS, we separately reserve space for
841     * a few objects (overlays, power context, cursors, etc).
842     */
843    if (pI830->have_gem &&
844	(pI830->use_drm_mode ||
845	 !(flags & (NEED_PHYSICAL_ADDR|NEED_LIFETIME_FIXED))))
846    {
847	return i830_allocate_memory_bo(pScrn, name, size, pitch, alignment, flags, tile_format);
848    } else
849    {
850	mem = i830_allocate_aperture(pScrn, name, size, pitch, alignment, flags, tile_format);
851	if (mem == NULL)
852	    return NULL;
853
854	if (!i830_allocate_agp_memory(pScrn, mem, flags)) {
855	    i830_free_memory(pScrn, mem);
856	    return NULL;
857	}
858
859	if (!i830_bind_memory(pScrn, mem)) {
860	    i830_free_memory(pScrn, mem);
861	    return NULL;
862	}
863    }
864
865    return mem;
866}
867
868void
869i830_describe_allocations(ScrnInfoPtr pScrn, int verbosity, const char *prefix)
870{
871    I830Ptr pI830 = I830PTR(pScrn);
872    i830_memory *mem;
873
874    if (pI830->memory_list == NULL) {
875	xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
876		       "%sMemory allocator not initialized\n", prefix);
877	return;
878    }
879
880    if (pI830->memory_list->next->next == NULL) {
881	xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
882		       "%sNo memory allocations\n", prefix);
883	return;
884    }
885
886    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
887		   "%sFixed memory allocation layout:\n", prefix);
888
889    for (mem = pI830->memory_list->next; mem->next != NULL; mem = mem->next) {
890	char phys_suffix[32] = "";
891	char *tile_suffix = "";
892
893	if (mem->offset >= pI830->stolen_size &&
894	    mem->prev->offset < pI830->stolen_size)
895	{
896	    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
897			   "%s0x%08lx:            end of stolen memory\n",
898			   prefix, pI830->stolen_size);
899	}
900
901	if (mem->bus_addr != 0)
902	    snprintf(phys_suffix, sizeof(phys_suffix),
903		    ", 0x%016" PRIx64 " physical\n", mem->bus_addr);
904	if (mem->tiling == TILE_XMAJOR)
905	    tile_suffix = " X tiled";
906	else if (mem->tiling == TILE_YMAJOR)
907	    tile_suffix = " Y tiled";
908
909	xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
910		       "%s0x%08lx-0x%08lx: %s (%ld kB%s)%s\n", prefix,
911		       mem->offset, mem->end - 1, mem->name,
912		       mem->size / 1024, phys_suffix, tile_suffix);
913    }
914    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
915		   "%s0x%08lx:            end of aperture\n",
916		   prefix, pI830->FbMapSize);
917
918    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
919		   "%sBO memory allocation layout:\n", prefix);
920    if (pI830->memory_manager) {
921	xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
922		       "%s0x%08lx:            start of memory manager\n",
923		       prefix, pI830->memory_manager->offset);
924    }
925    for (mem = pI830->bo_list; mem != NULL; mem = mem->next) {
926	char *tile_suffix = "";
927
928	if (mem->tiling == TILE_XMAJOR)
929	    tile_suffix = " X tiled";
930	else if (mem->tiling == TILE_YMAJOR)
931	    tile_suffix = " Y tiled";
932
933	if (mem->bound) {
934	    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
935			   "%s0x%08lx-0x%08lx: %s (%ld kB)%s\n", prefix,
936			   mem->offset, mem->end - 1, mem->name,
937			   mem->size / 1024, tile_suffix);
938	} else {
939	    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
940			   "%sunpinned          : %s (%ld kB)%s\n", prefix,
941			   mem->name, mem->size / 1024, tile_suffix);
942	}
943    }
944    if (pI830->memory_manager) {
945	xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
946		       "%s0x%08lx:            end of memory manager\n",
947		       prefix, pI830->memory_manager->end);
948    }
949}
950
951static Bool
952i830_allocate_ringbuffer(ScrnInfoPtr pScrn)
953{
954    I830Ptr pI830 = I830PTR(pScrn);
955
956    if (pI830->have_gem || pI830->ring.mem != NULL)
957	return TRUE;
958
959    /* We don't have any mechanism in the DRM yet to alert it that we've moved
960     * the ringbuffer since init time, so allocate it fixed for its lifetime.
961     */
962    pI830->ring.mem = i830_allocate_memory(pScrn, "ring buffer",
963					   PRIMARY_RINGBUFFER_SIZE, PITCH_NONE,
964					   GTT_PAGE_SIZE,
965					   NEED_LIFETIME_FIXED, TILE_NONE);
966    if (pI830->ring.mem == NULL) {
967	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
968		   "Failed to allocate Ring Buffer space\n");
969	return FALSE;
970    }
971
972    pI830->ring.tail_mask = pI830->ring.mem->size - 1;
973    pI830->ring.virtual_start = pI830->FbBase + pI830->ring.mem->offset;
974    return TRUE;
975}
976
977/**
978 * Allocate space for overlay registers.
979 */
980static Bool
981i830_allocate_overlay(ScrnInfoPtr pScrn)
982{
983    I830Ptr pI830 = I830PTR(pScrn);
984    int flags = 0;
985
986    /* Only allocate if overlay is going to be enabled. */
987    if (!pI830->XvEnabled)
988	return TRUE;
989
990    if (OVERLAY_NOEXIST(pI830))
991	return TRUE;
992
993    if (!OVERLAY_NOPHYSICAL(pI830)) {
994	if (pI830->use_drm_mode)
995            return TRUE;
996	flags |= NEED_PHYSICAL_ADDR;
997    }
998
999    pI830->overlay_regs = i830_allocate_memory(pScrn, "overlay registers",
1000					       OVERLAY_SIZE, PITCH_NONE, GTT_PAGE_SIZE,
1001					       flags, TILE_NONE);
1002    if (pI830->overlay_regs == NULL) {
1003	xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
1004		   "Failed to allocate Overlay register space.\n");
1005	/* This failure isn't fatal. */
1006    }
1007
1008    if (flags & NEED_PHYSICAL_ADDR)
1009	if (pI830->use_drm_mode)
1010	    ; /* need physical addr */
1011
1012    return TRUE;
1013}
1014
1015static Bool
1016IsTileable(ScrnInfoPtr pScrn, int pitch)
1017{
1018    I830Ptr pI830 = I830PTR(pScrn);
1019
1020    if (IS_I965G(pI830)) {
1021	if (pitch / 512 * 512 == pitch && pitch <= KB(128))
1022	    return TRUE;
1023	else
1024	    return FALSE;
1025    }
1026
1027    /*
1028     * Allow tiling for pitches that are a power of 2 multiple of 128 bytes,
1029     * up to 64 * 128 (= 8192) bytes.
1030     */
1031    switch (pitch) {
1032    case 128:
1033    case 256:
1034	if (IS_I945G(pI830) || IS_I945GM(pI830) || IS_G33CLASS(pI830))
1035	    return TRUE;
1036	else
1037	    return FALSE;
1038    case 512:
1039    case KB(1):
1040    case KB(2):
1041    case KB(4):
1042    case KB(8):
1043	return TRUE;
1044    default:
1045	return FALSE;
1046    }
1047}
1048
1049/**
1050 * Allocates a framebuffer for a screen.
1051 *
1052 * Used once for each X screen, so once with RandR 1.2 and twice with classic
1053 * dualhead.
1054 */
1055i830_memory *
1056i830_allocate_framebuffer(ScrnInfoPtr pScrn)
1057{
1058    I830Ptr pI830 = I830PTR(pScrn);
1059    unsigned int pitch = pScrn->displayWidth * pI830->cpp;
1060    unsigned long minspace;
1061    int align;
1062    long size, fb_height;
1063    int flags;
1064    i830_memory *front_buffer = NULL;
1065    enum tile_format tile_format = TILE_NONE;
1066
1067    flags = ALLOW_SHARING|DISABLE_REUSE;
1068
1069    /* We'll allocate the fb such that the root window will fit regardless of
1070     * rotation.
1071     */
1072    fb_height = pScrn->virtualY;
1073
1074    /* Calculate how much framebuffer memory to allocate.  For the
1075     * initial allocation, calculate a reasonable minimum.  This is
1076     * enough for the virtual screen size.
1077     */
1078    minspace = pitch * pScrn->virtualY;
1079
1080    size = ROUND_TO_PAGE(pitch * fb_height);
1081
1082    if (pI830->tiling)
1083	tile_format = TILE_XMAJOR;
1084
1085    if (!IsTileable(pScrn, pitch))
1086	tile_format = TILE_NONE;
1087
1088    if (!i830_check_display_stride(pScrn, pitch, tile_format != TILE_NONE)) {
1089	xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Front buffer stride %d kB "
1090		"exceed display limit\n", pitch/1024);
1091	return NULL;
1092    }
1093
1094    /* Attempt to allocate it tiled first if we have page flipping on. */
1095    if (tile_format != TILE_NONE) {
1096	/* XXX: probably not the case on 965 */
1097	if (IS_I9XX(pI830))
1098	    align = MB(1);
1099	else
1100	    align = KB(512);
1101    } else
1102	align = KB(64);
1103    front_buffer = i830_allocate_memory(pScrn, "front buffer", size,
1104					pitch, align, flags,
1105					tile_format);
1106
1107    if (front_buffer == NULL) {
1108	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1109		   "Failed to allocate framebuffer.\n");
1110	return NULL;
1111    }
1112
1113    if (pI830->FbBase && front_buffer->bound)
1114	memset (pI830->FbBase + front_buffer->offset, 0, size);
1115
1116    i830_set_max_gtt_map_size(pScrn);
1117
1118    return front_buffer;
1119}
1120
1121static Bool
1122i830_allocate_cursor_buffers(ScrnInfoPtr pScrn)
1123{
1124    I830Ptr pI830 = I830PTR(pScrn);
1125    xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
1126    int flags;
1127    int i;
1128    long size;
1129
1130    if (pI830->use_drm_mode)
1131	pI830->CursorNeedsPhysical = FALSE;
1132
1133    flags = pI830->CursorNeedsPhysical ? NEED_PHYSICAL_ADDR : 0;
1134
1135    flags |= DISABLE_REUSE;
1136
1137    if (!pI830->use_drm_mode) {
1138	/* Try to allocate one big blob for our cursor memory.  This works
1139	 * around a limitation in the FreeBSD AGP driver that allows only one
1140	 * physical allocation larger than a page, and could allow us
1141	 * to pack the cursors smaller.
1142	 */
1143	size = xf86_config->num_crtc * (HWCURSOR_SIZE + HWCURSOR_SIZE_ARGB);
1144
1145	pI830->cursor_mem = i830_allocate_memory(pScrn, "HW cursors",
1146						 size, PITCH_NONE, GTT_PAGE_SIZE,
1147						 flags, TILE_NONE);
1148	if (pI830->cursor_mem != NULL)
1149	    return TRUE;
1150    }
1151
1152    /*
1153     * Allocate four separate buffers when the kernel doesn't support
1154     * large allocations as on Linux. If any of these fail, just
1155     * bail back to software cursors everywhere
1156     */
1157    for (i = 0; i < xf86_config->num_crtc; i++)
1158    {
1159	if (!pI830->use_drm_mode) {
1160	    pI830->cursor_mem_classic[i] = i830_allocate_memory (pScrn,
1161								 "Core cursor",
1162								 HWCURSOR_SIZE,
1163								 PITCH_NONE,
1164								 GTT_PAGE_SIZE,
1165								 flags,
1166								 TILE_NONE);
1167	    if (!pI830->cursor_mem_classic[i])
1168		return FALSE;
1169	}
1170	pI830->cursor_mem_argb[i] = i830_allocate_memory (pScrn, "ARGB cursor",
1171							  HWCURSOR_SIZE_ARGB,
1172							  PITCH_NONE,
1173							  GTT_PAGE_SIZE,
1174							  flags,
1175							  TILE_NONE);
1176	if (!pI830->cursor_mem_argb[i])
1177	    return FALSE;
1178
1179    }
1180    return TRUE;
1181}
1182
1183static void i830_setup_fb_compression(ScrnInfoPtr pScrn)
1184{
1185    I830Ptr pI830 = I830PTR(pScrn);
1186    unsigned long compressed_size;
1187    unsigned long fb_height;
1188
1189    if (pScrn->virtualX > pScrn->virtualY)
1190	fb_height = pScrn->virtualX;
1191    else
1192	fb_height = pScrn->virtualY;
1193
1194    /* Only mobile chips since 845 support this feature */
1195    if (!IS_MOBILE(pI830)) {
1196	pI830->fb_compression = FALSE;
1197	goto out;
1198    }
1199
1200    if (IS_GM45(pI830)) {
1201	/* Update i830_display.c too if compression ratio changes */
1202	compressed_size = fb_height * (pScrn->displayWidth / 4);
1203    } else {
1204	compressed_size = MB(6);
1205    }
1206
1207    /*
1208     * Compressed framebuffer limitations:
1209     *   - contiguous, physical, uncached memory
1210     *   - ideally as large as the front buffer(s), smaller sizes cache less
1211     *   - uncompressed buffer must be tiled w/pitch 2k-16k
1212     *   - uncompressed fb is <= 2048 in width, 0 mod 8
1213     *   - uncompressed fb is <= 1536 in height, 0 mod 2
1214     *   - compressed fb stride is <= uncompressed stride
1215     *   - SR display watermarks must be equal between 16bpp and 32bpp?
1216     *   - both compressed and line buffers must be in stolen memory
1217     */
1218    pI830->compressed_front_buffer =
1219	i830_allocate_memory(pScrn, "compressed frame buffer",
1220			     compressed_size, PITCH_NONE,
1221			     KB(4), NEED_PHYSICAL_ADDR,
1222			     TILE_NONE);
1223
1224    if (!pI830->compressed_front_buffer) {
1225	pI830->fb_compression = FALSE;
1226	goto out;
1227    }
1228
1229    if (!IS_GM45(pI830)) {
1230	pI830->compressed_ll_buffer =
1231	    i830_allocate_memory(pScrn, "compressed ll buffer",
1232				 FBC_LL_SIZE + FBC_LL_PAD,
1233				 PITCH_NONE, KB(4),
1234				 NEED_PHYSICAL_ADDR,
1235				 TILE_NONE);
1236	if (!pI830->compressed_ll_buffer) {
1237	    i830_free_memory(pScrn, pI830->compressed_front_buffer);
1238	    pI830->fb_compression = FALSE;
1239	    goto out;
1240	}
1241    }
1242
1243out:
1244    if (!pI830->fb_compression)
1245	xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Allocation error, framebuffer"
1246		   " compression disabled\n");
1247
1248    return;
1249}
1250/*
1251 * Allocate memory for 2D operation.  This includes the (front) framebuffer,
1252 * ring buffer, scratch memory, HW cursor.
1253 */
1254Bool
1255i830_allocate_2d_memory(ScrnInfoPtr pScrn)
1256{
1257    I830Ptr pI830 = I830PTR(pScrn);
1258
1259    if (!pI830->use_drm_mode) {
1260	if (!xf86AgpGARTSupported() || !xf86AcquireGART(pScrn->scrnIndex)) {
1261	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1262		       "AGP GART support is either not available or cannot "
1263		       "be used.\n"
1264		       "\tMake sure your kernel has agpgart support or has\n"
1265		       "\tthe agpgart module loaded.\n");
1266	    return FALSE;
1267	}
1268
1269	/* Allocate the ring buffer first, so it ends up in stolen mem. */
1270	if (!i830_allocate_ringbuffer(pScrn))
1271	    return FALSE;
1272    }
1273
1274    if (pI830->fb_compression)
1275	i830_setup_fb_compression(pScrn);
1276
1277    /* Next, allocate other fixed-size allocations we have. */
1278    if (!i830_allocate_cursor_buffers(pScrn)) {
1279	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1280		   "Failed to allocate HW cursor space.\n");
1281	return FALSE;
1282    }
1283
1284    if (!pI830->have_gem) {
1285	pI830->fake_bufmgr_mem = i830_allocate_memory(pScrn, "fake bufmgr",
1286						      MB(8), PITCH_NONE, GTT_PAGE_SIZE, 0,
1287						      TILE_NONE);
1288	if (pI830->fake_bufmgr_mem == NULL) {
1289	    xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
1290		       "Failed to allocate fake bufmgr space.\n");
1291	    return FALSE;
1292	}
1293	i830_init_bufmgr(pScrn);
1294    }
1295
1296    if (!pI830->use_drm_mode)
1297	i830_allocate_overlay(pScrn);
1298
1299    pI830->front_buffer = i830_allocate_framebuffer(pScrn);
1300    if (pI830->front_buffer == NULL)
1301	return FALSE;
1302
1303    return TRUE;
1304}
1305
1306Bool
1307i830_allocate_pwrctx(ScrnInfoPtr pScrn)
1308{
1309    I830Ptr pI830 = I830PTR(pScrn);
1310
1311    if (pI830->use_drm_mode)
1312	return TRUE;
1313
1314    pI830->power_context = i830_allocate_memory(pScrn, "power context",
1315						PWRCTX_SIZE, PITCH_NONE,
1316						GTT_PAGE_SIZE,
1317						NEED_LIFETIME_FIXED,
1318						TILE_NONE);
1319    if (!pI830->power_context) {
1320	xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
1321		"Failed to allocate power context.\n");
1322	return FALSE;
1323    }
1324    return TRUE;
1325}
1326
1327/**
1328 * Sets up tiled surface registers ("fences") for the hardware.
1329 *
1330 * The fences control automatic tiled address swizzling for CPU access of the
1331 * framebuffer, and may be used in many rendering operations instead of
1332 * manually supplying tiling enables per surface.
1333 */
1334static int
1335i830_set_tiling(ScrnInfoPtr pScrn, unsigned int offset,
1336		unsigned int pitch, unsigned int size,
1337		enum tile_format tile_format)
1338{
1339    I830Ptr pI830 = I830PTR(pScrn);
1340    uint32_t val;
1341    uint32_t fence_mask = 0;
1342    unsigned int fence_pitch;
1343    unsigned int max_fence;
1344    unsigned int fence_nr;
1345
1346    DPRINTF(PFX, "i830_set_tiling(): 0x%08x, %d, %d kByte\n",
1347	    offset, pitch, size / 1024);
1348
1349    assert(tile_format != TILE_NONE);
1350
1351    I830Sync(pScrn);
1352
1353    if (IS_I965G(pI830))
1354	max_fence = FENCE_NEW_NR;
1355    else
1356	max_fence = FENCE_NR;
1357
1358    for (fence_nr = 0; fence_nr < max_fence; fence_nr++) {
1359	if (!pI830->fence_used[fence_nr])
1360	    break;
1361    }
1362    if (fence_nr == max_fence)
1363	FatalError("Ran out of fence registers at %d\n", fence_nr);
1364
1365    pI830->fence_used[fence_nr] = TRUE;
1366
1367    if (IS_I965G(pI830)) {
1368	uint32_t fence_start, fence_end;
1369
1370	switch (tile_format) {
1371	case TILE_XMAJOR:
1372	    fence_start = (((pitch / 128) - 1) << 2) | offset | 1;
1373	    fence_start |= I965_FENCE_X_MAJOR;
1374            break;
1375	case TILE_YMAJOR:
1376            /* YMajor can be 128B aligned but the current code dictates
1377             * otherwise. This isn't a problem apart from memory waste.
1378             * FIXME */
1379	    fence_start = (((pitch / 128) - 1) << 2) | offset | 1;
1380	    fence_start |= I965_FENCE_Y_MAJOR;
1381            break;
1382	default:
1383	    return -1;
1384	}
1385
1386	/* The end marker is the address of the last page in the allocation. */
1387	fence_end = offset + size - 4096;
1388
1389	OUTREG(FENCE_NEW + fence_nr * 8, fence_start);
1390	OUTREG(FENCE_NEW + fence_nr * 8 + 4, fence_end);
1391    } else {
1392	if (IS_I9XX(pI830))
1393	    fence_mask = ~I915G_FENCE_START_MASK;
1394	else
1395	    fence_mask = ~I830_FENCE_START_MASK;
1396
1397	if (offset & fence_mask) {
1398	    FatalError("i830_set_tiling(): %d: offset (0x%08x) is not %s "
1399		       "aligned\n",
1400		       fence_nr, offset, (IS_I9XX(pI830)) ? "1MB" : "512k");
1401	}
1402
1403	if (offset % size) {
1404	    FatalError("i830_set_tiling(): %d: offset (0x%08x) is not "
1405		       "size (%dk) aligned\n",
1406		       fence_nr, offset, size / 1024);
1407	}
1408
1409	if (pitch & 127) {
1410	    FatalError("i830_set_tiling(): %d: pitch (%d) not a multiple of "
1411		       "128 bytes\n",
1412		       fence_nr, pitch);
1413	}
1414
1415	val = offset | FENCE_VALID;
1416
1417	switch (tile_format) {
1418	case TILE_XMAJOR:
1419	    val |= FENCE_X_MAJOR;
1420	    break;
1421	case TILE_YMAJOR:
1422	    val |= FENCE_Y_MAJOR;
1423	    break;
1424	case TILE_NONE:
1425	    break;
1426	}
1427
1428	if (IS_I9XX(pI830)) {
1429	    switch (size) {
1430	    case MB(1):
1431		val |= I915G_FENCE_SIZE_1M;
1432		break;
1433	    case MB(2):
1434		val |= I915G_FENCE_SIZE_2M;
1435		break;
1436	    case MB(4):
1437		val |= I915G_FENCE_SIZE_4M;
1438		break;
1439	    case MB(8):
1440		val |= I915G_FENCE_SIZE_8M;
1441		break;
1442	    case MB(16):
1443		val |= I915G_FENCE_SIZE_16M;
1444		break;
1445	    case MB(32):
1446		val |= I915G_FENCE_SIZE_32M;
1447		break;
1448	    case MB(64):
1449		val |= I915G_FENCE_SIZE_64M;
1450		break;
1451	    default:
1452		FatalError("i830_set_tiling(): %d: illegal size (%d kByte)\n",
1453			   fence_nr, size / 1024);
1454	    }
1455	} else {
1456	    switch (size) {
1457	    case KB(512):
1458		val |= FENCE_SIZE_512K;
1459		break;
1460	    case MB(1):
1461		val |= FENCE_SIZE_1M;
1462		break;
1463	    case MB(2):
1464		val |= FENCE_SIZE_2M;
1465		break;
1466	    case MB(4):
1467		val |= FENCE_SIZE_4M;
1468		break;
1469	    case MB(8):
1470		val |= FENCE_SIZE_8M;
1471		break;
1472	    case MB(16):
1473		val |= FENCE_SIZE_16M;
1474		break;
1475	    case MB(32):
1476		val |= FENCE_SIZE_32M;
1477		break;
1478	    case MB(64):
1479		val |= FENCE_SIZE_64M;
1480		break;
1481	    default:
1482		FatalError("i830_set_tiling(): %d: illegal size (%d kByte)\n",
1483			   fence_nr, size / 1024);
1484	    }
1485	}
1486
1487	if ((IS_I945G(pI830) || IS_I945GM(pI830) || IS_G33CLASS(pI830)) &&
1488	    tile_format == TILE_YMAJOR)
1489	    fence_pitch = pitch / 128;
1490	else if (IS_I9XX(pI830))
1491	    fence_pitch = pitch / 512;
1492	else
1493	    fence_pitch = pitch / 128;
1494
1495	switch (fence_pitch) {
1496	case 1:
1497	    val |= FENCE_PITCH_1;
1498	    break;
1499	case 2:
1500	    val |= FENCE_PITCH_2;
1501	    break;
1502	case 4:
1503	    val |= FENCE_PITCH_4;
1504	    break;
1505	case 8:
1506	    val |= FENCE_PITCH_8;
1507	    break;
1508	case 16:
1509	    val |= FENCE_PITCH_16;
1510	    break;
1511	case 32:
1512	    val |= FENCE_PITCH_32;
1513	    break;
1514	case 64:
1515	    val |= FENCE_PITCH_64;
1516	    break;
1517	default:
1518	    FatalError("i830_set_tiling(): %d: illegal pitch (%d)\n",
1519		       fence_nr, pitch);
1520	}
1521
1522	OUTREG(FENCE + fence_nr * 4, val);
1523    }
1524
1525    return fence_nr;
1526}
1527
1528static void
1529i830_clear_tiling(ScrnInfoPtr pScrn, unsigned int fence_nr)
1530{
1531    I830Ptr pI830 = I830PTR(pScrn);
1532
1533    if (IS_I965G(pI830)) {
1534	OUTREG(FENCE_NEW + fence_nr * 8, 0);
1535	OUTREG(FENCE_NEW + fence_nr * 8 + 4, 0);
1536    } else {
1537	OUTREG(FENCE + fence_nr * 4, 0);
1538    }
1539    pI830->fence_used[fence_nr] = FALSE;
1540}
1541
1542/**
1543 * Called at EnterVT to grab the AGP GART and bind our allocations.
1544 *
1545 * In zaphod mode, this will walk the list trying to bind twice, since each
1546 * pI830 points to the same allocation list, but the bind_memory will just
1547 * no-op then.
1548 */
1549Bool
1550i830_bind_all_memory(ScrnInfoPtr pScrn)
1551{
1552    I830Ptr pI830 = I830PTR(pScrn);
1553
1554    if (pI830->memory_list == NULL)
1555	return TRUE;
1556
1557    if (pI830->use_drm_mode || (xf86AgpGARTSupported() &&
1558				!pI830->gtt_acquired)) {
1559	i830_memory *mem;
1560
1561	if (!pI830->use_drm_mode) {
1562	    if (!xf86AcquireGART(pScrn->scrnIndex))
1563		return FALSE;
1564	    pI830->gtt_acquired = TRUE;
1565	}
1566
1567	for (mem = pI830->memory_list->next; mem->next != NULL;
1568	     mem = mem->next)
1569	{
1570	    if (!mem->bound && !i830_bind_memory(pScrn, mem)) {
1571		/* This shouldn't happen */
1572		FatalError("Couldn't bind memory for %s\n", mem->name);
1573	    }
1574	}
1575	for (mem = pI830->bo_list; mem != NULL; mem = mem->next) {
1576	    if (mem->bound)
1577		continue;
1578	    if (!mem->lifetime_fixed_offset && !i830_bind_memory(pScrn, mem))
1579		FatalError("Couldn't bind memory for BO %s\n", mem->name);
1580	}
1581    }
1582    if (pI830->use_drm_mode) {
1583	int	i;
1584	xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
1585	for (i = 0; i < xf86_config->num_crtc; i++)
1586	    drmmode_crtc_set_cursor_bo(xf86_config->crtc[i], pI830->cursor_mem_argb[i]->bo);
1587    } else
1588	i830_update_cursor_offsets(pScrn);
1589    i830_set_max_gtt_map_size(pScrn);
1590
1591    if (pI830->front_buffer)
1592	pScrn->fbOffset = pI830->front_buffer->offset;
1593
1594    return TRUE;
1595}
1596
1597/** Called at LeaveVT, to unbind all of our AGP allocations. */
1598Bool
1599i830_unbind_all_memory(ScrnInfoPtr pScrn)
1600{
1601    I830Ptr pI830 = I830PTR(pScrn);
1602
1603    if (pI830->use_drm_mode || (xf86AgpGARTSupported() &&
1604				pI830->gtt_acquired)) {
1605	i830_memory *mem;
1606
1607	for (mem = pI830->memory_list->next; mem->next != NULL;
1608	     mem = mem->next)
1609	{
1610	    i830_unbind_memory(pScrn, mem);
1611	}
1612	for (mem = pI830->bo_list; mem != NULL; mem = mem->next) {
1613	    /* Don't unpin objects which require that their offsets never
1614	     * change.
1615	     */
1616	    if (!mem->lifetime_fixed_offset)
1617		i830_unbind_memory(pScrn, mem);
1618	}
1619
1620	if (!pI830->use_drm_mode) {
1621	    pI830->gtt_acquired = FALSE;
1622
1623	    if (!xf86ReleaseGART(pScrn->scrnIndex))
1624		return FALSE;
1625	}
1626    }
1627
1628    return TRUE;
1629}
1630
1631/**
1632 * Returns the amount of system memory that could potentially be allocated
1633 * from AGP, in kB.
1634 */
1635long
1636I830CheckAvailableMemory(ScrnInfoPtr pScrn)
1637{
1638    AgpInfoPtr agpinf;
1639    int maxPages;
1640
1641    if (!xf86AgpGARTSupported() ||
1642	!xf86AcquireGART(pScrn->scrnIndex) ||
1643	(agpinf = xf86GetAGPInfo(pScrn->scrnIndex)) == NULL ||
1644	!xf86ReleaseGART(pScrn->scrnIndex))
1645	return -1;
1646
1647    maxPages = agpinf->totalPages - agpinf->usedPages;
1648    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 2, "%s: %d kB available\n",
1649		   "I830CheckAvailableMemory", maxPages * 4);
1650
1651    return maxPages * 4;
1652}
1653
1654#ifdef INTEL_XVMC
1655/*
1656 * Allocate memory for MC compensation
1657 */
1658Bool i830_allocate_xvmc_buffer(ScrnInfoPtr pScrn, const char *name,
1659                               i830_memory **buffer, unsigned long size,
1660                               int flags)
1661{
1662    I830Ptr pI830 = I830PTR(pScrn);
1663
1664    *buffer = i830_allocate_memory(pScrn, name, size, PITCH_NONE,
1665                                   GTT_PAGE_SIZE, flags, TILE_NONE);
1666
1667    if (!*buffer) {
1668        xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1669                   "Failed to allocate memory for %s.\n", name);
1670        return FALSE;
1671    }
1672
1673    if (pI830->use_drm_mode && (*buffer)->bo) {
1674        if (drm_intel_bo_pin((*buffer)->bo, GTT_PAGE_SIZE)) {
1675            i830_free_memory(pScrn, *buffer);
1676            xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1677                       "Failed to bind XvMC buffer bo!\n");
1678            return FALSE;
1679        }
1680
1681        (*buffer)->offset = (*buffer)->bo->offset;
1682    }
1683
1684    return TRUE;
1685}
1686
1687void
1688i830_free_xvmc_buffer(ScrnInfoPtr pScrn, i830_memory *buffer)
1689{
1690    I830Ptr pI830 = I830PTR(pScrn);
1691
1692    if (pI830->use_drm_mode && buffer->bo)
1693        drm_intel_bo_unpin(buffer->bo);
1694
1695    i830_free_memory(pScrn, buffer);
1696}
1697
1698#endif
1699
1700void
1701i830_set_max_gtt_map_size(ScrnInfoPtr pScrn)
1702{
1703    I830Ptr pI830 = I830PTR(pScrn);
1704    struct drm_i915_gem_get_aperture aperture;
1705    int ret;
1706
1707    /* Default low value in case it gets used during server init. */
1708    pI830->max_gtt_map_size = 16 * 1024 * 1024;
1709
1710    if (!pI830->have_gem)
1711	return;
1712
1713    ret = ioctl(pI830->drmSubFD, DRM_IOCTL_I915_GEM_GET_APERTURE, &aperture);
1714    if (ret == 0) {
1715	/* Let objects up get bound up to the size where only 2 would fit in
1716	 * the aperture, but then leave slop to account for alignment like
1717	 * libdrm does.
1718	 */
1719	pI830->max_gtt_map_size = aperture.aper_available_size * 3 / 4 / 2;
1720    }
1721}
1722