radeon_kms.c revision c4ae5be6
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 RADEONIsFusionGARTWorking(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_FUSION_GART_WORKING
224#define RADEON_INFO_FUSION_GART_WORKING 0x0c
225#endif
226    memset(&ginfo, 0, sizeof(ginfo));
227    ginfo.request = RADEON_INFO_FUSION_GART_WORKING;
228    ginfo.value = (uintptr_t)&tmp;
229    r = drmCommandWriteRead(info->dri->drmFD, DRM_RADEON_INFO, &ginfo, sizeof(ginfo));
230    if (r) {
231	return FALSE;
232    }
233    if (tmp == 1)
234	return TRUE;
235    return FALSE;
236}
237
238static Bool RADEONIsAccelWorking(ScrnInfoPtr pScrn)
239{
240    RADEONInfoPtr info = RADEONPTR(pScrn);
241    struct drm_radeon_info ginfo;
242    int r;
243    uint32_t tmp;
244
245#ifndef RADEON_INFO_ACCEL_WORKING
246#define RADEON_INFO_ACCEL_WORKING 0x03
247#endif
248#ifndef RADEON_INFO_ACCEL_WORKING2
249#define RADEON_INFO_ACCEL_WORKING2 0x05
250#endif
251
252    memset(&ginfo, 0, sizeof(ginfo));
253    if (info->dri->pKernelDRMVersion->version_minor >= 5)
254	ginfo.request = RADEON_INFO_ACCEL_WORKING2;
255    else
256	ginfo.request = RADEON_INFO_ACCEL_WORKING;
257    ginfo.value = (uintptr_t)&tmp;
258    r = drmCommandWriteRead(info->dri->drmFD, DRM_RADEON_INFO, &ginfo, sizeof(ginfo));
259    if (r) {
260        /* If kernel is too old before 2.6.32 than assume accel is working */
261        if (r == -EINVAL) {
262            xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Kernel too old missing accel "
263                       "information, assuming accel is working\n");
264            return TRUE;
265        }
266        return FALSE;
267    }
268    if (tmp)
269        return TRUE;
270    return FALSE;
271}
272
273static Bool RADEONPreInitAccel_KMS(ScrnInfoPtr pScrn)
274{
275    RADEONInfoPtr  info = RADEONPTR(pScrn);
276
277    if (!(info->accel_state = calloc(1, sizeof(struct radeon_accel_state)))) {
278	xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Unable to allocate accel_state rec!\n");
279	return FALSE;
280    }
281
282    if (xf86ReturnOptValBool(info->Options, OPTION_NOACCEL, FALSE) ||
283	(!RADEONIsAccelWorking(pScrn))) {
284	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
285		   "GPU accel disabled or not working, using shadowfb for KMS\n");
286	info->r600_shadow_fb = TRUE;
287	if (!xf86LoadSubModule(pScrn, "shadow"))
288	    info->r600_shadow_fb = FALSE;
289	return TRUE;
290    }
291
292    if (info->ChipFamily == CHIP_FAMILY_PALM) {
293	info->accel_state->allowHWDFS = RADEONIsFusionGARTWorking(pScrn);
294    } else
295	info->accel_state->allowHWDFS = TRUE;
296
297    if ((info->ChipFamily == CHIP_FAMILY_RS100) ||
298	(info->ChipFamily == CHIP_FAMILY_RS200) ||
299	(info->ChipFamily == CHIP_FAMILY_RS300) ||
300	(info->ChipFamily == CHIP_FAMILY_RS400) ||
301	(info->ChipFamily == CHIP_FAMILY_RS480) ||
302	(info->ChipFamily == CHIP_FAMILY_RS600) ||
303	(info->ChipFamily == CHIP_FAMILY_RS690) ||
304	(info->ChipFamily == CHIP_FAMILY_RS740))
305	info->accel_state->has_tcl = FALSE;
306    else {
307	info->accel_state->has_tcl = TRUE;
308    }
309
310    info->useEXA = TRUE;
311
312    if (info->useEXA) {
313	int errmaj = 0, errmin = 0;
314	info->exaReq.majorversion = EXA_VERSION_MAJOR;
315	info->exaReq.minorversion = EXA_VERSION_MINOR;
316	if (!LoadSubModule(pScrn->module, "exa", NULL, NULL, NULL,
317			   &info->exaReq, &errmaj, &errmin)) {
318	    LoaderErrorMsg(NULL, "exa", errmaj, errmin);
319	    return FALSE;
320	}
321    }
322
323    return TRUE;
324}
325
326static Bool RADEONPreInitChipType_KMS(ScrnInfoPtr pScrn)
327{
328    RADEONInfoPtr  info   = RADEONPTR(pScrn);
329    uint32_t cmd_stat;
330    int i;
331
332    info->Chipset = PCI_DEV_DEVICE_ID(info->PciInfo);
333    pScrn->chipset = (char *)xf86TokenToString(RADEONChipsets, info->Chipset);
334    if (!pScrn->chipset) {
335	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
336		   "ChipID 0x%04x is not recognized\n", info->Chipset);
337	return FALSE;
338    }
339
340    if (info->Chipset < 0) {
341	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
342		   "Chipset \"%s\" is not recognized\n", pScrn->chipset);
343	return FALSE;
344    }
345    xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
346	       "Chipset: \"%s\" (ChipID = 0x%04x)\n",
347	       pScrn->chipset,
348	       info->Chipset);
349
350    for (i = 0; i < sizeof(RADEONCards) / sizeof(RADEONCardInfo); i++) {
351	if (info->Chipset == RADEONCards[i].pci_device_id) {
352	    RADEONCardInfo *card = &RADEONCards[i];
353	    info->ChipFamily = card->chip_family;
354	    info->IsMobility = card->mobility;
355	    info->IsIGP = card->igp;
356	    break;
357	}
358    }
359
360    info->cardType = CARD_PCI;
361
362    PCI_READ_LONG(info->PciInfo, &cmd_stat, PCI_CMD_STAT_REG);
363    if (cmd_stat & RADEON_CAP_LIST) {
364	uint32_t cap_ptr, cap_id;
365
366	PCI_READ_LONG(info->PciInfo, &cap_ptr, RADEON_CAPABILITIES_PTR_PCI_CONFIG);
367	cap_ptr &= RADEON_CAP_PTR_MASK;
368
369	while(cap_ptr != RADEON_CAP_ID_NULL) {
370	    PCI_READ_LONG(info->PciInfo, &cap_id, cap_ptr);
371	    if ((cap_id & 0xff)== RADEON_CAP_ID_AGP) {
372		info->cardType = CARD_AGP;
373		break;
374	    }
375	    if ((cap_id & 0xff)== RADEON_CAP_ID_EXP) {
376		info->cardType = CARD_PCIE;
377		break;
378	    }
379	    cap_ptr = (cap_id >> 8) & RADEON_CAP_PTR_MASK;
380	}
381    }
382
383
384    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "%s card detected\n",
385	       (info->cardType==CARD_PCI) ? "PCI" :
386		(info->cardType==CARD_PCIE) ? "PCIE" : "AGP");
387
388    /* treat PCIE IGP cards as PCI */
389    if (info->cardType == CARD_PCIE && info->IsIGP)
390	info->cardType = CARD_PCI;
391
392    if ((info->ChipFamily >= CHIP_FAMILY_R600) && info->IsIGP)
393	info->cardType = CARD_PCIE;
394
395    /* not sure about gart table requirements */
396    if ((info->ChipFamily == CHIP_FAMILY_RS600) && info->IsIGP)
397	info->cardType = CARD_PCIE;
398
399#ifdef RENDER
400    info->RenderAccel = xf86ReturnOptValBool(info->Options, OPTION_RENDER_ACCEL,
401					     info->Chipset != PCI_CHIP_RN50_515E &&
402					     info->Chipset != PCI_CHIP_RN50_5969);
403#endif
404    return TRUE;
405}
406
407static Bool radeon_alloc_dri(ScrnInfoPtr pScrn)
408{
409    RADEONInfoPtr  info   = RADEONPTR(pScrn);
410    if (!(info->dri = calloc(1, sizeof(struct radeon_dri)))) {
411	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,"Unable to allocate dri rec!\n");
412	return FALSE;
413    }
414
415    if (!(info->cp = calloc(1, sizeof(struct radeon_cp)))) {
416	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,"Unable to allocate cp rec!\n");
417	return FALSE;
418    }
419    return TRUE;
420}
421
422static Bool radeon_open_drm_master(ScrnInfoPtr pScrn)
423{
424    RADEONInfoPtr  info   = RADEONPTR(pScrn);
425    RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
426    struct pci_device *dev = info->PciInfo;
427    char *busid;
428    drmSetVersion sv;
429    int err;
430
431    if (pRADEONEnt->fd) {
432	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
433		   " reusing fd for second head\n");
434
435	info->dri2.drm_fd = pRADEONEnt->fd;
436	goto out;
437    }
438
439#if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,9,99,901,0)
440    XNFasprintf(&busid, "pci:%04x:%02x:%02x.%d",
441                dev->domain, dev->bus, dev->dev, dev->func);
442#else
443    busid = XNFprintf("pci:%04x:%02x:%02x.%d",
444		      dev->domain, dev->bus, dev->dev, dev->func);
445#endif
446
447    info->dri2.drm_fd = drmOpen("radeon", busid);
448    if (info->dri2.drm_fd == -1) {
449
450	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
451		   "[drm] Failed to open DRM device for %s: %s\n",
452		   busid, strerror(errno));
453	free(busid);
454	return FALSE;
455    }
456    free(busid);
457
458    /* Check that what we opened was a master or a master-capable FD,
459     * by setting the version of the interface we'll use to talk to it.
460     * (see DRIOpenDRMMaster() in DRI1)
461     */
462    sv.drm_di_major = 1;
463    sv.drm_di_minor = 1;
464    sv.drm_dd_major = -1;
465    sv.drm_dd_minor = -1;
466    err = drmSetInterfaceVersion(info->dri2.drm_fd, &sv);
467    if (err != 0) {
468	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
469		   "[drm] failed to set drm interface version.\n");
470	drmClose(info->dri2.drm_fd);
471	info->dri2.drm_fd = -1;
472
473	return FALSE;
474    }
475
476    pRADEONEnt->fd = info->dri2.drm_fd;
477 out:
478    info->drmmode.fd = info->dri2.drm_fd;
479    info->dri->drmFD = info->dri2.drm_fd;
480    return TRUE;
481}
482
483static Bool r600_get_tile_config(ScrnInfoPtr pScrn)
484{
485    RADEONInfoPtr  info   = RADEONPTR(pScrn);
486    struct drm_radeon_info ginfo;
487    int r;
488    uint32_t tmp;
489
490    if (info->ChipFamily < CHIP_FAMILY_R600)
491	return FALSE;
492
493#ifndef RADEON_INFO_TILING_CONFIG
494#define RADEON_INFO_TILING_CONFIG 0x6
495#endif
496
497    memset(&ginfo, 0, sizeof(ginfo));
498    ginfo.request = RADEON_INFO_TILING_CONFIG;
499    ginfo.value = (uintptr_t)&tmp;
500    r = drmCommandWriteRead(info->dri->drmFD, DRM_RADEON_INFO, &ginfo, sizeof(ginfo));
501    if (r)
502	return FALSE;
503
504    info->tile_config = tmp;
505    info->r7xx_bank_op = 0;
506    if (info->ChipFamily >= CHIP_FAMILY_CEDAR) {
507	if (info->dri->pKernelDRMVersion->version_minor >= 7) {
508	    switch (info->tile_config & 0xf) {
509	    case 0:
510                info->num_channels = 1;
511                break;
512	    case 1:
513                info->num_channels = 2;
514                break;
515	    case 2:
516                info->num_channels = 4;
517                break;
518	    case 3:
519                info->num_channels = 8;
520                break;
521	    default:
522                return FALSE;
523	    }
524
525	    info->num_banks = (info->tile_config & 0xf0) >> 4;
526
527	    switch ((info->tile_config & 0xf00) >> 8) {
528	    case 0:
529                info->group_bytes = 256;
530                break;
531	    case 1:
532                info->group_bytes = 512;
533                break;
534	    default:
535                return FALSE;
536	    }
537	} else
538	    return FALSE;
539    } else {
540	switch((info->tile_config & 0xe) >> 1) {
541	case 0:
542	    info->num_channels = 1;
543	    break;
544	case 1:
545	    info->num_channels = 2;
546	    break;
547	case 2:
548	    info->num_channels = 4;
549	    break;
550	case 3:
551	    info->num_channels = 8;
552	    break;
553	default:
554	    return FALSE;
555	}
556	switch((info->tile_config & 0x30) >> 4) {
557	case 0:
558	    info->num_banks = 4;
559	    break;
560	case 1:
561	    info->num_banks = 8;
562	    break;
563	default:
564	    return FALSE;
565	}
566	switch((info->tile_config & 0xc0) >> 6) {
567	case 0:
568	    info->group_bytes = 256;
569	    break;
570	case 1:
571	    info->group_bytes = 512;
572	    break;
573	default:
574	    return FALSE;
575	}
576    }
577
578    info->have_tiling_info = TRUE;
579    return TRUE;
580}
581
582Bool RADEONPreInit_KMS(ScrnInfoPtr pScrn, int flags)
583{
584    RADEONInfoPtr     info;
585    RADEONEntPtr pRADEONEnt;
586    DevUnion* pPriv;
587    Gamma  zeros = { 0.0, 0.0, 0.0 };
588    Bool colorTilingDefault;
589    uint32_t tiling = 0;
590    int cpp;
591
592    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
593		   "RADEONPreInit_KMS\n");
594    if (pScrn->numEntities != 1) return FALSE;
595    if (!RADEONGetRec(pScrn)) return FALSE;
596
597    info               = RADEONPTR(pScrn);
598    info->MMIO         = NULL;
599    info->IsSecondary  = FALSE;
600    info->IsPrimary = FALSE;
601    info->kms_enabled = TRUE;
602    info->pEnt         = xf86GetEntityInfo(pScrn->entityList[pScrn->numEntities - 1]);
603    if (info->pEnt->location.type != BUS_PCI) goto fail;
604
605    pPriv = xf86GetEntityPrivate(pScrn->entityList[0],
606				 getRADEONEntityIndex());
607    pRADEONEnt = pPriv->ptr;
608
609    if(xf86IsEntityShared(pScrn->entityList[0]))
610    {
611        if(xf86IsPrimInitDone(pScrn->entityList[0]))
612        {
613            info->IsSecondary = TRUE;
614            pRADEONEnt->pSecondaryScrn = pScrn;
615        }
616        else
617        {
618	    info->IsPrimary = TRUE;
619            xf86SetPrimInitDone(pScrn->entityList[0]);
620            pRADEONEnt->pPrimaryScrn = pScrn;
621            pRADEONEnt->HasSecondary = FALSE;
622        }
623    }
624
625    info->PciInfo = xf86GetPciInfoForEntity(info->pEnt->index);
626    pScrn->monitor     = pScrn->confScreen->monitor;
627
628    if (!RADEONPreInitVisual(pScrn))
629	goto fail;
630
631    xf86CollectOptions(pScrn, NULL);
632    if (!(info->Options = malloc(sizeof(RADEONOptions_KMS))))
633	goto fail;
634
635    memcpy(info->Options, RADEONOptions_KMS, sizeof(RADEONOptions_KMS));
636    xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, info->Options);
637
638    if (!RADEONPreInitWeight(pScrn))
639	goto fail;
640
641    if (!RADEONPreInitChipType_KMS(pScrn))
642        goto fail;
643
644    if (!radeon_alloc_dri(pScrn))
645	return FALSE;
646
647    if (radeon_open_drm_master(pScrn) == FALSE) {
648	xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Kernel modesetting setup failed\n");
649	goto fail;
650    }
651
652    info->dri2.enabled = FALSE;
653    info->dri->pKernelDRMVersion = drmGetVersion(info->dri->drmFD);
654    if (info->dri->pKernelDRMVersion == NULL) {
655	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
656		   "RADEONDRIGetVersion failed to get the DRM version\n");
657	goto fail;
658    }
659
660    if (!RADEONPreInitAccel_KMS(pScrn))              goto fail;
661
662    /* don't enable tiling if accel is not enabled */
663    if (!info->r600_shadow_fb) {
664	colorTilingDefault = info->ChipFamily >= CHIP_FAMILY_R300 &&
665	    info->ChipFamily <= CHIP_FAMILY_RS740;
666
667	if (info->ChipFamily >= CHIP_FAMILY_R600) {
668	    /* set default group bytes, overridden by kernel info below */
669	    info->group_bytes = 256;
670	    info->have_tiling_info = FALSE;
671	    if (info->dri->pKernelDRMVersion->version_minor >= 6) {
672		if (r600_get_tile_config(pScrn)) {
673		    info->allowColorTiling = xf86ReturnOptValBool(info->Options,
674								  OPTION_COLOR_TILING, colorTilingDefault);
675		    /* need working DFS for tiling */
676		    if ((info->ChipFamily == CHIP_FAMILY_PALM) &&
677			(!info->accel_state->allowHWDFS))
678			info->allowColorTiling = FALSE;
679		} else
680		    info->allowColorTiling = FALSE;
681	    } else
682		xf86DrvMsg(pScrn->scrnIndex, X_INFO,
683			   "R6xx+ KMS Color Tiling requires radeon drm 2.6.0 or newer\n");
684	} else
685	    info->allowColorTiling = xf86ReturnOptValBool(info->Options,
686							  OPTION_COLOR_TILING, colorTilingDefault);
687    } else
688	info->allowColorTiling = FALSE;
689
690    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
691	 "KMS Color Tiling: %sabled\n", info->allowColorTiling ? "en" : "dis");
692
693    if (info->dri->pKernelDRMVersion->version_minor >= 8) {
694	info->allowPageFlip = xf86ReturnOptValBool(info->Options,
695						   OPTION_PAGE_FLIP, TRUE);
696	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
697		   "KMS Pageflipping: %sabled\n", info->allowPageFlip ? "en" : "dis");
698    }
699
700    info->swapBuffersWait = xf86ReturnOptValBool(info->Options,
701						 OPTION_SWAPBUFFERS_WAIT, TRUE);
702    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
703	       "SwapBuffers wait for vsync: %sabled\n", info->swapBuffersWait ? "en" : "dis");
704
705    if (drmmode_pre_init(pScrn, &info->drmmode, pScrn->bitsPerPixel / 8) == FALSE) {
706	xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Kernel modesetting setup failed\n");
707	goto fail;
708    }
709
710    if (info->drmmode.mode_res->count_crtcs == 1)
711        pRADEONEnt->HasCRTC2 = FALSE;
712    else
713        pRADEONEnt->HasCRTC2 = TRUE;
714
715
716    /* fix up cloning on rn50 cards
717     * since they only have one crtc sometimes the xserver doesn't assign
718     * a crtc to one of the outputs even though both outputs have common modes
719     * which results in only one monitor being enabled.  Assign a crtc here so
720     * that both outputs light up.
721     */
722    if (info->ChipFamily == CHIP_FAMILY_RV100 && !pRADEONEnt->HasCRTC2) {
723	xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
724	int i;
725
726	for (i = 0; i < xf86_config->num_output; i++) {
727	    xf86OutputPtr output = xf86_config->output[i];
728
729	    /* XXX: double check crtc mode */
730	    if ((output->probed_modes != NULL) && (output->crtc == NULL))
731		output->crtc = xf86_config->crtc[0];
732	}
733    }
734
735    {
736	struct drm_radeon_gem_info mminfo;
737
738	if (!drmCommandWriteRead(info->dri->drmFD, DRM_RADEON_GEM_INFO, &mminfo, sizeof(mminfo)))
739	{
740	    info->vram_size = mminfo.vram_visible;
741	    info->gart_size = mminfo.gart_size;
742	    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
743		       "mem size init: gart size :%llx vram size: s:%llx visible:%llx\n",
744		       (unsigned long long)mminfo.gart_size,
745		       (unsigned long long)mminfo.vram_size,
746		       (unsigned long long)mminfo.vram_visible);
747	}
748    }
749
750    info->exa_pixmaps = xf86ReturnOptValBool(info->Options,
751                                             OPTION_EXA_PIXMAPS,
752					     ((info->vram_size > (32 * 1024 * 1024) &&
753					      info->RenderAccel)));
754    if (info->exa_pixmaps)
755    	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
756		"EXA: Driver will allow EXA pixmaps in VRAM\n");
757    else
758    	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
759		"EXA: Driver will not allow EXA pixmaps in VRAM\n");
760
761    /* no tiled scanout on r6xx+ yet */
762    if (info->allowColorTiling) {
763	if (info->ChipFamily >= CHIP_FAMILY_R600)
764	    tiling |= RADEON_TILING_MICRO;
765	else
766	    tiling |= RADEON_TILING_MACRO;
767    }
768    cpp = pScrn->bitsPerPixel / 8;
769    pScrn->displayWidth =
770	RADEON_ALIGN(pScrn->virtualX, drmmode_get_pitch_align(pScrn, cpp, tiling));
771    info->CurrentLayout.displayWidth = pScrn->displayWidth;
772
773    /* Set display resolution */
774    xf86SetDpi(pScrn, 0, 0);
775
776	/* Get ScreenInit function */
777    if (!xf86LoadSubModule(pScrn, "fb")) return FALSE;
778
779    if (!xf86SetGamma(pScrn, zeros)) return FALSE;
780
781    if (!xf86ReturnOptValBool(info->Options, OPTION_SW_CURSOR, FALSE)) {
782	if (!xf86LoadSubModule(pScrn, "ramdac")) return FALSE;
783    }
784
785    if (pScrn->modes == NULL) {
786      xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No modes.\n");
787      goto fail;
788   }
789
790    return TRUE;
791 fail:
792    RADEONFreeRec(pScrn);
793    return FALSE;
794
795}
796
797static Bool RADEONCursorInit_KMS(ScreenPtr pScreen)
798{
799    return xf86_cursors_init (pScreen, CURSOR_WIDTH, CURSOR_HEIGHT,
800			      (HARDWARE_CURSOR_TRUECOLOR_AT_8BPP |
801			       HARDWARE_CURSOR_AND_SOURCE_WITH_MASK |
802			       HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_1 |
803			       HARDWARE_CURSOR_UPDATE_UNHIDDEN |
804			       HARDWARE_CURSOR_ARGB));
805}
806
807static Bool RADEONSaveScreen_KMS(ScreenPtr pScreen, int mode)
808{
809    ScrnInfoPtr  pScrn = xf86Screens[pScreen->myNum];
810    Bool         unblank;
811
812    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
813		   "RADEONSaveScreen(%d)\n", mode);
814
815    unblank = xf86IsUnblank(mode);
816    if (unblank) SetTimeSinceLastInputEvent();
817
818    if ((pScrn != NULL) && pScrn->vtSema) {
819	if (unblank)
820	    RADEONUnblank(pScrn);
821	else
822	    RADEONBlank(pScrn);
823    }
824    return TRUE;
825}
826
827/* Called at the end of each server generation.  Restore the original
828 * text mode, unmap video memory, and unwrap and call the saved
829 * CloseScreen function.
830 */
831static Bool RADEONCloseScreen_KMS(int scrnIndex, ScreenPtr pScreen)
832{
833    ScrnInfoPtr    pScrn = xf86Screens[scrnIndex];
834    RADEONInfoPtr  info  = RADEONPTR(pScrn);
835
836    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
837		   "RADEONCloseScreen\n");
838
839    drmmode_uevent_fini(pScrn, &info->drmmode);
840    if (info->cs)
841      radeon_cs_flush_indirect(pScrn);
842
843    DeleteCallback(&FlushCallback, radeon_flush_callback, pScrn);
844
845    if (info->accel_state->exa) {
846	exaDriverFini(pScreen);
847	free(info->accel_state->exa);
848	info->accel_state->exa = NULL;
849    }
850
851    if (info->accel_state->use_vbos)
852        radeon_vbo_free_lists(pScrn);
853
854    drmDropMaster(info->dri->drmFD);
855
856    if (info->cursor) xf86DestroyCursorInfoRec(info->cursor);
857    info->cursor = NULL;
858
859    radeon_dri2_close_screen(pScreen);
860
861    pScrn->vtSema = FALSE;
862    xf86ClearPrimInitDone(info->pEnt->index);
863    pScreen->BlockHandler = info->BlockHandler;
864    pScreen->CloseScreen = info->CloseScreen;
865    return (*pScreen->CloseScreen)(scrnIndex, pScreen);
866}
867
868
869void RADEONFreeScreen_KMS(int scrnIndex, int flags)
870{
871    ScrnInfoPtr  pScrn = xf86Screens[scrnIndex];
872    RADEONInfoPtr  info  = RADEONPTR(pScrn);
873
874    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
875		   "RADEONFreeScreen\n");
876
877    /* when server quits at PreInit, we don't need do this anymore*/
878    if (!info) return;
879
880    RADEONFreeRec(pScrn);
881}
882
883Bool RADEONScreenInit_KMS(int scrnIndex, ScreenPtr pScreen,
884			  int argc, char **argv)
885{
886    ScrnInfoPtr    pScrn = xf86Screens[pScreen->myNum];
887    RADEONInfoPtr  info  = RADEONPTR(pScrn);
888    int            subPixelOrder = SubPixelUnknown;
889    char*          s;
890    void *front_ptr;
891    int ret;
892
893    pScrn->fbOffset = 0;
894
895    miClearVisualTypes();
896    if (!miSetVisualTypes(pScrn->depth,
897			  miGetDefaultVisualMask(pScrn->depth),
898			  pScrn->rgbBits,
899			  pScrn->defaultVisual)) return FALSE;
900    miSetPixmapDepths ();
901
902    ret = drmSetMaster(info->dri->drmFD);
903    if (ret) {
904        ErrorF("Unable to retrieve master\n");
905        return FALSE;
906    }
907    info->directRenderingEnabled = FALSE;
908    if (info->r600_shadow_fb == FALSE)
909        info->directRenderingEnabled = radeon_dri2_screen_init(pScreen);
910
911    front_ptr = info->FB;
912
913    if (!info->bufmgr)
914        info->bufmgr = radeon_bo_manager_gem_ctor(info->dri->drmFD);
915    if (!info->bufmgr) {
916	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
917		   "failed to initialise GEM buffer manager");
918	return FALSE;
919    }
920    drmmode_set_bufmgr(pScrn, &info->drmmode, info->bufmgr);
921
922    if (!info->csm)
923        info->csm = radeon_cs_manager_gem_ctor(info->dri->drmFD);
924    if (!info->csm) {
925	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
926		   "failed to initialise command submission manager");
927	return FALSE;
928    }
929
930    if (!info->cs)
931        info->cs = radeon_cs_create(info->csm, RADEON_BUFFER_SIZE/4);
932    if (!info->cs) {
933	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
934		   "failed to initialise command submission buffer");
935	return FALSE;
936    }
937
938    radeon_cs_set_limit(info->cs, RADEON_GEM_DOMAIN_GTT, info->gart_size);
939    radeon_cs_space_set_flush(info->cs, (void(*)(void *))radeon_cs_flush_indirect, pScrn);
940
941    radeon_setup_kernel_mem(pScreen);
942    front_ptr = info->front_bo->ptr;
943
944    if (info->r600_shadow_fb) {
945	info->fb_shadow = calloc(1,
946				 pScrn->displayWidth * pScrn->virtualY *
947				 ((pScrn->bitsPerPixel + 7) >> 3));
948	if (info->fb_shadow == NULL) {
949	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
950                       "Failed to allocate shadow framebuffer\n");
951	    info->r600_shadow_fb = FALSE;
952	} else {
953	    if (!fbScreenInit(pScreen, info->fb_shadow,
954			      pScrn->virtualX, pScrn->virtualY,
955			      pScrn->xDpi, pScrn->yDpi, pScrn->displayWidth,
956			      pScrn->bitsPerPixel))
957		return FALSE;
958	}
959    }
960
961    if (info->r600_shadow_fb == FALSE) {
962	/* Init fb layer */
963	if (!fbScreenInit(pScreen, front_ptr,
964			  pScrn->virtualX, pScrn->virtualY,
965			  pScrn->xDpi, pScrn->yDpi, pScrn->displayWidth,
966			  pScrn->bitsPerPixel))
967	    return FALSE;
968    }
969
970    xf86SetBlackWhitePixels(pScreen);
971
972    if (pScrn->bitsPerPixel > 8) {
973	VisualPtr  visual;
974
975	visual = pScreen->visuals + pScreen->numVisuals;
976	while (--visual >= pScreen->visuals) {
977	    if ((visual->class | DynamicClass) == DirectColor) {
978		visual->offsetRed   = pScrn->offset.red;
979		visual->offsetGreen = pScrn->offset.green;
980		visual->offsetBlue  = pScrn->offset.blue;
981		visual->redMask     = pScrn->mask.red;
982		visual->greenMask   = pScrn->mask.green;
983		visual->blueMask    = pScrn->mask.blue;
984	    }
985	}
986    }
987
988    /* Must be after RGB order fixed */
989    fbPictureInit (pScreen, 0, 0);
990
991#ifdef RENDER
992    if ((s = xf86GetOptValString(info->Options, OPTION_SUBPIXEL_ORDER))) {
993	if (strcmp(s, "RGB") == 0) subPixelOrder = SubPixelHorizontalRGB;
994	else if (strcmp(s, "BGR") == 0) subPixelOrder = SubPixelHorizontalBGR;
995	else if (strcmp(s, "NONE") == 0) subPixelOrder = SubPixelNone;
996	PictureSetSubpixelOrder (pScreen, subPixelOrder);
997    }
998#endif
999
1000    pScrn->vtSema = TRUE;
1001    /* Backing store setup */
1002    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
1003		   "Initializing backing store\n");
1004    miInitializeBackingStore(pScreen);
1005    xf86SetBackingStore(pScreen);
1006
1007
1008    if (info->directRenderingEnabled) {
1009	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Direct rendering enabled\n");
1010    } else {
1011	xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
1012		   "Direct rendering disabled\n");
1013    }
1014
1015    if (info->r600_shadow_fb) {
1016	xf86DrvMsg(scrnIndex, X_INFO, "Acceleration disabled\n");
1017	info->accelOn = FALSE;
1018    } else {
1019	xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
1020		       "Initializing Acceleration\n");
1021	if (RADEONAccelInit(pScreen)) {
1022	    xf86DrvMsg(scrnIndex, X_INFO, "Acceleration enabled\n");
1023	    info->accelOn = TRUE;
1024	} else {
1025	    xf86DrvMsg(scrnIndex, X_ERROR,
1026		       "Acceleration initialization failed\n");
1027	    xf86DrvMsg(scrnIndex, X_INFO, "Acceleration disabled\n");
1028	    info->accelOn = FALSE;
1029	}
1030    }
1031
1032    /* Init DPMS */
1033    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
1034		   "Initializing DPMS\n");
1035    xf86DPMSInit(pScreen, xf86DPMSSet, 0);
1036
1037    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
1038		   "Initializing Cursor\n");
1039
1040    /* Set Silken Mouse */
1041    xf86SetSilkenMouse(pScreen);
1042
1043    /* Cursor setup */
1044    miDCInitialize(pScreen, xf86GetPointerScreenFuncs());
1045
1046    if (!xf86ReturnOptValBool(info->Options, OPTION_SW_CURSOR, FALSE)) {
1047	if (RADEONCursorInit_KMS(pScreen)) {
1048	}
1049    }
1050
1051    /* DGA setup */
1052#ifdef XFreeXDGA
1053    /* DGA is dangerous on kms as the base and framebuffer location may change:
1054     * http://lists.freedesktop.org/archives/xorg-devel/2009-September/002113.html
1055     */
1056    /* xf86DiDGAInit(pScreen, info->LinearAddr + pScrn->fbOffset); */
1057#endif
1058    if (info->r600_shadow_fb == FALSE) {
1059        /* Init Xv */
1060        xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
1061                       "Initializing Xv\n");
1062        RADEONInitVideo(pScreen);
1063    }
1064
1065    if (info->r600_shadow_fb == TRUE) {
1066        if (!shadowSetup(pScreen)) {
1067	    xf86DrvMsg(scrnIndex, X_ERROR,
1068		       "Shadowfb initialization failed\n");
1069            return FALSE;
1070        }
1071    }
1072    pScrn->pScreen = pScreen;
1073
1074    /* Provide SaveScreen & wrap BlockHandler and CloseScreen */
1075    /* Wrap CloseScreen */
1076    info->CloseScreen    = pScreen->CloseScreen;
1077    pScreen->CloseScreen = RADEONCloseScreen_KMS;
1078    pScreen->SaveScreen  = RADEONSaveScreen_KMS;
1079    info->BlockHandler = pScreen->BlockHandler;
1080    pScreen->BlockHandler = RADEONBlockHandler_KMS;
1081
1082    if (!AddCallback(&FlushCallback, radeon_flush_callback, pScrn))
1083        return FALSE;
1084
1085    info->CreateScreenResources = pScreen->CreateScreenResources;
1086    pScreen->CreateScreenResources = RADEONCreateScreenResources_KMS;
1087
1088   if (!xf86CrtcScreenInit (pScreen))
1089       return FALSE;
1090
1091   /* Wrap pointer motion to flip touch screen around */
1092//    info->PointerMoved = pScrn->PointerMoved;
1093//    pScrn->PointerMoved = RADEONPointerMoved;
1094
1095    if (!drmmode_setup_colormap(pScreen, pScrn))
1096	return FALSE;
1097
1098   /* Note unused options */
1099    if (serverGeneration == 1)
1100	xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
1101
1102    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
1103		   "RADEONScreenInit finished\n");
1104
1105    info->accel_state->XInited3D = FALSE;
1106    info->accel_state->engineMode = EXA_ENGINEMODE_UNKNOWN;
1107
1108    return TRUE;
1109}
1110
1111Bool RADEONEnterVT_KMS(int scrnIndex, int flags)
1112{
1113    ScrnInfoPtr    pScrn = xf86Screens[scrnIndex];
1114    RADEONInfoPtr  info  = RADEONPTR(pScrn);
1115    int ret;
1116
1117    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
1118		   "RADEONEnterVT_KMS\n");
1119
1120
1121    ret = drmSetMaster(info->dri->drmFD);
1122    if (ret)
1123	ErrorF("Unable to retrieve master\n");
1124    info->accel_state->XInited3D = FALSE;
1125    info->accel_state->engineMode = EXA_ENGINEMODE_UNKNOWN;
1126
1127    pScrn->vtSema = TRUE;
1128
1129    if (!drmmode_set_desired_modes(pScrn, &info->drmmode))
1130	return FALSE;
1131
1132    if (info->adaptor)
1133	RADEONResetVideo(pScrn);
1134
1135    return TRUE;
1136}
1137
1138
1139void RADEONLeaveVT_KMS(int scrnIndex, int flags)
1140{
1141    ScrnInfoPtr    pScrn = xf86Screens[scrnIndex];
1142    RADEONInfoPtr  info  = RADEONPTR(pScrn);
1143
1144    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
1145		   "RADEONLeaveVT_KMS\n");
1146
1147    drmDropMaster(info->dri->drmFD);
1148
1149#ifdef HAVE_FREE_SHADOW
1150    xf86RotateFreeShadow(pScrn);
1151#endif
1152
1153    xf86_hide_cursors (pScrn);
1154    info->accel_state->XInited3D = FALSE;
1155    info->accel_state->engineMode = EXA_ENGINEMODE_UNKNOWN;
1156
1157    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
1158		   "Ok, leaving now...\n");
1159}
1160
1161
1162Bool RADEONSwitchMode_KMS(int scrnIndex, DisplayModePtr mode, int flags)
1163{
1164    ScrnInfoPtr    pScrn       = xf86Screens[scrnIndex];
1165    Bool ret;
1166    ret = xf86SetSingleMode (pScrn, mode, RR_Rotate_0);
1167    return ret;
1168
1169}
1170
1171void RADEONAdjustFrame_KMS(int scrnIndex, int x, int y, int flags)
1172{
1173    ScrnInfoPtr    pScrn       = xf86Screens[scrnIndex];
1174    RADEONInfoPtr  info        = RADEONPTR(pScrn);
1175    drmmode_adjust_frame(pScrn, &info->drmmode, x, y, flags);
1176    return;
1177}
1178
1179static Bool radeon_setup_kernel_mem(ScreenPtr pScreen)
1180{
1181    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
1182    RADEONInfoPtr info = RADEONPTR(pScrn);
1183    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
1184    int cpp = info->CurrentLayout.pixel_bytes;
1185    int screen_size;
1186    int pitch, base_align;
1187    int total_size_bytes = 0, remain_size_bytes;
1188    uint32_t tiling_flags = 0;
1189
1190    if (info->accel_state->exa != NULL) {
1191	xf86DrvMsg(pScreen->myNum, X_ERROR, "Memory map already initialized\n");
1192	return FALSE;
1193    }
1194    if (info->r600_shadow_fb == FALSE) {
1195        info->accel_state->exa = exaDriverAlloc();
1196        if (info->accel_state->exa == NULL)
1197	    return FALSE;
1198    }
1199
1200    if (info->allowColorTiling) {
1201	if (info->ChipFamily >= CHIP_FAMILY_R600)
1202	    tiling_flags |= RADEON_TILING_MICRO;
1203	else
1204	    tiling_flags |= RADEON_TILING_MACRO;
1205    }
1206    pitch = RADEON_ALIGN(pScrn->displayWidth, drmmode_get_pitch_align(pScrn, cpp, tiling_flags)) * cpp;
1207    screen_size = RADEON_ALIGN(pScrn->virtualY, drmmode_get_height_align(pScrn, tiling_flags)) * pitch;
1208    base_align = drmmode_get_base_align(pScrn, cpp, tiling_flags);
1209    {
1210	int cursor_size = 64 * 4 * 64;
1211	int c;
1212
1213	cursor_size = RADEON_ALIGN(cursor_size, RADEON_GPU_PAGE_SIZE);
1214	for (c = 0; c < xf86_config->num_crtc; c++) {
1215	    /* cursor objects */
1216            if (info->cursor_bo[c] == NULL) {
1217                info->cursor_bo[c] = radeon_bo_open(info->bufmgr, 0,
1218                                                    cursor_size, 0,
1219                                                    RADEON_GEM_DOMAIN_VRAM, 0);
1220                if (!info->cursor_bo[c]) {
1221                    return FALSE;
1222                }
1223
1224                if (radeon_bo_map(info->cursor_bo[c], 1)) {
1225                    ErrorF("Failed to map cursor buffer memory\n");
1226                }
1227
1228                drmmode_set_cursor(pScrn, &info->drmmode, c, info->cursor_bo[c]);
1229                total_size_bytes += cursor_size;
1230            }
1231        }
1232    }
1233
1234    screen_size = RADEON_ALIGN(screen_size, RADEON_GPU_PAGE_SIZE);
1235    /* keep area front front buffer - but don't allocate it yet */
1236    total_size_bytes += screen_size;
1237
1238    /* work out from the mm size what the exa / tex sizes need to be */
1239    remain_size_bytes = info->vram_size - total_size_bytes;
1240
1241    info->dri->textureSize = 0;
1242
1243    if (info->front_bo == NULL) {
1244        info->front_bo = radeon_bo_open(info->bufmgr, 0, screen_size,
1245                                        base_align, RADEON_GEM_DOMAIN_VRAM, 0);
1246        if (info->r600_shadow_fb == TRUE) {
1247            if (radeon_bo_map(info->front_bo, 1)) {
1248                ErrorF("Failed to map cursor buffer memory\n");
1249            }
1250        }
1251#if X_BYTE_ORDER == X_BIG_ENDIAN
1252	switch (cpp) {
1253	case 4:
1254	    tiling_flags |= RADEON_TILING_SWAP_32BIT;
1255	    break;
1256	case 2:
1257	    tiling_flags |= RADEON_TILING_SWAP_16BIT;
1258	    break;
1259	}
1260#endif
1261	if (tiling_flags)
1262            radeon_bo_set_tiling(info->front_bo, tiling_flags, pitch);
1263    }
1264
1265    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Front buffer size: %dK\n", info->front_bo->size/1024);
1266    radeon_kms_update_vram_limit(pScrn, screen_size);
1267    return TRUE;
1268}
1269
1270void radeon_kms_update_vram_limit(ScrnInfoPtr pScrn, int new_fb_size)
1271{
1272    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
1273    RADEONInfoPtr info = RADEONPTR(pScrn);
1274    int remain_size_bytes;
1275    int total_size_bytes;
1276    int c;
1277
1278    for (c = 0; c < xf86_config->num_crtc; c++) {
1279	if (info->cursor_bo[c] != NULL) {
1280	    total_size_bytes += (64 * 4 * 64);
1281	}
1282    }
1283
1284    total_size_bytes += new_fb_size;
1285    remain_size_bytes = info->vram_size - new_fb_size;
1286    remain_size_bytes = (remain_size_bytes / 10) * 9;
1287    radeon_cs_set_limit(info->cs, RADEON_GEM_DOMAIN_VRAM, remain_size_bytes);
1288
1289    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VRAM usage limit set to %dK\n", remain_size_bytes / 1024);
1290}
1291
1292
1293#endif
1294