radeon_kms.c revision 5f74fd6d
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"
35de2362d3Smrg#include "radeon_reg.h"
36de2362d3Smrg#include "radeon_probe.h"
37de2362d3Smrg#include "micmap.h"
38de2362d3Smrg
39de2362d3Smrg#include "radeon_version.h"
40de2362d3Smrg#include "shadow.h"
41de2362d3Smrg
42de2362d3Smrg#include "atipciids.h"
43de2362d3Smrg
44de2362d3Smrg/* DPMS */
45de2362d3Smrg#ifdef HAVE_XEXTPROTO_71
46de2362d3Smrg#include <X11/extensions/dpmsconst.h>
47de2362d3Smrg#else
48de2362d3Smrg#define DPMS_SERVER
49de2362d3Smrg#include <X11/extensions/dpms.h>
50de2362d3Smrg#endif
51de2362d3Smrg
52de2362d3Smrg#include "radeon_chipinfo_gen.h"
53de2362d3Smrg
54de2362d3Smrg#include "radeon_bo_gem.h"
55de2362d3Smrg#include "radeon_cs_gem.h"
56de2362d3Smrg#include "radeon_vbo.h"
57de2362d3Smrg
58de2362d3Smrgextern SymTabRec RADEONChipsets[];
59de2362d3Smrgstatic Bool radeon_setup_kernel_mem(ScreenPtr pScreen);
60de2362d3Smrg
61de2362d3Smrgconst OptionInfoRec RADEONOptions_KMS[] = {
62de2362d3Smrg    { OPTION_ACCEL,          "Accel",            OPTV_BOOLEAN, {0}, FALSE },
63de2362d3Smrg    { OPTION_SW_CURSOR,      "SWcursor",         OPTV_BOOLEAN, {0}, FALSE },
64de2362d3Smrg    { OPTION_PAGE_FLIP,      "EnablePageFlip",   OPTV_BOOLEAN, {0}, FALSE },
65de2362d3Smrg    { OPTION_COLOR_TILING,   "ColorTiling",      OPTV_BOOLEAN, {0}, FALSE },
66de2362d3Smrg    { OPTION_COLOR_TILING_2D,"ColorTiling2D",    OPTV_BOOLEAN, {0}, FALSE },
67de2362d3Smrg    { OPTION_RENDER_ACCEL,   "RenderAccel",      OPTV_BOOLEAN, {0}, FALSE },
68de2362d3Smrg    { OPTION_SUBPIXEL_ORDER, "SubPixelOrder",    OPTV_ANYSTR,  {0}, FALSE },
69de2362d3Smrg#ifdef USE_GLAMOR
70de2362d3Smrg    { OPTION_ACCELMETHOD,    "AccelMethod",      OPTV_STRING,  {0}, FALSE },
71de2362d3Smrg#endif
72de2362d3Smrg    { OPTION_EXA_VSYNC,      "EXAVSync",         OPTV_BOOLEAN, {0}, FALSE },
73de2362d3Smrg    { OPTION_EXA_PIXMAPS,    "EXAPixmaps",	 OPTV_BOOLEAN,   {0}, FALSE },
74de2362d3Smrg    { OPTION_ZAPHOD_HEADS,   "ZaphodHeads",      OPTV_STRING,  {0}, FALSE },
75de2362d3Smrg    { OPTION_PAGE_FLIP,      "EnablePageFlip",   OPTV_BOOLEAN, {0}, FALSE },
76de2362d3Smrg    { OPTION_SWAPBUFFERS_WAIT,"SwapbuffersWait", OPTV_BOOLEAN, {0}, FALSE },
77de2362d3Smrg    { -1,                    NULL,               OPTV_NONE,    {0}, FALSE }
78de2362d3Smrg};
79de2362d3Smrg
80de2362d3Smrgconst OptionInfoRec *RADEONOptionsWeak(void) { return RADEONOptions_KMS; }
81de2362d3Smrg
82de2362d3Smrgvoid radeon_cs_flush_indirect(ScrnInfoPtr pScrn)
83de2362d3Smrg{
84de2362d3Smrg    RADEONInfoPtr  info = RADEONPTR(pScrn);
85de2362d3Smrg    struct radeon_accel_state *accel_state = info->accel_state;
86de2362d3Smrg    int ret;
87de2362d3Smrg
88de2362d3Smrg    if (!info->cs->cdw)
89de2362d3Smrg	return;
90de2362d3Smrg
91de2362d3Smrg    /* release the current VBO so we don't block on mapping it later */
92de2362d3Smrg    if (info->accel_state->vbo.vb_offset && info->accel_state->vbo.vb_bo) {
93de2362d3Smrg        radeon_vbo_put(pScrn, &info->accel_state->vbo);
94de2362d3Smrg        info->accel_state->vbo.vb_start_op = -1;
95de2362d3Smrg    }
96de2362d3Smrg
97de2362d3Smrg    /* release the current VBO so we don't block on mapping it later */
98de2362d3Smrg    if (info->accel_state->cbuf.vb_bo) {
99de2362d3Smrg        radeon_vbo_put(pScrn, &info->accel_state->cbuf);
100de2362d3Smrg        info->accel_state->cbuf.vb_start_op = -1;
101de2362d3Smrg    }
102de2362d3Smrg
103de2362d3Smrg    radeon_cs_emit(info->cs);
104de2362d3Smrg    radeon_cs_erase(info->cs);
105de2362d3Smrg
106de2362d3Smrg    if (accel_state->use_vbos)
107de2362d3Smrg        radeon_vbo_flush_bos(pScrn);
108de2362d3Smrg
109de2362d3Smrg    ret = radeon_cs_space_check_with_bo(info->cs,
110de2362d3Smrg					accel_state->vbo.vb_bo,
111de2362d3Smrg					RADEON_GEM_DOMAIN_GTT, 0);
112de2362d3Smrg    if (ret)
113de2362d3Smrg      ErrorF("space check failed in flush\n");
114de2362d3Smrg
115de2362d3Smrg    if (info->reemit_current2d && info->state_2d.op)
116de2362d3Smrg        info->reemit_current2d(pScrn, info->state_2d.op);
117de2362d3Smrg
118de2362d3Smrg    if (info->dri2.enabled) {
119de2362d3Smrg        info->accel_state->XInited3D = FALSE;
120de2362d3Smrg        info->accel_state->engineMode = EXA_ENGINEMODE_UNKNOWN;
121de2362d3Smrg    }
122de2362d3Smrg
123de2362d3Smrg}
124de2362d3Smrg
125de2362d3Smrgvoid radeon_ddx_cs_start(ScrnInfoPtr pScrn,
126de2362d3Smrg			 int n, const char *file,
127de2362d3Smrg			 const char *func, int line)
128de2362d3Smrg{
129de2362d3Smrg    RADEONInfoPtr  info = RADEONPTR(pScrn);
130de2362d3Smrg
131de2362d3Smrg    if (info->cs->cdw + n > info->cs->ndw) {
132de2362d3Smrg	radeon_cs_flush_indirect(pScrn);
133de2362d3Smrg
134de2362d3Smrg    }
135de2362d3Smrg    radeon_cs_begin(info->cs, n, file, func, line);
136de2362d3Smrg}
137de2362d3Smrg
138de2362d3Smrg
139de2362d3Smrgextern _X_EXPORT int gRADEONEntityIndex;
140de2362d3Smrg
141de2362d3Smrgstatic int getRADEONEntityIndex(void)
142de2362d3Smrg{
143de2362d3Smrg    return gRADEONEntityIndex;
144de2362d3Smrg}
145de2362d3Smrg
146de2362d3Smrg
147de2362d3SmrgRADEONEntPtr RADEONEntPriv(ScrnInfoPtr pScrn)
148de2362d3Smrg{
149de2362d3Smrg    DevUnion     *pPriv;
150de2362d3Smrg    RADEONInfoPtr  info   = RADEONPTR(pScrn);
151de2362d3Smrg    pPriv = xf86GetEntityPrivate(info->pEnt->index,
152de2362d3Smrg                                 getRADEONEntityIndex());
153de2362d3Smrg    return pPriv->ptr;
154de2362d3Smrg}
155de2362d3Smrg
156de2362d3Smrg/* Allocate our private RADEONInfoRec */
157de2362d3Smrgstatic Bool RADEONGetRec(ScrnInfoPtr pScrn)
158de2362d3Smrg{
159de2362d3Smrg    if (pScrn->driverPrivate) return TRUE;
160de2362d3Smrg
161de2362d3Smrg    pScrn->driverPrivate = xnfcalloc(sizeof(RADEONInfoRec), 1);
162de2362d3Smrg    return TRUE;
163de2362d3Smrg}
164de2362d3Smrg
165de2362d3Smrg/* Free our private RADEONInfoRec */
166de2362d3Smrgstatic void RADEONFreeRec(ScrnInfoPtr pScrn)
167de2362d3Smrg{
168de2362d3Smrg    RADEONInfoPtr  info;
169de2362d3Smrg
170de2362d3Smrg    if (!pScrn || !pScrn->driverPrivate) return;
171de2362d3Smrg
172de2362d3Smrg    info = RADEONPTR(pScrn);
173de2362d3Smrg
174de2362d3Smrg    if (info->dri2.drm_fd > 0) {
175de2362d3Smrg        DevUnion *pPriv;
176de2362d3Smrg        RADEONEntPtr pRADEONEnt;
177de2362d3Smrg        pPriv = xf86GetEntityPrivate(pScrn->entityList[0],
178de2362d3Smrg				     getRADEONEntityIndex());
179de2362d3Smrg
180de2362d3Smrg        pRADEONEnt = pPriv->ptr;
181de2362d3Smrg        pRADEONEnt->fd_ref--;
182de2362d3Smrg        if (!pRADEONEnt->fd_ref) {
183de2362d3Smrg#ifdef XF86_PDEV_SERVER_FD
184de2362d3Smrg            if (!(pRADEONEnt->platform_dev &&
185de2362d3Smrg                    pRADEONEnt->platform_dev->flags & XF86_PDEV_SERVER_FD))
186de2362d3Smrg#endif
187de2362d3Smrg                drmClose(pRADEONEnt->fd);
188de2362d3Smrg            pRADEONEnt->fd = 0;
189de2362d3Smrg        }
190de2362d3Smrg    }
191de2362d3Smrg
192de2362d3Smrg    if (info->accel_state) {
193de2362d3Smrg	free(info->accel_state);
194de2362d3Smrg	info->accel_state = NULL;
195de2362d3Smrg    }
196de2362d3Smrg
197de2362d3Smrg    free(pScrn->driverPrivate);
198de2362d3Smrg    pScrn->driverPrivate = NULL;
199de2362d3Smrg}
200de2362d3Smrg
201de2362d3Smrgstatic void *
202de2362d3SmrgradeonShadowWindow(ScreenPtr screen, CARD32 row, CARD32 offset, int mode,
203de2362d3Smrg		   CARD32 *size, void *closure)
204de2362d3Smrg{
205de2362d3Smrg    ScrnInfoPtr pScrn = xf86ScreenToScrn(screen);
206de2362d3Smrg    RADEONInfoPtr  info   = RADEONPTR(pScrn);
207de2362d3Smrg    int stride;
208de2362d3Smrg
209de2362d3Smrg    stride = (pScrn->displayWidth * pScrn->bitsPerPixel) / 8;
210de2362d3Smrg    *size = stride;
211de2362d3Smrg
212de2362d3Smrg    return ((uint8_t *)info->front_bo->ptr + row * stride + offset);
213de2362d3Smrg}
214de2362d3Smrg
215de2362d3Smrgstatic void
216de2362d3SmrgradeonUpdatePacked(ScreenPtr pScreen, shadowBufPtr pBuf)
217de2362d3Smrg{
218de2362d3Smrg    shadowUpdatePacked(pScreen, pBuf);
219de2362d3Smrg}
220de2362d3Smrg
221de2362d3Smrgstatic Bool RADEONCreateScreenResources_KMS(ScreenPtr pScreen)
222de2362d3Smrg{
223de2362d3Smrg    ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
224de2362d3Smrg    RADEONInfoPtr  info   = RADEONPTR(pScrn);
225de2362d3Smrg    PixmapPtr pixmap;
226de2362d3Smrg    struct radeon_surface *surface;
227de2362d3Smrg
228de2362d3Smrg    pScreen->CreateScreenResources = info->CreateScreenResources;
229de2362d3Smrg    if (!(*pScreen->CreateScreenResources)(pScreen))
230de2362d3Smrg	return FALSE;
231de2362d3Smrg    pScreen->CreateScreenResources = RADEONCreateScreenResources_KMS;
232de2362d3Smrg
233de2362d3Smrg    if (!drmmode_set_desired_modes(pScrn, &info->drmmode))
234de2362d3Smrg	return FALSE;
235de2362d3Smrg
236de2362d3Smrg    drmmode_uevent_init(pScrn, &info->drmmode);
237de2362d3Smrg
238de2362d3Smrg    if (info->r600_shadow_fb) {
239de2362d3Smrg	pixmap = pScreen->GetScreenPixmap(pScreen);
240de2362d3Smrg
241de2362d3Smrg	if (!shadowAdd(pScreen, pixmap, radeonUpdatePacked,
242de2362d3Smrg		       radeonShadowWindow, 0, NULL))
243de2362d3Smrg	    return FALSE;
244de2362d3Smrg    }
245de2362d3Smrg
246de2362d3Smrg    if (info->dri2.enabled || info->use_glamor) {
247de2362d3Smrg	if (info->front_bo) {
248de2362d3Smrg	    PixmapPtr pPix = pScreen->GetScreenPixmap(pScreen);
249de2362d3Smrg	    radeon_set_pixmap_bo(pPix, info->front_bo);
250de2362d3Smrg	    surface = radeon_get_pixmap_surface(pPix);
251de2362d3Smrg	    if (surface) {
252de2362d3Smrg		*surface = info->front_surface;
253de2362d3Smrg	    }
254de2362d3Smrg	}
255de2362d3Smrg    }
256de2362d3Smrg
257de2362d3Smrg    if (info->use_glamor)
258de2362d3Smrg	radeon_glamor_create_screen_resources(pScreen);
259de2362d3Smrg
260de2362d3Smrg    return TRUE;
261de2362d3Smrg}
262de2362d3Smrg
263de2362d3Smrg#ifdef RADEON_PIXMAP_SHARING
264de2362d3Smrgstatic void
265de2362d3Smrgredisplay_dirty(ScreenPtr screen, PixmapDirtyUpdatePtr dirty)
266de2362d3Smrg{
267de2362d3Smrg	ScrnInfoPtr pScrn = xf86ScreenToScrn(screen);
268de2362d3Smrg	RegionRec pixregion;
269de2362d3Smrg
270de2362d3Smrg	PixmapRegionInit(&pixregion, dirty->slave_dst);
271de2362d3Smrg	DamageRegionAppend(&dirty->slave_dst->drawable, &pixregion);
2725f74fd6dSmrg#ifdef HAS_DIRTYTRACKING_ROTATION
2735f74fd6dSmrg	PixmapSyncDirtyHelper(dirty);
2745f74fd6dSmrg#else
275de2362d3Smrg	PixmapSyncDirtyHelper(dirty, &pixregion);
2765f74fd6dSmrg#endif
277de2362d3Smrg
278de2362d3Smrg	radeon_cs_flush_indirect(pScrn);
279de2362d3Smrg	DamageRegionProcessPending(&dirty->slave_dst->drawable);
280de2362d3Smrg	RegionUninit(&pixregion);
281de2362d3Smrg}
282de2362d3Smrg
283de2362d3Smrgstatic void
284de2362d3Smrgradeon_dirty_update(ScreenPtr screen)
285de2362d3Smrg{
286de2362d3Smrg	RegionPtr region;
287de2362d3Smrg	PixmapDirtyUpdatePtr ent;
288de2362d3Smrg
289de2362d3Smrg	if (xorg_list_is_empty(&screen->pixmap_dirty_list))
290de2362d3Smrg		return;
291de2362d3Smrg
292de2362d3Smrg	xorg_list_for_each_entry(ent, &screen->pixmap_dirty_list, ent) {
293de2362d3Smrg		region = DamageRegion(ent->damage);
294de2362d3Smrg		if (RegionNotEmpty(region)) {
295de2362d3Smrg			redisplay_dirty(screen, ent);
296de2362d3Smrg			DamageEmpty(ent->damage);
297de2362d3Smrg		}
298de2362d3Smrg	}
299de2362d3Smrg}
300de2362d3Smrg#endif
301de2362d3Smrg
302de2362d3Smrgstatic void RADEONBlockHandler_KMS(BLOCKHANDLER_ARGS_DECL)
303de2362d3Smrg{
304de2362d3Smrg    SCREEN_PTR(arg);
305de2362d3Smrg    ScrnInfoPtr    pScrn   = xf86ScreenToScrn(pScreen);
306de2362d3Smrg    RADEONInfoPtr  info    = RADEONPTR(pScrn);
307de2362d3Smrg
308de2362d3Smrg    pScreen->BlockHandler = info->BlockHandler;
309de2362d3Smrg    (*pScreen->BlockHandler) (BLOCKHANDLER_ARGS);
310de2362d3Smrg    pScreen->BlockHandler = RADEONBlockHandler_KMS;
311de2362d3Smrg
312de2362d3Smrg    if (info->use_glamor)
313de2362d3Smrg	radeon_glamor_flush(pScrn);
314de2362d3Smrg
315de2362d3Smrg    radeon_cs_flush_indirect(pScrn);
316de2362d3Smrg#ifdef RADEON_PIXMAP_SHARING
317de2362d3Smrg    radeon_dirty_update(pScreen);
318de2362d3Smrg#endif
319de2362d3Smrg}
320de2362d3Smrg
321de2362d3Smrgstatic void
322de2362d3Smrgradeon_flush_callback(CallbackListPtr *list,
323de2362d3Smrg		      pointer user_data, pointer call_data)
324de2362d3Smrg{
325de2362d3Smrg    ScrnInfoPtr pScrn = user_data;
326de2362d3Smrg
327de2362d3Smrg    if (pScrn->vtSema) {
328de2362d3Smrg        radeon_cs_flush_indirect(pScrn);
329de2362d3Smrg	radeon_glamor_flush(pScrn);
330de2362d3Smrg    }
331de2362d3Smrg}
332de2362d3Smrg
333de2362d3Smrgstatic Bool RADEONIsFastFBWorking(ScrnInfoPtr pScrn)
334de2362d3Smrg{
335de2362d3Smrg    RADEONInfoPtr info = RADEONPTR(pScrn);
336de2362d3Smrg    struct drm_radeon_info ginfo;
337de2362d3Smrg    int r;
338de2362d3Smrg    uint32_t tmp = 0;
339de2362d3Smrg
340de2362d3Smrg    memset(&ginfo, 0, sizeof(ginfo));
341de2362d3Smrg    ginfo.request = RADEON_INFO_FASTFB_WORKING;
342de2362d3Smrg    ginfo.value = (uintptr_t)&tmp;
343de2362d3Smrg    r = drmCommandWriteRead(info->dri2.drm_fd, DRM_RADEON_INFO, &ginfo, sizeof(ginfo));
344de2362d3Smrg    if (r) {
345de2362d3Smrg	return FALSE;
346de2362d3Smrg    }
347de2362d3Smrg    if (tmp == 1)
348de2362d3Smrg	return TRUE;
349de2362d3Smrg    return FALSE;
350de2362d3Smrg}
351de2362d3Smrg
352de2362d3Smrgstatic Bool RADEONIsFusionGARTWorking(ScrnInfoPtr pScrn)
353de2362d3Smrg{
354de2362d3Smrg    RADEONInfoPtr info = RADEONPTR(pScrn);
355de2362d3Smrg    struct drm_radeon_info ginfo;
356de2362d3Smrg    int r;
357de2362d3Smrg    uint32_t tmp;
358de2362d3Smrg
359de2362d3Smrg    memset(&ginfo, 0, sizeof(ginfo));
360de2362d3Smrg    ginfo.request = RADEON_INFO_FUSION_GART_WORKING;
361de2362d3Smrg    ginfo.value = (uintptr_t)&tmp;
362de2362d3Smrg    r = drmCommandWriteRead(info->dri2.drm_fd, DRM_RADEON_INFO, &ginfo, sizeof(ginfo));
363de2362d3Smrg    if (r) {
364de2362d3Smrg	return FALSE;
365de2362d3Smrg    }
366de2362d3Smrg    if (tmp == 1)
367de2362d3Smrg	return TRUE;
368de2362d3Smrg    return FALSE;
369de2362d3Smrg}
370de2362d3Smrg
371de2362d3Smrgstatic Bool RADEONIsAccelWorking(ScrnInfoPtr pScrn)
372de2362d3Smrg{
373de2362d3Smrg    RADEONInfoPtr info = RADEONPTR(pScrn);
374de2362d3Smrg    struct drm_radeon_info ginfo;
375de2362d3Smrg    int r;
376de2362d3Smrg    uint32_t tmp;
377de2362d3Smrg
378de2362d3Smrg    memset(&ginfo, 0, sizeof(ginfo));
379de2362d3Smrg    if (info->dri2.pKernelDRMVersion->version_minor >= 5)
380de2362d3Smrg	ginfo.request = RADEON_INFO_ACCEL_WORKING2;
381de2362d3Smrg    else
382de2362d3Smrg	ginfo.request = RADEON_INFO_ACCEL_WORKING;
383de2362d3Smrg    ginfo.value = (uintptr_t)&tmp;
384de2362d3Smrg    r = drmCommandWriteRead(info->dri2.drm_fd, DRM_RADEON_INFO, &ginfo, sizeof(ginfo));
385de2362d3Smrg    if (r) {
386de2362d3Smrg        /* If kernel is too old before 2.6.32 than assume accel is working */
387de2362d3Smrg        if (r == -EINVAL) {
388de2362d3Smrg            xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Kernel too old missing accel "
389de2362d3Smrg                       "information, assuming accel is working\n");
390de2362d3Smrg            return TRUE;
391de2362d3Smrg        }
392de2362d3Smrg        return FALSE;
393de2362d3Smrg    }
394de2362d3Smrg    if (info->ChipFamily == CHIP_FAMILY_HAWAII) {
395de2362d3Smrg        if (tmp == 2 || tmp == 3)
396de2362d3Smrg            return TRUE;
397de2362d3Smrg    } else if (tmp) {
398de2362d3Smrg        return TRUE;
399de2362d3Smrg    }
400de2362d3Smrg    return FALSE;
401de2362d3Smrg}
402de2362d3Smrg
403de2362d3Smrg/* This is called by RADEONPreInit to set up the default visual */
404de2362d3Smrgstatic Bool RADEONPreInitVisual(ScrnInfoPtr pScrn)
405de2362d3Smrg{
406de2362d3Smrg    RADEONInfoPtr  info = RADEONPTR(pScrn);
407de2362d3Smrg
408de2362d3Smrg    if (!xf86SetDepthBpp(pScrn, 0, 0, 0, Support32bppFb))
409de2362d3Smrg	return FALSE;
410de2362d3Smrg
411de2362d3Smrg    switch (pScrn->depth) {
412de2362d3Smrg    case 8:
413de2362d3Smrg    case 15:
414de2362d3Smrg    case 16:
415de2362d3Smrg    case 24:
416de2362d3Smrg	break;
417de2362d3Smrg
418de2362d3Smrg    default:
419de2362d3Smrg	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
420de2362d3Smrg		   "Given depth (%d) is not supported by %s driver\n",
421de2362d3Smrg		   pScrn->depth, RADEON_DRIVER_NAME);
422de2362d3Smrg	return FALSE;
423de2362d3Smrg    }
424de2362d3Smrg
425de2362d3Smrg    xf86PrintDepthBpp(pScrn);
426de2362d3Smrg
427de2362d3Smrg    info->pix24bpp                   = xf86GetBppFromDepth(pScrn,
428de2362d3Smrg							   pScrn->depth);
429de2362d3Smrg    info->pixel_bytes  = pScrn->bitsPerPixel / 8;
430de2362d3Smrg
431de2362d3Smrg    if (info->pix24bpp == 24) {
432de2362d3Smrg	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
433de2362d3Smrg		   "Radeon does NOT support 24bpp\n");
434de2362d3Smrg	return FALSE;
435de2362d3Smrg    }
436de2362d3Smrg
437de2362d3Smrg    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
438de2362d3Smrg	       "Pixel depth = %d bits stored in %d byte%s (%d bpp pixmaps)\n",
439de2362d3Smrg	       pScrn->depth,
440de2362d3Smrg	       info->pixel_bytes,
441de2362d3Smrg	       info->pixel_bytes > 1 ? "s" : "",
442de2362d3Smrg	       info->pix24bpp);
443de2362d3Smrg
444de2362d3Smrg    if (!xf86SetDefaultVisual(pScrn, -1)) return FALSE;
445de2362d3Smrg
446de2362d3Smrg    if (pScrn->depth > 8 && pScrn->defaultVisual != TrueColor) {
447de2362d3Smrg	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
448de2362d3Smrg		   "Default visual (%s) is not supported at depth %d\n",
449de2362d3Smrg		   xf86GetVisualName(pScrn->defaultVisual), pScrn->depth);
450de2362d3Smrg	return FALSE;
451de2362d3Smrg    }
452de2362d3Smrg    return TRUE;
453de2362d3Smrg}
454de2362d3Smrg
455de2362d3Smrg/* This is called by RADEONPreInit to handle all color weight issues */
456de2362d3Smrgstatic Bool RADEONPreInitWeight(ScrnInfoPtr pScrn)
457de2362d3Smrg{
458de2362d3Smrg    RADEONInfoPtr  info = RADEONPTR(pScrn);
459de2362d3Smrg
460de2362d3Smrg				/* Save flag for 6 bit DAC to use for
461de2362d3Smrg				   setting CRTC registers.  Otherwise use
462de2362d3Smrg				   an 8 bit DAC, even if xf86SetWeight sets
463de2362d3Smrg				   pScrn->rgbBits to some value other than
464de2362d3Smrg				   8. */
465de2362d3Smrg    info->dac6bits = FALSE;
466de2362d3Smrg
467de2362d3Smrg    if (pScrn->depth > 8) {
468de2362d3Smrg	rgb  defaultWeight = { 0, 0, 0 };
469de2362d3Smrg
470de2362d3Smrg	if (!xf86SetWeight(pScrn, defaultWeight, defaultWeight)) return FALSE;
471de2362d3Smrg    } else {
472de2362d3Smrg	pScrn->rgbBits = 8;
473de2362d3Smrg    }
474de2362d3Smrg
475de2362d3Smrg    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
476de2362d3Smrg	       "Using %d bits per RGB (%d bit DAC)\n",
477de2362d3Smrg	       pScrn->rgbBits, info->dac6bits ? 6 : 8);
478de2362d3Smrg
479de2362d3Smrg    return TRUE;
480de2362d3Smrg}
481de2362d3Smrg
482de2362d3Smrgstatic Bool RADEONPreInitAccel_KMS(ScrnInfoPtr pScrn)
483de2362d3Smrg{
484de2362d3Smrg    RADEONInfoPtr  info = RADEONPTR(pScrn);
485de2362d3Smrg
486de2362d3Smrg    if (!(info->accel_state = calloc(1, sizeof(struct radeon_accel_state)))) {
487de2362d3Smrg	xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Unable to allocate accel_state rec!\n");
488de2362d3Smrg	return FALSE;
489de2362d3Smrg    }
490de2362d3Smrg
491de2362d3Smrg    /* Check whether direct mapping is used for fast fb access*/
492de2362d3Smrg    if (RADEONIsFastFBWorking(pScrn)) {
493de2362d3Smrg	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Direct mapping of fb aperture is enabled for fast fb access.\n");
494de2362d3Smrg	info->is_fast_fb = TRUE;
495de2362d3Smrg    }
496de2362d3Smrg
497de2362d3Smrg    if (!xf86ReturnOptValBool(info->Options, OPTION_ACCEL, TRUE) ||
498de2362d3Smrg	(!RADEONIsAccelWorking(pScrn))) {
499de2362d3Smrg	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
500de2362d3Smrg		   "GPU accel disabled or not working, using shadowfb for KMS\n");
501de2362d3Smrgshadowfb:
502de2362d3Smrg	info->r600_shadow_fb = TRUE;
503de2362d3Smrg	if (!xf86LoadSubModule(pScrn, "shadow"))
504de2362d3Smrg	    info->r600_shadow_fb = FALSE;
505de2362d3Smrg	return TRUE;
506de2362d3Smrg    }
507de2362d3Smrg
508de2362d3Smrg#ifdef DRI2
509de2362d3Smrg    info->dri2.available = !!xf86LoadSubModule(pScrn, "dri2");
510de2362d3Smrg#endif
511de2362d3Smrg
512de2362d3Smrg    if (radeon_glamor_pre_init(pScrn))
513de2362d3Smrg	return TRUE;
514de2362d3Smrg
515de2362d3Smrg    if (info->ChipFamily >= CHIP_FAMILY_TAHITI) {
516de2362d3Smrg	goto shadowfb;
517de2362d3Smrg    } else if (info->ChipFamily == CHIP_FAMILY_PALM) {
518de2362d3Smrg	info->accel_state->allowHWDFS = RADEONIsFusionGARTWorking(pScrn);
519de2362d3Smrg    } else
520de2362d3Smrg	info->accel_state->allowHWDFS = TRUE;
521de2362d3Smrg
522de2362d3Smrg    if ((info->ChipFamily == CHIP_FAMILY_RS100) ||
523de2362d3Smrg	(info->ChipFamily == CHIP_FAMILY_RS200) ||
524de2362d3Smrg	(info->ChipFamily == CHIP_FAMILY_RS300) ||
525de2362d3Smrg	(info->ChipFamily == CHIP_FAMILY_RS400) ||
526de2362d3Smrg	(info->ChipFamily == CHIP_FAMILY_RS480) ||
527de2362d3Smrg	(info->ChipFamily == CHIP_FAMILY_RS600) ||
528de2362d3Smrg	(info->ChipFamily == CHIP_FAMILY_RS690) ||
529de2362d3Smrg	(info->ChipFamily == CHIP_FAMILY_RS740))
530de2362d3Smrg	info->accel_state->has_tcl = FALSE;
531de2362d3Smrg    else {
532de2362d3Smrg	info->accel_state->has_tcl = TRUE;
533de2362d3Smrg    }
534de2362d3Smrg
535de2362d3Smrg    {
536de2362d3Smrg	int errmaj = 0, errmin = 0;
537de2362d3Smrg	info->exaReq.majorversion = EXA_VERSION_MAJOR;
538de2362d3Smrg	info->exaReq.minorversion = EXA_VERSION_MINOR;
539de2362d3Smrg	if (!LoadSubModule(pScrn->module, "exa", NULL, NULL, NULL,
540de2362d3Smrg			   &info->exaReq, &errmaj, &errmin)) {
541de2362d3Smrg	    LoaderErrorMsg(NULL, "exa", errmaj, errmin);
542de2362d3Smrg	    return FALSE;
543de2362d3Smrg	}
544de2362d3Smrg    }
545de2362d3Smrg
546de2362d3Smrg    return TRUE;
547de2362d3Smrg}
548de2362d3Smrg
549de2362d3Smrgstatic Bool RADEONPreInitChipType_KMS(ScrnInfoPtr pScrn)
550de2362d3Smrg{
551de2362d3Smrg    RADEONInfoPtr  info   = RADEONPTR(pScrn);
552de2362d3Smrg    int i;
553de2362d3Smrg
554de2362d3Smrg    info->Chipset = PCI_DEV_DEVICE_ID(info->PciInfo);
555de2362d3Smrg    pScrn->chipset = (char *)xf86TokenToString(RADEONChipsets, info->Chipset);
556de2362d3Smrg    if (!pScrn->chipset) {
557de2362d3Smrg	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
558de2362d3Smrg		   "ChipID 0x%04x is not recognized\n", info->Chipset);
559de2362d3Smrg	return FALSE;
560de2362d3Smrg    }
561de2362d3Smrg
562de2362d3Smrg    if (info->Chipset < 0) {
563de2362d3Smrg	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
564de2362d3Smrg		   "Chipset \"%s\" is not recognized\n", pScrn->chipset);
565de2362d3Smrg	return FALSE;
566de2362d3Smrg    }
567de2362d3Smrg    xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
568de2362d3Smrg	       "Chipset: \"%s\" (ChipID = 0x%04x)\n",
569de2362d3Smrg	       pScrn->chipset,
570de2362d3Smrg	       info->Chipset);
571de2362d3Smrg
572de2362d3Smrg    for (i = 0; i < sizeof(RADEONCards) / sizeof(RADEONCardInfo); i++) {
573de2362d3Smrg	if (info->Chipset == RADEONCards[i].pci_device_id) {
574de2362d3Smrg	    RADEONCardInfo *card = &RADEONCards[i];
575de2362d3Smrg	    info->ChipFamily = card->chip_family;
576de2362d3Smrg	    break;
577de2362d3Smrg	}
578de2362d3Smrg    }
579de2362d3Smrg
580de2362d3Smrg#ifdef RENDER
581de2362d3Smrg    info->RenderAccel = xf86ReturnOptValBool(info->Options, OPTION_RENDER_ACCEL,
582de2362d3Smrg					     info->Chipset != PCI_CHIP_RN50_515E &&
583de2362d3Smrg					     info->Chipset != PCI_CHIP_RN50_5969);
584de2362d3Smrg#endif
585de2362d3Smrg    return TRUE;
586de2362d3Smrg}
587de2362d3Smrg
588de2362d3Smrgstatic int radeon_get_drm_master_fd(ScrnInfoPtr pScrn)
589de2362d3Smrg{
590de2362d3Smrg    RADEONInfoPtr  info   = RADEONPTR(pScrn);
591de2362d3Smrg#ifdef XF86_PDEV_SERVER_FD
592de2362d3Smrg    RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
593de2362d3Smrg#endif
594de2362d3Smrg    struct pci_device *dev = info->PciInfo;
595de2362d3Smrg    char *busid;
596de2362d3Smrg    int fd;
597de2362d3Smrg
598de2362d3Smrg#ifdef XF86_PDEV_SERVER_FD
599de2362d3Smrg    if (pRADEONEnt->platform_dev) {
600de2362d3Smrg        fd = xf86_get_platform_device_int_attrib(pRADEONEnt->platform_dev,
601de2362d3Smrg                                                 ODEV_ATTRIB_FD, -1);
602de2362d3Smrg        if (fd != -1)
603de2362d3Smrg            return fd;
604de2362d3Smrg    }
605de2362d3Smrg#endif
606de2362d3Smrg
607de2362d3Smrg#if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,9,99,901,0)
608de2362d3Smrg    XNFasprintf(&busid, "pci:%04x:%02x:%02x.%d",
609de2362d3Smrg                dev->domain, dev->bus, dev->dev, dev->func);
610de2362d3Smrg#else
611de2362d3Smrg    busid = XNFprintf("pci:%04x:%02x:%02x.%d",
612de2362d3Smrg		      dev->domain, dev->bus, dev->dev, dev->func);
613de2362d3Smrg#endif
614de2362d3Smrg
615de2362d3Smrg    fd = drmOpen(NULL, busid);
616de2362d3Smrg    if (fd == -1)
617de2362d3Smrg	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
618de2362d3Smrg		   "[drm] Failed to open DRM device for %s: %s\n",
619de2362d3Smrg		   busid, strerror(errno));
620de2362d3Smrg
621de2362d3Smrg    free(busid);
622de2362d3Smrg    return fd;
623de2362d3Smrg}
624de2362d3Smrg
625de2362d3Smrgstatic Bool radeon_open_drm_master(ScrnInfoPtr pScrn)
626de2362d3Smrg{
627de2362d3Smrg    RADEONInfoPtr  info   = RADEONPTR(pScrn);
628de2362d3Smrg    RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
629de2362d3Smrg    drmSetVersion sv;
630de2362d3Smrg    int err;
631de2362d3Smrg
632de2362d3Smrg    if (pRADEONEnt->fd) {
633de2362d3Smrg	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
634de2362d3Smrg		   " reusing fd for second head\n");
635de2362d3Smrg
636de2362d3Smrg	info->drmmode.fd = info->dri2.drm_fd = pRADEONEnt->fd;
637de2362d3Smrg	pRADEONEnt->fd_ref++;
638de2362d3Smrg        return TRUE;
639de2362d3Smrg    }
640de2362d3Smrg
641de2362d3Smrg    info->dri2.drm_fd = radeon_get_drm_master_fd(pScrn);
642de2362d3Smrg    if (info->dri2.drm_fd == -1)
643de2362d3Smrg	return FALSE;
644de2362d3Smrg
645de2362d3Smrg    /* Check that what we opened was a master or a master-capable FD,
646de2362d3Smrg     * by setting the version of the interface we'll use to talk to it.
647de2362d3Smrg     * (see DRIOpenDRMMaster() in DRI1)
648de2362d3Smrg     */
649de2362d3Smrg    sv.drm_di_major = 1;
650de2362d3Smrg    sv.drm_di_minor = 1;
651de2362d3Smrg    sv.drm_dd_major = -1;
652de2362d3Smrg    sv.drm_dd_minor = -1;
653de2362d3Smrg    err = drmSetInterfaceVersion(info->dri2.drm_fd, &sv);
654de2362d3Smrg    if (err != 0) {
655de2362d3Smrg	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
656de2362d3Smrg		   "[drm] failed to set drm interface version.\n");
657de2362d3Smrg	drmClose(info->dri2.drm_fd);
658de2362d3Smrg	info->dri2.drm_fd = -1;
659de2362d3Smrg
660de2362d3Smrg	return FALSE;
661de2362d3Smrg    }
662de2362d3Smrg
663de2362d3Smrg    pRADEONEnt->fd = info->dri2.drm_fd;
664de2362d3Smrg    pRADEONEnt->fd_ref = 1;
665de2362d3Smrg    info->drmmode.fd = info->dri2.drm_fd;
666de2362d3Smrg    return TRUE;
667de2362d3Smrg}
668de2362d3Smrg
669de2362d3Smrgstatic Bool r600_get_tile_config(ScrnInfoPtr pScrn)
670de2362d3Smrg{
671de2362d3Smrg    RADEONInfoPtr  info   = RADEONPTR(pScrn);
672de2362d3Smrg    struct drm_radeon_info ginfo;
673de2362d3Smrg    int r;
674de2362d3Smrg    uint32_t tmp;
675de2362d3Smrg
676de2362d3Smrg    if (info->ChipFamily < CHIP_FAMILY_R600)
677de2362d3Smrg	return FALSE;
678de2362d3Smrg
679de2362d3Smrg    memset(&ginfo, 0, sizeof(ginfo));
680de2362d3Smrg    ginfo.request = RADEON_INFO_TILING_CONFIG;
681de2362d3Smrg    ginfo.value = (uintptr_t)&tmp;
682de2362d3Smrg    r = drmCommandWriteRead(info->dri2.drm_fd, DRM_RADEON_INFO, &ginfo, sizeof(ginfo));
683de2362d3Smrg    if (r)
684de2362d3Smrg	return FALSE;
685de2362d3Smrg
686de2362d3Smrg    info->tile_config = tmp;
687de2362d3Smrg    info->r7xx_bank_op = 0;
688de2362d3Smrg    if (info->ChipFamily >= CHIP_FAMILY_CEDAR) {
689de2362d3Smrg	if (info->dri2.pKernelDRMVersion->version_minor >= 7) {
690de2362d3Smrg	    switch (info->tile_config & 0xf) {
691de2362d3Smrg	    case 0:
692de2362d3Smrg                info->num_channels = 1;
693de2362d3Smrg                break;
694de2362d3Smrg	    case 1:
695de2362d3Smrg                info->num_channels = 2;
696de2362d3Smrg                break;
697de2362d3Smrg	    case 2:
698de2362d3Smrg                info->num_channels = 4;
699de2362d3Smrg                break;
700de2362d3Smrg	    case 3:
701de2362d3Smrg                info->num_channels = 8;
702de2362d3Smrg                break;
703de2362d3Smrg	    default:
704de2362d3Smrg                return FALSE;
705de2362d3Smrg	    }
706de2362d3Smrg
707de2362d3Smrg	    switch((info->tile_config & 0xf0) >> 4) {
708de2362d3Smrg	    case 0:
709de2362d3Smrg		info->num_banks = 4;
710de2362d3Smrg		break;
711de2362d3Smrg	    case 1:
712de2362d3Smrg		info->num_banks = 8;
713de2362d3Smrg		break;
714de2362d3Smrg	    case 2:
715de2362d3Smrg		info->num_banks = 16;
716de2362d3Smrg		break;
717de2362d3Smrg	    default:
718de2362d3Smrg		return FALSE;
719de2362d3Smrg	    }
720de2362d3Smrg
721de2362d3Smrg	    switch ((info->tile_config & 0xf00) >> 8) {
722de2362d3Smrg	    case 0:
723de2362d3Smrg                info->group_bytes = 256;
724de2362d3Smrg                break;
725de2362d3Smrg	    case 1:
726de2362d3Smrg                info->group_bytes = 512;
727de2362d3Smrg                break;
728de2362d3Smrg	    default:
729de2362d3Smrg                return FALSE;
730de2362d3Smrg	    }
731de2362d3Smrg	} else
732de2362d3Smrg	    return FALSE;
733de2362d3Smrg    } else {
734de2362d3Smrg	switch((info->tile_config & 0xe) >> 1) {
735de2362d3Smrg	case 0:
736de2362d3Smrg	    info->num_channels = 1;
737de2362d3Smrg	    break;
738de2362d3Smrg	case 1:
739de2362d3Smrg	    info->num_channels = 2;
740de2362d3Smrg	    break;
741de2362d3Smrg	case 2:
742de2362d3Smrg	    info->num_channels = 4;
743de2362d3Smrg	    break;
744de2362d3Smrg	case 3:
745de2362d3Smrg	    info->num_channels = 8;
746de2362d3Smrg	    break;
747de2362d3Smrg	default:
748de2362d3Smrg	    return FALSE;
749de2362d3Smrg	}
750de2362d3Smrg	switch((info->tile_config & 0x30) >> 4) {
751de2362d3Smrg	case 0:
752de2362d3Smrg	    info->num_banks = 4;
753de2362d3Smrg	    break;
754de2362d3Smrg	case 1:
755de2362d3Smrg	    info->num_banks = 8;
756de2362d3Smrg	    break;
757de2362d3Smrg	default:
758de2362d3Smrg	    return FALSE;
759de2362d3Smrg	}
760de2362d3Smrg	switch((info->tile_config & 0xc0) >> 6) {
761de2362d3Smrg	case 0:
762de2362d3Smrg	    info->group_bytes = 256;
763de2362d3Smrg	    break;
764de2362d3Smrg	case 1:
765de2362d3Smrg	    info->group_bytes = 512;
766de2362d3Smrg	    break;
767de2362d3Smrg	default:
768de2362d3Smrg	    return FALSE;
769de2362d3Smrg	}
770de2362d3Smrg    }
771de2362d3Smrg
772de2362d3Smrg    info->have_tiling_info = TRUE;
773de2362d3Smrg    return TRUE;
774de2362d3Smrg}
775de2362d3Smrg
776de2362d3Smrgstatic void RADEONSetupCapabilities(ScrnInfoPtr pScrn)
777de2362d3Smrg{
778de2362d3Smrg#ifdef RADEON_PIXMAP_SHARING
779de2362d3Smrg    RADEONInfoPtr  info = RADEONPTR(pScrn);
780de2362d3Smrg    uint64_t value;
781de2362d3Smrg    int ret;
782de2362d3Smrg
783de2362d3Smrg    pScrn->capabilities = 0;
784de2362d3Smrg    ret = drmGetCap(info->dri2.drm_fd, DRM_CAP_PRIME, &value);
785de2362d3Smrg    if (ret == 0) {
786de2362d3Smrg	if (value & DRM_PRIME_CAP_EXPORT)
787de2362d3Smrg	    pScrn->capabilities |= RR_Capability_SourceOutput | RR_Capability_SinkOffload;
788de2362d3Smrg	if (value & DRM_PRIME_CAP_IMPORT)
789de2362d3Smrg	    pScrn->capabilities |= RR_Capability_SourceOffload | RR_Capability_SinkOutput;
790de2362d3Smrg    }
791de2362d3Smrg#endif
792de2362d3Smrg}
793de2362d3Smrg
794de2362d3SmrgBool RADEONPreInit_KMS(ScrnInfoPtr pScrn, int flags)
795de2362d3Smrg{
796de2362d3Smrg    RADEONInfoPtr     info;
797de2362d3Smrg    RADEONEntPtr pRADEONEnt;
798de2362d3Smrg    DevUnion* pPriv;
799de2362d3Smrg    Gamma  zeros = { 0.0, 0.0, 0.0 };
800de2362d3Smrg    uint32_t tiling = 0;
801de2362d3Smrg    int cpp;
802de2362d3Smrg
803de2362d3Smrg    if (flags & PROBE_DETECT)
804de2362d3Smrg        return TRUE;
805de2362d3Smrg
806de2362d3Smrg    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
807de2362d3Smrg		   "RADEONPreInit_KMS\n");
808de2362d3Smrg    if (pScrn->numEntities != 1) return FALSE;
809de2362d3Smrg    if (!RADEONGetRec(pScrn)) return FALSE;
810de2362d3Smrg
811de2362d3Smrg    info               = RADEONPTR(pScrn);
812de2362d3Smrg    info->IsSecondary  = FALSE;
813de2362d3Smrg    info->IsPrimary = FALSE;
814de2362d3Smrg    info->pEnt         = xf86GetEntityInfo(pScrn->entityList[pScrn->numEntities - 1]);
815de2362d3Smrg    if (info->pEnt->location.type != BUS_PCI
816de2362d3Smrg#ifdef XSERVER_PLATFORM_BUS
817de2362d3Smrg        && info->pEnt->location.type != BUS_PLATFORM
818de2362d3Smrg#endif
819de2362d3Smrg        )
820de2362d3Smrg        goto fail;
821de2362d3Smrg
822de2362d3Smrg    pPriv = xf86GetEntityPrivate(pScrn->entityList[0],
823de2362d3Smrg				 getRADEONEntityIndex());
824de2362d3Smrg    pRADEONEnt = pPriv->ptr;
825de2362d3Smrg
826de2362d3Smrg    if(xf86IsEntityShared(pScrn->entityList[0]))
827de2362d3Smrg    {
828de2362d3Smrg        if(xf86IsPrimInitDone(pScrn->entityList[0]))
829de2362d3Smrg        {
830de2362d3Smrg            info->IsSecondary = TRUE;
831de2362d3Smrg            pRADEONEnt->pSecondaryScrn = pScrn;
832de2362d3Smrg        }
833de2362d3Smrg        else
834de2362d3Smrg        {
835de2362d3Smrg	    info->IsPrimary = TRUE;
836de2362d3Smrg            xf86SetPrimInitDone(pScrn->entityList[0]);
837de2362d3Smrg            pRADEONEnt->pPrimaryScrn = pScrn;
838de2362d3Smrg            pRADEONEnt->HasSecondary = FALSE;
839de2362d3Smrg        }
840de2362d3Smrg    }
841de2362d3Smrg
842de2362d3Smrg    info->PciInfo = xf86GetPciInfoForEntity(info->pEnt->index);
843de2362d3Smrg    pScrn->monitor     = pScrn->confScreen->monitor;
844de2362d3Smrg
845de2362d3Smrg    if (!RADEONPreInitVisual(pScrn))
846de2362d3Smrg	goto fail;
847de2362d3Smrg
848de2362d3Smrg    xf86CollectOptions(pScrn, NULL);
849de2362d3Smrg    if (!(info->Options = malloc(sizeof(RADEONOptions_KMS))))
850de2362d3Smrg	goto fail;
851de2362d3Smrg
852de2362d3Smrg    memcpy(info->Options, RADEONOptions_KMS, sizeof(RADEONOptions_KMS));
853de2362d3Smrg    xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, info->Options);
854de2362d3Smrg
855de2362d3Smrg    if (!RADEONPreInitWeight(pScrn))
856de2362d3Smrg	goto fail;
857de2362d3Smrg
858de2362d3Smrg    if (!RADEONPreInitChipType_KMS(pScrn))
859de2362d3Smrg        goto fail;
860de2362d3Smrg
861de2362d3Smrg    if (radeon_open_drm_master(pScrn) == FALSE) {
862de2362d3Smrg	xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Kernel modesetting setup failed\n");
863de2362d3Smrg	goto fail;
864de2362d3Smrg    }
865de2362d3Smrg
866de2362d3Smrg    info->dri2.available = FALSE;
867de2362d3Smrg    info->dri2.enabled = FALSE;
868de2362d3Smrg    info->dri2.pKernelDRMVersion = drmGetVersion(info->dri2.drm_fd);
869de2362d3Smrg    if (info->dri2.pKernelDRMVersion == NULL) {
870de2362d3Smrg	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
871de2362d3Smrg		   "RADEONDRIGetVersion failed to get the DRM version\n");
872de2362d3Smrg	goto fail;
873de2362d3Smrg    }
874de2362d3Smrg
875de2362d3Smrg    if (!RADEONPreInitAccel_KMS(pScrn))              goto fail;
876de2362d3Smrg
877de2362d3Smrg    info->allowColorTiling2D = FALSE;
878de2362d3Smrg
879de2362d3Smrg    RADEONSetupCapabilities(pScrn);
880de2362d3Smrg
881de2362d3Smrg    /* don't enable tiling if accel is not enabled */
882de2362d3Smrg    if (!info->r600_shadow_fb) {
883de2362d3Smrg	Bool colorTilingDefault =
884de2362d3Smrg	    xorgGetVersion() >= XORG_VERSION_NUMERIC(1,9,4,901,0) &&
885de2362d3Smrg	    info->ChipFamily >= CHIP_FAMILY_R300 &&
886de2362d3Smrg	    /* this check could be removed sometime after a big mesa release
887de2362d3Smrg	     * with proper bit, in the meantime you need to set tiling option in
888de2362d3Smrg	     * xorg configuration files
889de2362d3Smrg	     */
890de2362d3Smrg	    info->ChipFamily <= CHIP_FAMILY_MULLINS &&
891de2362d3Smrg	    !info->is_fast_fb;
892de2362d3Smrg
893de2362d3Smrg	/* 2D color tiling */
894de2362d3Smrg	if (info->ChipFamily >= CHIP_FAMILY_R600) {
895de2362d3Smrg		info->allowColorTiling2D = xf86ReturnOptValBool(info->Options, OPTION_COLOR_TILING_2D,
896de2362d3Smrg                                                                info->ChipFamily <= CHIP_FAMILY_MULLINS);
897de2362d3Smrg	}
898de2362d3Smrg
899de2362d3Smrg	if (info->ChipFamily >= CHIP_FAMILY_R600) {
900de2362d3Smrg	    /* set default group bytes, overridden by kernel info below */
901de2362d3Smrg	    info->group_bytes = 256;
902de2362d3Smrg	    info->have_tiling_info = FALSE;
903de2362d3Smrg	    if (info->dri2.pKernelDRMVersion->version_minor >= 6) {
904de2362d3Smrg		if (r600_get_tile_config(pScrn)) {
905de2362d3Smrg		    info->allowColorTiling = xf86ReturnOptValBool(info->Options,
906de2362d3Smrg								  OPTION_COLOR_TILING, colorTilingDefault);
907de2362d3Smrg		    /* need working DFS for tiling */
908de2362d3Smrg		    if ((info->ChipFamily == CHIP_FAMILY_PALM) &&
909de2362d3Smrg			(!info->accel_state->allowHWDFS))
910de2362d3Smrg			info->allowColorTiling = FALSE;
911de2362d3Smrg		} else
912de2362d3Smrg		    info->allowColorTiling = FALSE;
913de2362d3Smrg	    } else
914de2362d3Smrg		xf86DrvMsg(pScrn->scrnIndex, X_INFO,
915de2362d3Smrg			   "R6xx+ KMS Color Tiling requires radeon drm 2.6.0 or newer\n");
916de2362d3Smrg	} else
917de2362d3Smrg	    info->allowColorTiling = xf86ReturnOptValBool(info->Options,
918de2362d3Smrg							  OPTION_COLOR_TILING, colorTilingDefault);
919de2362d3Smrg    } else
920de2362d3Smrg	info->allowColorTiling = FALSE;
921de2362d3Smrg
922de2362d3Smrg    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
923de2362d3Smrg	 "KMS Color Tiling: %sabled\n", info->allowColorTiling ? "en" : "dis");
924de2362d3Smrg    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
925de2362d3Smrg	 "KMS Color Tiling 2D: %sabled\n", info->allowColorTiling2D ? "en" : "dis");
926de2362d3Smrg
927de2362d3Smrg    if (info->dri2.pKernelDRMVersion->version_minor >= 8) {
928de2362d3Smrg	info->allowPageFlip = xf86ReturnOptValBool(info->Options,
929de2362d3Smrg						   OPTION_PAGE_FLIP, TRUE);
930de2362d3Smrg	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
931de2362d3Smrg		   "KMS Pageflipping: %sabled\n", info->allowPageFlip ? "en" : "dis");
932de2362d3Smrg    }
933de2362d3Smrg
934de2362d3Smrg    info->swapBuffersWait = xf86ReturnOptValBool(info->Options,
935de2362d3Smrg						 OPTION_SWAPBUFFERS_WAIT, TRUE);
936de2362d3Smrg    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
937de2362d3Smrg	       "SwapBuffers wait for vsync: %sabled\n", info->swapBuffersWait ? "en" : "dis");
938de2362d3Smrg
939de2362d3Smrg    if (drmmode_pre_init(pScrn, &info->drmmode, pScrn->bitsPerPixel / 8) == FALSE) {
940de2362d3Smrg	xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Kernel modesetting setup failed\n");
941de2362d3Smrg	goto fail;
942de2362d3Smrg    }
943de2362d3Smrg
944de2362d3Smrg    if (info->drmmode.mode_res->count_crtcs == 1)
945de2362d3Smrg        pRADEONEnt->HasCRTC2 = FALSE;
946de2362d3Smrg    else
947de2362d3Smrg        pRADEONEnt->HasCRTC2 = TRUE;
948de2362d3Smrg
949de2362d3Smrg
950de2362d3Smrg    /* fix up cloning on rn50 cards
951de2362d3Smrg     * since they only have one crtc sometimes the xserver doesn't assign
952de2362d3Smrg     * a crtc to one of the outputs even though both outputs have common modes
953de2362d3Smrg     * which results in only one monitor being enabled.  Assign a crtc here so
954de2362d3Smrg     * that both outputs light up.
955de2362d3Smrg     */
956de2362d3Smrg    if (info->ChipFamily == CHIP_FAMILY_RV100 && !pRADEONEnt->HasCRTC2) {
957de2362d3Smrg	xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
958de2362d3Smrg	int i;
959de2362d3Smrg
960de2362d3Smrg	for (i = 0; i < xf86_config->num_output; i++) {
961de2362d3Smrg	    xf86OutputPtr output = xf86_config->output[i];
962de2362d3Smrg
963de2362d3Smrg	    /* XXX: double check crtc mode */
964de2362d3Smrg	    if ((output->probed_modes != NULL) && (output->crtc == NULL))
965de2362d3Smrg		output->crtc = xf86_config->crtc[0];
966de2362d3Smrg	}
967de2362d3Smrg    }
968de2362d3Smrg
969de2362d3Smrg    /* set cursor size */
970de2362d3Smrg    if (info->ChipFamily >= CHIP_FAMILY_BONAIRE) {
971de2362d3Smrg	info->cursor_w = CURSOR_WIDTH_CIK;
972de2362d3Smrg	info->cursor_h = CURSOR_HEIGHT_CIK;
973de2362d3Smrg    } else {
974de2362d3Smrg	info->cursor_w = CURSOR_WIDTH;
975de2362d3Smrg	info->cursor_h = CURSOR_HEIGHT;
976de2362d3Smrg    }
977de2362d3Smrg
978de2362d3Smrg    {
979de2362d3Smrg	struct drm_radeon_gem_info mminfo;
980de2362d3Smrg
981de2362d3Smrg	if (!drmCommandWriteRead(info->dri2.drm_fd, DRM_RADEON_GEM_INFO, &mminfo, sizeof(mminfo)))
982de2362d3Smrg	{
983de2362d3Smrg	    info->vram_size = mminfo.vram_visible;
984de2362d3Smrg	    info->gart_size = mminfo.gart_size;
985de2362d3Smrg	    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
986de2362d3Smrg		       "mem size init: gart size :%llx vram size: s:%llx visible:%llx\n",
987de2362d3Smrg		       (unsigned long long)mminfo.gart_size,
988de2362d3Smrg		       (unsigned long long)mminfo.vram_size,
989de2362d3Smrg		       (unsigned long long)mminfo.vram_visible);
990de2362d3Smrg	}
991de2362d3Smrg    }
992de2362d3Smrg
993de2362d3Smrg    if (!info->use_glamor) {
994de2362d3Smrg	info->exa_pixmaps = xf86ReturnOptValBool(info->Options,
995de2362d3Smrg						 OPTION_EXA_PIXMAPS,
996de2362d3Smrg						 (info->vram_size > (32 * 1024 * 1024) &&
997de2362d3Smrg						 info->RenderAccel &&
998de2362d3Smrg                                                 !info->is_fast_fb));
999de2362d3Smrg	if (info->exa_pixmaps)
1000de2362d3Smrg	    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
1001de2362d3Smrg		       "EXA: Driver will allow EXA pixmaps in VRAM\n");
1002de2362d3Smrg	else
1003de2362d3Smrg	    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
1004de2362d3Smrg		       "EXA: Driver will not allow EXA pixmaps in VRAM\n");
1005de2362d3Smrg    }
1006de2362d3Smrg
1007de2362d3Smrg    /* no tiled scanout on r6xx+ yet */
1008de2362d3Smrg    if (info->allowColorTiling) {
1009de2362d3Smrg	if (info->ChipFamily >= CHIP_FAMILY_R600)
1010de2362d3Smrg	    tiling |= RADEON_TILING_MICRO;
1011de2362d3Smrg	else
1012de2362d3Smrg	    tiling |= RADEON_TILING_MACRO;
1013de2362d3Smrg    }
1014de2362d3Smrg    cpp = pScrn->bitsPerPixel / 8;
1015de2362d3Smrg    pScrn->displayWidth =
1016de2362d3Smrg	RADEON_ALIGN(pScrn->virtualX, drmmode_get_pitch_align(pScrn, cpp, tiling));
1017de2362d3Smrg
1018de2362d3Smrg    /* Set display resolution */
1019de2362d3Smrg    xf86SetDpi(pScrn, 0, 0);
1020de2362d3Smrg
1021de2362d3Smrg	/* Get ScreenInit function */
1022de2362d3Smrg    if (!xf86LoadSubModule(pScrn, "fb")) return FALSE;
1023de2362d3Smrg
1024de2362d3Smrg    if (!xf86SetGamma(pScrn, zeros)) return FALSE;
1025de2362d3Smrg
1026de2362d3Smrg    if (!xf86ReturnOptValBool(info->Options, OPTION_SW_CURSOR, FALSE)) {
1027de2362d3Smrg	if (!xf86LoadSubModule(pScrn, "ramdac")) return FALSE;
1028de2362d3Smrg    }
1029de2362d3Smrg
1030de2362d3Smrg    if (pScrn->modes == NULL
1031de2362d3Smrg#ifdef XSERVER_PLATFORM_BUS
1032de2362d3Smrg        && !pScrn->is_gpu
1033de2362d3Smrg#endif
1034de2362d3Smrg        ) {
1035de2362d3Smrg      xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No modes.\n");
1036de2362d3Smrg      goto fail;
1037de2362d3Smrg   }
1038de2362d3Smrg
1039de2362d3Smrg    return TRUE;
1040de2362d3Smrg fail:
1041de2362d3Smrg    RADEONFreeRec(pScrn);
1042de2362d3Smrg    return FALSE;
1043de2362d3Smrg
1044de2362d3Smrg}
1045de2362d3Smrg
1046de2362d3Smrgstatic Bool RADEONCursorInit_KMS(ScreenPtr pScreen)
1047de2362d3Smrg{
1048de2362d3Smrg    ScrnInfoPtr    pScrn = xf86ScreenToScrn(pScreen);
1049de2362d3Smrg    RADEONInfoPtr  info  = RADEONPTR(pScrn);
1050de2362d3Smrg
1051de2362d3Smrg    return xf86_cursors_init (pScreen, info->cursor_w, info->cursor_h,
1052de2362d3Smrg			      (HARDWARE_CURSOR_TRUECOLOR_AT_8BPP |
1053de2362d3Smrg			       HARDWARE_CURSOR_AND_SOURCE_WITH_MASK |
1054de2362d3Smrg			       HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_1 |
1055de2362d3Smrg			       HARDWARE_CURSOR_UPDATE_UNHIDDEN |
1056de2362d3Smrg			       HARDWARE_CURSOR_ARGB));
1057de2362d3Smrg}
1058de2362d3Smrg
1059de2362d3Smrgvoid
1060de2362d3SmrgRADEONBlank(ScrnInfoPtr pScrn)
1061de2362d3Smrg{
1062de2362d3Smrg    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
1063de2362d3Smrg    xf86OutputPtr output;
1064de2362d3Smrg    xf86CrtcPtr crtc;
1065de2362d3Smrg    int o, c;
1066de2362d3Smrg
1067de2362d3Smrg    for (c = 0; c < xf86_config->num_crtc; c++) {
1068de2362d3Smrg       crtc = xf86_config->crtc[c];
1069de2362d3Smrg       for (o = 0; o < xf86_config->num_output; o++) {
1070de2362d3Smrg           output = xf86_config->output[o];
1071de2362d3Smrg           if (output->crtc != crtc)
1072de2362d3Smrg               continue;
1073de2362d3Smrg
1074de2362d3Smrg           output->funcs->dpms(output, DPMSModeOff);
1075de2362d3Smrg       }
1076de2362d3Smrg      crtc->funcs->dpms(crtc, DPMSModeOff);
1077de2362d3Smrg    }
1078de2362d3Smrg}
1079de2362d3Smrg
1080de2362d3Smrgvoid
1081de2362d3SmrgRADEONUnblank(ScrnInfoPtr pScrn)
1082de2362d3Smrg{
1083de2362d3Smrg    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
1084de2362d3Smrg    xf86OutputPtr output;
1085de2362d3Smrg    xf86CrtcPtr crtc;
1086de2362d3Smrg    int o, c;
1087de2362d3Smrg    for (c = 0; c < xf86_config->num_crtc; c++) {
1088de2362d3Smrg       crtc = xf86_config->crtc[c];
1089de2362d3Smrg       if(!crtc->enabled)
1090de2362d3Smrg              continue;
1091de2362d3Smrg       crtc->funcs->dpms(crtc, DPMSModeOn);
1092de2362d3Smrg       for (o = 0; o < xf86_config->num_output; o++) {
1093de2362d3Smrg           output = xf86_config->output[o];
1094de2362d3Smrg           if (output->crtc != crtc)
1095de2362d3Smrg               continue;
1096de2362d3Smrg           output->funcs->dpms(output, DPMSModeOn);
1097de2362d3Smrg       }
1098de2362d3Smrg    }
1099de2362d3Smrg}
1100de2362d3Smrg
1101de2362d3Smrg
1102de2362d3Smrgstatic Bool RADEONSaveScreen_KMS(ScreenPtr pScreen, int mode)
1103de2362d3Smrg{
1104de2362d3Smrg    ScrnInfoPtr  pScrn = xf86ScreenToScrn(pScreen);
1105de2362d3Smrg    Bool         unblank;
1106de2362d3Smrg
1107de2362d3Smrg    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
1108de2362d3Smrg		   "RADEONSaveScreen(%d)\n", mode);
1109de2362d3Smrg
1110de2362d3Smrg    unblank = xf86IsUnblank(mode);
1111de2362d3Smrg    if (unblank) SetTimeSinceLastInputEvent();
1112de2362d3Smrg
1113de2362d3Smrg    if ((pScrn != NULL) && pScrn->vtSema) {
1114de2362d3Smrg	if (unblank)
1115de2362d3Smrg	    RADEONUnblank(pScrn);
1116de2362d3Smrg	else
1117de2362d3Smrg	    RADEONBlank(pScrn);
1118de2362d3Smrg    }
1119de2362d3Smrg    return TRUE;
1120de2362d3Smrg}
1121de2362d3Smrg
1122de2362d3Smrgstatic Bool radeon_set_drm_master(ScrnInfoPtr pScrn)
1123de2362d3Smrg{
1124de2362d3Smrg    RADEONInfoPtr  info  = RADEONPTR(pScrn);
1125de2362d3Smrg#ifdef XF86_PDEV_SERVER_FD
1126de2362d3Smrg    RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
1127de2362d3Smrg#endif
1128de2362d3Smrg    int err;
1129de2362d3Smrg
1130de2362d3Smrg#ifdef XF86_PDEV_SERVER_FD
1131de2362d3Smrg    if (pRADEONEnt->platform_dev &&
1132de2362d3Smrg            (pRADEONEnt->platform_dev->flags & XF86_PDEV_SERVER_FD))
1133de2362d3Smrg        return TRUE;
1134de2362d3Smrg#endif
1135de2362d3Smrg
1136de2362d3Smrg    err = drmSetMaster(info->dri2.drm_fd);
1137de2362d3Smrg    if (err)
1138de2362d3Smrg        ErrorF("Unable to retrieve master\n");
1139de2362d3Smrg
1140de2362d3Smrg    return err == 0;
1141de2362d3Smrg}
1142de2362d3Smrg
1143de2362d3Smrgstatic void radeon_drop_drm_master(ScrnInfoPtr pScrn)
1144de2362d3Smrg{
1145de2362d3Smrg    RADEONInfoPtr  info  = RADEONPTR(pScrn);
1146de2362d3Smrg#ifdef XF86_PDEV_SERVER_FD
1147de2362d3Smrg    RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
1148de2362d3Smrg
1149de2362d3Smrg    if (pRADEONEnt->platform_dev &&
1150de2362d3Smrg            (pRADEONEnt->platform_dev->flags & XF86_PDEV_SERVER_FD))
1151de2362d3Smrg        return;
1152de2362d3Smrg#endif
1153de2362d3Smrg
1154de2362d3Smrg    drmDropMaster(info->dri2.drm_fd);
1155de2362d3Smrg}
1156de2362d3Smrg
1157de2362d3Smrg/* Called at the end of each server generation.  Restore the original
1158de2362d3Smrg * text mode, unmap video memory, and unwrap and call the saved
1159de2362d3Smrg * CloseScreen function.
1160de2362d3Smrg */
1161de2362d3Smrgstatic Bool RADEONCloseScreen_KMS(CLOSE_SCREEN_ARGS_DECL)
1162de2362d3Smrg{
1163de2362d3Smrg    ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
1164de2362d3Smrg    RADEONInfoPtr  info  = RADEONPTR(pScrn);
1165de2362d3Smrg
1166de2362d3Smrg    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
1167de2362d3Smrg		   "RADEONCloseScreen\n");
1168de2362d3Smrg
1169de2362d3Smrg    drmmode_uevent_fini(pScrn, &info->drmmode);
1170de2362d3Smrg    radeon_cs_flush_indirect(pScrn);
1171de2362d3Smrg
1172de2362d3Smrg    DeleteCallback(&FlushCallback, radeon_flush_callback, pScrn);
1173de2362d3Smrg
1174de2362d3Smrg    if (info->accel_state->exa) {
1175de2362d3Smrg	exaDriverFini(pScreen);
1176de2362d3Smrg	free(info->accel_state->exa);
1177de2362d3Smrg	info->accel_state->exa = NULL;
1178de2362d3Smrg    }
1179de2362d3Smrg
1180de2362d3Smrg    if (info->accel_state->use_vbos)
1181de2362d3Smrg        radeon_vbo_free_lists(pScrn);
1182de2362d3Smrg
1183de2362d3Smrg    radeon_drop_drm_master(pScrn);
1184de2362d3Smrg
1185de2362d3Smrg    drmmode_fini(pScrn, &info->drmmode);
1186de2362d3Smrg    if (info->dri2.enabled)
1187de2362d3Smrg	radeon_dri2_close_screen(pScreen);
1188de2362d3Smrg
1189de2362d3Smrg    pScrn->vtSema = FALSE;
1190de2362d3Smrg    xf86ClearPrimInitDone(info->pEnt->index);
1191de2362d3Smrg    pScreen->BlockHandler = info->BlockHandler;
1192de2362d3Smrg    pScreen->CloseScreen = info->CloseScreen;
1193de2362d3Smrg    return (*pScreen->CloseScreen)(CLOSE_SCREEN_ARGS);
1194de2362d3Smrg}
1195de2362d3Smrg
1196de2362d3Smrg
1197de2362d3Smrgvoid RADEONFreeScreen_KMS(FREE_SCREEN_ARGS_DECL)
1198de2362d3Smrg{
1199de2362d3Smrg    SCRN_INFO_PTR(arg);
1200de2362d3Smrg    RADEONInfoPtr  info  = RADEONPTR(pScrn);
1201de2362d3Smrg
1202de2362d3Smrg    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
1203de2362d3Smrg		   "RADEONFreeScreen\n");
1204de2362d3Smrg
1205de2362d3Smrg    /* when server quits at PreInit, we don't need do this anymore*/
1206de2362d3Smrg    if (!info) return;
1207de2362d3Smrg
1208de2362d3Smrg    RADEONFreeRec(pScrn);
1209de2362d3Smrg}
1210de2362d3Smrg
1211de2362d3SmrgBool RADEONScreenInit_KMS(SCREEN_INIT_ARGS_DECL)
1212de2362d3Smrg{
1213de2362d3Smrg    ScrnInfoPtr    pScrn = xf86ScreenToScrn(pScreen);
1214de2362d3Smrg    RADEONInfoPtr  info  = RADEONPTR(pScrn);
1215de2362d3Smrg    int            subPixelOrder = SubPixelUnknown;
1216de2362d3Smrg    const char *s;
1217de2362d3Smrg    void *front_ptr;
1218de2362d3Smrg
1219de2362d3Smrg    pScrn->fbOffset = 0;
1220de2362d3Smrg
1221de2362d3Smrg    miClearVisualTypes();
1222de2362d3Smrg    if (!miSetVisualTypes(pScrn->depth,
1223de2362d3Smrg			  miGetDefaultVisualMask(pScrn->depth),
1224de2362d3Smrg			  pScrn->rgbBits,
1225de2362d3Smrg			  pScrn->defaultVisual)) return FALSE;
1226de2362d3Smrg    miSetPixmapDepths ();
1227de2362d3Smrg
1228de2362d3Smrg    if (!radeon_set_drm_master(pScrn))
1229de2362d3Smrg        return FALSE;
1230de2362d3Smrg
1231de2362d3Smrg    info->directRenderingEnabled = FALSE;
1232de2362d3Smrg    if (info->r600_shadow_fb == FALSE)
1233de2362d3Smrg        info->directRenderingEnabled = radeon_dri2_screen_init(pScreen);
1234de2362d3Smrg
1235de2362d3Smrg    info->surf_man = radeon_surface_manager_new(info->dri2.drm_fd);
1236de2362d3Smrg    if (!info->bufmgr)
1237de2362d3Smrg        info->bufmgr = radeon_bo_manager_gem_ctor(info->dri2.drm_fd);
1238de2362d3Smrg    if (!info->bufmgr) {
1239de2362d3Smrg	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1240de2362d3Smrg		   "failed to initialise GEM buffer manager");
1241de2362d3Smrg	return FALSE;
1242de2362d3Smrg    }
1243de2362d3Smrg    drmmode_set_bufmgr(pScrn, &info->drmmode, info->bufmgr);
1244de2362d3Smrg
1245de2362d3Smrg    if (!info->csm)
1246de2362d3Smrg        info->csm = radeon_cs_manager_gem_ctor(info->dri2.drm_fd);
1247de2362d3Smrg    if (!info->csm) {
1248de2362d3Smrg	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1249de2362d3Smrg		   "failed to initialise command submission manager");
1250de2362d3Smrg	return FALSE;
1251de2362d3Smrg    }
1252de2362d3Smrg
1253de2362d3Smrg    if (!info->cs)
1254de2362d3Smrg        info->cs = radeon_cs_create(info->csm, RADEON_BUFFER_SIZE/4);
1255de2362d3Smrg    if (!info->cs) {
1256de2362d3Smrg	xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1257de2362d3Smrg		   "failed to initialise command submission buffer");
1258de2362d3Smrg	return FALSE;
1259de2362d3Smrg    }
1260de2362d3Smrg
1261de2362d3Smrg    radeon_cs_set_limit(info->cs, RADEON_GEM_DOMAIN_GTT, info->gart_size);
1262de2362d3Smrg    radeon_cs_space_set_flush(info->cs, (void(*)(void *))radeon_cs_flush_indirect, pScrn);
1263de2362d3Smrg
1264de2362d3Smrg    if (!radeon_setup_kernel_mem(pScreen)) {
1265de2362d3Smrg	xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "radeon_setup_kernel_mem failed\n");
1266de2362d3Smrg	return FALSE;
1267de2362d3Smrg    }
1268de2362d3Smrg    front_ptr = info->front_bo->ptr;
1269de2362d3Smrg
1270de2362d3Smrg    if (info->r600_shadow_fb) {
1271de2362d3Smrg	info->fb_shadow = calloc(1,
1272de2362d3Smrg				 pScrn->displayWidth * pScrn->virtualY *
1273de2362d3Smrg				 ((pScrn->bitsPerPixel + 7) >> 3));
1274de2362d3Smrg	if (info->fb_shadow == NULL) {
1275de2362d3Smrg	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1276de2362d3Smrg                       "Failed to allocate shadow framebuffer\n");
1277de2362d3Smrg	    info->r600_shadow_fb = FALSE;
1278de2362d3Smrg	} else {
1279de2362d3Smrg	    if (!fbScreenInit(pScreen, info->fb_shadow,
1280de2362d3Smrg			      pScrn->virtualX, pScrn->virtualY,
1281de2362d3Smrg			      pScrn->xDpi, pScrn->yDpi, pScrn->displayWidth,
1282de2362d3Smrg			      pScrn->bitsPerPixel))
1283de2362d3Smrg		return FALSE;
1284de2362d3Smrg	}
1285de2362d3Smrg    }
1286de2362d3Smrg
1287de2362d3Smrg    if (info->r600_shadow_fb == FALSE) {
1288de2362d3Smrg	/* Init fb layer */
1289de2362d3Smrg	if (!fbScreenInit(pScreen, front_ptr,
1290de2362d3Smrg			  pScrn->virtualX, pScrn->virtualY,
1291de2362d3Smrg			  pScrn->xDpi, pScrn->yDpi, pScrn->displayWidth,
1292de2362d3Smrg			  pScrn->bitsPerPixel))
1293de2362d3Smrg	    return FALSE;
1294de2362d3Smrg    }
1295de2362d3Smrg
1296de2362d3Smrg    xf86SetBlackWhitePixels(pScreen);
1297de2362d3Smrg
1298de2362d3Smrg    if (pScrn->bitsPerPixel > 8) {
1299de2362d3Smrg	VisualPtr  visual;
1300de2362d3Smrg
1301de2362d3Smrg	visual = pScreen->visuals + pScreen->numVisuals;
1302de2362d3Smrg	while (--visual >= pScreen->visuals) {
1303de2362d3Smrg	    if ((visual->class | DynamicClass) == DirectColor) {
1304de2362d3Smrg		visual->offsetRed   = pScrn->offset.red;
1305de2362d3Smrg		visual->offsetGreen = pScrn->offset.green;
1306de2362d3Smrg		visual->offsetBlue  = pScrn->offset.blue;
1307de2362d3Smrg		visual->redMask     = pScrn->mask.red;
1308de2362d3Smrg		visual->greenMask   = pScrn->mask.green;
1309de2362d3Smrg		visual->blueMask    = pScrn->mask.blue;
1310de2362d3Smrg	    }
1311de2362d3Smrg	}
1312de2362d3Smrg    }
1313de2362d3Smrg
1314de2362d3Smrg    /* Must be after RGB order fixed */
1315de2362d3Smrg    fbPictureInit (pScreen, 0, 0);
1316de2362d3Smrg
1317de2362d3Smrg#ifdef RENDER
1318de2362d3Smrg    if ((s = xf86GetOptValString(info->Options, OPTION_SUBPIXEL_ORDER))) {
1319de2362d3Smrg	if (strcmp(s, "RGB") == 0) subPixelOrder = SubPixelHorizontalRGB;
1320de2362d3Smrg	else if (strcmp(s, "BGR") == 0) subPixelOrder = SubPixelHorizontalBGR;
1321de2362d3Smrg	else if (strcmp(s, "NONE") == 0) subPixelOrder = SubPixelNone;
1322de2362d3Smrg	PictureSetSubpixelOrder (pScreen, subPixelOrder);
1323de2362d3Smrg    }
1324de2362d3Smrg#endif
1325de2362d3Smrg
1326de2362d3Smrg    pScrn->vtSema = TRUE;
1327de2362d3Smrg    xf86SetBackingStore(pScreen);
1328de2362d3Smrg
1329de2362d3Smrg    if (info->directRenderingEnabled) {
1330de2362d3Smrg	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Direct rendering enabled\n");
1331de2362d3Smrg    } else {
1332de2362d3Smrg	xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
1333de2362d3Smrg		   "Direct rendering disabled\n");
1334de2362d3Smrg    }
1335de2362d3Smrg
1336de2362d3Smrg    if (info->r600_shadow_fb) {
1337de2362d3Smrg	xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Acceleration disabled\n");
1338de2362d3Smrg	info->accelOn = FALSE;
1339de2362d3Smrg    } else {
1340de2362d3Smrg	xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
1341de2362d3Smrg		       "Initializing Acceleration\n");
1342de2362d3Smrg	if (RADEONAccelInit(pScreen)) {
1343de2362d3Smrg	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Acceleration enabled\n");
1344de2362d3Smrg	    info->accelOn = TRUE;
1345de2362d3Smrg	} else {
1346de2362d3Smrg	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1347de2362d3Smrg		       "Acceleration initialization failed\n");
1348de2362d3Smrg	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Acceleration disabled\n");
1349de2362d3Smrg	    info->accelOn = FALSE;
1350de2362d3Smrg	}
1351de2362d3Smrg    }
1352de2362d3Smrg
1353de2362d3Smrg    /* Init DPMS */
1354de2362d3Smrg    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
1355de2362d3Smrg		   "Initializing DPMS\n");
1356de2362d3Smrg    xf86DPMSInit(pScreen, xf86DPMSSet, 0);
1357de2362d3Smrg
1358de2362d3Smrg    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
1359de2362d3Smrg		   "Initializing Cursor\n");
1360de2362d3Smrg
1361de2362d3Smrg    /* Set Silken Mouse */
1362de2362d3Smrg    xf86SetSilkenMouse(pScreen);
1363de2362d3Smrg
1364de2362d3Smrg    /* Cursor setup */
1365de2362d3Smrg    miDCInitialize(pScreen, xf86GetPointerScreenFuncs());
1366de2362d3Smrg
1367de2362d3Smrg    if (!xf86ReturnOptValBool(info->Options, OPTION_SW_CURSOR, FALSE)) {
1368de2362d3Smrg	if (RADEONCursorInit_KMS(pScreen)) {
1369de2362d3Smrg	}
1370de2362d3Smrg    }
1371de2362d3Smrg
1372de2362d3Smrg    /* DGA setup */
1373de2362d3Smrg#ifdef XFreeXDGA
1374de2362d3Smrg    /* DGA is dangerous on kms as the base and framebuffer location may change:
1375de2362d3Smrg     * http://lists.freedesktop.org/archives/xorg-devel/2009-September/002113.html
1376de2362d3Smrg     */
1377de2362d3Smrg    /* xf86DiDGAInit(pScreen, info->LinearAddr + pScrn->fbOffset); */
1378de2362d3Smrg#endif
1379de2362d3Smrg    if (info->r600_shadow_fb == FALSE) {
1380de2362d3Smrg        /* Init Xv */
1381de2362d3Smrg        xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
1382de2362d3Smrg                       "Initializing Xv\n");
1383de2362d3Smrg        RADEONInitVideo(pScreen);
1384de2362d3Smrg    }
1385de2362d3Smrg
1386de2362d3Smrg    if (info->r600_shadow_fb == TRUE) {
1387de2362d3Smrg        if (!shadowSetup(pScreen)) {
1388de2362d3Smrg	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1389de2362d3Smrg		       "Shadowfb initialization failed\n");
1390de2362d3Smrg            return FALSE;
1391de2362d3Smrg        }
1392de2362d3Smrg    }
1393de2362d3Smrg    pScrn->pScreen = pScreen;
1394de2362d3Smrg
1395de2362d3Smrg    /* Provide SaveScreen & wrap BlockHandler and CloseScreen */
1396de2362d3Smrg    /* Wrap CloseScreen */
1397de2362d3Smrg    info->CloseScreen    = pScreen->CloseScreen;
1398de2362d3Smrg    pScreen->CloseScreen = RADEONCloseScreen_KMS;
1399de2362d3Smrg    pScreen->SaveScreen  = RADEONSaveScreen_KMS;
1400de2362d3Smrg    info->BlockHandler = pScreen->BlockHandler;
1401de2362d3Smrg    pScreen->BlockHandler = RADEONBlockHandler_KMS;
1402de2362d3Smrg
1403de2362d3Smrg    if (!AddCallback(&FlushCallback, radeon_flush_callback, pScrn))
1404de2362d3Smrg        return FALSE;
1405de2362d3Smrg
1406de2362d3Smrg    info->CreateScreenResources = pScreen->CreateScreenResources;
1407de2362d3Smrg    pScreen->CreateScreenResources = RADEONCreateScreenResources_KMS;
1408de2362d3Smrg
1409de2362d3Smrg#ifdef RADEON_PIXMAP_SHARING
1410de2362d3Smrg    pScreen->StartPixmapTracking = PixmapStartDirtyTracking;
1411de2362d3Smrg    pScreen->StopPixmapTracking = PixmapStopDirtyTracking;
1412de2362d3Smrg#endif
1413de2362d3Smrg
1414de2362d3Smrg   if (!xf86CrtcScreenInit (pScreen))
1415de2362d3Smrg       return FALSE;
1416de2362d3Smrg
1417de2362d3Smrg   /* Wrap pointer motion to flip touch screen around */
1418de2362d3Smrg//    info->PointerMoved = pScrn->PointerMoved;
1419de2362d3Smrg//    pScrn->PointerMoved = RADEONPointerMoved;
1420de2362d3Smrg
1421de2362d3Smrg    if (!drmmode_setup_colormap(pScreen, pScrn))
1422de2362d3Smrg	return FALSE;
1423de2362d3Smrg
1424de2362d3Smrg   /* Note unused options */
1425de2362d3Smrg    if (serverGeneration == 1)
1426de2362d3Smrg	xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
1427de2362d3Smrg
1428de2362d3Smrg    drmmode_init(pScrn, &info->drmmode);
1429de2362d3Smrg
1430de2362d3Smrg    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
1431de2362d3Smrg		   "RADEONScreenInit finished\n");
1432de2362d3Smrg
1433de2362d3Smrg    info->accel_state->XInited3D = FALSE;
1434de2362d3Smrg    info->accel_state->engineMode = EXA_ENGINEMODE_UNKNOWN;
1435de2362d3Smrg
1436de2362d3Smrg    return TRUE;
1437de2362d3Smrg}
1438de2362d3Smrg
1439de2362d3SmrgBool RADEONEnterVT_KMS(VT_FUNC_ARGS_DECL)
1440de2362d3Smrg{
1441de2362d3Smrg    SCRN_INFO_PTR(arg);
1442de2362d3Smrg    RADEONInfoPtr  info  = RADEONPTR(pScrn);
1443de2362d3Smrg
1444de2362d3Smrg    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
1445de2362d3Smrg		   "RADEONEnterVT_KMS\n");
1446de2362d3Smrg
1447de2362d3Smrg    radeon_set_drm_master(pScrn);
1448de2362d3Smrg
1449de2362d3Smrg    info->accel_state->XInited3D = FALSE;
1450de2362d3Smrg    info->accel_state->engineMode = EXA_ENGINEMODE_UNKNOWN;
1451de2362d3Smrg
1452de2362d3Smrg    pScrn->vtSema = TRUE;
1453de2362d3Smrg
1454de2362d3Smrg    if (!drmmode_set_desired_modes(pScrn, &info->drmmode))
1455de2362d3Smrg	return FALSE;
1456de2362d3Smrg
1457de2362d3Smrg    return TRUE;
1458de2362d3Smrg}
1459de2362d3Smrg
1460de2362d3Smrg
1461de2362d3Smrgvoid RADEONLeaveVT_KMS(VT_FUNC_ARGS_DECL)
1462de2362d3Smrg{
1463de2362d3Smrg    SCRN_INFO_PTR(arg);
1464de2362d3Smrg    RADEONInfoPtr  info  = RADEONPTR(pScrn);
1465de2362d3Smrg
1466de2362d3Smrg    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
1467de2362d3Smrg		   "RADEONLeaveVT_KMS\n");
1468de2362d3Smrg
1469de2362d3Smrg    radeon_drop_drm_master(pScrn);
1470de2362d3Smrg
1471de2362d3Smrg    xf86RotateFreeShadow(pScrn);
1472de2362d3Smrg
1473de2362d3Smrg    xf86_hide_cursors (pScrn);
1474de2362d3Smrg    info->accel_state->XInited3D = FALSE;
1475de2362d3Smrg    info->accel_state->engineMode = EXA_ENGINEMODE_UNKNOWN;
1476de2362d3Smrg
1477de2362d3Smrg    xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
1478de2362d3Smrg		   "Ok, leaving now...\n");
1479de2362d3Smrg}
1480de2362d3Smrg
1481de2362d3Smrg
1482de2362d3SmrgBool RADEONSwitchMode_KMS(SWITCH_MODE_ARGS_DECL)
1483de2362d3Smrg{
1484de2362d3Smrg    SCRN_INFO_PTR(arg);
1485de2362d3Smrg    Bool ret;
1486de2362d3Smrg    ret = xf86SetSingleMode (pScrn, mode, RR_Rotate_0);
1487de2362d3Smrg    return ret;
1488de2362d3Smrg
1489de2362d3Smrg}
1490de2362d3Smrg
1491de2362d3Smrgvoid RADEONAdjustFrame_KMS(ADJUST_FRAME_ARGS_DECL)
1492de2362d3Smrg{
1493de2362d3Smrg    SCRN_INFO_PTR(arg);
1494de2362d3Smrg    RADEONInfoPtr  info        = RADEONPTR(pScrn);
1495de2362d3Smrg    drmmode_adjust_frame(pScrn, &info->drmmode, x, y);
1496de2362d3Smrg    return;
1497de2362d3Smrg}
1498de2362d3Smrg
1499de2362d3Smrgstatic Bool radeon_setup_kernel_mem(ScreenPtr pScreen)
1500de2362d3Smrg{
1501de2362d3Smrg    ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
1502de2362d3Smrg    RADEONInfoPtr info = RADEONPTR(pScrn);
1503de2362d3Smrg    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
1504de2362d3Smrg    int cpp = info->pixel_bytes;
1505de2362d3Smrg    uint32_t screen_size;
1506de2362d3Smrg    int pitch, base_align;
1507de2362d3Smrg    uint32_t tiling_flags = 0;
1508de2362d3Smrg    struct radeon_surface surface;
1509de2362d3Smrg
1510de2362d3Smrg    if (info->accel_state->exa != NULL) {
1511de2362d3Smrg	xf86DrvMsg(pScreen->myNum, X_ERROR, "Memory map already initialized\n");
1512de2362d3Smrg	return FALSE;
1513de2362d3Smrg    }
1514de2362d3Smrg    if (!info->use_glamor && info->r600_shadow_fb == FALSE) {
1515de2362d3Smrg        info->accel_state->exa = exaDriverAlloc();
1516de2362d3Smrg        if (info->accel_state->exa == NULL) {
1517de2362d3Smrg	    xf86DrvMsg(pScreen->myNum, X_ERROR, "exaDriverAlloc failed\n");
1518de2362d3Smrg	    return FALSE;
1519de2362d3Smrg	}
1520de2362d3Smrg    }
1521de2362d3Smrg
1522de2362d3Smrg    if (info->allowColorTiling) {
1523de2362d3Smrg	if (info->ChipFamily >= CHIP_FAMILY_R600) {
1524de2362d3Smrg		if (info->allowColorTiling2D) {
1525de2362d3Smrg			tiling_flags |= RADEON_TILING_MACRO;
1526de2362d3Smrg		} else {
1527de2362d3Smrg			tiling_flags |= RADEON_TILING_MICRO;
1528de2362d3Smrg		}
1529de2362d3Smrg	} else
1530de2362d3Smrg	    tiling_flags |= RADEON_TILING_MACRO;
1531de2362d3Smrg    }
1532de2362d3Smrg    pitch = RADEON_ALIGN(pScrn->virtualX, drmmode_get_pitch_align(pScrn, cpp, tiling_flags)) * cpp;
1533de2362d3Smrg    screen_size = RADEON_ALIGN(pScrn->virtualY, drmmode_get_height_align(pScrn, tiling_flags)) * pitch;
1534de2362d3Smrg    base_align = drmmode_get_base_align(pScrn, cpp, tiling_flags);
1535de2362d3Smrg	if (info->ChipFamily >= CHIP_FAMILY_R600) {
1536de2362d3Smrg		if(!info->surf_man) {
1537de2362d3Smrg			xf86DrvMsg(pScreen->myNum, X_ERROR,
1538de2362d3Smrg				   "failed to initialise surface manager\n");
1539de2362d3Smrg			return FALSE;
1540de2362d3Smrg		}
1541de2362d3Smrg		memset(&surface, 0, sizeof(struct radeon_surface));
1542de2362d3Smrg		surface.npix_x = pScrn->virtualX;
1543de2362d3Smrg		surface.npix_y = pScrn->virtualY;
1544de2362d3Smrg		surface.npix_z = 1;
1545de2362d3Smrg		surface.blk_w = 1;
1546de2362d3Smrg		surface.blk_h = 1;
1547de2362d3Smrg		surface.blk_d = 1;
1548de2362d3Smrg		surface.array_size = 1;
1549de2362d3Smrg		surface.last_level = 0;
1550de2362d3Smrg		surface.bpe = cpp;
1551de2362d3Smrg		surface.nsamples = 1;
1552de2362d3Smrg		surface.flags = RADEON_SURF_SCANOUT;
1553de2362d3Smrg		/* we are requiring a recent enough libdrm version */
1554de2362d3Smrg		surface.flags |= RADEON_SURF_HAS_TILE_MODE_INDEX;
1555de2362d3Smrg		surface.flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_2D, TYPE);
1556de2362d3Smrg		surface.flags |= RADEON_SURF_SET(RADEON_SURF_MODE_LINEAR_ALIGNED, MODE);
1557de2362d3Smrg		if (tiling_flags & RADEON_TILING_MICRO) {
1558de2362d3Smrg			surface.flags = RADEON_SURF_CLR(surface.flags, MODE);
1559de2362d3Smrg			surface.flags |= RADEON_SURF_SET(RADEON_SURF_MODE_1D, MODE);
1560de2362d3Smrg		}
1561de2362d3Smrg		if (tiling_flags & RADEON_TILING_MACRO) {
1562de2362d3Smrg			surface.flags = RADEON_SURF_CLR(surface.flags, MODE);
1563de2362d3Smrg			surface.flags |= RADEON_SURF_SET(RADEON_SURF_MODE_2D, MODE);
1564de2362d3Smrg		}
1565de2362d3Smrg		if (radeon_surface_best(info->surf_man, &surface)) {
1566de2362d3Smrg			xf86DrvMsg(pScreen->myNum, X_ERROR,
1567de2362d3Smrg				   "radeon_surface_best failed\n");
1568de2362d3Smrg			return FALSE;
1569de2362d3Smrg		}
1570de2362d3Smrg		if (radeon_surface_init(info->surf_man, &surface)) {
1571de2362d3Smrg			xf86DrvMsg(pScreen->myNum, X_ERROR,
1572de2362d3Smrg				   "radeon_surface_init failed\n");
1573de2362d3Smrg			return FALSE;
1574de2362d3Smrg		}
1575de2362d3Smrg		pitch = surface.level[0].pitch_bytes;
1576de2362d3Smrg		screen_size = surface.bo_size;
1577de2362d3Smrg		base_align = surface.bo_alignment;
1578de2362d3Smrg		tiling_flags = 0;
1579de2362d3Smrg		switch (surface.level[0].mode) {
1580de2362d3Smrg		case RADEON_SURF_MODE_2D:
1581de2362d3Smrg			tiling_flags |= RADEON_TILING_MACRO;
1582de2362d3Smrg			tiling_flags |= surface.bankw << RADEON_TILING_EG_BANKW_SHIFT;
1583de2362d3Smrg			tiling_flags |= surface.bankh << RADEON_TILING_EG_BANKH_SHIFT;
1584de2362d3Smrg			tiling_flags |= surface.mtilea << RADEON_TILING_EG_MACRO_TILE_ASPECT_SHIFT;
1585de2362d3Smrg			tiling_flags |= eg_tile_split(surface.tile_split) << RADEON_TILING_EG_TILE_SPLIT_SHIFT;
1586de2362d3Smrg			break;
1587de2362d3Smrg		case RADEON_SURF_MODE_1D:
1588de2362d3Smrg			tiling_flags |= RADEON_TILING_MICRO;
1589de2362d3Smrg			break;
1590de2362d3Smrg		default:
1591de2362d3Smrg			break;
1592de2362d3Smrg		}
1593de2362d3Smrg		info->front_surface = surface;
1594de2362d3Smrg	}
1595de2362d3Smrg    {
1596de2362d3Smrg	int cursor_size;
1597de2362d3Smrg	int c;
1598de2362d3Smrg
1599de2362d3Smrg	cursor_size = info->cursor_w * info->cursor_h * 4;
1600de2362d3Smrg	cursor_size = RADEON_ALIGN(cursor_size, RADEON_GPU_PAGE_SIZE);
1601de2362d3Smrg	for (c = 0; c < xf86_config->num_crtc; c++) {
1602de2362d3Smrg	    /* cursor objects */
1603de2362d3Smrg            if (info->cursor_bo[c] == NULL) {
1604de2362d3Smrg                info->cursor_bo[c] = radeon_bo_open(info->bufmgr, 0,
1605de2362d3Smrg                                                    cursor_size, 0,
1606de2362d3Smrg                                                    RADEON_GEM_DOMAIN_VRAM, 0);
1607de2362d3Smrg                if (!info->cursor_bo[c]) {
1608de2362d3Smrg                    ErrorF("Failed to allocate cursor buffer memory\n");
1609de2362d3Smrg                    return FALSE;
1610de2362d3Smrg                }
1611de2362d3Smrg
1612de2362d3Smrg                if (radeon_bo_map(info->cursor_bo[c], 1)) {
1613de2362d3Smrg                    ErrorF("Failed to map cursor buffer memory\n");
1614de2362d3Smrg                }
1615de2362d3Smrg
1616de2362d3Smrg                drmmode_set_cursor(pScrn, &info->drmmode, c, info->cursor_bo[c]);
1617de2362d3Smrg            }
1618de2362d3Smrg        }
1619de2362d3Smrg    }
1620de2362d3Smrg
1621de2362d3Smrg    screen_size = RADEON_ALIGN(screen_size, RADEON_GPU_PAGE_SIZE);
1622de2362d3Smrg
1623de2362d3Smrg    if (info->front_bo == NULL) {
1624de2362d3Smrg        info->front_bo = radeon_bo_open(info->bufmgr, 0, screen_size,
1625de2362d3Smrg                                        base_align, RADEON_GEM_DOMAIN_VRAM, 0);
1626de2362d3Smrg        if (info->r600_shadow_fb == TRUE) {
1627de2362d3Smrg            if (radeon_bo_map(info->front_bo, 1)) {
1628de2362d3Smrg                ErrorF("Failed to map cursor buffer memory\n");
1629de2362d3Smrg            }
1630de2362d3Smrg        }
1631de2362d3Smrg#if X_BYTE_ORDER == X_BIG_ENDIAN
1632de2362d3Smrg	switch (cpp) {
1633de2362d3Smrg	case 4:
1634de2362d3Smrg	    tiling_flags |= RADEON_TILING_SWAP_32BIT;
1635de2362d3Smrg	    break;
1636de2362d3Smrg	case 2:
1637de2362d3Smrg	    tiling_flags |= RADEON_TILING_SWAP_16BIT;
1638de2362d3Smrg	    break;
1639de2362d3Smrg	}
1640de2362d3Smrg	if (info->ChipFamily < CHIP_FAMILY_R600 &&
1641de2362d3Smrg	    info->r600_shadow_fb && tiling_flags)
1642de2362d3Smrg	    tiling_flags |= RADEON_TILING_SURFACE;
1643de2362d3Smrg#endif
1644de2362d3Smrg	if (tiling_flags)
1645de2362d3Smrg            radeon_bo_set_tiling(info->front_bo, tiling_flags, pitch);
1646de2362d3Smrg    }
1647de2362d3Smrg
1648de2362d3Smrg    pScrn->displayWidth = pitch / cpp;
1649de2362d3Smrg
1650de2362d3Smrg    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Front buffer size: %dK\n", info->front_bo->size/1024);
1651de2362d3Smrg    radeon_kms_update_vram_limit(pScrn, screen_size);
1652de2362d3Smrg    return TRUE;
1653de2362d3Smrg}
1654de2362d3Smrg
1655de2362d3Smrgvoid radeon_kms_update_vram_limit(ScrnInfoPtr pScrn, uint32_t new_fb_size)
1656de2362d3Smrg{
1657de2362d3Smrg    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
1658de2362d3Smrg    RADEONInfoPtr info = RADEONPTR(pScrn);
1659de2362d3Smrg    uint64_t remain_size_bytes;
1660de2362d3Smrg    int c;
1661de2362d3Smrg
1662de2362d3Smrg    for (c = 0; c < xf86_config->num_crtc; c++) {
1663de2362d3Smrg	if (info->cursor_bo[c] != NULL) {
1664de2362d3Smrg	    new_fb_size += (64 * 4 * 64);
1665de2362d3Smrg	}
1666de2362d3Smrg    }
1667de2362d3Smrg
1668de2362d3Smrg    remain_size_bytes = info->vram_size - new_fb_size;
1669de2362d3Smrg    remain_size_bytes = (remain_size_bytes / 10) * 9;
1670de2362d3Smrg    if (remain_size_bytes > 0xffffffff)
1671de2362d3Smrg	remain_size_bytes = 0xffffffff;
1672de2362d3Smrg    radeon_cs_set_limit(info->cs, RADEON_GEM_DOMAIN_VRAM,
1673de2362d3Smrg			(uint32_t)remain_size_bytes);
1674de2362d3Smrg
1675de2362d3Smrg    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VRAM usage limit set to %uK\n",
1676de2362d3Smrg	       (uint32_t)remain_size_bytes / 1024);
1677de2362d3Smrg}
1678de2362d3Smrg
1679de2362d3Smrg/* Used to disallow modes that are not supported by the hardware */
1680de2362d3SmrgModeStatus RADEONValidMode(SCRN_ARG_TYPE arg, DisplayModePtr mode,
1681de2362d3Smrg                           Bool verbose, int flag)
1682de2362d3Smrg{
1683de2362d3Smrg    SCRN_INFO_PTR(arg);
1684de2362d3Smrg    RADEONInfoPtr info = RADEONPTR(pScrn);
1685de2362d3Smrg    RADEONEntPtr pRADEONEnt = RADEONEntPriv(pScrn);
1686de2362d3Smrg
1687de2362d3Smrg    /*
1688de2362d3Smrg     * RN50 has effective maximum mode bandwidth of about 300MiB/s.
1689de2362d3Smrg     * XXX should really do this for all chips by properly computing
1690de2362d3Smrg     * memory bandwidth and an overhead factor.
1691de2362d3Smrg    */
1692de2362d3Smrg    if (info->ChipFamily == CHIP_FAMILY_RV100 && !pRADEONEnt->HasCRTC2) {
1693de2362d3Smrg       if (xf86ModeBandwidth(mode, pScrn->bitsPerPixel) > 300)
1694de2362d3Smrg          return MODE_BANDWIDTH;
1695de2362d3Smrg    }
1696de2362d3Smrg    /* There are problems with double scan mode at high clocks
1697de2362d3Smrg     * They're likely related PLL and display buffer settings.
1698de2362d3Smrg     * Disable these modes for now.
1699de2362d3Smrg     */
1700de2362d3Smrg    if (mode->Flags & V_DBLSCAN) {
1701de2362d3Smrg       if ((mode->CrtcHDisplay >= 1024) || (mode->CrtcVDisplay >= 768))
1702de2362d3Smrg           return MODE_CLOCK_RANGE;
1703de2362d3Smrg   }
1704de2362d3Smrg    return MODE_OK;
1705de2362d3Smrg}
1706