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