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