radeon_kms.c revision ad43ddac
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    { -1,                    NULL,               OPTV_NONE,    {0}, FALSE }
74};
75
76void radeon_cs_flush_indirect(ScrnInfoPtr pScrn)
77{
78    RADEONInfoPtr  info = RADEONPTR(pScrn);
79    struct radeon_accel_state *accel_state = info->accel_state;
80    int ret;
81
82    if (!info->cs->cdw)
83	return;
84
85    if (info->accel_state->vb_ptr)
86      info->accel_state->vb_ptr = NULL;
87
88    /* release the current VBO so we don't block on mapping it later */
89    if (info->accel_state->vb_offset && info->accel_state->vb_bo) {
90        radeon_vbo_put(pScrn);
91        info->accel_state->vb_start_op = -1;
92    }
93
94    radeon_cs_emit(info->cs);
95    radeon_cs_erase(info->cs);
96
97    if (accel_state->use_vbos)
98        radeon_vbo_flush_bos(pScrn);
99
100    ret = radeon_cs_space_check_with_bo(info->cs,
101					accel_state->vb_bo,
102					RADEON_GEM_DOMAIN_GTT, 0);
103    if (ret)
104      ErrorF("space check failed in flush\n");
105
106    if (info->reemit_current2d && info->state_2d.op)
107        info->reemit_current2d(pScrn, info->state_2d.op);
108
109    if (info->dri2.enabled) {
110        info->accel_state->XInited3D = FALSE;
111        info->accel_state->engineMode = EXA_ENGINEMODE_UNKNOWN;
112    }
113
114}
115
116void radeon_ddx_cs_start(ScrnInfoPtr pScrn,
117			 int n, const char *file,
118			 const char *func, int line)
119{
120    RADEONInfoPtr  info = RADEONPTR(pScrn);
121
122    if (info->cs->cdw + n > info->cs->ndw) {
123	radeon_cs_flush_indirect(pScrn);
124
125    }
126    radeon_cs_begin(info->cs, n, file, func, line);
127}
128
129
130extern _X_EXPORT int gRADEONEntityIndex;
131
132static int getRADEONEntityIndex(void)
133{
134    return gRADEONEntityIndex;
135}
136
137static void *
138radeonShadowWindow(ScreenPtr screen, CARD32 row, CARD32 offset, int mode,
139		   CARD32 *size, void *closure)
140{
141    ScrnInfoPtr pScrn = xf86Screens[screen->myNum];
142    RADEONInfoPtr  info   = RADEONPTR(pScrn);
143    int stride;
144
145    stride = (pScrn->displayWidth * pScrn->bitsPerPixel) / 8;
146    *size = stride;
147
148    return ((uint8_t *)info->front_bo->ptr + row * stride + offset);
149}
150
151static Bool RADEONCreateScreenResources_KMS(ScreenPtr pScreen)
152{
153    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
154    RADEONInfoPtr  info   = RADEONPTR(pScrn);
155    PixmapPtr pixmap;
156
157    pScreen->CreateScreenResources = info->CreateScreenResources;
158    if (!(*pScreen->CreateScreenResources)(pScreen))
159	return FALSE;
160    pScreen->CreateScreenResources = RADEONCreateScreenResources_KMS;
161
162    if (info->r600_shadow_fb) {
163	pixmap = pScreen->GetScreenPixmap(pScreen);
164
165	if (!shadowAdd(pScreen, pixmap, shadowUpdatePackedWeak(),
166		       radeonShadowWindow, 0, NULL))
167	    return FALSE;
168    }
169
170    if (info->dri2.enabled) {
171	if (info->front_bo) {
172	    PixmapPtr pPix = pScreen->GetScreenPixmap(pScreen);
173	    radeon_set_pixmap_bo(pPix, info->front_bo);
174	}
175    }
176    return TRUE;
177}
178
179static void RADEONBlockHandler_KMS(int i, pointer blockData,
180				   pointer pTimeout, pointer pReadmask)
181{
182    ScreenPtr      pScreen = screenInfo.screens[i];
183    ScrnInfoPtr    pScrn   = xf86Screens[i];
184    RADEONInfoPtr  info    = RADEONPTR(pScrn);
185
186    pScreen->BlockHandler = info->BlockHandler;
187    (*pScreen->BlockHandler) (i, blockData, pTimeout, pReadmask);
188    pScreen->BlockHandler = RADEONBlockHandler_KMS;
189
190    if (info->VideoTimerCallback)
191	(*info->VideoTimerCallback)(pScrn, currentTime.milliseconds);
192
193    radeon_cs_flush_indirect(pScrn);
194}
195
196static Bool RADEONIsAccelWorking(ScrnInfoPtr pScrn)
197{
198    RADEONInfoPtr info = RADEONPTR(pScrn);
199    struct drm_radeon_info ginfo;
200    int r;
201    uint32_t tmp;
202
203    memset(&ginfo, 0, sizeof(ginfo));
204    ginfo.request = 0x3;
205    ginfo.value = (uintptr_t)&tmp;
206    r = drmCommandWriteRead(info->dri->drmFD, DRM_RADEON_INFO, &ginfo, sizeof(ginfo));
207    if (r) {
208        /* If kernel is too old before 2.6.32 than assume accel is working */
209        if (r == -EINVAL) {
210            xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Kernel too old missing accel "
211                       "information, assuming accel is working\n");
212            return TRUE;
213        }
214        return FALSE;
215    }
216    if (tmp)
217        return TRUE;
218    return FALSE;
219}
220
221static Bool RADEONPreInitAccel_KMS(ScrnInfoPtr pScrn)
222{
223    RADEONInfoPtr  info = RADEONPTR(pScrn);
224
225    if (!(info->accel_state = xcalloc(1, sizeof(struct radeon_accel_state)))) {
226	xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Unable to allocate accel_state rec!\n");
227	return FALSE;
228    }
229
230    if (xf86ReturnOptValBool(info->Options, OPTION_NOACCEL, FALSE) ||
231	(!RADEONIsAccelWorking(pScrn))) {
232	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
233		   "GPU accel disabled or not working, using shadowfb for KMS\n");
234	info->r600_shadow_fb = TRUE;
235	if (!xf86LoadSubModule(pScrn, "shadow"))
236	    info->r600_shadow_fb = FALSE;
237	return TRUE;
238    }
239
240    if ((info->ChipFamily == CHIP_FAMILY_RS100) ||
241	(info->ChipFamily == CHIP_FAMILY_RS200) ||
242	(info->ChipFamily == CHIP_FAMILY_RS300) ||
243	(info->ChipFamily == CHIP_FAMILY_RS400) ||
244	(info->ChipFamily == CHIP_FAMILY_RS480) ||
245	(info->ChipFamily == CHIP_FAMILY_RS600) ||
246	(info->ChipFamily == CHIP_FAMILY_RS690) ||
247	(info->ChipFamily == CHIP_FAMILY_RS740))
248	info->accel_state->has_tcl = FALSE;
249    else {
250	info->accel_state->has_tcl = TRUE;
251    }
252
253    info->useEXA = TRUE;
254
255    if (info->useEXA) {
256	int errmaj = 0, errmin = 0;
257	info->exaReq.majorversion = EXA_VERSION_MAJOR;
258	info->exaReq.minorversion = EXA_VERSION_MINOR;
259	if (!LoadSubModule(pScrn->module, "exa", NULL, NULL, NULL,
260			   &info->exaReq, &errmaj, &errmin)) {
261	    LoaderErrorMsg(NULL, "exa", errmaj, errmin);
262	    return FALSE;
263	}
264    }
265
266    return TRUE;
267}
268
269static Bool RADEONPreInitChipType_KMS(ScrnInfoPtr pScrn)
270{
271    RADEONInfoPtr  info   = RADEONPTR(pScrn);
272    uint32_t cmd_stat;
273    int i;
274
275    info->Chipset = PCI_DEV_DEVICE_ID(info->PciInfo);
276    pScrn->chipset = (char *)xf86TokenToString(RADEONChipsets, info->Chipset);
277    if (!pScrn->chipset) {
278	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
279		   "ChipID 0x%04x is not recognized\n", info->Chipset);
280	return FALSE;
281    }
282
283    if (info->Chipset < 0) {
284	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
285		   "Chipset \"%s\" is not recognized\n", pScrn->chipset);
286	return FALSE;
287    }
288    xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
289	       "Chipset: \"%s\" (ChipID = 0x%04x)\n",
290	       pScrn->chipset,
291	       info->Chipset);
292
293    for (i = 0; i < sizeof(RADEONCards) / sizeof(RADEONCardInfo); i++) {
294	if (info->Chipset == RADEONCards[i].pci_device_id) {
295	    RADEONCardInfo *card = &RADEONCards[i];
296	    info->ChipFamily = card->chip_family;
297	    info->IsMobility = card->mobility;
298	    info->IsIGP = card->igp;
299	    break;
300	}
301    }
302
303    info->cardType = CARD_PCI;
304
305    PCI_READ_LONG(info->PciInfo, &cmd_stat, PCI_CMD_STAT_REG);
306    if (cmd_stat & RADEON_CAP_LIST) {
307	uint32_t cap_ptr, cap_id;
308
309	PCI_READ_LONG(info->PciInfo, &cap_ptr, RADEON_CAPABILITIES_PTR_PCI_CONFIG);
310	cap_ptr &= RADEON_CAP_PTR_MASK;
311
312	while(cap_ptr != RADEON_CAP_ID_NULL) {
313	    PCI_READ_LONG(info->PciInfo, &cap_id, cap_ptr);
314	    if ((cap_id & 0xff)== RADEON_CAP_ID_AGP) {
315		info->cardType = CARD_AGP;
316		break;
317	    }
318	    if ((cap_id & 0xff)== RADEON_CAP_ID_EXP) {
319		info->cardType = CARD_PCIE;
320		break;
321	    }
322	    cap_ptr = (cap_id >> 8) & RADEON_CAP_PTR_MASK;
323	}
324    }
325
326
327    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "%s card detected\n",
328	       (info->cardType==CARD_PCI) ? "PCI" :
329		(info->cardType==CARD_PCIE) ? "PCIE" : "AGP");
330
331    /* treat PCIE IGP cards as PCI */
332    if (info->cardType == CARD_PCIE && info->IsIGP)
333	info->cardType = CARD_PCI;
334
335    if ((info->ChipFamily >= CHIP_FAMILY_R600) && info->IsIGP)
336	info->cardType = CARD_PCIE;
337
338    /* not sure about gart table requirements */
339    if ((info->ChipFamily == CHIP_FAMILY_RS600) && info->IsIGP)
340	info->cardType = CARD_PCIE;
341
342#ifdef RENDER
343    info->RenderAccel = xf86ReturnOptValBool(info->Options, OPTION_RENDER_ACCEL,
344					     info->Chipset != PCI_CHIP_RN50_515E &&
345					     info->Chipset != PCI_CHIP_RN50_5969);
346#endif
347    return TRUE;
348}
349
350static Bool radeon_alloc_dri(ScrnInfoPtr pScrn)
351{
352    RADEONInfoPtr  info   = RADEONPTR(pScrn);
353    if (!(info->dri = xcalloc(1, sizeof(struct radeon_dri)))) {
354	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,"Unable to allocate dri rec!\n");
355	return FALSE;
356    }
357
358    if (!(info->cp = xcalloc(1, sizeof(struct radeon_cp)))) {
359	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,"Unable to allocate cp rec!\n");
360	return FALSE;
361    }
362    return TRUE;
363}
364
365static Bool radeon_open_drm_master(ScrnInfoPtr pScrn)
366{
367    RADEONInfoPtr  info   = RADEONPTR(pScrn);
368    RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
369    struct pci_device *dev = info->PciInfo;
370    char *busid;
371    drmSetVersion sv;
372    int err;
373
374    if (pRADEONEnt->fd) {
375	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
376		   " reusing fd for second head\n");
377
378	info->dri2.drm_fd = pRADEONEnt->fd;
379	goto out;
380    }
381
382    busid = XNFprintf("pci:%04x:%02x:%02x.%d",
383		      dev->domain, dev->bus, dev->dev, dev->func);
384
385    info->dri2.drm_fd = drmOpen("radeon", busid);
386    if (info->dri2.drm_fd == -1) {
387
388	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
389		   "[drm] Failed to open DRM device for %s: %s\n",
390		   busid, strerror(errno));
391	xfree(busid);
392	return FALSE;
393    }
394    xfree(busid);
395
396    /* Check that what we opened was a master or a master-capable FD,
397     * by setting the version of the interface we'll use to talk to it.
398     * (see DRIOpenDRMMaster() in DRI1)
399     */
400    sv.drm_di_major = 1;
401    sv.drm_di_minor = 1;
402    sv.drm_dd_major = -1;
403    sv.drm_dd_minor = -1;
404    err = drmSetInterfaceVersion(info->dri2.drm_fd, &sv);
405    if (err != 0) {
406	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
407		   "[drm] failed to set drm interface version.\n");
408	drmClose(info->dri2.drm_fd);
409	info->dri2.drm_fd = -1;
410
411	return FALSE;
412    }
413
414    pRADEONEnt->fd = info->dri2.drm_fd;
415 out:
416    info->drmmode.fd = info->dri2.drm_fd;
417    info->dri->drmFD = info->dri2.drm_fd;
418    return TRUE;
419}
420
421Bool RADEONPreInit_KMS(ScrnInfoPtr pScrn, int flags)
422{
423    RADEONInfoPtr     info;
424    RADEONEntPtr pRADEONEnt;
425    DevUnion* pPriv;
426    Gamma  zeros = { 0.0, 0.0, 0.0 };
427
428    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
429		   "RADEONPreInit_KMS\n");
430    if (pScrn->numEntities != 1) return FALSE;
431    if (!RADEONGetRec(pScrn)) return FALSE;
432
433    info               = RADEONPTR(pScrn);
434    info->MMIO         = NULL;
435    info->IsSecondary  = FALSE;
436    info->IsPrimary = FALSE;
437    info->kms_enabled = TRUE;
438    info->pEnt         = xf86GetEntityInfo(pScrn->entityList[pScrn->numEntities - 1]);
439    if (info->pEnt->location.type != BUS_PCI) goto fail;
440
441    pPriv = xf86GetEntityPrivate(pScrn->entityList[0],
442				 getRADEONEntityIndex());
443    pRADEONEnt = pPriv->ptr;
444
445    if(xf86IsEntityShared(pScrn->entityList[0]))
446    {
447        if(xf86IsPrimInitDone(pScrn->entityList[0]))
448        {
449            info->IsSecondary = TRUE;
450            pRADEONEnt->pSecondaryScrn = pScrn;
451        }
452        else
453        {
454	    info->IsPrimary = TRUE;
455            xf86SetPrimInitDone(pScrn->entityList[0]);
456            pRADEONEnt->pPrimaryScrn = pScrn;
457            pRADEONEnt->HasSecondary = FALSE;
458        }
459    }
460
461    info->PciInfo = xf86GetPciInfoForEntity(info->pEnt->index);
462    pScrn->monitor     = pScrn->confScreen->monitor;
463
464    if (!RADEONPreInitVisual(pScrn))
465	goto fail;
466
467    xf86CollectOptions(pScrn, NULL);
468    if (!(info->Options = xalloc(sizeof(RADEONOptions_KMS))))
469	goto fail;
470
471    memcpy(info->Options, RADEONOptions_KMS, sizeof(RADEONOptions_KMS));
472    xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, info->Options);
473
474    if (!RADEONPreInitWeight(pScrn))
475	goto fail;
476
477    if (!RADEONPreInitChipType_KMS(pScrn))
478        goto fail;
479
480    if (!radeon_alloc_dri(pScrn))
481	return FALSE;
482
483    info->allowColorTiling = xf86ReturnOptValBool(info->Options,
484                                        OPTION_COLOR_TILING, FALSE);
485    if (info->ChipFamily >= CHIP_FAMILY_R600) {
486	    xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Color tiling is not yet supported on R600/R700\n");
487	    info->allowColorTiling = FALSE;
488    }
489    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
490	 "KMS Color Tiling: %sabled\n", info->allowColorTiling ? "en" : "dis");
491
492    if (radeon_open_drm_master(pScrn) == FALSE) {
493	xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Kernel modesetting setup failed\n");
494	goto fail;
495    }
496    if (drmmode_pre_init(pScrn, &info->drmmode, pScrn->bitsPerPixel / 8) == FALSE) {
497	xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Kernel modesetting setup failed\n");
498	goto fail;
499    }
500
501    info->dri2.enabled = FALSE;
502    info->dri->pKernelDRMVersion = drmGetVersion(info->dri->drmFD);
503    if (info->dri->pKernelDRMVersion == NULL) {
504	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
505		   "RADEONDRIGetVersion failed to get the DRM version\n");
506	goto fail;
507    }
508
509    {
510	struct drm_radeon_gem_info mminfo;
511
512	if (!drmCommandWriteRead(info->dri->drmFD, DRM_RADEON_GEM_INFO, &mminfo, sizeof(mminfo)))
513	{
514	    info->vram_size = mminfo.vram_visible;
515	    info->gart_size = mminfo.gart_size;
516	    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
517		       "mem size init: gart size :%llx vram size: s:%llx visible:%llx\n",
518		       (unsigned long long)mminfo.gart_size,
519		       (unsigned long long)mminfo.vram_size,
520		       (unsigned long long)mminfo.vram_visible);
521	}
522    }
523
524    info->exa_pixmaps = xf86ReturnOptValBool(info->Options,
525                                             OPTION_EXA_PIXMAPS,
526					     ((info->vram_size > (32 * 1024 * 1024) &&
527					      info->RenderAccel)));
528    if (info->exa_pixmaps)
529    	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
530		"EXA: Driver will allow EXA pixmaps in VRAM\n");
531    else
532    	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
533		"EXA: Driver will not allow EXA pixmaps in VRAM\n");
534    RADEONSetPitch(pScrn);
535
536    /* Set display resolution */
537    xf86SetDpi(pScrn, 0, 0);
538
539	/* Get ScreenInit function */
540    if (!xf86LoadSubModule(pScrn, "fb")) return FALSE;
541
542    if (!xf86SetGamma(pScrn, zeros)) return FALSE;
543
544    if (!xf86ReturnOptValBool(info->Options, OPTION_SW_CURSOR, FALSE)) {
545	if (!xf86LoadSubModule(pScrn, "ramdac")) return FALSE;
546    }
547
548    if (!RADEONPreInitAccel_KMS(pScrn))              goto fail;
549
550    if (pScrn->modes == NULL) {
551      xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No modes.\n");
552      goto fail;
553   }
554
555    return TRUE;
556 fail:
557    RADEONFreeRec(pScrn);
558    return FALSE;
559
560}
561
562static Bool RADEONCursorInit_KMS(ScreenPtr pScreen)
563{
564    return xf86_cursors_init (pScreen, CURSOR_WIDTH, CURSOR_HEIGHT,
565			      (HARDWARE_CURSOR_TRUECOLOR_AT_8BPP |
566			       HARDWARE_CURSOR_AND_SOURCE_WITH_MASK |
567			       HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_1 |
568			       HARDWARE_CURSOR_UPDATE_UNHIDDEN |
569			       HARDWARE_CURSOR_ARGB));
570}
571
572static Bool RADEONSaveScreen_KMS(ScreenPtr pScreen, int mode)
573{
574    ScrnInfoPtr  pScrn = xf86Screens[pScreen->myNum];
575    Bool         unblank;
576
577    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
578		   "RADEONSaveScreen(%d)\n", mode);
579
580    unblank = xf86IsUnblank(mode);
581    if (unblank) SetTimeSinceLastInputEvent();
582
583    if ((pScrn != NULL) && pScrn->vtSema) {
584	if (unblank)
585	    RADEONUnblank(pScrn);
586	else
587	    RADEONBlank(pScrn);
588    }
589    return TRUE;
590}
591
592/* Called at the end of each server generation.  Restore the original
593 * text mode, unmap video memory, and unwrap and call the saved
594 * CloseScreen function.
595 */
596static Bool RADEONCloseScreen_KMS(int scrnIndex, ScreenPtr pScreen)
597{
598    ScrnInfoPtr    pScrn = xf86Screens[scrnIndex];
599    RADEONInfoPtr  info  = RADEONPTR(pScrn);
600
601    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
602		   "RADEONCloseScreen\n");
603
604    if (info->cs)
605      radeon_cs_flush_indirect(pScrn);
606
607    if (info->accel_state->exa) {
608	exaDriverFini(pScreen);
609	xfree(info->accel_state->exa);
610	info->accel_state->exa = NULL;
611    }
612
613    if (info->accel_state->use_vbos)
614        radeon_vbo_free_lists(pScrn);
615
616    drmDropMaster(info->dri->drmFD);
617
618    if (info->cursor) xf86DestroyCursorInfoRec(info->cursor);
619    info->cursor = NULL;
620
621    radeon_dri2_close_screen(pScreen);
622
623    pScrn->vtSema = FALSE;
624    xf86ClearPrimInitDone(info->pEnt->index);
625    pScreen->BlockHandler = info->BlockHandler;
626    pScreen->CloseScreen = info->CloseScreen;
627    return (*pScreen->CloseScreen)(scrnIndex, pScreen);
628}
629
630
631void RADEONFreeScreen_KMS(int scrnIndex, int flags)
632{
633    ScrnInfoPtr  pScrn = xf86Screens[scrnIndex];
634    RADEONInfoPtr  info  = RADEONPTR(pScrn);
635
636    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
637		   "RADEONFreeScreen\n");
638
639    /* when server quits at PreInit, we don't need do this anymore*/
640    if (!info) return;
641
642    RADEONFreeRec(pScrn);
643}
644
645Bool RADEONScreenInit_KMS(int scrnIndex, ScreenPtr pScreen,
646			  int argc, char **argv)
647{
648    ScrnInfoPtr    pScrn = xf86Screens[pScreen->myNum];
649    RADEONInfoPtr  info  = RADEONPTR(pScrn);
650    int            subPixelOrder = SubPixelUnknown;
651    char*          s;
652    void *front_ptr;
653    int ret;
654
655    pScrn->fbOffset = 0;
656
657    miClearVisualTypes();
658    if (!miSetVisualTypes(pScrn->depth,
659			  miGetDefaultVisualMask(pScrn->depth),
660			  pScrn->rgbBits,
661			  pScrn->defaultVisual)) return FALSE;
662    miSetPixmapDepths ();
663
664    ret = drmSetMaster(info->dri->drmFD);
665    if (ret) {
666        ErrorF("Unable to retrieve master\n");
667        return FALSE;
668    }
669    info->directRenderingEnabled = FALSE;
670    if (info->r600_shadow_fb == FALSE)
671        info->directRenderingEnabled = radeon_dri2_screen_init(pScreen);
672
673    front_ptr = info->FB;
674
675    if (!info->bufmgr)
676        info->bufmgr = radeon_bo_manager_gem_ctor(info->dri->drmFD);
677    if (!info->bufmgr) {
678	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
679		   "failed to initialise GEM buffer manager");
680	return FALSE;
681    }
682    drmmode_set_bufmgr(pScrn, &info->drmmode, info->bufmgr);
683
684    if (!info->csm)
685        info->csm = radeon_cs_manager_gem_ctor(info->dri->drmFD);
686    if (!info->csm) {
687	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
688		   "failed to initialise command submission manager");
689	return FALSE;
690    }
691
692    if (!info->cs)
693        info->cs = radeon_cs_create(info->csm, RADEON_BUFFER_SIZE/4);
694    if (!info->cs) {
695	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
696		   "failed to initialise command submission buffer");
697	return FALSE;
698    }
699
700    radeon_cs_set_limit(info->cs, RADEON_GEM_DOMAIN_GTT, info->gart_size);
701    radeon_cs_space_set_flush(info->cs, (void(*)(void *))radeon_cs_flush_indirect, pScrn);
702
703    radeon_setup_kernel_mem(pScreen);
704    front_ptr = info->front_bo->ptr;
705
706    if (info->r600_shadow_fb) {
707	info->fb_shadow = xcalloc(1,
708				  pScrn->displayWidth * pScrn->virtualY *
709				  ((pScrn->bitsPerPixel + 7) >> 3));
710	if (info->fb_shadow == NULL) {
711	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
712                       "Failed to allocate shadow framebuffer\n");
713	    info->r600_shadow_fb = FALSE;
714	} else {
715	    if (!fbScreenInit(pScreen, info->fb_shadow,
716			      pScrn->virtualX, pScrn->virtualY,
717			      pScrn->xDpi, pScrn->yDpi, pScrn->displayWidth,
718			      pScrn->bitsPerPixel))
719		return FALSE;
720	}
721    }
722
723    if (info->r600_shadow_fb == FALSE) {
724	/* Init fb layer */
725	if (!fbScreenInit(pScreen, front_ptr,
726			  pScrn->virtualX, pScrn->virtualY,
727			  pScrn->xDpi, pScrn->yDpi, pScrn->displayWidth,
728			  pScrn->bitsPerPixel))
729	    return FALSE;
730    }
731
732    xf86SetBlackWhitePixels(pScreen);
733
734    if (pScrn->bitsPerPixel > 8) {
735	VisualPtr  visual;
736
737	visual = pScreen->visuals + pScreen->numVisuals;
738	while (--visual >= pScreen->visuals) {
739	    if ((visual->class | DynamicClass) == DirectColor) {
740		visual->offsetRed   = pScrn->offset.red;
741		visual->offsetGreen = pScrn->offset.green;
742		visual->offsetBlue  = pScrn->offset.blue;
743		visual->redMask     = pScrn->mask.red;
744		visual->greenMask   = pScrn->mask.green;
745		visual->blueMask    = pScrn->mask.blue;
746	    }
747	}
748    }
749
750    /* Must be after RGB order fixed */
751    fbPictureInit (pScreen, 0, 0);
752
753#ifdef RENDER
754    if ((s = xf86GetOptValString(info->Options, OPTION_SUBPIXEL_ORDER))) {
755	if (strcmp(s, "RGB") == 0) subPixelOrder = SubPixelHorizontalRGB;
756	else if (strcmp(s, "BGR") == 0) subPixelOrder = SubPixelHorizontalBGR;
757	else if (strcmp(s, "NONE") == 0) subPixelOrder = SubPixelNone;
758	PictureSetSubpixelOrder (pScreen, subPixelOrder);
759    }
760#endif
761
762    pScrn->vtSema = TRUE;
763    /* Backing store setup */
764    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
765		   "Initializing backing store\n");
766    miInitializeBackingStore(pScreen);
767    xf86SetBackingStore(pScreen);
768
769
770    if (info->directRenderingEnabled) {
771	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Direct rendering enabled\n");
772    } else {
773	xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
774		   "Direct rendering disabled\n");
775    }
776
777    if (info->r600_shadow_fb) {
778	xf86DrvMsg(scrnIndex, X_INFO, "Acceleration disabled\n");
779	info->accelOn = FALSE;
780    } else {
781	xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
782		       "Initializing Acceleration\n");
783	if (RADEONAccelInit(pScreen)) {
784	    xf86DrvMsg(scrnIndex, X_INFO, "Acceleration enabled\n");
785	    info->accelOn = TRUE;
786	} else {
787	    xf86DrvMsg(scrnIndex, X_ERROR,
788		       "Acceleration initialization failed\n");
789	    xf86DrvMsg(scrnIndex, X_INFO, "Acceleration disabled\n");
790	    info->accelOn = FALSE;
791	}
792    }
793
794    /* Init DPMS */
795    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
796		   "Initializing DPMS\n");
797    xf86DPMSInit(pScreen, xf86DPMSSet, 0);
798
799    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
800		   "Initializing Cursor\n");
801
802    /* Set Silken Mouse */
803    xf86SetSilkenMouse(pScreen);
804
805    /* Cursor setup */
806    miDCInitialize(pScreen, xf86GetPointerScreenFuncs());
807
808    if (!xf86ReturnOptValBool(info->Options, OPTION_SW_CURSOR, FALSE)) {
809	if (RADEONCursorInit_KMS(pScreen)) {
810	}
811    }
812
813    /* DGA setup */
814#ifdef XFreeXDGA
815    /* DGA is dangerous on kms as the base and framebuffer location may change:
816     * http://lists.freedesktop.org/archives/xorg-devel/2009-September/002113.html
817     */
818    /* xf86DiDGAInit(pScreen, info->LinearAddr + pScrn->fbOffset); */
819#endif
820    if (info->r600_shadow_fb == FALSE) {
821        /* Init Xv */
822        xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
823                       "Initializing Xv\n");
824        RADEONInitVideo(pScreen);
825    }
826
827    if (info->r600_shadow_fb == TRUE) {
828        if (!shadowSetup(pScreen)) {
829	    xf86DrvMsg(scrnIndex, X_ERROR,
830		       "Shadowfb initialization failed\n");
831            return FALSE;
832        }
833    }
834    pScrn->pScreen = pScreen;
835
836    if (!drmmode_set_desired_modes(pScrn, &info->drmmode))
837	return FALSE;
838
839    /* Provide SaveScreen & wrap BlockHandler and CloseScreen */
840    /* Wrap CloseScreen */
841    info->CloseScreen    = pScreen->CloseScreen;
842    pScreen->CloseScreen = RADEONCloseScreen_KMS;
843    pScreen->SaveScreen  = RADEONSaveScreen_KMS;
844    info->BlockHandler = pScreen->BlockHandler;
845    pScreen->BlockHandler = RADEONBlockHandler_KMS;
846    info->CreateScreenResources = pScreen->CreateScreenResources;
847    pScreen->CreateScreenResources = RADEONCreateScreenResources_KMS;
848
849   if (!xf86CrtcScreenInit (pScreen))
850       return FALSE;
851
852   /* Wrap pointer motion to flip touch screen around */
853//    info->PointerMoved = pScrn->PointerMoved;
854//    pScrn->PointerMoved = RADEONPointerMoved;
855
856    if (!drmmode_setup_colormap(pScreen, pScrn))
857	return FALSE;
858
859   /* Note unused options */
860    if (serverGeneration == 1)
861	xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
862
863    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
864		   "RADEONScreenInit finished\n");
865
866    info->accel_state->XInited3D = FALSE;
867    info->accel_state->engineMode = EXA_ENGINEMODE_UNKNOWN;
868
869    return TRUE;
870}
871
872Bool RADEONEnterVT_KMS(int scrnIndex, int flags)
873{
874    ScrnInfoPtr    pScrn = xf86Screens[scrnIndex];
875    RADEONInfoPtr  info  = RADEONPTR(pScrn);
876    int ret;
877
878    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
879		   "RADEONEnterVT_KMS\n");
880
881
882    ret = drmSetMaster(info->dri->drmFD);
883    if (ret)
884	ErrorF("Unable to retrieve master\n");
885    info->accel_state->XInited3D = FALSE;
886    info->accel_state->engineMode = EXA_ENGINEMODE_UNKNOWN;
887
888    pScrn->vtSema = TRUE;
889
890    if (!drmmode_set_desired_modes(pScrn, &info->drmmode))
891	return FALSE;
892
893    if (info->adaptor)
894	RADEONResetVideo(pScrn);
895
896    return TRUE;
897}
898
899
900void RADEONLeaveVT_KMS(int scrnIndex, int flags)
901{
902    ScrnInfoPtr    pScrn = xf86Screens[scrnIndex];
903    RADEONInfoPtr  info  = RADEONPTR(pScrn);
904
905    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
906		   "RADEONLeaveVT_KMS\n");
907
908    drmDropMaster(info->dri->drmFD);
909
910#ifdef HAVE_FREE_SHADOW
911    xf86RotateFreeShadow(pScrn);
912#endif
913
914    xf86_hide_cursors (pScrn);
915    info->accel_state->XInited3D = FALSE;
916    info->accel_state->engineMode = EXA_ENGINEMODE_UNKNOWN;
917
918    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
919		   "Ok, leaving now...\n");
920}
921
922
923Bool RADEONSwitchMode_KMS(int scrnIndex, DisplayModePtr mode, int flags)
924{
925    ScrnInfoPtr    pScrn       = xf86Screens[scrnIndex];
926    Bool ret;
927    ret = xf86SetSingleMode (pScrn, mode, RR_Rotate_0);
928    return ret;
929
930}
931
932void RADEONAdjustFrame_KMS(int scrnIndex, int x, int y, int flags)
933{
934    ScrnInfoPtr    pScrn       = xf86Screens[scrnIndex];
935    RADEONInfoPtr  info        = RADEONPTR(pScrn);
936    drmmode_adjust_frame(pScrn, &info->drmmode, x, y, flags);
937    return;
938}
939
940static Bool radeon_setup_kernel_mem(ScreenPtr pScreen)
941{
942    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
943    RADEONInfoPtr info = RADEONPTR(pScrn);
944    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
945    int cpp = info->CurrentLayout.pixel_bytes;
946    int screen_size;
947    int stride = pScrn->displayWidth * cpp;
948    int total_size_bytes = 0, remain_size_bytes;
949
950    if (info->accel_state->exa != NULL) {
951	xf86DrvMsg(pScreen->myNum, X_ERROR, "Memory map already initialized\n");
952	return FALSE;
953    }
954    if (info->r600_shadow_fb == FALSE) {
955        info->accel_state->exa = exaDriverAlloc();
956        if (info->accel_state->exa == NULL)
957	    return FALSE;
958    }
959
960    screen_size = RADEON_ALIGN(pScrn->virtualY, 16) * stride;
961    {
962	int cursor_size = 64 * 4 * 64;
963	int c;
964
965	cursor_size = RADEON_ALIGN(cursor_size, RADEON_GPU_PAGE_SIZE);
966	for (c = 0; c < xf86_config->num_crtc; c++) {
967	    /* cursor objects */
968            if (info->cursor_bo[c] == NULL) {
969                info->cursor_bo[c] = radeon_bo_open(info->bufmgr, 0,
970                                                    cursor_size, 0,
971                                                    RADEON_GEM_DOMAIN_VRAM, 0);
972                if (!info->cursor_bo[c]) {
973                    return FALSE;
974                }
975
976#if X_BYTE_ORDER == X_BIG_ENDIAN
977		radeon_bo_set_tiling(info->cursor_bo[c], RADEON_TILING_SWAP_32BIT |
978				     RADEON_TILING_SURFACE, stride);
979#endif
980
981                if (radeon_bo_map(info->cursor_bo[c], 1)) {
982                    ErrorF("Failed to map cursor buffer memory\n");
983                }
984
985                drmmode_set_cursor(pScrn, &info->drmmode, c, info->cursor_bo[c]);
986                total_size_bytes += cursor_size;
987            }
988        }
989    }
990
991    screen_size = RADEON_ALIGN(screen_size, RADEON_GPU_PAGE_SIZE);
992    /* keep area front front buffer - but don't allocate it yet */
993    total_size_bytes += screen_size;
994
995    /* work out from the mm size what the exa / tex sizes need to be */
996    remain_size_bytes = info->vram_size - total_size_bytes;
997
998    info->dri->textureSize = 0;
999
1000    if (info->front_bo == NULL) {
1001	uint32_t tiling_flags = 0;
1002
1003        info->front_bo = radeon_bo_open(info->bufmgr, 0, screen_size,
1004                                        0, RADEON_GEM_DOMAIN_VRAM, 0);
1005        if (info->r600_shadow_fb == TRUE) {
1006            if (radeon_bo_map(info->front_bo, 1)) {
1007                ErrorF("Failed to map cursor buffer memory\n");
1008            }
1009        }
1010        if (info->allowColorTiling) {
1011	    tiling_flags |= RADEON_TILING_MACRO;
1012        }
1013#if X_BYTE_ORDER == X_BIG_ENDIAN
1014	switch (cpp) {
1015	case 4:
1016	    tiling_flags |= RADEON_TILING_SWAP_32BIT;
1017	    break;
1018	case 2:
1019	    tiling_flags |= RADEON_TILING_SWAP_16BIT;
1020	    break;
1021	}
1022#endif
1023	if (tiling_flags) {
1024            radeon_bo_set_tiling(info->front_bo,
1025				 tiling_flags | RADEON_TILING_SURFACE, stride);
1026	}
1027    }
1028
1029    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Front buffer size: %dK\n", info->front_bo->size/1024);
1030    radeon_kms_update_vram_limit(pScrn, screen_size);
1031    return TRUE;
1032}
1033
1034void radeon_kms_update_vram_limit(ScrnInfoPtr pScrn, int new_fb_size)
1035{
1036    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
1037    RADEONInfoPtr info = RADEONPTR(pScrn);
1038    int remain_size_bytes;
1039    int total_size_bytes;
1040    int c;
1041
1042    for (c = 0; c < xf86_config->num_crtc; c++) {
1043	if (info->cursor_bo[c] != NULL) {
1044	    total_size_bytes += (64 * 4 * 64);
1045	}
1046    }
1047
1048    total_size_bytes += new_fb_size;
1049    remain_size_bytes = info->vram_size - new_fb_size;
1050    remain_size_bytes = (remain_size_bytes / 10) * 9;
1051    radeon_cs_set_limit(info->cs, RADEON_GEM_DOMAIN_VRAM, remain_size_bytes);
1052
1053    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VRAM usage limit set to %dK\n", remain_size_bytes / 1024);
1054}
1055
1056
1057#endif
1058