radeon_kms.c revision 921a55d8
1/*
2 * Copyright © 2009 Red Hat, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 * SOFTWARE.
22 *
23 * Authors:
24 *    Dave Airlie <airlied@redhat.com>
25 *
26 */
27#ifdef HAVE_CONFIG_H
28#include "config.h"
29#endif
30
31#include <errno.h>
32#include <sys/ioctl.h>
33/* Driver data structures */
34#include "radeon.h"
35#include "radeon_reg.h"
36#include "radeon_probe.h"
37#include "micmap.h"
38
39#include "shadow.h"
40
41#include "atipciids.h"
42
43
44#ifdef XF86DRM_MODE
45
46#include "radeon_chipset_gen.h"
47#include "radeon_chipinfo_gen.h"
48
49#define CURSOR_WIDTH	64
50#define CURSOR_HEIGHT	64
51
52#include "radeon_bo_gem.h"
53#include "radeon_cs_gem.h"
54#include "radeon_vbo.h"
55
56static Bool radeon_setup_kernel_mem(ScreenPtr pScreen);
57
58const OptionInfoRec RADEONOptions_KMS[] = {
59    { OPTION_NOACCEL,        "NoAccel",          OPTV_BOOLEAN, {0}, FALSE },
60    { OPTION_SW_CURSOR,      "SWcursor",         OPTV_BOOLEAN, {0}, FALSE },
61    { OPTION_PAGE_FLIP,      "EnablePageFlip",   OPTV_BOOLEAN, {0}, FALSE },
62    { OPTION_ACCEL_DFS,      "AccelDFS",         OPTV_BOOLEAN, {0}, FALSE },
63    { OPTION_IGNORE_EDID,    "IgnoreEDID",       OPTV_BOOLEAN, {0}, FALSE },
64    { OPTION_COLOR_TILING,   "ColorTiling",      OPTV_BOOLEAN, {0}, FALSE },
65    { OPTION_RENDER_ACCEL,   "RenderAccel",      OPTV_BOOLEAN, {0}, FALSE },
66    { OPTION_SUBPIXEL_ORDER, "SubPixelOrder",    OPTV_ANYSTR,  {0}, FALSE },
67    { OPTION_ACCELMETHOD,    "AccelMethod",      OPTV_STRING,  {0}, FALSE },
68    { OPTION_DRI,            "DRI",       	 OPTV_BOOLEAN, {0}, FALSE },
69    { OPTION_TVSTD,          "TVStandard",       OPTV_STRING,  {0}, FALSE },
70    { OPTION_EXA_VSYNC,      "EXAVSync",         OPTV_BOOLEAN, {0}, FALSE },
71    { OPTION_EXA_PIXMAPS,    "EXAPixmaps",	 OPTV_BOOLEAN,   {0}, FALSE },
72    { OPTION_ZAPHOD_HEADS,   "ZaphodHeads",      OPTV_STRING,  {0}, FALSE },
73    { OPTION_PAGE_FLIP,      "EnablePageFlip",   OPTV_BOOLEAN, {0}, FALSE },
74    { OPTION_SWAPBUFFERS_WAIT,"SwapbuffersWait", OPTV_BOOLEAN, {0}, FALSE },
75    { -1,                    NULL,               OPTV_NONE,    {0}, FALSE }
76};
77
78void radeon_cs_flush_indirect(ScrnInfoPtr pScrn)
79{
80    RADEONInfoPtr  info = RADEONPTR(pScrn);
81    struct radeon_accel_state *accel_state = info->accel_state;
82    int ret;
83
84    if (!info->cs->cdw)
85	return;
86
87    /* release the current VBO so we don't block on mapping it later */
88    if (info->accel_state->vbo.vb_offset && info->accel_state->vbo.vb_bo) {
89        radeon_vbo_put(pScrn, &info->accel_state->vbo);
90        info->accel_state->vbo.vb_start_op = -1;
91    }
92
93    /* release the current VBO so we don't block on mapping it later */
94    if (info->accel_state->cbuf.vb_bo) {
95        radeon_vbo_put(pScrn, &info->accel_state->cbuf);
96        info->accel_state->cbuf.vb_start_op = -1;
97    }
98
99    radeon_cs_emit(info->cs);
100    radeon_cs_erase(info->cs);
101
102    if (accel_state->use_vbos)
103        radeon_vbo_flush_bos(pScrn);
104
105    ret = radeon_cs_space_check_with_bo(info->cs,
106					accel_state->vbo.vb_bo,
107					RADEON_GEM_DOMAIN_GTT, 0);
108    if (ret)
109      ErrorF("space check failed in flush\n");
110
111    if (info->reemit_current2d && info->state_2d.op)
112        info->reemit_current2d(pScrn, info->state_2d.op);
113
114    if (info->dri2.enabled) {
115        info->accel_state->XInited3D = FALSE;
116        info->accel_state->engineMode = EXA_ENGINEMODE_UNKNOWN;
117    }
118
119}
120
121void radeon_ddx_cs_start(ScrnInfoPtr pScrn,
122			 int n, const char *file,
123			 const char *func, int line)
124{
125    RADEONInfoPtr  info = RADEONPTR(pScrn);
126
127    if (info->cs->cdw + n > info->cs->ndw) {
128	radeon_cs_flush_indirect(pScrn);
129
130    }
131    radeon_cs_begin(info->cs, n, file, func, line);
132}
133
134
135extern _X_EXPORT int gRADEONEntityIndex;
136
137static int getRADEONEntityIndex(void)
138{
139    return gRADEONEntityIndex;
140}
141
142static void *
143radeonShadowWindow(ScreenPtr screen, CARD32 row, CARD32 offset, int mode,
144		   CARD32 *size, void *closure)
145{
146    ScrnInfoPtr pScrn = xf86Screens[screen->myNum];
147    RADEONInfoPtr  info   = RADEONPTR(pScrn);
148    int stride;
149
150    stride = (pScrn->displayWidth * pScrn->bitsPerPixel) / 8;
151    *size = stride;
152
153    return ((uint8_t *)info->front_bo->ptr + row * stride + offset);
154}
155
156static Bool RADEONCreateScreenResources_KMS(ScreenPtr pScreen)
157{
158    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
159    RADEONInfoPtr  info   = RADEONPTR(pScrn);
160    PixmapPtr pixmap;
161
162    pScreen->CreateScreenResources = info->CreateScreenResources;
163    if (!(*pScreen->CreateScreenResources)(pScreen))
164	return FALSE;
165    pScreen->CreateScreenResources = RADEONCreateScreenResources_KMS;
166
167    if (!drmmode_set_desired_modes(pScrn, &info->drmmode))
168	return FALSE;
169
170    drmmode_uevent_init(pScrn, &info->drmmode);
171
172    if (info->r600_shadow_fb) {
173	pixmap = pScreen->GetScreenPixmap(pScreen);
174
175	if (!shadowAdd(pScreen, pixmap, shadowUpdatePackedWeak(),
176		       radeonShadowWindow, 0, NULL))
177	    return FALSE;
178    }
179
180    if (info->dri2.enabled) {
181	if (info->front_bo) {
182	    PixmapPtr pPix = pScreen->GetScreenPixmap(pScreen);
183	    radeon_set_pixmap_bo(pPix, info->front_bo);
184	}
185    }
186    return TRUE;
187}
188
189static void RADEONBlockHandler_KMS(int i, pointer blockData,
190				   pointer pTimeout, pointer pReadmask)
191{
192    ScreenPtr      pScreen = screenInfo.screens[i];
193    ScrnInfoPtr    pScrn   = xf86Screens[i];
194    RADEONInfoPtr  info    = RADEONPTR(pScrn);
195
196    pScreen->BlockHandler = info->BlockHandler;
197    (*pScreen->BlockHandler) (i, blockData, pTimeout, pReadmask);
198    pScreen->BlockHandler = RADEONBlockHandler_KMS;
199
200    if (info->VideoTimerCallback)
201	(*info->VideoTimerCallback)(pScrn, currentTime.milliseconds);
202    radeon_cs_flush_indirect(pScrn);
203}
204
205static void
206radeon_flush_callback(CallbackListPtr *list,
207		      pointer user_data, pointer call_data)
208{
209    ScrnInfoPtr pScrn = user_data;
210
211    if (pScrn->vtSema) {
212        radeon_cs_flush_indirect(pScrn);
213    }
214}
215
216static Bool RADEONIsAccelWorking(ScrnInfoPtr pScrn)
217{
218    RADEONInfoPtr info = RADEONPTR(pScrn);
219    struct drm_radeon_info ginfo;
220    int r;
221    uint32_t tmp;
222
223#ifndef RADEON_INFO_ACCEL_WORKING
224#define RADEON_INFO_ACCEL_WORKING 0x03
225#endif
226#ifndef RADEON_INFO_ACCEL_WORKING2
227#define RADEON_INFO_ACCEL_WORKING2 0x05
228#endif
229
230    memset(&ginfo, 0, sizeof(ginfo));
231    if (info->dri->pKernelDRMVersion->version_minor >= 5)
232	ginfo.request = RADEON_INFO_ACCEL_WORKING2;
233    else
234	ginfo.request = RADEON_INFO_ACCEL_WORKING;
235    ginfo.value = (uintptr_t)&tmp;
236    r = drmCommandWriteRead(info->dri->drmFD, DRM_RADEON_INFO, &ginfo, sizeof(ginfo));
237    if (r) {
238        /* If kernel is too old before 2.6.32 than assume accel is working */
239        if (r == -EINVAL) {
240            xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Kernel too old missing accel "
241                       "information, assuming accel is working\n");
242            return TRUE;
243        }
244        return FALSE;
245    }
246    if (tmp)
247        return TRUE;
248    return FALSE;
249}
250
251static Bool RADEONPreInitAccel_KMS(ScrnInfoPtr pScrn)
252{
253    RADEONInfoPtr  info = RADEONPTR(pScrn);
254
255    if (!(info->accel_state = calloc(1, sizeof(struct radeon_accel_state)))) {
256	xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Unable to allocate accel_state rec!\n");
257	return FALSE;
258    }
259
260    if (xf86ReturnOptValBool(info->Options, OPTION_NOACCEL, FALSE) ||
261	(!RADEONIsAccelWorking(pScrn))) {
262	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
263		   "GPU accel disabled or not working, using shadowfb for KMS\n");
264	info->r600_shadow_fb = TRUE;
265	if (!xf86LoadSubModule(pScrn, "shadow"))
266	    info->r600_shadow_fb = FALSE;
267	return TRUE;
268    }
269
270    if ((info->ChipFamily == CHIP_FAMILY_RS100) ||
271	(info->ChipFamily == CHIP_FAMILY_RS200) ||
272	(info->ChipFamily == CHIP_FAMILY_RS300) ||
273	(info->ChipFamily == CHIP_FAMILY_RS400) ||
274	(info->ChipFamily == CHIP_FAMILY_RS480) ||
275	(info->ChipFamily == CHIP_FAMILY_RS600) ||
276	(info->ChipFamily == CHIP_FAMILY_RS690) ||
277	(info->ChipFamily == CHIP_FAMILY_RS740))
278	info->accel_state->has_tcl = FALSE;
279    else {
280	info->accel_state->has_tcl = TRUE;
281    }
282
283    info->useEXA = TRUE;
284
285    if (info->useEXA) {
286	int errmaj = 0, errmin = 0;
287	info->exaReq.majorversion = EXA_VERSION_MAJOR;
288	info->exaReq.minorversion = EXA_VERSION_MINOR;
289	if (!LoadSubModule(pScrn->module, "exa", NULL, NULL, NULL,
290			   &info->exaReq, &errmaj, &errmin)) {
291	    LoaderErrorMsg(NULL, "exa", errmaj, errmin);
292	    return FALSE;
293	}
294    }
295
296    return TRUE;
297}
298
299static Bool RADEONPreInitChipType_KMS(ScrnInfoPtr pScrn)
300{
301    RADEONInfoPtr  info   = RADEONPTR(pScrn);
302    uint32_t cmd_stat;
303    int i;
304
305    info->Chipset = PCI_DEV_DEVICE_ID(info->PciInfo);
306    pScrn->chipset = (char *)xf86TokenToString(RADEONChipsets, info->Chipset);
307    if (!pScrn->chipset) {
308	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
309		   "ChipID 0x%04x is not recognized\n", info->Chipset);
310	return FALSE;
311    }
312
313    if (info->Chipset < 0) {
314	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
315		   "Chipset \"%s\" is not recognized\n", pScrn->chipset);
316	return FALSE;
317    }
318    xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
319	       "Chipset: \"%s\" (ChipID = 0x%04x)\n",
320	       pScrn->chipset,
321	       info->Chipset);
322
323    for (i = 0; i < sizeof(RADEONCards) / sizeof(RADEONCardInfo); i++) {
324	if (info->Chipset == RADEONCards[i].pci_device_id) {
325	    RADEONCardInfo *card = &RADEONCards[i];
326	    info->ChipFamily = card->chip_family;
327	    info->IsMobility = card->mobility;
328	    info->IsIGP = card->igp;
329	    break;
330	}
331    }
332
333    info->cardType = CARD_PCI;
334
335    PCI_READ_LONG(info->PciInfo, &cmd_stat, PCI_CMD_STAT_REG);
336    if (cmd_stat & RADEON_CAP_LIST) {
337	uint32_t cap_ptr, cap_id;
338
339	PCI_READ_LONG(info->PciInfo, &cap_ptr, RADEON_CAPABILITIES_PTR_PCI_CONFIG);
340	cap_ptr &= RADEON_CAP_PTR_MASK;
341
342	while(cap_ptr != RADEON_CAP_ID_NULL) {
343	    PCI_READ_LONG(info->PciInfo, &cap_id, cap_ptr);
344	    if ((cap_id & 0xff)== RADEON_CAP_ID_AGP) {
345		info->cardType = CARD_AGP;
346		break;
347	    }
348	    if ((cap_id & 0xff)== RADEON_CAP_ID_EXP) {
349		info->cardType = CARD_PCIE;
350		break;
351	    }
352	    cap_ptr = (cap_id >> 8) & RADEON_CAP_PTR_MASK;
353	}
354    }
355
356
357    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "%s card detected\n",
358	       (info->cardType==CARD_PCI) ? "PCI" :
359		(info->cardType==CARD_PCIE) ? "PCIE" : "AGP");
360
361    /* treat PCIE IGP cards as PCI */
362    if (info->cardType == CARD_PCIE && info->IsIGP)
363	info->cardType = CARD_PCI;
364
365    if ((info->ChipFamily >= CHIP_FAMILY_R600) && info->IsIGP)
366	info->cardType = CARD_PCIE;
367
368    /* not sure about gart table requirements */
369    if ((info->ChipFamily == CHIP_FAMILY_RS600) && info->IsIGP)
370	info->cardType = CARD_PCIE;
371
372#ifdef RENDER
373    info->RenderAccel = xf86ReturnOptValBool(info->Options, OPTION_RENDER_ACCEL,
374					     info->Chipset != PCI_CHIP_RN50_515E &&
375					     info->Chipset != PCI_CHIP_RN50_5969);
376#endif
377    return TRUE;
378}
379
380static Bool radeon_alloc_dri(ScrnInfoPtr pScrn)
381{
382    RADEONInfoPtr  info   = RADEONPTR(pScrn);
383    if (!(info->dri = calloc(1, sizeof(struct radeon_dri)))) {
384	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,"Unable to allocate dri rec!\n");
385	return FALSE;
386    }
387
388    if (!(info->cp = calloc(1, sizeof(struct radeon_cp)))) {
389	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,"Unable to allocate cp rec!\n");
390	return FALSE;
391    }
392    return TRUE;
393}
394
395static Bool radeon_open_drm_master(ScrnInfoPtr pScrn)
396{
397    RADEONInfoPtr  info   = RADEONPTR(pScrn);
398    RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
399    struct pci_device *dev = info->PciInfo;
400    char *busid;
401    drmSetVersion sv;
402    int err;
403
404    if (pRADEONEnt->fd) {
405	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
406		   " reusing fd for second head\n");
407
408	info->dri2.drm_fd = pRADEONEnt->fd;
409	goto out;
410    }
411
412    busid = XNFprintf("pci:%04x:%02x:%02x.%d",
413		      dev->domain, dev->bus, dev->dev, dev->func);
414
415    info->dri2.drm_fd = drmOpen("radeon", busid);
416    if (info->dri2.drm_fd == -1) {
417
418	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
419		   "[drm] Failed to open DRM device for %s: %s\n",
420		   busid, strerror(errno));
421	free(busid);
422	return FALSE;
423    }
424    free(busid);
425
426    /* Check that what we opened was a master or a master-capable FD,
427     * by setting the version of the interface we'll use to talk to it.
428     * (see DRIOpenDRMMaster() in DRI1)
429     */
430    sv.drm_di_major = 1;
431    sv.drm_di_minor = 1;
432    sv.drm_dd_major = -1;
433    sv.drm_dd_minor = -1;
434    err = drmSetInterfaceVersion(info->dri2.drm_fd, &sv);
435    if (err != 0) {
436	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
437		   "[drm] failed to set drm interface version.\n");
438	drmClose(info->dri2.drm_fd);
439	info->dri2.drm_fd = -1;
440
441	return FALSE;
442    }
443
444    pRADEONEnt->fd = info->dri2.drm_fd;
445 out:
446    info->drmmode.fd = info->dri2.drm_fd;
447    info->dri->drmFD = info->dri2.drm_fd;
448    return TRUE;
449}
450
451static Bool r600_get_tile_config(ScrnInfoPtr pScrn)
452{
453    RADEONInfoPtr  info   = RADEONPTR(pScrn);
454    struct drm_radeon_info ginfo;
455    int r;
456    uint32_t tmp;
457
458    if (info->ChipFamily < CHIP_FAMILY_R600)
459	return FALSE;
460
461#ifndef RADEON_INFO_TILING_CONFIG
462#define RADEON_INFO_TILING_CONFIG 0x6
463#endif
464
465    memset(&ginfo, 0, sizeof(ginfo));
466    ginfo.request = RADEON_INFO_TILING_CONFIG;
467    ginfo.value = (uintptr_t)&tmp;
468    r = drmCommandWriteRead(info->dri->drmFD, DRM_RADEON_INFO, &ginfo, sizeof(ginfo));
469    if (r)
470	return FALSE;
471
472    info->tile_config = tmp;
473    info->r7xx_bank_op = 0;
474    if (info->ChipFamily >= CHIP_FAMILY_CEDAR) {
475	/* for now */
476	return FALSE;
477    } else {
478	switch((info->tile_config & 0xe) >> 1) {
479	case 0:
480	    info->num_channels = 1;
481	    break;
482	case 1:
483	    info->num_channels = 2;
484	    break;
485	case 2:
486	    info->num_channels = 4;
487	    break;
488	case 3:
489	    info->num_channels = 8;
490	    break;
491	default:
492	    return FALSE;
493	}
494	switch((info->tile_config & 0x30) >> 4) {
495	case 0:
496	    info->num_banks = 4;
497	    break;
498	case 1:
499	    info->num_banks = 8;
500	    break;
501	default:
502	    return FALSE;
503	}
504	switch((info->tile_config & 0xc0) >> 6) {
505	case 0:
506	    info->group_bytes = 256;
507	    break;
508	case 1:
509	    info->group_bytes = 512;
510	    break;
511	default:
512	    return FALSE;
513	}
514    }
515
516    return TRUE;
517}
518
519Bool RADEONPreInit_KMS(ScrnInfoPtr pScrn, int flags)
520{
521    RADEONInfoPtr     info;
522    RADEONEntPtr pRADEONEnt;
523    DevUnion* pPriv;
524    Gamma  zeros = { 0.0, 0.0, 0.0 };
525    Bool colorTilingDefault;
526    uint32_t tiling = 0;
527    int cpp;
528
529    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
530		   "RADEONPreInit_KMS\n");
531    if (pScrn->numEntities != 1) return FALSE;
532    if (!RADEONGetRec(pScrn)) return FALSE;
533
534    info               = RADEONPTR(pScrn);
535    info->MMIO         = NULL;
536    info->IsSecondary  = FALSE;
537    info->IsPrimary = FALSE;
538    info->kms_enabled = TRUE;
539    info->pEnt         = xf86GetEntityInfo(pScrn->entityList[pScrn->numEntities - 1]);
540    if (info->pEnt->location.type != BUS_PCI) goto fail;
541
542    pPriv = xf86GetEntityPrivate(pScrn->entityList[0],
543				 getRADEONEntityIndex());
544    pRADEONEnt = pPriv->ptr;
545
546    if(xf86IsEntityShared(pScrn->entityList[0]))
547    {
548        if(xf86IsPrimInitDone(pScrn->entityList[0]))
549        {
550            info->IsSecondary = TRUE;
551            pRADEONEnt->pSecondaryScrn = pScrn;
552        }
553        else
554        {
555	    info->IsPrimary = TRUE;
556            xf86SetPrimInitDone(pScrn->entityList[0]);
557            pRADEONEnt->pPrimaryScrn = pScrn;
558            pRADEONEnt->HasSecondary = FALSE;
559        }
560    }
561
562    info->PciInfo = xf86GetPciInfoForEntity(info->pEnt->index);
563    pScrn->monitor     = pScrn->confScreen->monitor;
564
565    if (!RADEONPreInitVisual(pScrn))
566	goto fail;
567
568    xf86CollectOptions(pScrn, NULL);
569    if (!(info->Options = malloc(sizeof(RADEONOptions_KMS))))
570	goto fail;
571
572    memcpy(info->Options, RADEONOptions_KMS, sizeof(RADEONOptions_KMS));
573    xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, info->Options);
574
575    if (!RADEONPreInitWeight(pScrn))
576	goto fail;
577
578    if (!RADEONPreInitChipType_KMS(pScrn))
579        goto fail;
580
581    if (!radeon_alloc_dri(pScrn))
582	return FALSE;
583
584    if (radeon_open_drm_master(pScrn) == FALSE) {
585	xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Kernel modesetting setup failed\n");
586	goto fail;
587    }
588
589    info->dri2.enabled = FALSE;
590    info->dri->pKernelDRMVersion = drmGetVersion(info->dri->drmFD);
591    if (info->dri->pKernelDRMVersion == NULL) {
592	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
593		   "RADEONDRIGetVersion failed to get the DRM version\n");
594	goto fail;
595    }
596
597    colorTilingDefault = info->ChipFamily >= CHIP_FAMILY_R300 &&
598                         info->ChipFamily <= CHIP_FAMILY_RS740;
599
600    if (info->ChipFamily >= CHIP_FAMILY_R600) {
601	/* set default group bytes, overridden by kernel info below */
602	info->group_bytes = 256;
603	if (info->dri->pKernelDRMVersion->version_minor >= 6) {
604	    info->allowColorTiling = xf86ReturnOptValBool(info->Options,
605							  OPTION_COLOR_TILING, colorTilingDefault);
606	    if (info->allowColorTiling)
607		info->allowColorTiling = r600_get_tile_config(pScrn);
608	} else
609	    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
610		       "R6xx+ KMS Color Tiling requires radeon drm 2.6.0 or newer\n");
611    } else
612	info->allowColorTiling = xf86ReturnOptValBool(info->Options,
613						      OPTION_COLOR_TILING, colorTilingDefault);
614
615    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
616	 "KMS Color Tiling: %sabled\n", info->allowColorTiling ? "en" : "dis");
617
618    if (info->dri->pKernelDRMVersion->version_minor >= 8) {
619	info->allowPageFlip = xf86ReturnOptValBool(info->Options,
620						   OPTION_PAGE_FLIP, TRUE);
621	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
622		   "KMS Pageflipping: %sabled\n", info->allowPageFlip ? "en" : "dis");
623    }
624
625    info->swapBuffersWait = xf86ReturnOptValBool(info->Options,
626						 OPTION_SWAPBUFFERS_WAIT, TRUE);
627    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
628	       "SwapBuffers wait for vsync: %sabled\n", info->swapBuffersWait ? "en" : "dis");
629
630    if (drmmode_pre_init(pScrn, &info->drmmode, pScrn->bitsPerPixel / 8) == FALSE) {
631	xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Kernel modesetting setup failed\n");
632	goto fail;
633    }
634
635    if (info->drmmode.mode_res->count_crtcs == 1)
636        pRADEONEnt->HasCRTC2 = FALSE;
637    else
638        pRADEONEnt->HasCRTC2 = TRUE;
639
640
641    /* fix up cloning on rn50 cards
642     * since they only have one crtc sometimes the xserver doesn't assign
643     * a crtc to one of the outputs even though both outputs have common modes
644     * which results in only one monitor being enabled.  Assign a crtc here so
645     * that both outputs light up.
646     */
647    if (info->ChipFamily == CHIP_FAMILY_RV100 && !pRADEONEnt->HasCRTC2) {
648	xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
649	int i;
650
651	for (i = 0; i < xf86_config->num_output; i++) {
652	    xf86OutputPtr output = xf86_config->output[i];
653
654	    /* XXX: double check crtc mode */
655	    if ((output->probed_modes != NULL) && (output->crtc == NULL))
656		output->crtc = xf86_config->crtc[0];
657	}
658    }
659
660    {
661	struct drm_radeon_gem_info mminfo;
662
663	if (!drmCommandWriteRead(info->dri->drmFD, DRM_RADEON_GEM_INFO, &mminfo, sizeof(mminfo)))
664	{
665	    info->vram_size = mminfo.vram_visible;
666	    info->gart_size = mminfo.gart_size;
667	    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
668		       "mem size init: gart size :%llx vram size: s:%llx visible:%llx\n",
669		       (unsigned long long)mminfo.gart_size,
670		       (unsigned long long)mminfo.vram_size,
671		       (unsigned long long)mminfo.vram_visible);
672	}
673    }
674
675    info->exa_pixmaps = xf86ReturnOptValBool(info->Options,
676                                             OPTION_EXA_PIXMAPS,
677					     ((info->vram_size > (32 * 1024 * 1024) &&
678					      info->RenderAccel)));
679    if (info->exa_pixmaps)
680    	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
681		"EXA: Driver will allow EXA pixmaps in VRAM\n");
682    else
683    	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
684		"EXA: Driver will not allow EXA pixmaps in VRAM\n");
685
686    /* no tiled scanout on r6xx+ yet */
687    if (info->allowColorTiling) {
688	if (info->ChipFamily >= CHIP_FAMILY_R600)
689	    tiling |= RADEON_TILING_MICRO;
690	else
691	    tiling |= RADEON_TILING_MACRO;
692    }
693    cpp = pScrn->bitsPerPixel / 8;
694    pScrn->displayWidth =
695	RADEON_ALIGN(pScrn->virtualX, drmmode_get_pitch_align(pScrn, cpp, tiling));
696    info->CurrentLayout.displayWidth = pScrn->displayWidth;
697
698    /* Set display resolution */
699    xf86SetDpi(pScrn, 0, 0);
700
701	/* Get ScreenInit function */
702    if (!xf86LoadSubModule(pScrn, "fb")) return FALSE;
703
704    if (!xf86SetGamma(pScrn, zeros)) return FALSE;
705
706    if (!xf86ReturnOptValBool(info->Options, OPTION_SW_CURSOR, FALSE)) {
707	if (!xf86LoadSubModule(pScrn, "ramdac")) return FALSE;
708    }
709
710    if (!RADEONPreInitAccel_KMS(pScrn))              goto fail;
711
712    if (pScrn->modes == NULL) {
713      xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No modes.\n");
714      goto fail;
715   }
716
717    return TRUE;
718 fail:
719    RADEONFreeRec(pScrn);
720    return FALSE;
721
722}
723
724static Bool RADEONCursorInit_KMS(ScreenPtr pScreen)
725{
726    return xf86_cursors_init (pScreen, CURSOR_WIDTH, CURSOR_HEIGHT,
727			      (HARDWARE_CURSOR_TRUECOLOR_AT_8BPP |
728			       HARDWARE_CURSOR_AND_SOURCE_WITH_MASK |
729			       HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_1 |
730			       HARDWARE_CURSOR_UPDATE_UNHIDDEN |
731			       HARDWARE_CURSOR_ARGB));
732}
733
734static Bool RADEONSaveScreen_KMS(ScreenPtr pScreen, int mode)
735{
736    ScrnInfoPtr  pScrn = xf86Screens[pScreen->myNum];
737    Bool         unblank;
738
739    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
740		   "RADEONSaveScreen(%d)\n", mode);
741
742    unblank = xf86IsUnblank(mode);
743    if (unblank) SetTimeSinceLastInputEvent();
744
745    if ((pScrn != NULL) && pScrn->vtSema) {
746	if (unblank)
747	    RADEONUnblank(pScrn);
748	else
749	    RADEONBlank(pScrn);
750    }
751    return TRUE;
752}
753
754/* Called at the end of each server generation.  Restore the original
755 * text mode, unmap video memory, and unwrap and call the saved
756 * CloseScreen function.
757 */
758static Bool RADEONCloseScreen_KMS(int scrnIndex, ScreenPtr pScreen)
759{
760    ScrnInfoPtr    pScrn = xf86Screens[scrnIndex];
761    RADEONInfoPtr  info  = RADEONPTR(pScrn);
762
763    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
764		   "RADEONCloseScreen\n");
765
766    drmmode_uevent_fini(pScrn, &info->drmmode);
767    if (info->cs)
768      radeon_cs_flush_indirect(pScrn);
769
770    DeleteCallback(&FlushCallback, radeon_flush_callback, pScrn);
771
772    if (info->accel_state->exa) {
773	exaDriverFini(pScreen);
774	free(info->accel_state->exa);
775	info->accel_state->exa = NULL;
776    }
777
778    if (info->accel_state->use_vbos)
779        radeon_vbo_free_lists(pScrn);
780
781    drmDropMaster(info->dri->drmFD);
782
783    if (info->cursor) xf86DestroyCursorInfoRec(info->cursor);
784    info->cursor = NULL;
785
786    radeon_dri2_close_screen(pScreen);
787
788    pScrn->vtSema = FALSE;
789    xf86ClearPrimInitDone(info->pEnt->index);
790    pScreen->BlockHandler = info->BlockHandler;
791    pScreen->CloseScreen = info->CloseScreen;
792    return (*pScreen->CloseScreen)(scrnIndex, pScreen);
793}
794
795
796void RADEONFreeScreen_KMS(int scrnIndex, int flags)
797{
798    ScrnInfoPtr  pScrn = xf86Screens[scrnIndex];
799    RADEONInfoPtr  info  = RADEONPTR(pScrn);
800
801    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
802		   "RADEONFreeScreen\n");
803
804    /* when server quits at PreInit, we don't need do this anymore*/
805    if (!info) return;
806
807    RADEONFreeRec(pScrn);
808}
809
810Bool RADEONScreenInit_KMS(int scrnIndex, ScreenPtr pScreen,
811			  int argc, char **argv)
812{
813    ScrnInfoPtr    pScrn = xf86Screens[pScreen->myNum];
814    RADEONInfoPtr  info  = RADEONPTR(pScrn);
815    int            subPixelOrder = SubPixelUnknown;
816    char*          s;
817    void *front_ptr;
818    int ret;
819
820    pScrn->fbOffset = 0;
821
822    miClearVisualTypes();
823    if (!miSetVisualTypes(pScrn->depth,
824			  miGetDefaultVisualMask(pScrn->depth),
825			  pScrn->rgbBits,
826			  pScrn->defaultVisual)) return FALSE;
827    miSetPixmapDepths ();
828
829    ret = drmSetMaster(info->dri->drmFD);
830    if (ret) {
831        ErrorF("Unable to retrieve master\n");
832        return FALSE;
833    }
834    info->directRenderingEnabled = FALSE;
835    if (info->r600_shadow_fb == FALSE)
836        info->directRenderingEnabled = radeon_dri2_screen_init(pScreen);
837
838    front_ptr = info->FB;
839
840    if (!info->bufmgr)
841        info->bufmgr = radeon_bo_manager_gem_ctor(info->dri->drmFD);
842    if (!info->bufmgr) {
843	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
844		   "failed to initialise GEM buffer manager");
845	return FALSE;
846    }
847    drmmode_set_bufmgr(pScrn, &info->drmmode, info->bufmgr);
848
849    if (!info->csm)
850        info->csm = radeon_cs_manager_gem_ctor(info->dri->drmFD);
851    if (!info->csm) {
852	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
853		   "failed to initialise command submission manager");
854	return FALSE;
855    }
856
857    if (!info->cs)
858        info->cs = radeon_cs_create(info->csm, RADEON_BUFFER_SIZE/4);
859    if (!info->cs) {
860	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
861		   "failed to initialise command submission buffer");
862	return FALSE;
863    }
864
865    radeon_cs_set_limit(info->cs, RADEON_GEM_DOMAIN_GTT, info->gart_size);
866    radeon_cs_space_set_flush(info->cs, (void(*)(void *))radeon_cs_flush_indirect, pScrn);
867
868    radeon_setup_kernel_mem(pScreen);
869    front_ptr = info->front_bo->ptr;
870
871    if (info->r600_shadow_fb) {
872	info->fb_shadow = calloc(1,
873				 pScrn->displayWidth * pScrn->virtualY *
874				 ((pScrn->bitsPerPixel + 7) >> 3));
875	if (info->fb_shadow == NULL) {
876	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
877                       "Failed to allocate shadow framebuffer\n");
878	    info->r600_shadow_fb = FALSE;
879	} else {
880	    if (!fbScreenInit(pScreen, info->fb_shadow,
881			      pScrn->virtualX, pScrn->virtualY,
882			      pScrn->xDpi, pScrn->yDpi, pScrn->displayWidth,
883			      pScrn->bitsPerPixel))
884		return FALSE;
885	}
886    }
887
888    if (info->r600_shadow_fb == FALSE) {
889	/* Init fb layer */
890	if (!fbScreenInit(pScreen, front_ptr,
891			  pScrn->virtualX, pScrn->virtualY,
892			  pScrn->xDpi, pScrn->yDpi, pScrn->displayWidth,
893			  pScrn->bitsPerPixel))
894	    return FALSE;
895    }
896
897    xf86SetBlackWhitePixels(pScreen);
898
899    if (pScrn->bitsPerPixel > 8) {
900	VisualPtr  visual;
901
902	visual = pScreen->visuals + pScreen->numVisuals;
903	while (--visual >= pScreen->visuals) {
904	    if ((visual->class | DynamicClass) == DirectColor) {
905		visual->offsetRed   = pScrn->offset.red;
906		visual->offsetGreen = pScrn->offset.green;
907		visual->offsetBlue  = pScrn->offset.blue;
908		visual->redMask     = pScrn->mask.red;
909		visual->greenMask   = pScrn->mask.green;
910		visual->blueMask    = pScrn->mask.blue;
911	    }
912	}
913    }
914
915    /* Must be after RGB order fixed */
916    fbPictureInit (pScreen, 0, 0);
917
918#ifdef RENDER
919    if ((s = xf86GetOptValString(info->Options, OPTION_SUBPIXEL_ORDER))) {
920	if (strcmp(s, "RGB") == 0) subPixelOrder = SubPixelHorizontalRGB;
921	else if (strcmp(s, "BGR") == 0) subPixelOrder = SubPixelHorizontalBGR;
922	else if (strcmp(s, "NONE") == 0) subPixelOrder = SubPixelNone;
923	PictureSetSubpixelOrder (pScreen, subPixelOrder);
924    }
925#endif
926
927    pScrn->vtSema = TRUE;
928    /* Backing store setup */
929    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
930		   "Initializing backing store\n");
931    miInitializeBackingStore(pScreen);
932    xf86SetBackingStore(pScreen);
933
934
935    if (info->directRenderingEnabled) {
936	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Direct rendering enabled\n");
937    } else {
938	xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
939		   "Direct rendering disabled\n");
940    }
941
942    if (info->r600_shadow_fb) {
943	xf86DrvMsg(scrnIndex, X_INFO, "Acceleration disabled\n");
944	info->accelOn = FALSE;
945    } else {
946	xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
947		       "Initializing Acceleration\n");
948	if (RADEONAccelInit(pScreen)) {
949	    xf86DrvMsg(scrnIndex, X_INFO, "Acceleration enabled\n");
950	    info->accelOn = TRUE;
951	} else {
952	    xf86DrvMsg(scrnIndex, X_ERROR,
953		       "Acceleration initialization failed\n");
954	    xf86DrvMsg(scrnIndex, X_INFO, "Acceleration disabled\n");
955	    info->accelOn = FALSE;
956	}
957    }
958
959    /* Init DPMS */
960    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
961		   "Initializing DPMS\n");
962    xf86DPMSInit(pScreen, xf86DPMSSet, 0);
963
964    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
965		   "Initializing Cursor\n");
966
967    /* Set Silken Mouse */
968    xf86SetSilkenMouse(pScreen);
969
970    /* Cursor setup */
971    miDCInitialize(pScreen, xf86GetPointerScreenFuncs());
972
973    if (!xf86ReturnOptValBool(info->Options, OPTION_SW_CURSOR, FALSE)) {
974	if (RADEONCursorInit_KMS(pScreen)) {
975	}
976    }
977
978    /* DGA setup */
979#ifdef XFreeXDGA
980    /* DGA is dangerous on kms as the base and framebuffer location may change:
981     * http://lists.freedesktop.org/archives/xorg-devel/2009-September/002113.html
982     */
983    /* xf86DiDGAInit(pScreen, info->LinearAddr + pScrn->fbOffset); */
984#endif
985    if (info->r600_shadow_fb == FALSE) {
986        /* Init Xv */
987        xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
988                       "Initializing Xv\n");
989        RADEONInitVideo(pScreen);
990    }
991
992    if (info->r600_shadow_fb == TRUE) {
993        if (!shadowSetup(pScreen)) {
994	    xf86DrvMsg(scrnIndex, X_ERROR,
995		       "Shadowfb initialization failed\n");
996            return FALSE;
997        }
998    }
999    pScrn->pScreen = pScreen;
1000
1001    /* Provide SaveScreen & wrap BlockHandler and CloseScreen */
1002    /* Wrap CloseScreen */
1003    info->CloseScreen    = pScreen->CloseScreen;
1004    pScreen->CloseScreen = RADEONCloseScreen_KMS;
1005    pScreen->SaveScreen  = RADEONSaveScreen_KMS;
1006    info->BlockHandler = pScreen->BlockHandler;
1007    pScreen->BlockHandler = RADEONBlockHandler_KMS;
1008
1009    if (!AddCallback(&FlushCallback, radeon_flush_callback, pScrn))
1010        return FALSE;
1011
1012    info->CreateScreenResources = pScreen->CreateScreenResources;
1013    pScreen->CreateScreenResources = RADEONCreateScreenResources_KMS;
1014
1015   if (!xf86CrtcScreenInit (pScreen))
1016       return FALSE;
1017
1018   /* Wrap pointer motion to flip touch screen around */
1019//    info->PointerMoved = pScrn->PointerMoved;
1020//    pScrn->PointerMoved = RADEONPointerMoved;
1021
1022    if (!drmmode_setup_colormap(pScreen, pScrn))
1023	return FALSE;
1024
1025   /* Note unused options */
1026    if (serverGeneration == 1)
1027	xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
1028
1029    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
1030		   "RADEONScreenInit finished\n");
1031
1032    info->accel_state->XInited3D = FALSE;
1033    info->accel_state->engineMode = EXA_ENGINEMODE_UNKNOWN;
1034
1035    return TRUE;
1036}
1037
1038Bool RADEONEnterVT_KMS(int scrnIndex, int flags)
1039{
1040    ScrnInfoPtr    pScrn = xf86Screens[scrnIndex];
1041    RADEONInfoPtr  info  = RADEONPTR(pScrn);
1042    int ret;
1043
1044    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
1045		   "RADEONEnterVT_KMS\n");
1046
1047
1048    ret = drmSetMaster(info->dri->drmFD);
1049    if (ret)
1050	ErrorF("Unable to retrieve master\n");
1051    info->accel_state->XInited3D = FALSE;
1052    info->accel_state->engineMode = EXA_ENGINEMODE_UNKNOWN;
1053
1054    pScrn->vtSema = TRUE;
1055
1056    if (!drmmode_set_desired_modes(pScrn, &info->drmmode))
1057	return FALSE;
1058
1059    if (info->adaptor)
1060	RADEONResetVideo(pScrn);
1061
1062    return TRUE;
1063}
1064
1065
1066void RADEONLeaveVT_KMS(int scrnIndex, int flags)
1067{
1068    ScrnInfoPtr    pScrn = xf86Screens[scrnIndex];
1069    RADEONInfoPtr  info  = RADEONPTR(pScrn);
1070
1071    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
1072		   "RADEONLeaveVT_KMS\n");
1073
1074    drmDropMaster(info->dri->drmFD);
1075
1076#ifdef HAVE_FREE_SHADOW
1077    xf86RotateFreeShadow(pScrn);
1078#endif
1079
1080    xf86_hide_cursors (pScrn);
1081    info->accel_state->XInited3D = FALSE;
1082    info->accel_state->engineMode = EXA_ENGINEMODE_UNKNOWN;
1083
1084    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
1085		   "Ok, leaving now...\n");
1086}
1087
1088
1089Bool RADEONSwitchMode_KMS(int scrnIndex, DisplayModePtr mode, int flags)
1090{
1091    ScrnInfoPtr    pScrn       = xf86Screens[scrnIndex];
1092    Bool ret;
1093    ret = xf86SetSingleMode (pScrn, mode, RR_Rotate_0);
1094    return ret;
1095
1096}
1097
1098void RADEONAdjustFrame_KMS(int scrnIndex, int x, int y, int flags)
1099{
1100    ScrnInfoPtr    pScrn       = xf86Screens[scrnIndex];
1101    RADEONInfoPtr  info        = RADEONPTR(pScrn);
1102    drmmode_adjust_frame(pScrn, &info->drmmode, x, y, flags);
1103    return;
1104}
1105
1106static Bool radeon_setup_kernel_mem(ScreenPtr pScreen)
1107{
1108    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
1109    RADEONInfoPtr info = RADEONPTR(pScrn);
1110    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
1111    int cpp = info->CurrentLayout.pixel_bytes;
1112    int screen_size;
1113    int pitch, base_align;
1114    int total_size_bytes = 0, remain_size_bytes;
1115    uint32_t tiling_flags = 0;
1116
1117    if (info->accel_state->exa != NULL) {
1118	xf86DrvMsg(pScreen->myNum, X_ERROR, "Memory map already initialized\n");
1119	return FALSE;
1120    }
1121    if (info->r600_shadow_fb == FALSE) {
1122        info->accel_state->exa = exaDriverAlloc();
1123        if (info->accel_state->exa == NULL)
1124	    return FALSE;
1125    }
1126
1127    if (info->allowColorTiling) {
1128	if (info->ChipFamily >= CHIP_FAMILY_R600)
1129	    tiling_flags |= RADEON_TILING_MICRO;
1130	else
1131	    tiling_flags |= RADEON_TILING_MACRO;
1132    }
1133    pitch = RADEON_ALIGN(pScrn->displayWidth, drmmode_get_pitch_align(pScrn, cpp, tiling_flags)) * cpp;
1134    screen_size = RADEON_ALIGN(pScrn->virtualY, drmmode_get_height_align(pScrn, tiling_flags)) * pitch;
1135    base_align = drmmode_get_base_align(pScrn, cpp, tiling_flags);
1136    {
1137	int cursor_size = 64 * 4 * 64;
1138	int c;
1139
1140	cursor_size = RADEON_ALIGN(cursor_size, RADEON_GPU_PAGE_SIZE);
1141	for (c = 0; c < xf86_config->num_crtc; c++) {
1142	    /* cursor objects */
1143            if (info->cursor_bo[c] == NULL) {
1144                info->cursor_bo[c] = radeon_bo_open(info->bufmgr, 0,
1145                                                    cursor_size, 0,
1146                                                    RADEON_GEM_DOMAIN_VRAM, 0);
1147                if (!info->cursor_bo[c]) {
1148                    return FALSE;
1149                }
1150
1151#if X_BYTE_ORDER == X_BIG_ENDIAN
1152		radeon_bo_set_tiling(info->cursor_bo[c], RADEON_TILING_SWAP_32BIT |
1153				     RADEON_TILING_SURFACE, CURSOR_WIDTH);
1154#endif
1155
1156                if (radeon_bo_map(info->cursor_bo[c], 1)) {
1157                    ErrorF("Failed to map cursor buffer memory\n");
1158                }
1159
1160                drmmode_set_cursor(pScrn, &info->drmmode, c, info->cursor_bo[c]);
1161                total_size_bytes += cursor_size;
1162            }
1163        }
1164    }
1165
1166    screen_size = RADEON_ALIGN(screen_size, RADEON_GPU_PAGE_SIZE);
1167    /* keep area front front buffer - but don't allocate it yet */
1168    total_size_bytes += screen_size;
1169
1170    /* work out from the mm size what the exa / tex sizes need to be */
1171    remain_size_bytes = info->vram_size - total_size_bytes;
1172
1173    info->dri->textureSize = 0;
1174
1175    if (info->front_bo == NULL) {
1176        info->front_bo = radeon_bo_open(info->bufmgr, 0, screen_size,
1177                                        base_align, RADEON_GEM_DOMAIN_VRAM, 0);
1178        if (info->r600_shadow_fb == TRUE) {
1179            if (radeon_bo_map(info->front_bo, 1)) {
1180                ErrorF("Failed to map cursor buffer memory\n");
1181            }
1182        }
1183#if X_BYTE_ORDER == X_BIG_ENDIAN
1184	switch (cpp) {
1185	case 4:
1186	    tiling_flags |= RADEON_TILING_SWAP_32BIT;
1187	    break;
1188	case 2:
1189	    tiling_flags |= RADEON_TILING_SWAP_16BIT;
1190	    break;
1191	}
1192#endif
1193	if (tiling_flags) {
1194            radeon_bo_set_tiling(info->front_bo,
1195				 tiling_flags | RADEON_TILING_SURFACE, pitch);
1196	}
1197    }
1198
1199    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Front buffer size: %dK\n", info->front_bo->size/1024);
1200    radeon_kms_update_vram_limit(pScrn, screen_size);
1201    return TRUE;
1202}
1203
1204void radeon_kms_update_vram_limit(ScrnInfoPtr pScrn, int new_fb_size)
1205{
1206    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
1207    RADEONInfoPtr info = RADEONPTR(pScrn);
1208    int remain_size_bytes;
1209    int total_size_bytes;
1210    int c;
1211
1212    for (c = 0; c < xf86_config->num_crtc; c++) {
1213	if (info->cursor_bo[c] != NULL) {
1214	    total_size_bytes += (64 * 4 * 64);
1215	}
1216    }
1217
1218    total_size_bytes += new_fb_size;
1219    remain_size_bytes = info->vram_size - new_fb_size;
1220    remain_size_bytes = (remain_size_bytes / 10) * 9;
1221    radeon_cs_set_limit(info->cs, RADEON_GEM_DOMAIN_VRAM, remain_size_bytes);
1222
1223    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VRAM usage limit set to %dK\n", remain_size_bytes / 1024);
1224}
1225
1226
1227#endif
1228