radeon_kms.c revision 935f1ae0
1de2362d3Smrg/*
2de2362d3Smrg * Copyright © 2009 Red Hat, Inc.
3de2362d3Smrg *
4de2362d3Smrg * Permission is hereby granted, free of charge, to any person obtaining a
5de2362d3Smrg * copy of this software and associated documentation files (the "Software"),
6de2362d3Smrg * to deal in the Software without restriction, including without limitation
7de2362d3Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8de2362d3Smrg * and/or sell copies of the Software, and to permit persons to whom the
9de2362d3Smrg * Software is furnished to do so, subject to the following conditions:
10de2362d3Smrg *
11de2362d3Smrg * The above copyright notice and this permission notice (including the next
12de2362d3Smrg * paragraph) shall be included in all copies or substantial portions of the
13de2362d3Smrg * Software.
14de2362d3Smrg *
15de2362d3Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16de2362d3Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17de2362d3Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18de2362d3Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19de2362d3Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20de2362d3Smrg * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21de2362d3Smrg * SOFTWARE.
22de2362d3Smrg *
23de2362d3Smrg * Authors:
24de2362d3Smrg *    Dave Airlie <airlied@redhat.com>
25de2362d3Smrg *
26de2362d3Smrg */
27de2362d3Smrg#ifdef HAVE_CONFIG_H
28de2362d3Smrg#include "config.h"
29de2362d3Smrg#endif
30de2362d3Smrg
31de2362d3Smrg#include <errno.h>
32de2362d3Smrg#include <sys/ioctl.h>
33de2362d3Smrg/* Driver data structures */
34de2362d3Smrg#include "radeon.h"
35935f1ae0Smrg#include "radeon_drm_queue.h"
36935f1ae0Smrg#include "radeon_glamor.h"
37de2362d3Smrg#include "radeon_reg.h"
38de2362d3Smrg#include "radeon_probe.h"
39de2362d3Smrg#include "micmap.h"
40de2362d3Smrg
41de2362d3Smrg#include "radeon_version.h"
42de2362d3Smrg#include "shadow.h"
43de2362d3Smrg
44de2362d3Smrg#include "atipciids.h"
45de2362d3Smrg
46de2362d3Smrg/* DPMS */
47de2362d3Smrg#ifdef HAVE_XEXTPROTO_71
48de2362d3Smrg#include <X11/extensions/dpmsconst.h>
49de2362d3Smrg#else
50de2362d3Smrg#define DPMS_SERVER
51de2362d3Smrg#include <X11/extensions/dpms.h>
52de2362d3Smrg#endif
53de2362d3Smrg
54de2362d3Smrg#include "radeon_chipinfo_gen.h"
55de2362d3Smrg
56de2362d3Smrg#include "radeon_bo_gem.h"
57de2362d3Smrg#include "radeon_cs_gem.h"
58de2362d3Smrg#include "radeon_vbo.h"
59de2362d3Smrg
60de2362d3Smrgextern SymTabRec RADEONChipsets[];
61de2362d3Smrgstatic Bool radeon_setup_kernel_mem(ScreenPtr pScreen);
62de2362d3Smrg
63de2362d3Smrgconst OptionInfoRec RADEONOptions_KMS[] = {
64de2362d3Smrg    { OPTION_ACCEL,          "Accel",            OPTV_BOOLEAN, {0}, FALSE },
65de2362d3Smrg    { OPTION_SW_CURSOR,      "SWcursor",         OPTV_BOOLEAN, {0}, FALSE },
66de2362d3Smrg    { OPTION_PAGE_FLIP,      "EnablePageFlip",   OPTV_BOOLEAN, {0}, FALSE },
67de2362d3Smrg    { OPTION_COLOR_TILING,   "ColorTiling",      OPTV_BOOLEAN, {0}, FALSE },
68de2362d3Smrg    { OPTION_COLOR_TILING_2D,"ColorTiling2D",    OPTV_BOOLEAN, {0}, FALSE },
69de2362d3Smrg    { OPTION_RENDER_ACCEL,   "RenderAccel",      OPTV_BOOLEAN, {0}, FALSE },
70de2362d3Smrg    { OPTION_SUBPIXEL_ORDER, "SubPixelOrder",    OPTV_ANYSTR,  {0}, FALSE },
71de2362d3Smrg#ifdef USE_GLAMOR
72de2362d3Smrg    { OPTION_ACCELMETHOD,    "AccelMethod",      OPTV_STRING,  {0}, FALSE },
73935f1ae0Smrg    { OPTION_SHADOW_PRIMARY, "ShadowPrimary",    OPTV_BOOLEAN, {0}, FALSE },
74de2362d3Smrg#endif
75de2362d3Smrg    { OPTION_EXA_VSYNC,      "EXAVSync",         OPTV_BOOLEAN, {0}, FALSE },
76de2362d3Smrg    { OPTION_EXA_PIXMAPS,    "EXAPixmaps",	 OPTV_BOOLEAN,   {0}, FALSE },
77de2362d3Smrg    { OPTION_ZAPHOD_HEADS,   "ZaphodHeads",      OPTV_STRING,  {0}, FALSE },
78de2362d3Smrg    { OPTION_SWAPBUFFERS_WAIT,"SwapbuffersWait", OPTV_BOOLEAN, {0}, FALSE },
79935f1ae0Smrg    { OPTION_DELETE_DP12,    "DeleteUnusedDP12Displays", OPTV_BOOLEAN, {0}, FALSE},
80935f1ae0Smrg    { OPTION_DRI3,           "DRI3",             OPTV_BOOLEAN, {0}, FALSE },
81935f1ae0Smrg    { OPTION_DRI,            "DRI",              OPTV_INTEGER, {0}, FALSE },
82935f1ae0Smrg    { OPTION_TEAR_FREE,      "TearFree",         OPTV_BOOLEAN, {0}, FALSE },
83de2362d3Smrg    { -1,                    NULL,               OPTV_NONE,    {0}, FALSE }
84de2362d3Smrg};
85de2362d3Smrg
86de2362d3Smrgconst OptionInfoRec *RADEONOptionsWeak(void) { return RADEONOptions_KMS; }
87de2362d3Smrg
88de2362d3Smrgvoid radeon_cs_flush_indirect(ScrnInfoPtr pScrn)
89de2362d3Smrg{
90de2362d3Smrg    RADEONInfoPtr  info = RADEONPTR(pScrn);
91935f1ae0Smrg    struct radeon_accel_state *accel_state;
92de2362d3Smrg    int ret;
93de2362d3Smrg
94935f1ae0Smrg#ifdef USE_GLAMOR
95935f1ae0Smrg    if (info->use_glamor) {
96935f1ae0Smrg	glamor_block_handler(pScrn->pScreen);
97935f1ae0Smrg	info->gpu_flushed++;
98935f1ae0Smrg	return;
99935f1ae0Smrg    }
100935f1ae0Smrg#endif
101935f1ae0Smrg
102de2362d3Smrg    if (!info->cs->cdw)
103de2362d3Smrg	return;
104de2362d3Smrg
105935f1ae0Smrg    accel_state = info->accel_state;
106935f1ae0Smrg
107de2362d3Smrg    /* release the current VBO so we don't block on mapping it later */
108de2362d3Smrg    if (info->accel_state->vbo.vb_offset && info->accel_state->vbo.vb_bo) {
109de2362d3Smrg        radeon_vbo_put(pScrn, &info->accel_state->vbo);
110de2362d3Smrg        info->accel_state->vbo.vb_start_op = -1;
111de2362d3Smrg    }
112de2362d3Smrg
113de2362d3Smrg    /* release the current VBO so we don't block on mapping it later */
114de2362d3Smrg    if (info->accel_state->cbuf.vb_bo) {
115de2362d3Smrg        radeon_vbo_put(pScrn, &info->accel_state->cbuf);
116de2362d3Smrg        info->accel_state->cbuf.vb_start_op = -1;
117de2362d3Smrg    }
118de2362d3Smrg
119de2362d3Smrg    radeon_cs_emit(info->cs);
120de2362d3Smrg    radeon_cs_erase(info->cs);
121de2362d3Smrg
122de2362d3Smrg    if (accel_state->use_vbos)
123de2362d3Smrg        radeon_vbo_flush_bos(pScrn);
124de2362d3Smrg
125de2362d3Smrg    ret = radeon_cs_space_check_with_bo(info->cs,
126de2362d3Smrg					accel_state->vbo.vb_bo,
127de2362d3Smrg					RADEON_GEM_DOMAIN_GTT, 0);
128de2362d3Smrg    if (ret)
129de2362d3Smrg      ErrorF("space check failed in flush\n");
130de2362d3Smrg
131de2362d3Smrg    if (info->reemit_current2d && info->state_2d.op)
132de2362d3Smrg        info->reemit_current2d(pScrn, info->state_2d.op);
133de2362d3Smrg
134de2362d3Smrg    if (info->dri2.enabled) {
135de2362d3Smrg        info->accel_state->XInited3D = FALSE;
136de2362d3Smrg        info->accel_state->engineMode = EXA_ENGINEMODE_UNKNOWN;
137de2362d3Smrg    }
138de2362d3Smrg
139de2362d3Smrg}
140de2362d3Smrg
141de2362d3Smrgvoid radeon_ddx_cs_start(ScrnInfoPtr pScrn,
142de2362d3Smrg			 int n, const char *file,
143de2362d3Smrg			 const char *func, int line)
144de2362d3Smrg{
145de2362d3Smrg    RADEONInfoPtr  info = RADEONPTR(pScrn);
146de2362d3Smrg
147de2362d3Smrg    if (info->cs->cdw + n > info->cs->ndw) {
148de2362d3Smrg	radeon_cs_flush_indirect(pScrn);
149de2362d3Smrg
150de2362d3Smrg    }
151de2362d3Smrg    radeon_cs_begin(info->cs, n, file, func, line);
152de2362d3Smrg}
153de2362d3Smrg
154de2362d3Smrg
155de2362d3Smrgextern _X_EXPORT int gRADEONEntityIndex;
156de2362d3Smrg
157de2362d3Smrgstatic int getRADEONEntityIndex(void)
158de2362d3Smrg{
159de2362d3Smrg    return gRADEONEntityIndex;
160de2362d3Smrg}
161de2362d3Smrg
162de2362d3Smrg
163de2362d3SmrgRADEONEntPtr RADEONEntPriv(ScrnInfoPtr pScrn)
164de2362d3Smrg{
165de2362d3Smrg    DevUnion     *pPriv;
166de2362d3Smrg    RADEONInfoPtr  info   = RADEONPTR(pScrn);
167de2362d3Smrg    pPriv = xf86GetEntityPrivate(info->pEnt->index,
168de2362d3Smrg                                 getRADEONEntityIndex());
169de2362d3Smrg    return pPriv->ptr;
170de2362d3Smrg}
171de2362d3Smrg
172de2362d3Smrg/* Allocate our private RADEONInfoRec */
173de2362d3Smrgstatic Bool RADEONGetRec(ScrnInfoPtr pScrn)
174de2362d3Smrg{
175de2362d3Smrg    if (pScrn->driverPrivate) return TRUE;
176de2362d3Smrg
177de2362d3Smrg    pScrn->driverPrivate = xnfcalloc(sizeof(RADEONInfoRec), 1);
178de2362d3Smrg    return TRUE;
179de2362d3Smrg}
180de2362d3Smrg
181de2362d3Smrg/* Free our private RADEONInfoRec */
182de2362d3Smrgstatic void RADEONFreeRec(ScrnInfoPtr pScrn)
183de2362d3Smrg{
184de2362d3Smrg    RADEONInfoPtr  info;
185de2362d3Smrg
186de2362d3Smrg    if (!pScrn || !pScrn->driverPrivate) return;
187de2362d3Smrg
188de2362d3Smrg    info = RADEONPTR(pScrn);
189de2362d3Smrg
190935f1ae0Smrg    if (info->fbcon_pixmap)
191935f1ae0Smrg	pScrn->pScreen->DestroyPixmap(info->fbcon_pixmap);
192935f1ae0Smrg
193de2362d3Smrg    if (info->dri2.drm_fd > 0) {
194de2362d3Smrg        DevUnion *pPriv;
195de2362d3Smrg        RADEONEntPtr pRADEONEnt;
196de2362d3Smrg        pPriv = xf86GetEntityPrivate(pScrn->entityList[0],
197de2362d3Smrg				     getRADEONEntityIndex());
198de2362d3Smrg
199de2362d3Smrg        pRADEONEnt = pPriv->ptr;
200de2362d3Smrg        pRADEONEnt->fd_ref--;
201de2362d3Smrg        if (!pRADEONEnt->fd_ref) {
202de2362d3Smrg#ifdef XF86_PDEV_SERVER_FD
203de2362d3Smrg            if (!(pRADEONEnt->platform_dev &&
204de2362d3Smrg                    pRADEONEnt->platform_dev->flags & XF86_PDEV_SERVER_FD))
205de2362d3Smrg#endif
206de2362d3Smrg                drmClose(pRADEONEnt->fd);
207de2362d3Smrg            pRADEONEnt->fd = 0;
208de2362d3Smrg        }
209de2362d3Smrg    }
210de2362d3Smrg
211de2362d3Smrg    if (info->accel_state) {
212de2362d3Smrg	free(info->accel_state);
213de2362d3Smrg	info->accel_state = NULL;
214de2362d3Smrg    }
215de2362d3Smrg
216de2362d3Smrg    free(pScrn->driverPrivate);
217de2362d3Smrg    pScrn->driverPrivate = NULL;
218de2362d3Smrg}
219de2362d3Smrg
220de2362d3Smrgstatic void *
221de2362d3SmrgradeonShadowWindow(ScreenPtr screen, CARD32 row, CARD32 offset, int mode,
222de2362d3Smrg		   CARD32 *size, void *closure)
223de2362d3Smrg{
224de2362d3Smrg    ScrnInfoPtr pScrn = xf86ScreenToScrn(screen);
225de2362d3Smrg    RADEONInfoPtr  info   = RADEONPTR(pScrn);
226de2362d3Smrg    int stride;
227de2362d3Smrg
228de2362d3Smrg    stride = (pScrn->displayWidth * pScrn->bitsPerPixel) / 8;
229de2362d3Smrg    *size = stride;
230de2362d3Smrg
231de2362d3Smrg    return ((uint8_t *)info->front_bo->ptr + row * stride + offset);
232de2362d3Smrg}
233de2362d3Smrg
234de2362d3Smrgstatic void
235de2362d3SmrgradeonUpdatePacked(ScreenPtr pScreen, shadowBufPtr pBuf)
236de2362d3Smrg{
237de2362d3Smrg    shadowUpdatePacked(pScreen, pBuf);
238de2362d3Smrg}
239de2362d3Smrg
240de2362d3Smrgstatic Bool RADEONCreateScreenResources_KMS(ScreenPtr pScreen)
241de2362d3Smrg{
242de2362d3Smrg    ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
243de2362d3Smrg    RADEONInfoPtr  info   = RADEONPTR(pScrn);
244935f1ae0Smrg    rrScrPrivPtr rrScrPriv = rrGetScrPriv(pScreen);
245de2362d3Smrg    PixmapPtr pixmap;
246de2362d3Smrg    struct radeon_surface *surface;
247de2362d3Smrg
248de2362d3Smrg    pScreen->CreateScreenResources = info->CreateScreenResources;
249de2362d3Smrg    if (!(*pScreen->CreateScreenResources)(pScreen))
250de2362d3Smrg	return FALSE;
251de2362d3Smrg    pScreen->CreateScreenResources = RADEONCreateScreenResources_KMS;
252de2362d3Smrg
253935f1ae0Smrg    /* Set the RandR primary output if Xorg hasn't */
254935f1ae0Smrg    if (
255935f1ae0Smrg#ifdef RADEON_PIXMAP_SHARING
256935f1ae0Smrg	!pScreen->isGPU &&
257935f1ae0Smrg#endif
258935f1ae0Smrg	!rrScrPriv->primaryOutput)
259935f1ae0Smrg    {
260935f1ae0Smrg	xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
261935f1ae0Smrg
262935f1ae0Smrg	rrScrPriv->primaryOutput = xf86_config->output[0]->randr_output;
263935f1ae0Smrg	RROutputChanged(rrScrPriv->primaryOutput, FALSE);
264935f1ae0Smrg	rrScrPriv->layoutChanged = TRUE;
265935f1ae0Smrg    }
266935f1ae0Smrg
267935f1ae0Smrg    if (!drmmode_set_desired_modes(pScrn, &info->drmmode, FALSE))
268de2362d3Smrg	return FALSE;
269de2362d3Smrg
270de2362d3Smrg    drmmode_uevent_init(pScrn, &info->drmmode);
271de2362d3Smrg
272de2362d3Smrg    if (info->r600_shadow_fb) {
273de2362d3Smrg	pixmap = pScreen->GetScreenPixmap(pScreen);
274de2362d3Smrg
275de2362d3Smrg	if (!shadowAdd(pScreen, pixmap, radeonUpdatePacked,
276de2362d3Smrg		       radeonShadowWindow, 0, NULL))
277de2362d3Smrg	    return FALSE;
278de2362d3Smrg    }
279de2362d3Smrg
280de2362d3Smrg    if (info->dri2.enabled || info->use_glamor) {
281de2362d3Smrg	if (info->front_bo) {
282de2362d3Smrg	    PixmapPtr pPix = pScreen->GetScreenPixmap(pScreen);
283de2362d3Smrg	    radeon_set_pixmap_bo(pPix, info->front_bo);
284de2362d3Smrg	    surface = radeon_get_pixmap_surface(pPix);
285de2362d3Smrg	    if (surface) {
286de2362d3Smrg		*surface = info->front_surface;
287de2362d3Smrg	    }
288de2362d3Smrg	}
289de2362d3Smrg    }
290de2362d3Smrg
291de2362d3Smrg    if (info->use_glamor)
292de2362d3Smrg	radeon_glamor_create_screen_resources(pScreen);
293de2362d3Smrg
294de2362d3Smrg    return TRUE;
295de2362d3Smrg}
296de2362d3Smrg
297de2362d3Smrg#ifdef RADEON_PIXMAP_SHARING
298de2362d3Smrgstatic void
299de2362d3Smrgredisplay_dirty(ScreenPtr screen, PixmapDirtyUpdatePtr dirty)
300de2362d3Smrg{
301de2362d3Smrg	ScrnInfoPtr pScrn = xf86ScreenToScrn(screen);
302de2362d3Smrg	RegionRec pixregion;
303de2362d3Smrg
304de2362d3Smrg	PixmapRegionInit(&pixregion, dirty->slave_dst);
305de2362d3Smrg	DamageRegionAppend(&dirty->slave_dst->drawable, &pixregion);
3065f74fd6dSmrg#ifdef HAS_DIRTYTRACKING_ROTATION
3075f74fd6dSmrg	PixmapSyncDirtyHelper(dirty);
3085f74fd6dSmrg#else
309de2362d3Smrg	PixmapSyncDirtyHelper(dirty, &pixregion);
3105f74fd6dSmrg#endif
311de2362d3Smrg
312de2362d3Smrg	radeon_cs_flush_indirect(pScrn);
313de2362d3Smrg	DamageRegionProcessPending(&dirty->slave_dst->drawable);
314de2362d3Smrg	RegionUninit(&pixregion);
315de2362d3Smrg}
316de2362d3Smrg
317de2362d3Smrgstatic void
318de2362d3Smrgradeon_dirty_update(ScreenPtr screen)
319de2362d3Smrg{
320de2362d3Smrg	RegionPtr region;
321de2362d3Smrg	PixmapDirtyUpdatePtr ent;
322de2362d3Smrg
323de2362d3Smrg	if (xorg_list_is_empty(&screen->pixmap_dirty_list))
324de2362d3Smrg		return;
325de2362d3Smrg
326de2362d3Smrg	xorg_list_for_each_entry(ent, &screen->pixmap_dirty_list, ent) {
327de2362d3Smrg		region = DamageRegion(ent->damage);
328de2362d3Smrg		if (RegionNotEmpty(region)) {
329de2362d3Smrg			redisplay_dirty(screen, ent);
330de2362d3Smrg			DamageEmpty(ent->damage);
331de2362d3Smrg		}
332de2362d3Smrg	}
333de2362d3Smrg}
334de2362d3Smrg#endif
335de2362d3Smrg
336935f1ae0Smrgstatic Bool
337935f1ae0Smrgradeon_scanout_extents_intersect(xf86CrtcPtr xf86_crtc, BoxPtr extents, int w,
338935f1ae0Smrg				 int h)
339935f1ae0Smrg{
340935f1ae0Smrg    extents->x1 = max(extents->x1 - xf86_crtc->x, 0);
341935f1ae0Smrg    extents->y1 = max(extents->y1 - xf86_crtc->y, 0);
342935f1ae0Smrg
343935f1ae0Smrg    switch (xf86_crtc->rotation & 0xf) {
344935f1ae0Smrg    case RR_Rotate_90:
345935f1ae0Smrg    case RR_Rotate_270:
346935f1ae0Smrg	extents->x2 = min(extents->x2 - xf86_crtc->x, h);
347935f1ae0Smrg	extents->y2 = min(extents->y2 - xf86_crtc->y, w);
348935f1ae0Smrg	break;
349935f1ae0Smrg    default:
350935f1ae0Smrg	extents->x2 = min(extents->x2 - xf86_crtc->x, w);
351935f1ae0Smrg	extents->y2 = min(extents->y2 - xf86_crtc->y, h);
352935f1ae0Smrg    }
353935f1ae0Smrg
354935f1ae0Smrg    return (extents->x1 < extents->x2 && extents->y1 < extents->y2);
355935f1ae0Smrg}
356935f1ae0Smrg
357935f1ae0Smrgstatic Bool
358935f1ae0Smrgradeon_scanout_do_update(xf86CrtcPtr xf86_crtc, int scanout_id)
359935f1ae0Smrg{
360935f1ae0Smrg    drmmode_crtc_private_ptr drmmode_crtc = xf86_crtc->driver_private;
361935f1ae0Smrg    ScrnInfoPtr scrn;
362935f1ae0Smrg    DamagePtr pDamage;
363935f1ae0Smrg    RegionPtr pRegion;
364935f1ae0Smrg    DrawablePtr pDraw;
365935f1ae0Smrg    ScreenPtr pScreen;
366935f1ae0Smrg    BoxRec extents;
367935f1ae0Smrg    RADEONInfoPtr info;
368935f1ae0Smrg    Bool force;
369935f1ae0Smrg
370935f1ae0Smrg    if (!xf86_crtc->enabled ||
371935f1ae0Smrg	drmmode_crtc->dpms_mode != DPMSModeOn ||
372935f1ae0Smrg	!drmmode_crtc->scanout[scanout_id].pixmap)
373935f1ae0Smrg	return FALSE;
374935f1ae0Smrg
375935f1ae0Smrg    pDamage = drmmode_crtc->scanout[scanout_id].damage;
376935f1ae0Smrg    if (!pDamage)
377935f1ae0Smrg	return FALSE;
378935f1ae0Smrg
379935f1ae0Smrg    pRegion = DamageRegion(pDamage);
380935f1ae0Smrg    if (!RegionNotEmpty(pRegion))
381935f1ae0Smrg	return FALSE;
382935f1ae0Smrg
383935f1ae0Smrg    pDraw = &drmmode_crtc->scanout[scanout_id].pixmap->drawable;
384935f1ae0Smrg    pScreen = pDraw->pScreen;
385935f1ae0Smrg    extents = *RegionExtents(pRegion);
386935f1ae0Smrg    RegionEmpty(pRegion);
387935f1ae0Smrg    if (!radeon_scanout_extents_intersect(xf86_crtc, &extents, pDraw->width,
388935f1ae0Smrg					  pDraw->height))
389935f1ae0Smrg	return FALSE;
390935f1ae0Smrg
391935f1ae0Smrg    scrn = xf86_crtc->scrn;
392935f1ae0Smrg    info = RADEONPTR(scrn);
393935f1ae0Smrg    force = info->accel_state->force;
394935f1ae0Smrg    info->accel_state->force = TRUE;
395935f1ae0Smrg
396935f1ae0Smrg#if XF86_CRTC_VERSION >= 4
397935f1ae0Smrg    if (xf86_crtc->driverIsPerformingTransform) {
398935f1ae0Smrg	SourceValidateProcPtr SourceValidate = pScreen->SourceValidate;
399935f1ae0Smrg	PictFormatPtr format = PictureWindowFormat(pScreen->root);
400935f1ae0Smrg	int error;
401935f1ae0Smrg	PicturePtr src, dst;
402935f1ae0Smrg	XID include_inferiors = IncludeInferiors;
403935f1ae0Smrg
404935f1ae0Smrg	src = CreatePicture(None,
405935f1ae0Smrg			    &pScreen->root->drawable,
406935f1ae0Smrg			    format,
407935f1ae0Smrg			    CPSubwindowMode,
408935f1ae0Smrg			    &include_inferiors, serverClient, &error);
409935f1ae0Smrg	if (!src) {
410935f1ae0Smrg	    ErrorF("Failed to create source picture for transformed scanout "
411935f1ae0Smrg		   "update\n");
412935f1ae0Smrg	    goto out;
413935f1ae0Smrg	}
414935f1ae0Smrg
415935f1ae0Smrg	dst = CreatePicture(None, pDraw, format, 0L, NULL, serverClient, &error);
416935f1ae0Smrg	if (!dst) {
417935f1ae0Smrg	    ErrorF("Failed to create destination picture for transformed scanout "
418935f1ae0Smrg		   "update\n");
419935f1ae0Smrg	    goto free_src;
420935f1ae0Smrg	}
421935f1ae0Smrg
422935f1ae0Smrg	error = SetPictureTransform(src, &xf86_crtc->crtc_to_framebuffer);
423935f1ae0Smrg	if (error) {
424935f1ae0Smrg	    ErrorF("SetPictureTransform failed for transformed scanout "
425935f1ae0Smrg		   "update\n");
426935f1ae0Smrg	    goto free_dst;
427935f1ae0Smrg	}
428935f1ae0Smrg
429935f1ae0Smrg	if (xf86_crtc->filter)
430935f1ae0Smrg	    SetPicturePictFilter(src, xf86_crtc->filter, xf86_crtc->params,
431935f1ae0Smrg				 xf86_crtc->nparams);
432935f1ae0Smrg
433935f1ae0Smrg	extents.x1 += xf86_crtc->x - (xf86_crtc->filter_width >> 1);
434935f1ae0Smrg	extents.x2 += xf86_crtc->x + (xf86_crtc->filter_width >> 1);
435935f1ae0Smrg	extents.y1 += xf86_crtc->y - (xf86_crtc->filter_height >> 1);
436935f1ae0Smrg	extents.y2 += xf86_crtc->y + (xf86_crtc->filter_height >> 1);
437935f1ae0Smrg	pixman_f_transform_bounds(&xf86_crtc->f_framebuffer_to_crtc, &extents);
438935f1ae0Smrg
439935f1ae0Smrg	pScreen->SourceValidate = NULL;
440935f1ae0Smrg	CompositePicture(PictOpSrc,
441935f1ae0Smrg			 src, NULL, dst,
442935f1ae0Smrg			 extents.x1, extents.y1, 0, 0, extents.x1,
443935f1ae0Smrg			 extents.y1, extents.x2 - extents.x1,
444935f1ae0Smrg			 extents.y2 - extents.y1);
445935f1ae0Smrg	pScreen->SourceValidate = SourceValidate;
446935f1ae0Smrg
447935f1ae0Smrg free_dst:
448935f1ae0Smrg	FreePicture(dst, None);
449935f1ae0Smrg free_src:
450935f1ae0Smrg	FreePicture(src, None);
451935f1ae0Smrg    } else
452935f1ae0Smrg out:
453935f1ae0Smrg#endif /* XF86_CRTC_VERSION >= 4 */
454935f1ae0Smrg    {
455935f1ae0Smrg	GCPtr gc = GetScratchGC(pDraw->depth, pScreen);
456935f1ae0Smrg
457935f1ae0Smrg	ValidateGC(pDraw, gc);
458935f1ae0Smrg	(*gc->ops->CopyArea)(&pScreen->GetScreenPixmap(pScreen)->drawable,
459935f1ae0Smrg			     pDraw, gc,
460935f1ae0Smrg			     xf86_crtc->x + extents.x1, xf86_crtc->y + extents.y1,
461935f1ae0Smrg			     extents.x2 - extents.x1, extents.y2 - extents.y1,
462935f1ae0Smrg			     extents.x1, extents.y1);
463935f1ae0Smrg	FreeScratchGC(gc);
464935f1ae0Smrg    }
465935f1ae0Smrg
466935f1ae0Smrg    radeon_cs_flush_indirect(scrn);
467935f1ae0Smrg
468935f1ae0Smrg    info->accel_state->force = force;
469935f1ae0Smrg
470935f1ae0Smrg    return TRUE;
471935f1ae0Smrg}
472935f1ae0Smrg
473935f1ae0Smrgstatic void
474935f1ae0Smrgradeon_scanout_update_abort(xf86CrtcPtr crtc, void *event_data)
475935f1ae0Smrg{
476935f1ae0Smrg    drmmode_crtc_private_ptr drmmode_crtc = event_data;
477935f1ae0Smrg
478935f1ae0Smrg    drmmode_crtc->scanout_update_pending = FALSE;
479935f1ae0Smrg}
480935f1ae0Smrg
481935f1ae0Smrgvoid
482935f1ae0Smrgradeon_scanout_update_handler(xf86CrtcPtr crtc, uint32_t frame, uint64_t usec,
483935f1ae0Smrg			      void *event_data)
484935f1ae0Smrg{
485935f1ae0Smrg    radeon_scanout_do_update(crtc, 0);
486935f1ae0Smrg
487935f1ae0Smrg    radeon_scanout_update_abort(crtc, event_data);
488935f1ae0Smrg}
489935f1ae0Smrg
490935f1ae0Smrgstatic void
491935f1ae0Smrgradeon_scanout_update(xf86CrtcPtr xf86_crtc)
492935f1ae0Smrg{
493935f1ae0Smrg    drmmode_crtc_private_ptr drmmode_crtc = xf86_crtc->driver_private;
494935f1ae0Smrg    uintptr_t drm_queue_seq;
495935f1ae0Smrg    ScrnInfoPtr scrn;
496935f1ae0Smrg    drmVBlank vbl;
497935f1ae0Smrg    DamagePtr pDamage;
498935f1ae0Smrg    RegionPtr pRegion;
499935f1ae0Smrg    DrawablePtr pDraw;
500935f1ae0Smrg    BoxRec extents;
501935f1ae0Smrg
502935f1ae0Smrg    if (!xf86_crtc->enabled ||
503935f1ae0Smrg	drmmode_crtc->scanout_update_pending ||
504935f1ae0Smrg	!drmmode_crtc->scanout[0].pixmap ||
505935f1ae0Smrg	drmmode_crtc->dpms_mode != DPMSModeOn)
506935f1ae0Smrg	return;
507935f1ae0Smrg
508935f1ae0Smrg    pDamage = drmmode_crtc->scanout[0].damage;
509935f1ae0Smrg    if (!pDamage)
510935f1ae0Smrg	return;
511935f1ae0Smrg
512935f1ae0Smrg    pRegion = DamageRegion(pDamage);
513935f1ae0Smrg    if (!RegionNotEmpty(pRegion))
514935f1ae0Smrg	return;
515935f1ae0Smrg
516935f1ae0Smrg    pDraw = &drmmode_crtc->scanout[0].pixmap->drawable;
517935f1ae0Smrg    extents = *RegionExtents(pRegion);
518935f1ae0Smrg    if (!radeon_scanout_extents_intersect(xf86_crtc, &extents, pDraw->width,
519935f1ae0Smrg					  pDraw->height))
520935f1ae0Smrg	return;
521935f1ae0Smrg
522935f1ae0Smrg    scrn = xf86_crtc->scrn;
523935f1ae0Smrg    drm_queue_seq = radeon_drm_queue_alloc(xf86_crtc,
524935f1ae0Smrg					   RADEON_DRM_QUEUE_CLIENT_DEFAULT,
525935f1ae0Smrg					   RADEON_DRM_QUEUE_ID_DEFAULT,
526935f1ae0Smrg					   drmmode_crtc,
527935f1ae0Smrg					   radeon_scanout_update_handler,
528935f1ae0Smrg					   radeon_scanout_update_abort);
529935f1ae0Smrg    if (!drm_queue_seq) {
530935f1ae0Smrg	xf86DrvMsg(scrn->scrnIndex, X_WARNING,
531935f1ae0Smrg		   "radeon_drm_queue_alloc failed for scanout update\n");
532935f1ae0Smrg	return;
533935f1ae0Smrg    }
534935f1ae0Smrg
535935f1ae0Smrg    vbl.request.type = DRM_VBLANK_RELATIVE | DRM_VBLANK_EVENT;
536935f1ae0Smrg    vbl.request.type |= radeon_populate_vbl_request_type(xf86_crtc);
537935f1ae0Smrg    vbl.request.sequence = 1;
538935f1ae0Smrg    vbl.request.signal = drm_queue_seq;
539935f1ae0Smrg    if (drmWaitVBlank(RADEONPTR(scrn)->dri2.drm_fd, &vbl)) {
540935f1ae0Smrg	xf86DrvMsg(scrn->scrnIndex, X_WARNING,
541935f1ae0Smrg		   "drmWaitVBlank failed for scanout update: %s\n",
542935f1ae0Smrg		   strerror(errno));
543935f1ae0Smrg	radeon_drm_abort_entry(drm_queue_seq);
544935f1ae0Smrg	return;
545935f1ae0Smrg    }
546935f1ae0Smrg
547935f1ae0Smrg    drmmode_crtc->scanout_update_pending = TRUE;
548935f1ae0Smrg}
549935f1ae0Smrg
550935f1ae0Smrgstatic void
551935f1ae0Smrgradeon_scanout_flip_abort(xf86CrtcPtr crtc, void *event_data)
552935f1ae0Smrg{
553935f1ae0Smrg    drmmode_crtc_private_ptr drmmode_crtc = event_data;
554935f1ae0Smrg
555935f1ae0Smrg    drmmode_crtc->scanout_update_pending = FALSE;
556935f1ae0Smrg    drmmode_crtc->flip_pending = FALSE;
557935f1ae0Smrg}
558935f1ae0Smrg
559935f1ae0Smrgstatic void
560935f1ae0Smrgradeon_scanout_flip(ScreenPtr pScreen, RADEONInfoPtr info,
561935f1ae0Smrg		    xf86CrtcPtr xf86_crtc)
562935f1ae0Smrg{
563935f1ae0Smrg    drmmode_crtc_private_ptr drmmode_crtc = xf86_crtc->driver_private;
564935f1ae0Smrg    ScrnInfoPtr scrn;
565935f1ae0Smrg    uintptr_t drm_queue_seq;
566935f1ae0Smrg    unsigned scanout_id;
567935f1ae0Smrg
568935f1ae0Smrg    if (drmmode_crtc->scanout_update_pending)
569935f1ae0Smrg	return;
570935f1ae0Smrg
571935f1ae0Smrg    scanout_id = drmmode_crtc->scanout_id ^ 1;
572935f1ae0Smrg    if (!radeon_scanout_do_update(xf86_crtc, scanout_id))
573935f1ae0Smrg	return;
574935f1ae0Smrg
575935f1ae0Smrg    scrn = xf86_crtc->scrn;
576935f1ae0Smrg    drm_queue_seq = radeon_drm_queue_alloc(xf86_crtc,
577935f1ae0Smrg					   RADEON_DRM_QUEUE_CLIENT_DEFAULT,
578935f1ae0Smrg					   RADEON_DRM_QUEUE_ID_DEFAULT,
579935f1ae0Smrg					   drmmode_crtc, NULL,
580935f1ae0Smrg					   radeon_scanout_flip_abort);
581935f1ae0Smrg    if (!drm_queue_seq) {
582935f1ae0Smrg	xf86DrvMsg(scrn->scrnIndex, X_WARNING,
583935f1ae0Smrg		   "Allocating DRM event queue entry failed.\n");
584935f1ae0Smrg	return;
585935f1ae0Smrg    }
586935f1ae0Smrg
587935f1ae0Smrg    if (drmModePageFlip(drmmode_crtc->drmmode->fd, drmmode_crtc->mode_crtc->crtc_id,
588935f1ae0Smrg			drmmode_crtc->scanout[scanout_id].fb_id,
589935f1ae0Smrg			DRM_MODE_PAGE_FLIP_EVENT, (void*)drm_queue_seq)) {
590935f1ae0Smrg	xf86DrvMsg(scrn->scrnIndex, X_WARNING, "flip queue failed in %s: %s\n",
591935f1ae0Smrg		   __func__, strerror(errno));
592935f1ae0Smrg	return;
593935f1ae0Smrg    }
594935f1ae0Smrg
595935f1ae0Smrg    drmmode_crtc->scanout_id = scanout_id;
596935f1ae0Smrg    drmmode_crtc->scanout_update_pending = TRUE;
597935f1ae0Smrg    drmmode_crtc->flip_pending = TRUE;
598935f1ae0Smrg}
599935f1ae0Smrg
600de2362d3Smrgstatic void RADEONBlockHandler_KMS(BLOCKHANDLER_ARGS_DECL)
601de2362d3Smrg{
602de2362d3Smrg    SCREEN_PTR(arg);
603de2362d3Smrg    ScrnInfoPtr    pScrn   = xf86ScreenToScrn(pScreen);
604de2362d3Smrg    RADEONInfoPtr  info    = RADEONPTR(pScrn);
605935f1ae0Smrg    xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
606935f1ae0Smrg    int c;
607de2362d3Smrg
608de2362d3Smrg    pScreen->BlockHandler = info->BlockHandler;
609de2362d3Smrg    (*pScreen->BlockHandler) (BLOCKHANDLER_ARGS);
610de2362d3Smrg    pScreen->BlockHandler = RADEONBlockHandler_KMS;
611de2362d3Smrg
612935f1ae0Smrg    for (c = 0; c < xf86_config->num_crtc; c++) {
613935f1ae0Smrg	if (info->tear_free)
614935f1ae0Smrg	    radeon_scanout_flip(pScreen, info, xf86_config->crtc[c]);
615935f1ae0Smrg	else if (info->shadow_primary
616935f1ae0Smrg#if XF86_CRTC_VERSION >= 4
617935f1ae0Smrg		 || xf86_config->crtc[c]->driverIsPerformingTransform
618935f1ae0Smrg#endif
619935f1ae0Smrg	    )
620935f1ae0Smrg	    radeon_scanout_update(xf86_config->crtc[c]);
621935f1ae0Smrg    }
622de2362d3Smrg
623de2362d3Smrg    radeon_cs_flush_indirect(pScrn);
624935f1ae0Smrg
625de2362d3Smrg#ifdef RADEON_PIXMAP_SHARING
626de2362d3Smrg    radeon_dirty_update(pScreen);
627de2362d3Smrg#endif
628de2362d3Smrg}
629de2362d3Smrg
630935f1ae0Smrgstatic void RADEONBlockHandler_oneshot(BLOCKHANDLER_ARGS_DECL)
631935f1ae0Smrg{
632935f1ae0Smrg    SCREEN_PTR(arg);
633935f1ae0Smrg    ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
634935f1ae0Smrg    RADEONInfoPtr info = RADEONPTR(pScrn);
635935f1ae0Smrg
636935f1ae0Smrg    RADEONBlockHandler_KMS(BLOCKHANDLER_ARGS);
637935f1ae0Smrg
638935f1ae0Smrg    drmmode_set_desired_modes(pScrn, &info->drmmode, TRUE);
639935f1ae0Smrg}
640935f1ae0Smrg
641de2362d3Smrgstatic void
642de2362d3Smrgradeon_flush_callback(CallbackListPtr *list,
643de2362d3Smrg		      pointer user_data, pointer call_data)
644de2362d3Smrg{
645de2362d3Smrg    ScrnInfoPtr pScrn = user_data;
646de2362d3Smrg
647935f1ae0Smrg    if (pScrn->vtSema)
648de2362d3Smrg        radeon_cs_flush_indirect(pScrn);
649de2362d3Smrg}
650de2362d3Smrg
651de2362d3Smrgstatic Bool RADEONIsFastFBWorking(ScrnInfoPtr pScrn)
652de2362d3Smrg{
653de2362d3Smrg    RADEONInfoPtr info = RADEONPTR(pScrn);
654de2362d3Smrg    struct drm_radeon_info ginfo;
655de2362d3Smrg    int r;
656de2362d3Smrg    uint32_t tmp = 0;
657de2362d3Smrg
658de2362d3Smrg    memset(&ginfo, 0, sizeof(ginfo));
659de2362d3Smrg    ginfo.request = RADEON_INFO_FASTFB_WORKING;
660de2362d3Smrg    ginfo.value = (uintptr_t)&tmp;
661de2362d3Smrg    r = drmCommandWriteRead(info->dri2.drm_fd, DRM_RADEON_INFO, &ginfo, sizeof(ginfo));
662de2362d3Smrg    if (r) {
663de2362d3Smrg	return FALSE;
664de2362d3Smrg    }
665de2362d3Smrg    if (tmp == 1)
666de2362d3Smrg	return TRUE;
667de2362d3Smrg    return FALSE;
668de2362d3Smrg}
669de2362d3Smrg
670de2362d3Smrgstatic Bool RADEONIsFusionGARTWorking(ScrnInfoPtr pScrn)
671de2362d3Smrg{
672de2362d3Smrg    RADEONInfoPtr info = RADEONPTR(pScrn);
673de2362d3Smrg    struct drm_radeon_info ginfo;
674de2362d3Smrg    int r;
675de2362d3Smrg    uint32_t tmp;
676de2362d3Smrg
677de2362d3Smrg    memset(&ginfo, 0, sizeof(ginfo));
678de2362d3Smrg    ginfo.request = RADEON_INFO_FUSION_GART_WORKING;
679de2362d3Smrg    ginfo.value = (uintptr_t)&tmp;
680de2362d3Smrg    r = drmCommandWriteRead(info->dri2.drm_fd, DRM_RADEON_INFO, &ginfo, sizeof(ginfo));
681de2362d3Smrg    if (r) {
682de2362d3Smrg	return FALSE;
683de2362d3Smrg    }
684de2362d3Smrg    if (tmp == 1)
685de2362d3Smrg	return TRUE;
686de2362d3Smrg    return FALSE;
687de2362d3Smrg}
688de2362d3Smrg
689de2362d3Smrgstatic Bool RADEONIsAccelWorking(ScrnInfoPtr pScrn)
690de2362d3Smrg{
691de2362d3Smrg    RADEONInfoPtr info = RADEONPTR(pScrn);
692de2362d3Smrg    struct drm_radeon_info ginfo;
693de2362d3Smrg    int r;
694de2362d3Smrg    uint32_t tmp;
695de2362d3Smrg
696de2362d3Smrg    memset(&ginfo, 0, sizeof(ginfo));
697de2362d3Smrg    if (info->dri2.pKernelDRMVersion->version_minor >= 5)
698de2362d3Smrg	ginfo.request = RADEON_INFO_ACCEL_WORKING2;
699de2362d3Smrg    else
700de2362d3Smrg	ginfo.request = RADEON_INFO_ACCEL_WORKING;
701de2362d3Smrg    ginfo.value = (uintptr_t)&tmp;
702de2362d3Smrg    r = drmCommandWriteRead(info->dri2.drm_fd, DRM_RADEON_INFO, &ginfo, sizeof(ginfo));
703de2362d3Smrg    if (r) {
704de2362d3Smrg        /* If kernel is too old before 2.6.32 than assume accel is working */
705de2362d3Smrg        if (r == -EINVAL) {
706de2362d3Smrg            xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Kernel too old missing accel "
707de2362d3Smrg                       "information, assuming accel is working\n");
708de2362d3Smrg            return TRUE;
709de2362d3Smrg        }
710de2362d3Smrg        return FALSE;
711de2362d3Smrg    }
712de2362d3Smrg    if (info->ChipFamily == CHIP_FAMILY_HAWAII) {
713de2362d3Smrg        if (tmp == 2 || tmp == 3)
714de2362d3Smrg            return TRUE;
715de2362d3Smrg    } else if (tmp) {
716de2362d3Smrg        return TRUE;
717de2362d3Smrg    }
718de2362d3Smrg    return FALSE;
719de2362d3Smrg}
720de2362d3Smrg
721de2362d3Smrg/* This is called by RADEONPreInit to set up the default visual */
722de2362d3Smrgstatic Bool RADEONPreInitVisual(ScrnInfoPtr pScrn)
723de2362d3Smrg{
724de2362d3Smrg    RADEONInfoPtr  info = RADEONPTR(pScrn);
725de2362d3Smrg
726de2362d3Smrg    if (!xf86SetDepthBpp(pScrn, 0, 0, 0, Support32bppFb))
727de2362d3Smrg	return FALSE;
728de2362d3Smrg
729de2362d3Smrg    switch (pScrn->depth) {
730de2362d3Smrg    case 8:
731de2362d3Smrg    case 15:
732de2362d3Smrg    case 16:
733de2362d3Smrg    case 24:
734de2362d3Smrg	break;
735de2362d3Smrg
736de2362d3Smrg    default:
737de2362d3Smrg	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
738de2362d3Smrg		   "Given depth (%d) is not supported by %s driver\n",
739de2362d3Smrg		   pScrn->depth, RADEON_DRIVER_NAME);
740de2362d3Smrg	return FALSE;
741de2362d3Smrg    }
742de2362d3Smrg
743de2362d3Smrg    xf86PrintDepthBpp(pScrn);
744de2362d3Smrg
745de2362d3Smrg    info->pix24bpp                   = xf86GetBppFromDepth(pScrn,
746de2362d3Smrg							   pScrn->depth);
747de2362d3Smrg    info->pixel_bytes  = pScrn->bitsPerPixel / 8;
748de2362d3Smrg
749de2362d3Smrg    if (info->pix24bpp == 24) {
750de2362d3Smrg	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
751de2362d3Smrg		   "Radeon does NOT support 24bpp\n");
752de2362d3Smrg	return FALSE;
753de2362d3Smrg    }
754de2362d3Smrg
755de2362d3Smrg    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
756de2362d3Smrg	       "Pixel depth = %d bits stored in %d byte%s (%d bpp pixmaps)\n",
757de2362d3Smrg	       pScrn->depth,
758de2362d3Smrg	       info->pixel_bytes,
759de2362d3Smrg	       info->pixel_bytes > 1 ? "s" : "",
760de2362d3Smrg	       info->pix24bpp);
761de2362d3Smrg
762de2362d3Smrg    if (!xf86SetDefaultVisual(pScrn, -1)) return FALSE;
763de2362d3Smrg
764de2362d3Smrg    if (pScrn->depth > 8 && pScrn->defaultVisual != TrueColor) {
765de2362d3Smrg	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
766de2362d3Smrg		   "Default visual (%s) is not supported at depth %d\n",
767de2362d3Smrg		   xf86GetVisualName(pScrn->defaultVisual), pScrn->depth);
768de2362d3Smrg	return FALSE;
769de2362d3Smrg    }
770de2362d3Smrg    return TRUE;
771de2362d3Smrg}
772de2362d3Smrg
773de2362d3Smrg/* This is called by RADEONPreInit to handle all color weight issues */
774de2362d3Smrgstatic Bool RADEONPreInitWeight(ScrnInfoPtr pScrn)
775de2362d3Smrg{
776de2362d3Smrg    RADEONInfoPtr  info = RADEONPTR(pScrn);
777de2362d3Smrg
778de2362d3Smrg				/* Save flag for 6 bit DAC to use for
779de2362d3Smrg				   setting CRTC registers.  Otherwise use
780de2362d3Smrg				   an 8 bit DAC, even if xf86SetWeight sets
781de2362d3Smrg				   pScrn->rgbBits to some value other than
782de2362d3Smrg				   8. */
783de2362d3Smrg    info->dac6bits = FALSE;
784de2362d3Smrg
785de2362d3Smrg    if (pScrn->depth > 8) {
786de2362d3Smrg	rgb  defaultWeight = { 0, 0, 0 };
787de2362d3Smrg
788de2362d3Smrg	if (!xf86SetWeight(pScrn, defaultWeight, defaultWeight)) return FALSE;
789de2362d3Smrg    } else {
790de2362d3Smrg	pScrn->rgbBits = 8;
791de2362d3Smrg    }
792de2362d3Smrg
793de2362d3Smrg    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
794de2362d3Smrg	       "Using %d bits per RGB (%d bit DAC)\n",
795de2362d3Smrg	       pScrn->rgbBits, info->dac6bits ? 6 : 8);
796de2362d3Smrg
797de2362d3Smrg    return TRUE;
798de2362d3Smrg}
799de2362d3Smrg
800de2362d3Smrgstatic Bool RADEONPreInitAccel_KMS(ScrnInfoPtr pScrn)
801de2362d3Smrg{
802de2362d3Smrg    RADEONInfoPtr  info = RADEONPTR(pScrn);
803de2362d3Smrg
804de2362d3Smrg    if (!(info->accel_state = calloc(1, sizeof(struct radeon_accel_state)))) {
805de2362d3Smrg	xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Unable to allocate accel_state rec!\n");
806de2362d3Smrg	return FALSE;
807de2362d3Smrg    }
808de2362d3Smrg
809de2362d3Smrg    /* Check whether direct mapping is used for fast fb access*/
810de2362d3Smrg    if (RADEONIsFastFBWorking(pScrn)) {
811de2362d3Smrg	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Direct mapping of fb aperture is enabled for fast fb access.\n");
812de2362d3Smrg	info->is_fast_fb = TRUE;
813de2362d3Smrg    }
814de2362d3Smrg
815de2362d3Smrg    if (!xf86ReturnOptValBool(info->Options, OPTION_ACCEL, TRUE) ||
816de2362d3Smrg	(!RADEONIsAccelWorking(pScrn))) {
817de2362d3Smrg	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
818de2362d3Smrg		   "GPU accel disabled or not working, using shadowfb for KMS\n");
819de2362d3Smrgshadowfb:
820de2362d3Smrg	info->r600_shadow_fb = TRUE;
821de2362d3Smrg	if (!xf86LoadSubModule(pScrn, "shadow"))
822de2362d3Smrg	    info->r600_shadow_fb = FALSE;
823de2362d3Smrg	return TRUE;
824de2362d3Smrg    }
825de2362d3Smrg
826de2362d3Smrg#ifdef DRI2
827de2362d3Smrg    info->dri2.available = !!xf86LoadSubModule(pScrn, "dri2");
828de2362d3Smrg#endif
829de2362d3Smrg
830de2362d3Smrg    if (radeon_glamor_pre_init(pScrn))
831de2362d3Smrg	return TRUE;
832de2362d3Smrg
833de2362d3Smrg    if (info->ChipFamily >= CHIP_FAMILY_TAHITI) {
834de2362d3Smrg	goto shadowfb;
835de2362d3Smrg    } else if (info->ChipFamily == CHIP_FAMILY_PALM) {
836de2362d3Smrg	info->accel_state->allowHWDFS = RADEONIsFusionGARTWorking(pScrn);
837de2362d3Smrg    } else
838de2362d3Smrg	info->accel_state->allowHWDFS = TRUE;
839de2362d3Smrg
840de2362d3Smrg    if ((info->ChipFamily == CHIP_FAMILY_RS100) ||
841de2362d3Smrg	(info->ChipFamily == CHIP_FAMILY_RS200) ||
842de2362d3Smrg	(info->ChipFamily == CHIP_FAMILY_RS300) ||
843de2362d3Smrg	(info->ChipFamily == CHIP_FAMILY_RS400) ||
844de2362d3Smrg	(info->ChipFamily == CHIP_FAMILY_RS480) ||
845de2362d3Smrg	(info->ChipFamily == CHIP_FAMILY_RS600) ||
846de2362d3Smrg	(info->ChipFamily == CHIP_FAMILY_RS690) ||
847de2362d3Smrg	(info->ChipFamily == CHIP_FAMILY_RS740))
848de2362d3Smrg	info->accel_state->has_tcl = FALSE;
849de2362d3Smrg    else {
850de2362d3Smrg	info->accel_state->has_tcl = TRUE;
851de2362d3Smrg    }
852de2362d3Smrg
853de2362d3Smrg    {
854de2362d3Smrg	int errmaj = 0, errmin = 0;
855de2362d3Smrg	info->exaReq.majorversion = EXA_VERSION_MAJOR;
856de2362d3Smrg	info->exaReq.minorversion = EXA_VERSION_MINOR;
857de2362d3Smrg	if (!LoadSubModule(pScrn->module, "exa", NULL, NULL, NULL,
858de2362d3Smrg			   &info->exaReq, &errmaj, &errmin)) {
859de2362d3Smrg	    LoaderErrorMsg(NULL, "exa", errmaj, errmin);
860de2362d3Smrg	    return FALSE;
861de2362d3Smrg	}
862de2362d3Smrg    }
863de2362d3Smrg
864de2362d3Smrg    return TRUE;
865de2362d3Smrg}
866de2362d3Smrg
867de2362d3Smrgstatic Bool RADEONPreInitChipType_KMS(ScrnInfoPtr pScrn)
868de2362d3Smrg{
869de2362d3Smrg    RADEONInfoPtr  info   = RADEONPTR(pScrn);
870de2362d3Smrg    int i;
871de2362d3Smrg
872de2362d3Smrg    info->Chipset = PCI_DEV_DEVICE_ID(info->PciInfo);
873de2362d3Smrg    pScrn->chipset = (char *)xf86TokenToString(RADEONChipsets, info->Chipset);
874de2362d3Smrg    if (!pScrn->chipset) {
875de2362d3Smrg	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
876de2362d3Smrg		   "ChipID 0x%04x is not recognized\n", info->Chipset);
877de2362d3Smrg	return FALSE;
878de2362d3Smrg    }
879de2362d3Smrg
880de2362d3Smrg    if (info->Chipset < 0) {
881de2362d3Smrg	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
882de2362d3Smrg		   "Chipset \"%s\" is not recognized\n", pScrn->chipset);
883de2362d3Smrg	return FALSE;
884de2362d3Smrg    }
885de2362d3Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
886de2362d3Smrg	       "Chipset: \"%s\" (ChipID = 0x%04x)\n",
887de2362d3Smrg	       pScrn->chipset,
888de2362d3Smrg	       info->Chipset);
889de2362d3Smrg
890de2362d3Smrg    for (i = 0; i < sizeof(RADEONCards) / sizeof(RADEONCardInfo); i++) {
891de2362d3Smrg	if (info->Chipset == RADEONCards[i].pci_device_id) {
892de2362d3Smrg	    RADEONCardInfo *card = &RADEONCards[i];
893de2362d3Smrg	    info->ChipFamily = card->chip_family;
894de2362d3Smrg	    break;
895de2362d3Smrg	}
896de2362d3Smrg    }
897de2362d3Smrg
898de2362d3Smrg#ifdef RENDER
899de2362d3Smrg    info->RenderAccel = xf86ReturnOptValBool(info->Options, OPTION_RENDER_ACCEL,
900de2362d3Smrg					     info->Chipset != PCI_CHIP_RN50_515E &&
901de2362d3Smrg					     info->Chipset != PCI_CHIP_RN50_5969);
902de2362d3Smrg#endif
903de2362d3Smrg    return TRUE;
904de2362d3Smrg}
905de2362d3Smrg
906de2362d3Smrgstatic int radeon_get_drm_master_fd(ScrnInfoPtr pScrn)
907de2362d3Smrg{
908de2362d3Smrg    RADEONInfoPtr  info   = RADEONPTR(pScrn);
909de2362d3Smrg#ifdef XF86_PDEV_SERVER_FD
910de2362d3Smrg    RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
911de2362d3Smrg#endif
912de2362d3Smrg    struct pci_device *dev = info->PciInfo;
913de2362d3Smrg    char *busid;
914de2362d3Smrg    int fd;
915de2362d3Smrg
916de2362d3Smrg#ifdef XF86_PDEV_SERVER_FD
917de2362d3Smrg    if (pRADEONEnt->platform_dev) {
918de2362d3Smrg        fd = xf86_get_platform_device_int_attrib(pRADEONEnt->platform_dev,
919de2362d3Smrg                                                 ODEV_ATTRIB_FD, -1);
920de2362d3Smrg        if (fd != -1)
921de2362d3Smrg            return fd;
922de2362d3Smrg    }
923de2362d3Smrg#endif
924de2362d3Smrg
925de2362d3Smrg#if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,9,99,901,0)
926de2362d3Smrg    XNFasprintf(&busid, "pci:%04x:%02x:%02x.%d",
927de2362d3Smrg                dev->domain, dev->bus, dev->dev, dev->func);
928de2362d3Smrg#else
929de2362d3Smrg    busid = XNFprintf("pci:%04x:%02x:%02x.%d",
930de2362d3Smrg		      dev->domain, dev->bus, dev->dev, dev->func);
931de2362d3Smrg#endif
932de2362d3Smrg
933de2362d3Smrg    fd = drmOpen(NULL, busid);
934de2362d3Smrg    if (fd == -1)
935de2362d3Smrg	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
936de2362d3Smrg		   "[drm] Failed to open DRM device for %s: %s\n",
937de2362d3Smrg		   busid, strerror(errno));
938de2362d3Smrg
939de2362d3Smrg    free(busid);
940de2362d3Smrg    return fd;
941de2362d3Smrg}
942de2362d3Smrg
943de2362d3Smrgstatic Bool radeon_open_drm_master(ScrnInfoPtr pScrn)
944de2362d3Smrg{
945de2362d3Smrg    RADEONInfoPtr  info   = RADEONPTR(pScrn);
946de2362d3Smrg    RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
947de2362d3Smrg    drmSetVersion sv;
948de2362d3Smrg    int err;
949de2362d3Smrg
950de2362d3Smrg    if (pRADEONEnt->fd) {
951de2362d3Smrg	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
952de2362d3Smrg		   " reusing fd for second head\n");
953de2362d3Smrg
954de2362d3Smrg	info->drmmode.fd = info->dri2.drm_fd = pRADEONEnt->fd;
955de2362d3Smrg	pRADEONEnt->fd_ref++;
956de2362d3Smrg        return TRUE;
957de2362d3Smrg    }
958de2362d3Smrg
959de2362d3Smrg    info->dri2.drm_fd = radeon_get_drm_master_fd(pScrn);
960de2362d3Smrg    if (info->dri2.drm_fd == -1)
961de2362d3Smrg	return FALSE;
962de2362d3Smrg
963de2362d3Smrg    /* Check that what we opened was a master or a master-capable FD,
964de2362d3Smrg     * by setting the version of the interface we'll use to talk to it.
965de2362d3Smrg     * (see DRIOpenDRMMaster() in DRI1)
966de2362d3Smrg     */
967de2362d3Smrg    sv.drm_di_major = 1;
968de2362d3Smrg    sv.drm_di_minor = 1;
969de2362d3Smrg    sv.drm_dd_major = -1;
970de2362d3Smrg    sv.drm_dd_minor = -1;
971de2362d3Smrg    err = drmSetInterfaceVersion(info->dri2.drm_fd, &sv);
972de2362d3Smrg    if (err != 0) {
973de2362d3Smrg	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
974de2362d3Smrg		   "[drm] failed to set drm interface version.\n");
975de2362d3Smrg	drmClose(info->dri2.drm_fd);
976de2362d3Smrg	info->dri2.drm_fd = -1;
977de2362d3Smrg
978de2362d3Smrg	return FALSE;
979de2362d3Smrg    }
980de2362d3Smrg
981de2362d3Smrg    pRADEONEnt->fd = info->dri2.drm_fd;
982de2362d3Smrg    pRADEONEnt->fd_ref = 1;
983de2362d3Smrg    info->drmmode.fd = info->dri2.drm_fd;
984de2362d3Smrg    return TRUE;
985de2362d3Smrg}
986de2362d3Smrg
987de2362d3Smrgstatic Bool r600_get_tile_config(ScrnInfoPtr pScrn)
988de2362d3Smrg{
989de2362d3Smrg    RADEONInfoPtr  info   = RADEONPTR(pScrn);
990de2362d3Smrg    struct drm_radeon_info ginfo;
991de2362d3Smrg    int r;
992de2362d3Smrg    uint32_t tmp;
993de2362d3Smrg
994de2362d3Smrg    if (info->ChipFamily < CHIP_FAMILY_R600)
995de2362d3Smrg	return FALSE;
996de2362d3Smrg
997de2362d3Smrg    memset(&ginfo, 0, sizeof(ginfo));
998de2362d3Smrg    ginfo.request = RADEON_INFO_TILING_CONFIG;
999de2362d3Smrg    ginfo.value = (uintptr_t)&tmp;
1000de2362d3Smrg    r = drmCommandWriteRead(info->dri2.drm_fd, DRM_RADEON_INFO, &ginfo, sizeof(ginfo));
1001de2362d3Smrg    if (r)
1002de2362d3Smrg	return FALSE;
1003de2362d3Smrg
1004de2362d3Smrg    info->tile_config = tmp;
1005de2362d3Smrg    info->r7xx_bank_op = 0;
1006de2362d3Smrg    if (info->ChipFamily >= CHIP_FAMILY_CEDAR) {
1007de2362d3Smrg	if (info->dri2.pKernelDRMVersion->version_minor >= 7) {
1008de2362d3Smrg	    switch (info->tile_config & 0xf) {
1009de2362d3Smrg	    case 0:
1010de2362d3Smrg                info->num_channels = 1;
1011de2362d3Smrg                break;
1012de2362d3Smrg	    case 1:
1013de2362d3Smrg                info->num_channels = 2;
1014de2362d3Smrg                break;
1015de2362d3Smrg	    case 2:
1016de2362d3Smrg                info->num_channels = 4;
1017de2362d3Smrg                break;
1018de2362d3Smrg	    case 3:
1019de2362d3Smrg                info->num_channels = 8;
1020de2362d3Smrg                break;
1021de2362d3Smrg	    default:
1022de2362d3Smrg                return FALSE;
1023de2362d3Smrg	    }
1024de2362d3Smrg
1025de2362d3Smrg	    switch((info->tile_config & 0xf0) >> 4) {
1026de2362d3Smrg	    case 0:
1027de2362d3Smrg		info->num_banks = 4;
1028de2362d3Smrg		break;
1029de2362d3Smrg	    case 1:
1030de2362d3Smrg		info->num_banks = 8;
1031de2362d3Smrg		break;
1032de2362d3Smrg	    case 2:
1033de2362d3Smrg		info->num_banks = 16;
1034de2362d3Smrg		break;
1035de2362d3Smrg	    default:
1036de2362d3Smrg		return FALSE;
1037de2362d3Smrg	    }
1038de2362d3Smrg
1039de2362d3Smrg	    switch ((info->tile_config & 0xf00) >> 8) {
1040de2362d3Smrg	    case 0:
1041de2362d3Smrg                info->group_bytes = 256;
1042de2362d3Smrg                break;
1043de2362d3Smrg	    case 1:
1044de2362d3Smrg                info->group_bytes = 512;
1045de2362d3Smrg                break;
1046de2362d3Smrg	    default:
1047de2362d3Smrg                return FALSE;
1048de2362d3Smrg	    }
1049de2362d3Smrg	} else
1050de2362d3Smrg	    return FALSE;
1051de2362d3Smrg    } else {
1052de2362d3Smrg	switch((info->tile_config & 0xe) >> 1) {
1053de2362d3Smrg	case 0:
1054de2362d3Smrg	    info->num_channels = 1;
1055de2362d3Smrg	    break;
1056de2362d3Smrg	case 1:
1057de2362d3Smrg	    info->num_channels = 2;
1058de2362d3Smrg	    break;
1059de2362d3Smrg	case 2:
1060de2362d3Smrg	    info->num_channels = 4;
1061de2362d3Smrg	    break;
1062de2362d3Smrg	case 3:
1063de2362d3Smrg	    info->num_channels = 8;
1064de2362d3Smrg	    break;
1065de2362d3Smrg	default:
1066de2362d3Smrg	    return FALSE;
1067de2362d3Smrg	}
1068de2362d3Smrg	switch((info->tile_config & 0x30) >> 4) {
1069de2362d3Smrg	case 0:
1070de2362d3Smrg	    info->num_banks = 4;
1071de2362d3Smrg	    break;
1072de2362d3Smrg	case 1:
1073de2362d3Smrg	    info->num_banks = 8;
1074de2362d3Smrg	    break;
1075de2362d3Smrg	default:
1076de2362d3Smrg	    return FALSE;
1077de2362d3Smrg	}
1078de2362d3Smrg	switch((info->tile_config & 0xc0) >> 6) {
1079de2362d3Smrg	case 0:
1080de2362d3Smrg	    info->group_bytes = 256;
1081de2362d3Smrg	    break;
1082de2362d3Smrg	case 1:
1083de2362d3Smrg	    info->group_bytes = 512;
1084de2362d3Smrg	    break;
1085de2362d3Smrg	default:
1086de2362d3Smrg	    return FALSE;
1087de2362d3Smrg	}
1088de2362d3Smrg    }
1089de2362d3Smrg
1090de2362d3Smrg    info->have_tiling_info = TRUE;
1091de2362d3Smrg    return TRUE;
1092de2362d3Smrg}
1093de2362d3Smrg
1094de2362d3Smrgstatic void RADEONSetupCapabilities(ScrnInfoPtr pScrn)
1095de2362d3Smrg{
1096de2362d3Smrg#ifdef RADEON_PIXMAP_SHARING
1097de2362d3Smrg    RADEONInfoPtr  info = RADEONPTR(pScrn);
1098de2362d3Smrg    uint64_t value;
1099de2362d3Smrg    int ret;
1100de2362d3Smrg
1101de2362d3Smrg    pScrn->capabilities = 0;
1102935f1ae0Smrg
1103935f1ae0Smrg    /* PRIME offloading requires acceleration */
1104935f1ae0Smrg    if (info->r600_shadow_fb)
1105935f1ae0Smrg	return;
1106935f1ae0Smrg
1107de2362d3Smrg    ret = drmGetCap(info->dri2.drm_fd, DRM_CAP_PRIME, &value);
1108de2362d3Smrg    if (ret == 0) {
1109de2362d3Smrg	if (value & DRM_PRIME_CAP_EXPORT)
1110de2362d3Smrg	    pScrn->capabilities |= RR_Capability_SourceOutput | RR_Capability_SinkOffload;
1111de2362d3Smrg	if (value & DRM_PRIME_CAP_IMPORT)
1112935f1ae0Smrg	    pScrn->capabilities |= RR_Capability_SinkOutput | RR_Capability_SourceOffload;
1113de2362d3Smrg    }
1114de2362d3Smrg#endif
1115de2362d3Smrg}
1116de2362d3Smrg
1117935f1ae0Smrg#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) >= 10
1118935f1ae0Smrg
1119935f1ae0Smrg/* When the root window is created, initialize the screen contents from
1120935f1ae0Smrg * console if -background none was specified on the command line
1121935f1ae0Smrg */
1122935f1ae0Smrgstatic Bool RADEONCreateWindow_oneshot(WindowPtr pWin)
1123935f1ae0Smrg{
1124935f1ae0Smrg    ScreenPtr pScreen = pWin->drawable.pScreen;
1125935f1ae0Smrg    ScrnInfoPtr pScrn;
1126935f1ae0Smrg    RADEONInfoPtr info;
1127935f1ae0Smrg    Bool ret;
1128935f1ae0Smrg
1129935f1ae0Smrg    if (pWin != pScreen->root)
1130935f1ae0Smrg	ErrorF("%s called for non-root window %p\n", __func__, pWin);
1131935f1ae0Smrg
1132935f1ae0Smrg    pScrn = xf86ScreenToScrn(pScreen);
1133935f1ae0Smrg    info = RADEONPTR(pScrn);
1134935f1ae0Smrg    pScreen->CreateWindow = info->CreateWindow;
1135935f1ae0Smrg    ret = pScreen->CreateWindow(pWin);
1136935f1ae0Smrg
1137935f1ae0Smrg    if (ret)
1138935f1ae0Smrg	drmmode_copy_fb(pScrn, &info->drmmode);
1139935f1ae0Smrg
1140935f1ae0Smrg    return ret;
1141935f1ae0Smrg}
1142935f1ae0Smrg
1143935f1ae0Smrg#endif
1144935f1ae0Smrg
1145de2362d3SmrgBool RADEONPreInit_KMS(ScrnInfoPtr pScrn, int flags)
1146de2362d3Smrg{
1147de2362d3Smrg    RADEONInfoPtr     info;
1148de2362d3Smrg    RADEONEntPtr pRADEONEnt;
1149de2362d3Smrg    DevUnion* pPriv;
1150de2362d3Smrg    Gamma  zeros = { 0.0, 0.0, 0.0 };
1151de2362d3Smrg    uint32_t tiling = 0;
1152de2362d3Smrg    int cpp;
1153de2362d3Smrg
1154de2362d3Smrg    if (flags & PROBE_DETECT)
1155de2362d3Smrg        return TRUE;
1156de2362d3Smrg
1157de2362d3Smrg    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
1158de2362d3Smrg		   "RADEONPreInit_KMS\n");
1159de2362d3Smrg    if (pScrn->numEntities != 1) return FALSE;
1160de2362d3Smrg    if (!RADEONGetRec(pScrn)) return FALSE;
1161de2362d3Smrg
1162de2362d3Smrg    info               = RADEONPTR(pScrn);
1163de2362d3Smrg    info->IsSecondary  = FALSE;
1164de2362d3Smrg    info->pEnt         = xf86GetEntityInfo(pScrn->entityList[pScrn->numEntities - 1]);
1165de2362d3Smrg    if (info->pEnt->location.type != BUS_PCI
1166de2362d3Smrg#ifdef XSERVER_PLATFORM_BUS
1167de2362d3Smrg        && info->pEnt->location.type != BUS_PLATFORM
1168de2362d3Smrg#endif
1169de2362d3Smrg        )
1170de2362d3Smrg        goto fail;
1171de2362d3Smrg
1172de2362d3Smrg    pPriv = xf86GetEntityPrivate(pScrn->entityList[0],
1173de2362d3Smrg				 getRADEONEntityIndex());
1174de2362d3Smrg    pRADEONEnt = pPriv->ptr;
1175de2362d3Smrg
1176de2362d3Smrg    if(xf86IsEntityShared(pScrn->entityList[0]))
1177de2362d3Smrg    {
1178de2362d3Smrg        if(xf86IsPrimInitDone(pScrn->entityList[0]))
1179de2362d3Smrg        {
1180de2362d3Smrg            info->IsSecondary = TRUE;
1181de2362d3Smrg        }
1182de2362d3Smrg        else
1183de2362d3Smrg        {
1184de2362d3Smrg            xf86SetPrimInitDone(pScrn->entityList[0]);
1185de2362d3Smrg        }
1186de2362d3Smrg    }
1187de2362d3Smrg
1188de2362d3Smrg    info->PciInfo = xf86GetPciInfoForEntity(info->pEnt->index);
1189de2362d3Smrg    pScrn->monitor     = pScrn->confScreen->monitor;
1190de2362d3Smrg
1191de2362d3Smrg    if (!RADEONPreInitVisual(pScrn))
1192de2362d3Smrg	goto fail;
1193de2362d3Smrg
1194de2362d3Smrg    xf86CollectOptions(pScrn, NULL);
1195de2362d3Smrg    if (!(info->Options = malloc(sizeof(RADEONOptions_KMS))))
1196de2362d3Smrg	goto fail;
1197de2362d3Smrg
1198de2362d3Smrg    memcpy(info->Options, RADEONOptions_KMS, sizeof(RADEONOptions_KMS));
1199de2362d3Smrg    xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, info->Options);
1200de2362d3Smrg
1201de2362d3Smrg    if (!RADEONPreInitWeight(pScrn))
1202de2362d3Smrg	goto fail;
1203de2362d3Smrg
1204de2362d3Smrg    if (!RADEONPreInitChipType_KMS(pScrn))
1205de2362d3Smrg        goto fail;
1206de2362d3Smrg
1207de2362d3Smrg    if (radeon_open_drm_master(pScrn) == FALSE) {
1208de2362d3Smrg	xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Kernel modesetting setup failed\n");
1209de2362d3Smrg	goto fail;
1210de2362d3Smrg    }
1211de2362d3Smrg
1212de2362d3Smrg    info->dri2.available = FALSE;
1213de2362d3Smrg    info->dri2.enabled = FALSE;
1214de2362d3Smrg    info->dri2.pKernelDRMVersion = drmGetVersion(info->dri2.drm_fd);
1215de2362d3Smrg    if (info->dri2.pKernelDRMVersion == NULL) {
1216de2362d3Smrg	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1217de2362d3Smrg		   "RADEONDRIGetVersion failed to get the DRM version\n");
1218de2362d3Smrg	goto fail;
1219de2362d3Smrg    }
1220de2362d3Smrg
1221935f1ae0Smrg    /* Get ScreenInit function */
1222935f1ae0Smrg    if (!xf86LoadSubModule(pScrn, "fb"))
1223935f1ae0Smrg	return FALSE;
1224935f1ae0Smrg
1225de2362d3Smrg    if (!RADEONPreInitAccel_KMS(pScrn))              goto fail;
1226de2362d3Smrg
1227935f1ae0Smrg    radeon_drm_queue_init();
1228935f1ae0Smrg
1229de2362d3Smrg    info->allowColorTiling2D = FALSE;
1230de2362d3Smrg
1231de2362d3Smrg    RADEONSetupCapabilities(pScrn);
1232de2362d3Smrg
1233de2362d3Smrg    /* don't enable tiling if accel is not enabled */
1234de2362d3Smrg    if (!info->r600_shadow_fb) {
1235de2362d3Smrg	Bool colorTilingDefault =
1236de2362d3Smrg	    xorgGetVersion() >= XORG_VERSION_NUMERIC(1,9,4,901,0) &&
1237de2362d3Smrg	    info->ChipFamily >= CHIP_FAMILY_R300 &&
1238de2362d3Smrg	    /* this check could be removed sometime after a big mesa release
1239de2362d3Smrg	     * with proper bit, in the meantime you need to set tiling option in
1240de2362d3Smrg	     * xorg configuration files
1241de2362d3Smrg	     */
1242de2362d3Smrg	    info->ChipFamily <= CHIP_FAMILY_MULLINS &&
1243de2362d3Smrg	    !info->is_fast_fb;
1244de2362d3Smrg
1245de2362d3Smrg	/* 2D color tiling */
1246de2362d3Smrg	if (info->ChipFamily >= CHIP_FAMILY_R600) {
1247de2362d3Smrg		info->allowColorTiling2D = xf86ReturnOptValBool(info->Options, OPTION_COLOR_TILING_2D,
1248de2362d3Smrg                                                                info->ChipFamily <= CHIP_FAMILY_MULLINS);
1249de2362d3Smrg	}
1250de2362d3Smrg
1251de2362d3Smrg	if (info->ChipFamily >= CHIP_FAMILY_R600) {
1252de2362d3Smrg	    /* set default group bytes, overridden by kernel info below */
1253de2362d3Smrg	    info->group_bytes = 256;
1254de2362d3Smrg	    info->have_tiling_info = FALSE;
1255de2362d3Smrg	    if (info->dri2.pKernelDRMVersion->version_minor >= 6) {
1256de2362d3Smrg		if (r600_get_tile_config(pScrn)) {
1257de2362d3Smrg		    info->allowColorTiling = xf86ReturnOptValBool(info->Options,
1258de2362d3Smrg								  OPTION_COLOR_TILING, colorTilingDefault);
1259de2362d3Smrg		    /* need working DFS for tiling */
1260de2362d3Smrg		    if ((info->ChipFamily == CHIP_FAMILY_PALM) &&
1261de2362d3Smrg			(!info->accel_state->allowHWDFS))
1262de2362d3Smrg			info->allowColorTiling = FALSE;
1263de2362d3Smrg		} else
1264de2362d3Smrg		    info->allowColorTiling = FALSE;
1265de2362d3Smrg	    } else
1266de2362d3Smrg		xf86DrvMsg(pScrn->scrnIndex, X_INFO,
1267de2362d3Smrg			   "R6xx+ KMS Color Tiling requires radeon drm 2.6.0 or newer\n");
1268de2362d3Smrg	} else
1269de2362d3Smrg	    info->allowColorTiling = xf86ReturnOptValBool(info->Options,
1270de2362d3Smrg							  OPTION_COLOR_TILING, colorTilingDefault);
1271de2362d3Smrg    } else
1272de2362d3Smrg	info->allowColorTiling = FALSE;
1273de2362d3Smrg
1274de2362d3Smrg    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
1275de2362d3Smrg	 "KMS Color Tiling: %sabled\n", info->allowColorTiling ? "en" : "dis");
1276de2362d3Smrg    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
1277de2362d3Smrg	 "KMS Color Tiling 2D: %sabled\n", info->allowColorTiling2D ? "en" : "dis");
1278de2362d3Smrg
1279935f1ae0Smrg#if USE_GLAMOR
1280935f1ae0Smrg    if (info->use_glamor) {
1281935f1ae0Smrg	info->shadow_primary = xf86ReturnOptValBool(info->Options,
1282935f1ae0Smrg						   OPTION_SHADOW_PRIMARY, FALSE);
1283935f1ae0Smrg
1284935f1ae0Smrg	if (info->shadow_primary)
1285935f1ae0Smrg	    xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ShadowPrimary enabled\n");
1286935f1ae0Smrg    }
1287935f1ae0Smrg#endif
1288935f1ae0Smrg
1289935f1ae0Smrg    if (!info->r600_shadow_fb) {
1290935f1ae0Smrg	info->tear_free = xf86ReturnOptValBool(info->Options, OPTION_TEAR_FREE,
1291935f1ae0Smrg					       FALSE);
1292935f1ae0Smrg
1293935f1ae0Smrg	if (info->tear_free)
1294935f1ae0Smrg	    xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "TearFree enabled\n");
1295935f1ae0Smrg    }
1296935f1ae0Smrg
1297de2362d3Smrg    if (info->dri2.pKernelDRMVersion->version_minor >= 8) {
1298935f1ae0Smrg	Bool sw_cursor = xf86ReturnOptValBool(info->Options, OPTION_SW_CURSOR, FALSE);
1299935f1ae0Smrg
1300de2362d3Smrg	info->allowPageFlip = xf86ReturnOptValBool(info->Options,
1301de2362d3Smrg						   OPTION_PAGE_FLIP, TRUE);
1302935f1ae0Smrg
1303935f1ae0Smrg	if (sw_cursor || info->tear_free || info->shadow_primary) {
1304935f1ae0Smrg	    xf86DrvMsg(pScrn->scrnIndex,
1305935f1ae0Smrg		       info->allowPageFlip ? X_WARNING : X_DEFAULT,
1306935f1ae0Smrg		       "KMS Pageflipping: disabled%s\n",
1307935f1ae0Smrg		       info->allowPageFlip ?
1308935f1ae0Smrg		       (sw_cursor ? " because of SWcursor" :
1309935f1ae0Smrg			" because of ShadowPrimary/TearFree") : "");
1310935f1ae0Smrg	    info->allowPageFlip = FALSE;
1311935f1ae0Smrg	} else {
1312935f1ae0Smrg	    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
1313935f1ae0Smrg		       "KMS Pageflipping: %sabled\n", info->allowPageFlip ? "en" : "dis");
1314935f1ae0Smrg	}
1315de2362d3Smrg    }
1316de2362d3Smrg
1317de2362d3Smrg    info->swapBuffersWait = xf86ReturnOptValBool(info->Options,
1318de2362d3Smrg						 OPTION_SWAPBUFFERS_WAIT, TRUE);
1319de2362d3Smrg    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
1320de2362d3Smrg	       "SwapBuffers wait for vsync: %sabled\n", info->swapBuffersWait ? "en" : "dis");
1321de2362d3Smrg
1322935f1ae0Smrg    if (xf86ReturnOptValBool(info->Options, OPTION_DELETE_DP12, FALSE)) {
1323935f1ae0Smrg        info->drmmode.delete_dp_12_displays = TRUE;
1324935f1ae0Smrg    }
1325935f1ae0Smrg
1326de2362d3Smrg    if (drmmode_pre_init(pScrn, &info->drmmode, pScrn->bitsPerPixel / 8) == FALSE) {
1327de2362d3Smrg	xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Kernel modesetting setup failed\n");
1328de2362d3Smrg	goto fail;
1329de2362d3Smrg    }
1330de2362d3Smrg
1331935f1ae0Smrg    if (info->drmmode.count_crtcs == 1)
1332de2362d3Smrg        pRADEONEnt->HasCRTC2 = FALSE;
1333de2362d3Smrg    else
1334de2362d3Smrg        pRADEONEnt->HasCRTC2 = TRUE;
1335de2362d3Smrg
1336de2362d3Smrg
1337de2362d3Smrg    /* fix up cloning on rn50 cards
1338de2362d3Smrg     * since they only have one crtc sometimes the xserver doesn't assign
1339de2362d3Smrg     * a crtc to one of the outputs even though both outputs have common modes
1340de2362d3Smrg     * which results in only one monitor being enabled.  Assign a crtc here so
1341de2362d3Smrg     * that both outputs light up.
1342de2362d3Smrg     */
1343de2362d3Smrg    if (info->ChipFamily == CHIP_FAMILY_RV100 && !pRADEONEnt->HasCRTC2) {
1344de2362d3Smrg	xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
1345de2362d3Smrg	int i;
1346de2362d3Smrg
1347de2362d3Smrg	for (i = 0; i < xf86_config->num_output; i++) {
1348de2362d3Smrg	    xf86OutputPtr output = xf86_config->output[i];
1349de2362d3Smrg
1350de2362d3Smrg	    /* XXX: double check crtc mode */
1351de2362d3Smrg	    if ((output->probed_modes != NULL) && (output->crtc == NULL))
1352de2362d3Smrg		output->crtc = xf86_config->crtc[0];
1353de2362d3Smrg	}
1354de2362d3Smrg    }
1355de2362d3Smrg
1356de2362d3Smrg    /* set cursor size */
1357de2362d3Smrg    if (info->ChipFamily >= CHIP_FAMILY_BONAIRE) {
1358de2362d3Smrg	info->cursor_w = CURSOR_WIDTH_CIK;
1359de2362d3Smrg	info->cursor_h = CURSOR_HEIGHT_CIK;
1360de2362d3Smrg    } else {
1361de2362d3Smrg	info->cursor_w = CURSOR_WIDTH;
1362de2362d3Smrg	info->cursor_h = CURSOR_HEIGHT;
1363de2362d3Smrg    }
1364de2362d3Smrg
1365de2362d3Smrg    {
1366de2362d3Smrg	struct drm_radeon_gem_info mminfo;
1367de2362d3Smrg
1368de2362d3Smrg	if (!drmCommandWriteRead(info->dri2.drm_fd, DRM_RADEON_GEM_INFO, &mminfo, sizeof(mminfo)))
1369de2362d3Smrg	{
1370de2362d3Smrg	    info->vram_size = mminfo.vram_visible;
1371de2362d3Smrg	    info->gart_size = mminfo.gart_size;
1372de2362d3Smrg	    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
1373de2362d3Smrg		       "mem size init: gart size :%llx vram size: s:%llx visible:%llx\n",
1374de2362d3Smrg		       (unsigned long long)mminfo.gart_size,
1375de2362d3Smrg		       (unsigned long long)mminfo.vram_size,
1376de2362d3Smrg		       (unsigned long long)mminfo.vram_visible);
1377de2362d3Smrg	}
1378de2362d3Smrg    }
1379de2362d3Smrg
1380de2362d3Smrg    if (!info->use_glamor) {
1381de2362d3Smrg	info->exa_pixmaps = xf86ReturnOptValBool(info->Options,
1382de2362d3Smrg						 OPTION_EXA_PIXMAPS,
1383de2362d3Smrg						 (info->vram_size > (32 * 1024 * 1024) &&
1384de2362d3Smrg						 info->RenderAccel &&
1385de2362d3Smrg                                                 !info->is_fast_fb));
1386de2362d3Smrg	if (info->exa_pixmaps)
1387de2362d3Smrg	    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
1388de2362d3Smrg		       "EXA: Driver will allow EXA pixmaps in VRAM\n");
1389de2362d3Smrg	else
1390de2362d3Smrg	    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
1391de2362d3Smrg		       "EXA: Driver will not allow EXA pixmaps in VRAM\n");
1392de2362d3Smrg    }
1393de2362d3Smrg
1394de2362d3Smrg    /* no tiled scanout on r6xx+ yet */
1395de2362d3Smrg    if (info->allowColorTiling) {
1396de2362d3Smrg	if (info->ChipFamily >= CHIP_FAMILY_R600)
1397de2362d3Smrg	    tiling |= RADEON_TILING_MICRO;
1398de2362d3Smrg	else
1399de2362d3Smrg	    tiling |= RADEON_TILING_MACRO;
1400de2362d3Smrg    }
1401de2362d3Smrg    cpp = pScrn->bitsPerPixel / 8;
1402de2362d3Smrg    pScrn->displayWidth =
1403de2362d3Smrg	RADEON_ALIGN(pScrn->virtualX, drmmode_get_pitch_align(pScrn, cpp, tiling));
1404de2362d3Smrg
1405de2362d3Smrg    /* Set display resolution */
1406de2362d3Smrg    xf86SetDpi(pScrn, 0, 0);
1407de2362d3Smrg
1408de2362d3Smrg    if (!xf86SetGamma(pScrn, zeros)) return FALSE;
1409de2362d3Smrg
1410de2362d3Smrg    if (!xf86ReturnOptValBool(info->Options, OPTION_SW_CURSOR, FALSE)) {
1411de2362d3Smrg	if (!xf86LoadSubModule(pScrn, "ramdac")) return FALSE;
1412de2362d3Smrg    }
1413de2362d3Smrg
1414de2362d3Smrg    if (pScrn->modes == NULL
1415de2362d3Smrg#ifdef XSERVER_PLATFORM_BUS
1416de2362d3Smrg        && !pScrn->is_gpu
1417de2362d3Smrg#endif
1418de2362d3Smrg        ) {
1419de2362d3Smrg      xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No modes.\n");
1420de2362d3Smrg      goto fail;
1421de2362d3Smrg   }
1422de2362d3Smrg
1423de2362d3Smrg    return TRUE;
1424de2362d3Smrg fail:
1425de2362d3Smrg    RADEONFreeRec(pScrn);
1426de2362d3Smrg    return FALSE;
1427de2362d3Smrg
1428de2362d3Smrg}
1429de2362d3Smrg
1430de2362d3Smrgstatic Bool RADEONCursorInit_KMS(ScreenPtr pScreen)
1431de2362d3Smrg{
1432de2362d3Smrg    ScrnInfoPtr    pScrn = xf86ScreenToScrn(pScreen);
1433de2362d3Smrg    RADEONInfoPtr  info  = RADEONPTR(pScrn);
1434de2362d3Smrg
1435de2362d3Smrg    return xf86_cursors_init (pScreen, info->cursor_w, info->cursor_h,
1436de2362d3Smrg			      (HARDWARE_CURSOR_TRUECOLOR_AT_8BPP |
1437de2362d3Smrg			       HARDWARE_CURSOR_AND_SOURCE_WITH_MASK |
1438de2362d3Smrg			       HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_1 |
1439de2362d3Smrg			       HARDWARE_CURSOR_UPDATE_UNHIDDEN |
1440de2362d3Smrg			       HARDWARE_CURSOR_ARGB));
1441de2362d3Smrg}
1442de2362d3Smrg
1443de2362d3Smrgvoid
1444de2362d3SmrgRADEONBlank(ScrnInfoPtr pScrn)
1445de2362d3Smrg{
1446de2362d3Smrg    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
1447de2362d3Smrg    xf86OutputPtr output;
1448de2362d3Smrg    xf86CrtcPtr crtc;
1449de2362d3Smrg    int o, c;
1450de2362d3Smrg
1451de2362d3Smrg    for (c = 0; c < xf86_config->num_crtc; c++) {
1452de2362d3Smrg       crtc = xf86_config->crtc[c];
1453de2362d3Smrg       for (o = 0; o < xf86_config->num_output; o++) {
1454de2362d3Smrg           output = xf86_config->output[o];
1455de2362d3Smrg           if (output->crtc != crtc)
1456de2362d3Smrg               continue;
1457de2362d3Smrg
1458de2362d3Smrg           output->funcs->dpms(output, DPMSModeOff);
1459de2362d3Smrg       }
1460de2362d3Smrg      crtc->funcs->dpms(crtc, DPMSModeOff);
1461de2362d3Smrg    }
1462de2362d3Smrg}
1463de2362d3Smrg
1464de2362d3Smrgvoid
1465de2362d3SmrgRADEONUnblank(ScrnInfoPtr pScrn)
1466de2362d3Smrg{
1467de2362d3Smrg    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
1468de2362d3Smrg    xf86OutputPtr output;
1469de2362d3Smrg    xf86CrtcPtr crtc;
1470de2362d3Smrg    int o, c;
1471de2362d3Smrg    for (c = 0; c < xf86_config->num_crtc; c++) {
1472de2362d3Smrg       crtc = xf86_config->crtc[c];
1473de2362d3Smrg       if(!crtc->enabled)
1474de2362d3Smrg              continue;
1475de2362d3Smrg       crtc->funcs->dpms(crtc, DPMSModeOn);
1476de2362d3Smrg       for (o = 0; o < xf86_config->num_output; o++) {
1477de2362d3Smrg           output = xf86_config->output[o];
1478de2362d3Smrg           if (output->crtc != crtc)
1479de2362d3Smrg               continue;
1480de2362d3Smrg           output->funcs->dpms(output, DPMSModeOn);
1481de2362d3Smrg       }
1482de2362d3Smrg    }
1483de2362d3Smrg}
1484de2362d3Smrg
1485de2362d3Smrg
1486de2362d3Smrgstatic Bool RADEONSaveScreen_KMS(ScreenPtr pScreen, int mode)
1487de2362d3Smrg{
1488de2362d3Smrg    ScrnInfoPtr  pScrn = xf86ScreenToScrn(pScreen);
1489de2362d3Smrg    Bool         unblank;
1490de2362d3Smrg
1491de2362d3Smrg    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
1492de2362d3Smrg		   "RADEONSaveScreen(%d)\n", mode);
1493de2362d3Smrg
1494de2362d3Smrg    unblank = xf86IsUnblank(mode);
1495de2362d3Smrg    if (unblank) SetTimeSinceLastInputEvent();
1496de2362d3Smrg
1497de2362d3Smrg    if ((pScrn != NULL) && pScrn->vtSema) {
1498de2362d3Smrg	if (unblank)
1499de2362d3Smrg	    RADEONUnblank(pScrn);
1500de2362d3Smrg	else
1501de2362d3Smrg	    RADEONBlank(pScrn);
1502de2362d3Smrg    }
1503de2362d3Smrg    return TRUE;
1504de2362d3Smrg}
1505de2362d3Smrg
1506de2362d3Smrgstatic Bool radeon_set_drm_master(ScrnInfoPtr pScrn)
1507de2362d3Smrg{
1508de2362d3Smrg    RADEONInfoPtr  info  = RADEONPTR(pScrn);
1509de2362d3Smrg#ifdef XF86_PDEV_SERVER_FD
1510de2362d3Smrg    RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
1511de2362d3Smrg#endif
1512de2362d3Smrg    int err;
1513de2362d3Smrg
1514de2362d3Smrg#ifdef XF86_PDEV_SERVER_FD
1515de2362d3Smrg    if (pRADEONEnt->platform_dev &&
1516de2362d3Smrg            (pRADEONEnt->platform_dev->flags & XF86_PDEV_SERVER_FD))
1517de2362d3Smrg        return TRUE;
1518de2362d3Smrg#endif
1519de2362d3Smrg
1520de2362d3Smrg    err = drmSetMaster(info->dri2.drm_fd);
1521de2362d3Smrg    if (err)
1522de2362d3Smrg        ErrorF("Unable to retrieve master\n");
1523de2362d3Smrg
1524de2362d3Smrg    return err == 0;
1525de2362d3Smrg}
1526de2362d3Smrg
1527de2362d3Smrgstatic void radeon_drop_drm_master(ScrnInfoPtr pScrn)
1528de2362d3Smrg{
1529de2362d3Smrg    RADEONInfoPtr  info  = RADEONPTR(pScrn);
1530de2362d3Smrg#ifdef XF86_PDEV_SERVER_FD
1531de2362d3Smrg    RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
1532de2362d3Smrg
1533de2362d3Smrg    if (pRADEONEnt->platform_dev &&
1534de2362d3Smrg            (pRADEONEnt->platform_dev->flags & XF86_PDEV_SERVER_FD))
1535de2362d3Smrg        return;
1536de2362d3Smrg#endif
1537de2362d3Smrg
1538de2362d3Smrg    drmDropMaster(info->dri2.drm_fd);
1539de2362d3Smrg}
1540de2362d3Smrg
1541de2362d3Smrg/* Called at the end of each server generation.  Restore the original
1542de2362d3Smrg * text mode, unmap video memory, and unwrap and call the saved
1543de2362d3Smrg * CloseScreen function.
1544de2362d3Smrg */
1545de2362d3Smrgstatic Bool RADEONCloseScreen_KMS(CLOSE_SCREEN_ARGS_DECL)
1546de2362d3Smrg{
1547de2362d3Smrg    ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
1548de2362d3Smrg    RADEONInfoPtr  info  = RADEONPTR(pScrn);
1549935f1ae0Smrg    RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
1550de2362d3Smrg
1551de2362d3Smrg    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
1552de2362d3Smrg		   "RADEONCloseScreen\n");
1553de2362d3Smrg
1554935f1ae0Smrg    /* Clear mask of assigned crtc's in this generation */
1555935f1ae0Smrg    pRADEONEnt->assigned_crtcs = 0;
1556935f1ae0Smrg
1557de2362d3Smrg    drmmode_uevent_fini(pScrn, &info->drmmode);
1558935f1ae0Smrg    radeon_drm_queue_close(pScrn);
1559de2362d3Smrg    radeon_cs_flush_indirect(pScrn);
1560de2362d3Smrg
1561de2362d3Smrg    DeleteCallback(&FlushCallback, radeon_flush_callback, pScrn);
1562de2362d3Smrg
1563de2362d3Smrg    if (info->accel_state->exa) {
1564de2362d3Smrg	exaDriverFini(pScreen);
1565de2362d3Smrg	free(info->accel_state->exa);
1566de2362d3Smrg	info->accel_state->exa = NULL;
1567de2362d3Smrg    }
1568de2362d3Smrg
1569935f1ae0Smrg    radeon_sync_close(pScreen);
1570935f1ae0Smrg
1571de2362d3Smrg    if (info->accel_state->use_vbos)
1572de2362d3Smrg        radeon_vbo_free_lists(pScrn);
1573de2362d3Smrg
1574de2362d3Smrg    radeon_drop_drm_master(pScrn);
1575de2362d3Smrg
1576de2362d3Smrg    drmmode_fini(pScrn, &info->drmmode);
1577de2362d3Smrg    if (info->dri2.enabled)
1578de2362d3Smrg	radeon_dri2_close_screen(pScreen);
1579de2362d3Smrg
1580935f1ae0Smrg    radeon_glamor_fini(pScreen);
1581935f1ae0Smrg
1582de2362d3Smrg    pScrn->vtSema = FALSE;
1583de2362d3Smrg    xf86ClearPrimInitDone(info->pEnt->index);
1584de2362d3Smrg    pScreen->BlockHandler = info->BlockHandler;
1585de2362d3Smrg    pScreen->CloseScreen = info->CloseScreen;
1586de2362d3Smrg    return (*pScreen->CloseScreen)(CLOSE_SCREEN_ARGS);
1587de2362d3Smrg}
1588de2362d3Smrg
1589de2362d3Smrg
1590de2362d3Smrgvoid RADEONFreeScreen_KMS(FREE_SCREEN_ARGS_DECL)
1591de2362d3Smrg{
1592de2362d3Smrg    SCRN_INFO_PTR(arg);
1593de2362d3Smrg    RADEONInfoPtr  info  = RADEONPTR(pScrn);
1594de2362d3Smrg
1595de2362d3Smrg    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
1596de2362d3Smrg		   "RADEONFreeScreen\n");
1597de2362d3Smrg
1598de2362d3Smrg    /* when server quits at PreInit, we don't need do this anymore*/
1599de2362d3Smrg    if (!info) return;
1600de2362d3Smrg
1601de2362d3Smrg    RADEONFreeRec(pScrn);
1602de2362d3Smrg}
1603de2362d3Smrg
1604de2362d3SmrgBool RADEONScreenInit_KMS(SCREEN_INIT_ARGS_DECL)
1605de2362d3Smrg{
1606de2362d3Smrg    ScrnInfoPtr    pScrn = xf86ScreenToScrn(pScreen);
1607de2362d3Smrg    RADEONInfoPtr  info  = RADEONPTR(pScrn);
1608de2362d3Smrg    int            subPixelOrder = SubPixelUnknown;
1609935f1ae0Smrg    MessageType from;
1610935f1ae0Smrg    Bool value;
1611935f1ae0Smrg    int driLevel;
1612de2362d3Smrg    const char *s;
1613de2362d3Smrg    void *front_ptr;
1614de2362d3Smrg
1615de2362d3Smrg    pScrn->fbOffset = 0;
1616de2362d3Smrg
1617de2362d3Smrg    miClearVisualTypes();
1618de2362d3Smrg    if (!miSetVisualTypes(pScrn->depth,
1619de2362d3Smrg			  miGetDefaultVisualMask(pScrn->depth),
1620de2362d3Smrg			  pScrn->rgbBits,
1621de2362d3Smrg			  pScrn->defaultVisual)) return FALSE;
1622de2362d3Smrg    miSetPixmapDepths ();
1623de2362d3Smrg
1624de2362d3Smrg    if (!radeon_set_drm_master(pScrn))
1625de2362d3Smrg        return FALSE;
1626de2362d3Smrg
1627de2362d3Smrg    info->directRenderingEnabled = FALSE;
1628de2362d3Smrg    if (info->r600_shadow_fb == FALSE)
1629de2362d3Smrg        info->directRenderingEnabled = radeon_dri2_screen_init(pScreen);
1630de2362d3Smrg
1631de2362d3Smrg    info->surf_man = radeon_surface_manager_new(info->dri2.drm_fd);
1632de2362d3Smrg    if (!info->bufmgr)
1633de2362d3Smrg        info->bufmgr = radeon_bo_manager_gem_ctor(info->dri2.drm_fd);
1634de2362d3Smrg    if (!info->bufmgr) {
1635de2362d3Smrg	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1636de2362d3Smrg		   "failed to initialise GEM buffer manager");
1637de2362d3Smrg	return FALSE;
1638de2362d3Smrg    }
1639de2362d3Smrg    drmmode_set_bufmgr(pScrn, &info->drmmode, info->bufmgr);
1640de2362d3Smrg
1641de2362d3Smrg    if (!info->csm)
1642de2362d3Smrg        info->csm = radeon_cs_manager_gem_ctor(info->dri2.drm_fd);
1643de2362d3Smrg    if (!info->csm) {
1644de2362d3Smrg	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1645de2362d3Smrg		   "failed to initialise command submission manager");
1646de2362d3Smrg	return FALSE;
1647de2362d3Smrg    }
1648de2362d3Smrg
1649de2362d3Smrg    if (!info->cs)
1650de2362d3Smrg        info->cs = radeon_cs_create(info->csm, RADEON_BUFFER_SIZE/4);
1651de2362d3Smrg    if (!info->cs) {
1652de2362d3Smrg	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1653de2362d3Smrg		   "failed to initialise command submission buffer");
1654de2362d3Smrg	return FALSE;
1655de2362d3Smrg    }
1656de2362d3Smrg
1657de2362d3Smrg    radeon_cs_set_limit(info->cs, RADEON_GEM_DOMAIN_GTT, info->gart_size);
1658de2362d3Smrg    radeon_cs_space_set_flush(info->cs, (void(*)(void *))radeon_cs_flush_indirect, pScrn);
1659de2362d3Smrg
1660de2362d3Smrg    if (!radeon_setup_kernel_mem(pScreen)) {
1661de2362d3Smrg	xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "radeon_setup_kernel_mem failed\n");
1662de2362d3Smrg	return FALSE;
1663de2362d3Smrg    }
1664de2362d3Smrg    front_ptr = info->front_bo->ptr;
1665de2362d3Smrg
1666de2362d3Smrg    if (info->r600_shadow_fb) {
1667de2362d3Smrg	info->fb_shadow = calloc(1,
1668de2362d3Smrg				 pScrn->displayWidth * pScrn->virtualY *
1669de2362d3Smrg				 ((pScrn->bitsPerPixel + 7) >> 3));
1670de2362d3Smrg	if (info->fb_shadow == NULL) {
1671de2362d3Smrg	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1672de2362d3Smrg                       "Failed to allocate shadow framebuffer\n");
1673de2362d3Smrg	    info->r600_shadow_fb = FALSE;
1674de2362d3Smrg	} else {
1675de2362d3Smrg	    if (!fbScreenInit(pScreen, info->fb_shadow,
1676de2362d3Smrg			      pScrn->virtualX, pScrn->virtualY,
1677de2362d3Smrg			      pScrn->xDpi, pScrn->yDpi, pScrn->displayWidth,
1678de2362d3Smrg			      pScrn->bitsPerPixel))
1679de2362d3Smrg		return FALSE;
1680de2362d3Smrg	}
1681de2362d3Smrg    }
1682de2362d3Smrg
1683de2362d3Smrg    if (info->r600_shadow_fb == FALSE) {
1684de2362d3Smrg	/* Init fb layer */
1685de2362d3Smrg	if (!fbScreenInit(pScreen, front_ptr,
1686de2362d3Smrg			  pScrn->virtualX, pScrn->virtualY,
1687de2362d3Smrg			  pScrn->xDpi, pScrn->yDpi, pScrn->displayWidth,
1688de2362d3Smrg			  pScrn->bitsPerPixel))
1689de2362d3Smrg	    return FALSE;
1690de2362d3Smrg    }
1691de2362d3Smrg
1692de2362d3Smrg    xf86SetBlackWhitePixels(pScreen);
1693de2362d3Smrg
1694de2362d3Smrg    if (pScrn->bitsPerPixel > 8) {
1695de2362d3Smrg	VisualPtr  visual;
1696de2362d3Smrg
1697de2362d3Smrg	visual = pScreen->visuals + pScreen->numVisuals;
1698de2362d3Smrg	while (--visual >= pScreen->visuals) {
1699de2362d3Smrg	    if ((visual->class | DynamicClass) == DirectColor) {
1700de2362d3Smrg		visual->offsetRed   = pScrn->offset.red;
1701de2362d3Smrg		visual->offsetGreen = pScrn->offset.green;
1702de2362d3Smrg		visual->offsetBlue  = pScrn->offset.blue;
1703de2362d3Smrg		visual->redMask     = pScrn->mask.red;
1704de2362d3Smrg		visual->greenMask   = pScrn->mask.green;
1705de2362d3Smrg		visual->blueMask    = pScrn->mask.blue;
1706de2362d3Smrg	    }
1707de2362d3Smrg	}
1708de2362d3Smrg    }
1709de2362d3Smrg
1710de2362d3Smrg    /* Must be after RGB order fixed */
1711de2362d3Smrg    fbPictureInit (pScreen, 0, 0);
1712de2362d3Smrg
1713de2362d3Smrg#ifdef RENDER
1714de2362d3Smrg    if ((s = xf86GetOptValString(info->Options, OPTION_SUBPIXEL_ORDER))) {
1715de2362d3Smrg	if (strcmp(s, "RGB") == 0) subPixelOrder = SubPixelHorizontalRGB;
1716de2362d3Smrg	else if (strcmp(s, "BGR") == 0) subPixelOrder = SubPixelHorizontalBGR;
1717de2362d3Smrg	else if (strcmp(s, "NONE") == 0) subPixelOrder = SubPixelNone;
1718de2362d3Smrg	PictureSetSubpixelOrder (pScreen, subPixelOrder);
1719de2362d3Smrg    }
1720de2362d3Smrg#endif
1721de2362d3Smrg
1722935f1ae0Smrg    value = FALSE;
1723935f1ae0Smrg    from = X_DEFAULT;
1724935f1ae0Smrg
1725935f1ae0Smrg    if (!info->r600_shadow_fb) {
1726935f1ae0Smrg	if (xf86GetOptValBool(info->Options, OPTION_DRI3, &value))
1727935f1ae0Smrg	    from = X_CONFIG;
1728935f1ae0Smrg
1729935f1ae0Smrg	if (xf86GetOptValInteger(info->Options, OPTION_DRI, &driLevel) &&
1730935f1ae0Smrg	    (driLevel == 2 || driLevel == 3)) {
1731935f1ae0Smrg	    from = X_CONFIG;
1732935f1ae0Smrg	    value = driLevel == 3;
1733935f1ae0Smrg	}
1734935f1ae0Smrg    }
1735935f1ae0Smrg
1736935f1ae0Smrg    if (value) {
1737935f1ae0Smrg	value = radeon_sync_init(pScreen) &&
1738935f1ae0Smrg	    radeon_present_screen_init(pScreen) &&
1739935f1ae0Smrg	    radeon_dri3_screen_init(pScreen);
1740935f1ae0Smrg
1741935f1ae0Smrg	if (!value)
1742935f1ae0Smrg	    from = X_WARNING;
1743935f1ae0Smrg    }
1744935f1ae0Smrg
1745935f1ae0Smrg    xf86DrvMsg(pScrn->scrnIndex, from, "DRI3 %sabled\n", value ? "en" : "dis");
1746935f1ae0Smrg
1747de2362d3Smrg    pScrn->vtSema = TRUE;
1748de2362d3Smrg    xf86SetBackingStore(pScreen);
1749de2362d3Smrg
1750de2362d3Smrg    if (info->directRenderingEnabled) {
1751de2362d3Smrg	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Direct rendering enabled\n");
1752de2362d3Smrg    } else {
1753de2362d3Smrg	xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
1754de2362d3Smrg		   "Direct rendering disabled\n");
1755de2362d3Smrg    }
1756de2362d3Smrg
1757de2362d3Smrg    if (info->r600_shadow_fb) {
1758de2362d3Smrg	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Acceleration disabled\n");
1759de2362d3Smrg	info->accelOn = FALSE;
1760de2362d3Smrg    } else {
1761de2362d3Smrg	xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
1762de2362d3Smrg		       "Initializing Acceleration\n");
1763de2362d3Smrg	if (RADEONAccelInit(pScreen)) {
1764de2362d3Smrg	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Acceleration enabled\n");
1765de2362d3Smrg	    info->accelOn = TRUE;
1766de2362d3Smrg	} else {
1767de2362d3Smrg	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1768de2362d3Smrg		       "Acceleration initialization failed\n");
1769de2362d3Smrg	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Acceleration disabled\n");
1770de2362d3Smrg	    info->accelOn = FALSE;
1771de2362d3Smrg	}
1772de2362d3Smrg    }
1773de2362d3Smrg
1774de2362d3Smrg    /* Init DPMS */
1775de2362d3Smrg    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
1776de2362d3Smrg		   "Initializing DPMS\n");
1777de2362d3Smrg    xf86DPMSInit(pScreen, xf86DPMSSet, 0);
1778de2362d3Smrg
1779de2362d3Smrg    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
1780de2362d3Smrg		   "Initializing Cursor\n");
1781de2362d3Smrg
1782de2362d3Smrg    /* Set Silken Mouse */
1783de2362d3Smrg    xf86SetSilkenMouse(pScreen);
1784de2362d3Smrg
1785de2362d3Smrg    /* Cursor setup */
1786de2362d3Smrg    miDCInitialize(pScreen, xf86GetPointerScreenFuncs());
1787de2362d3Smrg
1788de2362d3Smrg    if (!xf86ReturnOptValBool(info->Options, OPTION_SW_CURSOR, FALSE)) {
1789de2362d3Smrg	if (RADEONCursorInit_KMS(pScreen)) {
1790de2362d3Smrg	}
1791de2362d3Smrg    }
1792de2362d3Smrg
1793de2362d3Smrg    /* DGA setup */
1794de2362d3Smrg#ifdef XFreeXDGA
1795de2362d3Smrg    /* DGA is dangerous on kms as the base and framebuffer location may change:
1796de2362d3Smrg     * http://lists.freedesktop.org/archives/xorg-devel/2009-September/002113.html
1797de2362d3Smrg     */
1798de2362d3Smrg    /* xf86DiDGAInit(pScreen, info->LinearAddr + pScrn->fbOffset); */
1799de2362d3Smrg#endif
1800de2362d3Smrg    if (info->r600_shadow_fb == FALSE) {
1801de2362d3Smrg        /* Init Xv */
1802de2362d3Smrg        xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
1803de2362d3Smrg                       "Initializing Xv\n");
1804de2362d3Smrg        RADEONInitVideo(pScreen);
1805de2362d3Smrg    }
1806de2362d3Smrg
1807de2362d3Smrg    if (info->r600_shadow_fb == TRUE) {
1808de2362d3Smrg        if (!shadowSetup(pScreen)) {
1809de2362d3Smrg	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1810de2362d3Smrg		       "Shadowfb initialization failed\n");
1811de2362d3Smrg            return FALSE;
1812de2362d3Smrg        }
1813de2362d3Smrg    }
1814de2362d3Smrg    pScrn->pScreen = pScreen;
1815de2362d3Smrg
1816935f1ae0Smrg#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) >= 10
1817935f1ae0Smrg    if (serverGeneration == 1 && bgNoneRoot && info->accelOn) {
1818935f1ae0Smrg	info->CreateWindow = pScreen->CreateWindow;
1819935f1ae0Smrg	pScreen->CreateWindow = RADEONCreateWindow_oneshot;
1820935f1ae0Smrg    }
1821935f1ae0Smrg#endif
1822935f1ae0Smrg
1823de2362d3Smrg    /* Provide SaveScreen & wrap BlockHandler and CloseScreen */
1824de2362d3Smrg    /* Wrap CloseScreen */
1825de2362d3Smrg    info->CloseScreen    = pScreen->CloseScreen;
1826de2362d3Smrg    pScreen->CloseScreen = RADEONCloseScreen_KMS;
1827de2362d3Smrg    pScreen->SaveScreen  = RADEONSaveScreen_KMS;
1828de2362d3Smrg    info->BlockHandler = pScreen->BlockHandler;
1829935f1ae0Smrg    pScreen->BlockHandler = RADEONBlockHandler_oneshot;
1830de2362d3Smrg
1831de2362d3Smrg    if (!AddCallback(&FlushCallback, radeon_flush_callback, pScrn))
1832de2362d3Smrg        return FALSE;
1833de2362d3Smrg
1834de2362d3Smrg    info->CreateScreenResources = pScreen->CreateScreenResources;
1835de2362d3Smrg    pScreen->CreateScreenResources = RADEONCreateScreenResources_KMS;
1836de2362d3Smrg
1837de2362d3Smrg#ifdef RADEON_PIXMAP_SHARING
1838de2362d3Smrg    pScreen->StartPixmapTracking = PixmapStartDirtyTracking;
1839de2362d3Smrg    pScreen->StopPixmapTracking = PixmapStopDirtyTracking;
1840de2362d3Smrg#endif
1841de2362d3Smrg
1842de2362d3Smrg   if (!xf86CrtcScreenInit (pScreen))
1843de2362d3Smrg       return FALSE;
1844de2362d3Smrg
1845de2362d3Smrg   /* Wrap pointer motion to flip touch screen around */
1846de2362d3Smrg//    info->PointerMoved = pScrn->PointerMoved;
1847de2362d3Smrg//    pScrn->PointerMoved = RADEONPointerMoved;
1848de2362d3Smrg
1849de2362d3Smrg    if (!drmmode_setup_colormap(pScreen, pScrn))
1850de2362d3Smrg	return FALSE;
1851de2362d3Smrg
1852de2362d3Smrg   /* Note unused options */
1853de2362d3Smrg    if (serverGeneration == 1)
1854de2362d3Smrg	xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
1855de2362d3Smrg
1856de2362d3Smrg    drmmode_init(pScrn, &info->drmmode);
1857de2362d3Smrg
1858de2362d3Smrg    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
1859de2362d3Smrg		   "RADEONScreenInit finished\n");
1860de2362d3Smrg
1861de2362d3Smrg    info->accel_state->XInited3D = FALSE;
1862de2362d3Smrg    info->accel_state->engineMode = EXA_ENGINEMODE_UNKNOWN;
1863de2362d3Smrg
1864de2362d3Smrg    return TRUE;
1865de2362d3Smrg}
1866de2362d3Smrg
1867de2362d3SmrgBool RADEONEnterVT_KMS(VT_FUNC_ARGS_DECL)
1868de2362d3Smrg{
1869de2362d3Smrg    SCRN_INFO_PTR(arg);
1870de2362d3Smrg    RADEONInfoPtr  info  = RADEONPTR(pScrn);
1871de2362d3Smrg
1872de2362d3Smrg    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
1873de2362d3Smrg		   "RADEONEnterVT_KMS\n");
1874de2362d3Smrg
1875de2362d3Smrg    radeon_set_drm_master(pScrn);
1876de2362d3Smrg
1877de2362d3Smrg    info->accel_state->XInited3D = FALSE;
1878de2362d3Smrg    info->accel_state->engineMode = EXA_ENGINEMODE_UNKNOWN;
1879de2362d3Smrg
1880de2362d3Smrg    pScrn->vtSema = TRUE;
1881de2362d3Smrg
1882935f1ae0Smrg    if (!drmmode_set_desired_modes(pScrn, &info->drmmode, TRUE))
1883de2362d3Smrg	return FALSE;
1884de2362d3Smrg
1885de2362d3Smrg    return TRUE;
1886de2362d3Smrg}
1887de2362d3Smrg
1888de2362d3Smrg
1889de2362d3Smrgvoid RADEONLeaveVT_KMS(VT_FUNC_ARGS_DECL)
1890de2362d3Smrg{
1891de2362d3Smrg    SCRN_INFO_PTR(arg);
1892de2362d3Smrg    RADEONInfoPtr  info  = RADEONPTR(pScrn);
1893de2362d3Smrg
1894de2362d3Smrg    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
1895de2362d3Smrg		   "RADEONLeaveVT_KMS\n");
1896de2362d3Smrg
1897de2362d3Smrg    radeon_drop_drm_master(pScrn);
1898de2362d3Smrg
1899de2362d3Smrg    xf86RotateFreeShadow(pScrn);
1900935f1ae0Smrg    drmmode_scanout_free(pScrn);
1901de2362d3Smrg
1902de2362d3Smrg    xf86_hide_cursors (pScrn);
1903de2362d3Smrg    info->accel_state->XInited3D = FALSE;
1904de2362d3Smrg    info->accel_state->engineMode = EXA_ENGINEMODE_UNKNOWN;
1905de2362d3Smrg
1906de2362d3Smrg    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
1907de2362d3Smrg		   "Ok, leaving now...\n");
1908de2362d3Smrg}
1909de2362d3Smrg
1910de2362d3Smrg
1911de2362d3SmrgBool RADEONSwitchMode_KMS(SWITCH_MODE_ARGS_DECL)
1912de2362d3Smrg{
1913de2362d3Smrg    SCRN_INFO_PTR(arg);
1914de2362d3Smrg    Bool ret;
1915de2362d3Smrg    ret = xf86SetSingleMode (pScrn, mode, RR_Rotate_0);
1916de2362d3Smrg    return ret;
1917de2362d3Smrg
1918de2362d3Smrg}
1919de2362d3Smrg
1920de2362d3Smrgvoid RADEONAdjustFrame_KMS(ADJUST_FRAME_ARGS_DECL)
1921de2362d3Smrg{
1922de2362d3Smrg    SCRN_INFO_PTR(arg);
1923de2362d3Smrg    RADEONInfoPtr  info        = RADEONPTR(pScrn);
1924de2362d3Smrg    drmmode_adjust_frame(pScrn, &info->drmmode, x, y);
1925de2362d3Smrg    return;
1926de2362d3Smrg}
1927de2362d3Smrg
1928de2362d3Smrgstatic Bool radeon_setup_kernel_mem(ScreenPtr pScreen)
1929de2362d3Smrg{
1930de2362d3Smrg    ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
1931de2362d3Smrg    RADEONInfoPtr info = RADEONPTR(pScrn);
1932de2362d3Smrg    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
1933de2362d3Smrg    int cpp = info->pixel_bytes;
1934de2362d3Smrg    uint32_t screen_size;
1935de2362d3Smrg    int pitch, base_align;
1936de2362d3Smrg    uint32_t tiling_flags = 0;
1937de2362d3Smrg    struct radeon_surface surface;
1938de2362d3Smrg
1939de2362d3Smrg    if (info->accel_state->exa != NULL) {
1940de2362d3Smrg	xf86DrvMsg(pScreen->myNum, X_ERROR, "Memory map already initialized\n");
1941de2362d3Smrg	return FALSE;
1942de2362d3Smrg    }
1943de2362d3Smrg    if (!info->use_glamor && info->r600_shadow_fb == FALSE) {
1944de2362d3Smrg        info->accel_state->exa = exaDriverAlloc();
1945de2362d3Smrg        if (info->accel_state->exa == NULL) {
1946de2362d3Smrg	    xf86DrvMsg(pScreen->myNum, X_ERROR, "exaDriverAlloc failed\n");
1947de2362d3Smrg	    return FALSE;
1948de2362d3Smrg	}
1949de2362d3Smrg    }
1950de2362d3Smrg
1951935f1ae0Smrg    if (info->allowColorTiling && !info->shadow_primary) {
1952de2362d3Smrg	if (info->ChipFamily >= CHIP_FAMILY_R600) {
1953de2362d3Smrg		if (info->allowColorTiling2D) {
1954de2362d3Smrg			tiling_flags |= RADEON_TILING_MACRO;
1955de2362d3Smrg		} else {
1956de2362d3Smrg			tiling_flags |= RADEON_TILING_MICRO;
1957de2362d3Smrg		}
1958de2362d3Smrg	} else
1959de2362d3Smrg	    tiling_flags |= RADEON_TILING_MACRO;
1960de2362d3Smrg    }
1961de2362d3Smrg    pitch = RADEON_ALIGN(pScrn->virtualX, drmmode_get_pitch_align(pScrn, cpp, tiling_flags)) * cpp;
1962de2362d3Smrg    screen_size = RADEON_ALIGN(pScrn->virtualY, drmmode_get_height_align(pScrn, tiling_flags)) * pitch;
1963de2362d3Smrg    base_align = drmmode_get_base_align(pScrn, cpp, tiling_flags);
1964de2362d3Smrg	if (info->ChipFamily >= CHIP_FAMILY_R600) {
1965de2362d3Smrg		if(!info->surf_man) {
1966de2362d3Smrg			xf86DrvMsg(pScreen->myNum, X_ERROR,
1967de2362d3Smrg				   "failed to initialise surface manager\n");
1968de2362d3Smrg			return FALSE;
1969de2362d3Smrg		}
1970de2362d3Smrg		memset(&surface, 0, sizeof(struct radeon_surface));
1971de2362d3Smrg		surface.npix_x = pScrn->virtualX;
1972de2362d3Smrg		surface.npix_y = pScrn->virtualY;
1973de2362d3Smrg		surface.npix_z = 1;
1974de2362d3Smrg		surface.blk_w = 1;
1975de2362d3Smrg		surface.blk_h = 1;
1976de2362d3Smrg		surface.blk_d = 1;
1977de2362d3Smrg		surface.array_size = 1;
1978de2362d3Smrg		surface.last_level = 0;
1979de2362d3Smrg		surface.bpe = cpp;
1980de2362d3Smrg		surface.nsamples = 1;
1981de2362d3Smrg		surface.flags = RADEON_SURF_SCANOUT;
1982de2362d3Smrg		/* we are requiring a recent enough libdrm version */
1983de2362d3Smrg		surface.flags |= RADEON_SURF_HAS_TILE_MODE_INDEX;
1984de2362d3Smrg		surface.flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_2D, TYPE);
1985de2362d3Smrg		surface.flags |= RADEON_SURF_SET(RADEON_SURF_MODE_LINEAR_ALIGNED, MODE);
1986de2362d3Smrg		if (tiling_flags & RADEON_TILING_MICRO) {
1987de2362d3Smrg			surface.flags = RADEON_SURF_CLR(surface.flags, MODE);
1988de2362d3Smrg			surface.flags |= RADEON_SURF_SET(RADEON_SURF_MODE_1D, MODE);
1989de2362d3Smrg		}
1990de2362d3Smrg		if (tiling_flags & RADEON_TILING_MACRO) {
1991de2362d3Smrg			surface.flags = RADEON_SURF_CLR(surface.flags, MODE);
1992de2362d3Smrg			surface.flags |= RADEON_SURF_SET(RADEON_SURF_MODE_2D, MODE);
1993de2362d3Smrg		}
1994de2362d3Smrg		if (radeon_surface_best(info->surf_man, &surface)) {
1995de2362d3Smrg			xf86DrvMsg(pScreen->myNum, X_ERROR,
1996de2362d3Smrg				   "radeon_surface_best failed\n");
1997de2362d3Smrg			return FALSE;
1998de2362d3Smrg		}
1999de2362d3Smrg		if (radeon_surface_init(info->surf_man, &surface)) {
2000de2362d3Smrg			xf86DrvMsg(pScreen->myNum, X_ERROR,
2001de2362d3Smrg				   "radeon_surface_init failed\n");
2002de2362d3Smrg			return FALSE;
2003de2362d3Smrg		}
2004de2362d3Smrg		pitch = surface.level[0].pitch_bytes;
2005de2362d3Smrg		screen_size = surface.bo_size;
2006de2362d3Smrg		base_align = surface.bo_alignment;
2007de2362d3Smrg		tiling_flags = 0;
2008de2362d3Smrg		switch (surface.level[0].mode) {
2009de2362d3Smrg		case RADEON_SURF_MODE_2D:
2010de2362d3Smrg			tiling_flags |= RADEON_TILING_MACRO;
2011de2362d3Smrg			tiling_flags |= surface.bankw << RADEON_TILING_EG_BANKW_SHIFT;
2012de2362d3Smrg			tiling_flags |= surface.bankh << RADEON_TILING_EG_BANKH_SHIFT;
2013de2362d3Smrg			tiling_flags |= surface.mtilea << RADEON_TILING_EG_MACRO_TILE_ASPECT_SHIFT;
2014935f1ae0Smrg			if (surface.tile_split)
2015935f1ae0Smrg				tiling_flags |= eg_tile_split(surface.tile_split)
2016935f1ae0Smrg						<< RADEON_TILING_EG_TILE_SPLIT_SHIFT;
2017de2362d3Smrg			break;
2018de2362d3Smrg		case RADEON_SURF_MODE_1D:
2019de2362d3Smrg			tiling_flags |= RADEON_TILING_MICRO;
2020de2362d3Smrg			break;
2021de2362d3Smrg		default:
2022de2362d3Smrg			break;
2023de2362d3Smrg		}
2024de2362d3Smrg		info->front_surface = surface;
2025de2362d3Smrg	}
2026de2362d3Smrg    {
2027de2362d3Smrg	int cursor_size;
2028de2362d3Smrg	int c;
2029de2362d3Smrg
2030de2362d3Smrg	cursor_size = info->cursor_w * info->cursor_h * 4;
2031de2362d3Smrg	cursor_size = RADEON_ALIGN(cursor_size, RADEON_GPU_PAGE_SIZE);
2032de2362d3Smrg	for (c = 0; c < xf86_config->num_crtc; c++) {
2033de2362d3Smrg	    /* cursor objects */
2034de2362d3Smrg            if (info->cursor_bo[c] == NULL) {
2035de2362d3Smrg                info->cursor_bo[c] = radeon_bo_open(info->bufmgr, 0,
2036de2362d3Smrg                                                    cursor_size, 0,
2037de2362d3Smrg                                                    RADEON_GEM_DOMAIN_VRAM, 0);
2038de2362d3Smrg                if (!info->cursor_bo[c]) {
2039de2362d3Smrg                    ErrorF("Failed to allocate cursor buffer memory\n");
2040de2362d3Smrg                    return FALSE;
2041de2362d3Smrg                }
2042de2362d3Smrg
2043de2362d3Smrg                if (radeon_bo_map(info->cursor_bo[c], 1)) {
2044de2362d3Smrg                    ErrorF("Failed to map cursor buffer memory\n");
2045de2362d3Smrg                }
2046de2362d3Smrg
2047de2362d3Smrg                drmmode_set_cursor(pScrn, &info->drmmode, c, info->cursor_bo[c]);
2048de2362d3Smrg            }
2049de2362d3Smrg        }
2050de2362d3Smrg    }
2051de2362d3Smrg
2052de2362d3Smrg    screen_size = RADEON_ALIGN(screen_size, RADEON_GPU_PAGE_SIZE);
2053de2362d3Smrg
2054de2362d3Smrg    if (info->front_bo == NULL) {
2055de2362d3Smrg        info->front_bo = radeon_bo_open(info->bufmgr, 0, screen_size,
2056935f1ae0Smrg                                        base_align,
2057935f1ae0Smrg                                        info->shadow_primary ?
2058935f1ae0Smrg                                        RADEON_GEM_DOMAIN_GTT :
2059935f1ae0Smrg                                        RADEON_GEM_DOMAIN_VRAM,
2060935f1ae0Smrg                                        tiling_flags ? RADEON_GEM_NO_CPU_ACCESS : 0);
2061de2362d3Smrg        if (info->r600_shadow_fb == TRUE) {
2062de2362d3Smrg            if (radeon_bo_map(info->front_bo, 1)) {
2063de2362d3Smrg                ErrorF("Failed to map cursor buffer memory\n");
2064de2362d3Smrg            }
2065de2362d3Smrg        }
2066de2362d3Smrg#if X_BYTE_ORDER == X_BIG_ENDIAN
2067de2362d3Smrg	switch (cpp) {
2068de2362d3Smrg	case 4:
2069de2362d3Smrg	    tiling_flags |= RADEON_TILING_SWAP_32BIT;
2070de2362d3Smrg	    break;
2071de2362d3Smrg	case 2:
2072de2362d3Smrg	    tiling_flags |= RADEON_TILING_SWAP_16BIT;
2073de2362d3Smrg	    break;
2074de2362d3Smrg	}
2075de2362d3Smrg	if (info->ChipFamily < CHIP_FAMILY_R600 &&
2076de2362d3Smrg	    info->r600_shadow_fb && tiling_flags)
2077de2362d3Smrg	    tiling_flags |= RADEON_TILING_SURFACE;
2078de2362d3Smrg#endif
2079de2362d3Smrg	if (tiling_flags)
2080de2362d3Smrg            radeon_bo_set_tiling(info->front_bo, tiling_flags, pitch);
2081de2362d3Smrg    }
2082de2362d3Smrg
2083de2362d3Smrg    pScrn->displayWidth = pitch / cpp;
2084de2362d3Smrg
2085de2362d3Smrg    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Front buffer size: %dK\n", info->front_bo->size/1024);
2086de2362d3Smrg    radeon_kms_update_vram_limit(pScrn, screen_size);
2087de2362d3Smrg    return TRUE;
2088de2362d3Smrg}
2089de2362d3Smrg
2090de2362d3Smrgvoid radeon_kms_update_vram_limit(ScrnInfoPtr pScrn, uint32_t new_fb_size)
2091de2362d3Smrg{
2092de2362d3Smrg    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
2093de2362d3Smrg    RADEONInfoPtr info = RADEONPTR(pScrn);
2094de2362d3Smrg    uint64_t remain_size_bytes;
2095de2362d3Smrg    int c;
2096de2362d3Smrg
2097de2362d3Smrg    for (c = 0; c < xf86_config->num_crtc; c++) {
2098de2362d3Smrg	if (info->cursor_bo[c] != NULL) {
2099de2362d3Smrg	    new_fb_size += (64 * 4 * 64);
2100de2362d3Smrg	}
2101de2362d3Smrg    }
2102de2362d3Smrg
2103de2362d3Smrg    remain_size_bytes = info->vram_size - new_fb_size;
2104de2362d3Smrg    remain_size_bytes = (remain_size_bytes / 10) * 9;
2105de2362d3Smrg    if (remain_size_bytes > 0xffffffff)
2106de2362d3Smrg	remain_size_bytes = 0xffffffff;
2107de2362d3Smrg    radeon_cs_set_limit(info->cs, RADEON_GEM_DOMAIN_VRAM,
2108de2362d3Smrg			(uint32_t)remain_size_bytes);
2109de2362d3Smrg
2110de2362d3Smrg    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VRAM usage limit set to %uK\n",
2111de2362d3Smrg	       (uint32_t)remain_size_bytes / 1024);
2112de2362d3Smrg}
2113de2362d3Smrg
2114de2362d3Smrg/* Used to disallow modes that are not supported by the hardware */
2115de2362d3SmrgModeStatus RADEONValidMode(SCRN_ARG_TYPE arg, DisplayModePtr mode,
2116de2362d3Smrg                           Bool verbose, int flag)
2117de2362d3Smrg{
2118de2362d3Smrg    SCRN_INFO_PTR(arg);
2119de2362d3Smrg    RADEONInfoPtr info = RADEONPTR(pScrn);
2120de2362d3Smrg    RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
2121de2362d3Smrg
2122de2362d3Smrg    /*
2123de2362d3Smrg     * RN50 has effective maximum mode bandwidth of about 300MiB/s.
2124de2362d3Smrg     * XXX should really do this for all chips by properly computing
2125de2362d3Smrg     * memory bandwidth and an overhead factor.
2126de2362d3Smrg    */
2127de2362d3Smrg    if (info->ChipFamily == CHIP_FAMILY_RV100 && !pRADEONEnt->HasCRTC2) {
2128de2362d3Smrg       if (xf86ModeBandwidth(mode, pScrn->bitsPerPixel) > 300)
2129de2362d3Smrg          return MODE_BANDWIDTH;
2130de2362d3Smrg    }
2131de2362d3Smrg    /* There are problems with double scan mode at high clocks
2132de2362d3Smrg     * They're likely related PLL and display buffer settings.
2133de2362d3Smrg     * Disable these modes for now.
2134de2362d3Smrg     */
2135de2362d3Smrg    if (mode->Flags & V_DBLSCAN) {
2136de2362d3Smrg       if ((mode->CrtcHDisplay >= 1024) || (mode->CrtcVDisplay >= 768))
2137de2362d3Smrg           return MODE_CLOCK_RANGE;
2138de2362d3Smrg   }
2139de2362d3Smrg    return MODE_OK;
2140de2362d3Smrg}
2141