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