lx_display.c revision f29dbc25
1f29dbc25Smrg/* Copyright (c) 2008 Advanced Micro Devices, Inc. 2f29dbc25Smrg * 3f29dbc25Smrg * Permission is hereby granted, free of charge, to any person obtaining a copy 4f29dbc25Smrg * of this software and associated documentation files (the "Software"), to 5f29dbc25Smrg * deal in the Software without restriction, including without limitation the 6f29dbc25Smrg * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7f29dbc25Smrg * sell copies of the Software, and to permit persons to whom the Software is 8f29dbc25Smrg * furnished to do so, subject to the following conditions: 9f29dbc25Smrg * 10f29dbc25Smrg * The above copyright notice and this permission notice shall be included in 11f29dbc25Smrg * all copies or substantial portions of the Software. 12f29dbc25Smrg * 13f29dbc25Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14f29dbc25Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15f29dbc25Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16f29dbc25Smrg * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17f29dbc25Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18f29dbc25Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19f29dbc25Smrg * IN THE SOFTWARE. 20f29dbc25Smrg * 21f29dbc25Smrg * Neither the name of the Advanced Micro Devices, Inc. nor the names of its 22f29dbc25Smrg * contributors may be used to endorse or promote products derived from this 23f29dbc25Smrg * software without specific prior written permission. 24f29dbc25Smrg */ 25f29dbc25Smrg 26f29dbc25Smrg#ifdef HAVE_CONFIG_H 27f29dbc25Smrg#include "config.h" 28f29dbc25Smrg#endif 29f29dbc25Smrg 30f29dbc25Smrg#include "xf86.h" 31f29dbc25Smrg#include "geode.h" 32f29dbc25Smrg#include "xf86Crtc.h" 33f29dbc25Smrg#include "cim/cim_defs.h" 34f29dbc25Smrg#include "cim/cim_regs.h" 35f29dbc25Smrg 36f29dbc25Smrgtypedef struct _LXOutputPrivateRec 37f29dbc25Smrg{ 38f29dbc25Smrg int video_enable; 39f29dbc25Smrg unsigned long video_flags; 40f29dbc25Smrg GeodeMemPtr rotate_mem; 41f29dbc25Smrg} LXCrtcPrivateRec, *LXCrtcPrivatePtr; 42f29dbc25Smrg 43f29dbc25Smrgstatic void 44f29dbc25Smrglx_enable_dac_power(ScrnInfoPtr pScrni, int option) 45f29dbc25Smrg{ 46f29dbc25Smrg GeodeRec *pGeode = GEODEPTR(pScrni); 47f29dbc25Smrg 48f29dbc25Smrg df_set_crt_enable(DF_CRT_ENABLE); 49f29dbc25Smrg 50f29dbc25Smrg /* Turn off the DAC if we don't need the CRT */ 51f29dbc25Smrg 52f29dbc25Smrg if (option && (!(pGeode->Output & OUTPUT_CRT))) { 53f29dbc25Smrg unsigned int misc = READ_VID32(DF_VID_MISC); 54f29dbc25Smrg 55f29dbc25Smrg misc |= DF_DAC_POWER_DOWN; 56f29dbc25Smrg WRITE_VID32(DF_VID_MISC, misc); 57f29dbc25Smrg } 58f29dbc25Smrg 59f29dbc25Smrg if (pGeode->Output & OUTPUT_PANEL) 60f29dbc25Smrg df_set_panel_enable(1); 61f29dbc25Smrg} 62f29dbc25Smrg 63f29dbc25Smrgstatic void 64f29dbc25Smrglx_disable_dac_power(ScrnInfoPtr pScrni, int option) 65f29dbc25Smrg{ 66f29dbc25Smrg GeodeRec *pGeode = GEODEPTR(pScrni); 67f29dbc25Smrg 68f29dbc25Smrg if (pGeode->Output & OUTPUT_PANEL) 69f29dbc25Smrg df_set_panel_enable(0); 70f29dbc25Smrg 71f29dbc25Smrg if (pGeode->Output & OUTPUT_CRT) { 72f29dbc25Smrg 73f29dbc25Smrg /* Wait for the panel to finish its procedure */ 74f29dbc25Smrg 75f29dbc25Smrg if (pGeode->Output & OUTPUT_PANEL) 76f29dbc25Smrg while ((READ_VID32(DF_POWER_MANAGEMENT) & 2) == 0) ; 77f29dbc25Smrg df_set_crt_enable(option); 78f29dbc25Smrg } 79f29dbc25Smrg} 80f29dbc25Smrg 81f29dbc25Smrgstatic void 82f29dbc25Smrglx_set_panel_mode(VG_DISPLAY_MODE * mode, DisplayModePtr pMode) 83f29dbc25Smrg{ 84f29dbc25Smrg int hsync, vsync; 85f29dbc25Smrg 86f29dbc25Smrg mode->mode_width = mode->panel_width = pMode->HDisplay; 87f29dbc25Smrg mode->mode_height = mode->panel_height = pMode->VDisplay; 88f29dbc25Smrg 89f29dbc25Smrg mode->hactive = pMode->HDisplay; 90f29dbc25Smrg mode->hblankstart = pMode->HDisplay; 91f29dbc25Smrg mode->hsyncstart = pMode->HSyncStart; 92f29dbc25Smrg mode->hsyncend = pMode->HSyncEnd; 93f29dbc25Smrg mode->hblankend = pMode->HTotal; 94f29dbc25Smrg mode->htotal = pMode->HTotal; 95f29dbc25Smrg 96f29dbc25Smrg mode->vactive = pMode->VDisplay; 97f29dbc25Smrg mode->vblankstart = pMode->VDisplay; 98f29dbc25Smrg mode->vsyncstart = pMode->VSyncStart; 99f29dbc25Smrg mode->vsyncend = pMode->VSyncEnd; 100f29dbc25Smrg mode->vblankend = pMode->VTotal; 101f29dbc25Smrg mode->vtotal = pMode->VTotal; 102f29dbc25Smrg 103f29dbc25Smrg mode->vactive_even = pMode->VDisplay; 104f29dbc25Smrg mode->vblankstart_even = pMode->VDisplay; 105f29dbc25Smrg mode->vsyncstart_even = pMode->VSyncStart; 106f29dbc25Smrg mode->vsyncend_even = pMode->VSyncEnd; 107f29dbc25Smrg mode->vblankend_even = pMode->VTotal; 108f29dbc25Smrg mode->vtotal_even = pMode->VTotal; 109f29dbc25Smrg 110f29dbc25Smrg mode->frequency = (int)((pMode->Clock / 1000.0) * 0x10000); 111f29dbc25Smrg 112f29dbc25Smrg /* In panel mode, Cimarron purposely swizzles these, 113f29dbc25Smrg * so we swizzle them first */ 114f29dbc25Smrg 115f29dbc25Smrg hsync = (pMode->Flags & V_NHSYNC) ? 0 : 1; 116f29dbc25Smrg vsync = (pMode->Flags & V_NVSYNC) ? 0 : 1; 117f29dbc25Smrg 118f29dbc25Smrg mode->flags |= (hsync) ? VG_MODEFLAG_NEG_HSYNC : 0; 119f29dbc25Smrg mode->flags |= (vsync) ? VG_MODEFLAG_NEG_VSYNC : 0; 120f29dbc25Smrg} 121f29dbc25Smrg 122f29dbc25Smrgstatic void 123f29dbc25Smrglx_set_crt_mode(VG_DISPLAY_MODE * mode, DisplayModePtr pMode) 124f29dbc25Smrg{ 125f29dbc25Smrg int hsync, vsync; 126f29dbc25Smrg 127f29dbc25Smrg mode->mode_width = mode->panel_width = pMode->HDisplay; 128f29dbc25Smrg mode->mode_height = mode->panel_height = pMode->VDisplay; 129f29dbc25Smrg 130f29dbc25Smrg mode->hactive = pMode->CrtcHDisplay; 131f29dbc25Smrg mode->hblankstart = pMode->CrtcHBlankStart; 132f29dbc25Smrg mode->hsyncstart = pMode->CrtcHSyncStart; 133f29dbc25Smrg mode->hsyncend = pMode->CrtcHSyncEnd; 134f29dbc25Smrg mode->hblankend = pMode->CrtcHBlankEnd; 135f29dbc25Smrg mode->htotal = pMode->CrtcHTotal; 136f29dbc25Smrg 137f29dbc25Smrg mode->vactive = pMode->CrtcVDisplay; 138f29dbc25Smrg mode->vblankstart = pMode->CrtcVBlankStart; 139f29dbc25Smrg mode->vsyncstart = pMode->CrtcVSyncStart; 140f29dbc25Smrg mode->vsyncend = pMode->CrtcVSyncEnd; 141f29dbc25Smrg mode->vblankend = pMode->CrtcVBlankEnd; 142f29dbc25Smrg mode->vtotal = pMode->CrtcVTotal; 143f29dbc25Smrg 144f29dbc25Smrg mode->vactive_even = pMode->CrtcVDisplay; 145f29dbc25Smrg mode->vblankstart_even = pMode->CrtcVBlankStart; 146f29dbc25Smrg mode->vsyncstart_even = pMode->CrtcVSyncStart; 147f29dbc25Smrg mode->vsyncend_even = pMode->CrtcVSyncEnd; 148f29dbc25Smrg mode->vblankend_even = pMode->CrtcVBlankEnd; 149f29dbc25Smrg mode->vtotal_even = pMode->CrtcVTotal; 150f29dbc25Smrg 151f29dbc25Smrg mode->frequency = (int)((pMode->Clock / 1000.0) * 0x10000); 152f29dbc25Smrg 153f29dbc25Smrg hsync = (pMode->Flags & V_NHSYNC) ? 1 : 0; 154f29dbc25Smrg vsync = (pMode->Flags & V_NVSYNC) ? 1 : 0; 155f29dbc25Smrg 156f29dbc25Smrg mode->flags |= (hsync) ? VG_MODEFLAG_NEG_HSYNC : 0; 157f29dbc25Smrg mode->flags |= (vsync) ? VG_MODEFLAG_NEG_VSYNC : 0; 158f29dbc25Smrg} 159f29dbc25Smrg 160f29dbc25Smrgstatic int 161f29dbc25Smrglx_set_mode(ScrnInfoPtr pScrni, DisplayModePtr pMode, int bpp) 162f29dbc25Smrg{ 163f29dbc25Smrg GeodeRec *pGeode = GEODEPTR(pScrni); 164f29dbc25Smrg VG_DISPLAY_MODE mode; 165f29dbc25Smrg int ret; 166f29dbc25Smrg 167f29dbc25Smrg memset(&mode, 0, sizeof(mode)); 168f29dbc25Smrg 169f29dbc25Smrg mode.flags |= pGeode->Output & OUTPUT_CRT ? VG_MODEFLAG_CRT_AND_FP : 0; 170f29dbc25Smrg 171f29dbc25Smrg if (pGeode->Output & OUTPUT_PANEL) { 172f29dbc25Smrg mode.flags |= VG_MODEFLAG_PANELOUT; 173f29dbc25Smrg if (pGeode->Output & OUTPUT_CRT) 174f29dbc25Smrg mode.flags |= VG_MODEFLAG_CRT_AND_FP; 175f29dbc25Smrg } 176f29dbc25Smrg 177f29dbc25Smrg if (pGeode->Output & OUTPUT_PANEL && pGeode->Scale) 178f29dbc25Smrg lx_set_panel_mode(&mode, pGeode->panelMode); 179f29dbc25Smrg else 180f29dbc25Smrg lx_set_crt_mode(&mode, pMode); 181f29dbc25Smrg 182f29dbc25Smrg mode.src_width = pMode->HDisplay; 183f29dbc25Smrg mode.src_height = pMode->VDisplay; 184f29dbc25Smrg 185f29dbc25Smrg /* Set the filter coefficients to the default values */ 186f29dbc25Smrg vg_set_scaler_filter_coefficients(NULL, NULL); 187f29dbc25Smrg 188f29dbc25Smrg ret = vg_set_custom_mode(&mode, bpp); 189f29dbc25Smrg return (ret == CIM_STATUS_OK) ? 0 : -1; 190f29dbc25Smrg} 191f29dbc25Smrg 192f29dbc25Smrgstatic void 193f29dbc25Smrglx_crtc_dpms(xf86CrtcPtr crtc, int mode) 194f29dbc25Smrg{ 195f29dbc25Smrg ScrnInfoPtr pScrni = crtc->scrn; 196f29dbc25Smrg GeodeRec *pGeode = GEODEPTR(pScrni); 197f29dbc25Smrg 198f29dbc25Smrg if (pGeode->Output & OUTPUT_DCON) 199f29dbc25Smrg DCONDPMSSet(pScrni, mode); 200f29dbc25Smrg 201f29dbc25Smrg switch (mode) { 202f29dbc25Smrg case DPMSModeOn: 203f29dbc25Smrg lx_enable_dac_power(pScrni, 1); 204f29dbc25Smrg break; 205f29dbc25Smrg 206f29dbc25Smrg case DPMSModeStandby: 207f29dbc25Smrg lx_disable_dac_power(pScrni, DF_CRT_STANDBY); 208f29dbc25Smrg break; 209f29dbc25Smrg 210f29dbc25Smrg case DPMSModeSuspend: 211f29dbc25Smrg lx_disable_dac_power(pScrni, DF_CRT_SUSPEND); 212f29dbc25Smrg break; 213f29dbc25Smrg 214f29dbc25Smrg case DPMSModeOff: 215f29dbc25Smrg lx_disable_dac_power(pScrni, DF_CRT_DISABLE); 216f29dbc25Smrg break; 217f29dbc25Smrg } 218f29dbc25Smrg} 219f29dbc25Smrg 220f29dbc25Smrgstatic Bool 221f29dbc25Smrglx_crtc_lock(xf86CrtcPtr crtc) 222f29dbc25Smrg{ 223f29dbc25Smrg /* Wait until the GPU is idle */ 224f29dbc25Smrg gp_wait_until_idle(); 225f29dbc25Smrg return TRUE; 226f29dbc25Smrg} 227f29dbc25Smrg 228f29dbc25Smrgstatic void 229f29dbc25Smrglx_crtc_unlock(xf86CrtcPtr crtc) 230f29dbc25Smrg{ 231f29dbc25Smrg /* Nothing to do here */ 232f29dbc25Smrg} 233f29dbc25Smrg 234f29dbc25Smrgstatic void 235f29dbc25Smrglx_crtc_prepare(xf86CrtcPtr crtc) 236f29dbc25Smrg{ 237f29dbc25Smrg LXCrtcPrivatePtr lx_crtc = crtc->driver_private; 238f29dbc25Smrg 239f29dbc25Smrg /* Disable the video */ 240f29dbc25Smrg df_get_video_enable(&lx_crtc->video_enable, &lx_crtc->video_flags); 241f29dbc25Smrg 242f29dbc25Smrg if (lx_crtc->video_enable) 243f29dbc25Smrg df_set_video_enable(0, 0); 244f29dbc25Smrg 245f29dbc25Smrg /* Turn off compression */ 246f29dbc25Smrg vg_set_compression_enable(0); 247f29dbc25Smrg 248f29dbc25Smrg /* Hide the cursor */ 249f29dbc25Smrg crtc->funcs->hide_cursor(crtc); 250f29dbc25Smrg 251f29dbc25Smrg /* Turn off the display */ 252f29dbc25Smrg crtc->funcs->dpms(crtc, DPMSModeOff); 253f29dbc25Smrg} 254f29dbc25Smrg 255f29dbc25Smrgstatic Bool 256f29dbc25Smrglx_crtc_mode_fixup(xf86CrtcPtr crtc, DisplayModePtr mode, 257f29dbc25Smrg DisplayModePtr adjusted_mode) 258f29dbc25Smrg{ 259f29dbc25Smrg return TRUE; 260f29dbc25Smrg} 261f29dbc25Smrg 262f29dbc25Smrgstatic void 263f29dbc25Smrglx_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode, 264f29dbc25Smrg DisplayModePtr adjusted_mode, int x, int y) 265f29dbc25Smrg{ 266f29dbc25Smrg ScrnInfoPtr pScrni = crtc->scrn; 267f29dbc25Smrg GeodeRec *pGeode = GEODEPTR(pScrni); 268f29dbc25Smrg DF_VIDEO_SOURCE_PARAMS vs_odd, vs_even; 269f29dbc25Smrg 270f29dbc25Smrg df_get_video_source_configuration(&vs_odd, &vs_even); 271f29dbc25Smrg 272f29dbc25Smrg /* Note - the memory gets adjusted when virtualX/virtualY 273f29dbc25Smrg * gets changed - so we don't need to worry about it here 274f29dbc25Smrg */ 275f29dbc25Smrg 276f29dbc25Smrg if (lx_set_mode(pScrni, adjusted_mode, pScrni->bitsPerPixel)) 277f29dbc25Smrg ErrorF("ERROR! Unable to set the mode!\n"); 278f29dbc25Smrg 279f29dbc25Smrg /* The output gets turned in in the output code as 280f29dbc25Smrg * per convention */ 281f29dbc25Smrg 282f29dbc25Smrg vg_set_display_pitch(pGeode->Pitch); 283f29dbc25Smrg gp_set_bpp(pScrni->bitsPerPixel); 284f29dbc25Smrg 285f29dbc25Smrg /* Set the acceleration offset if we are drawing to a shadow */ 286f29dbc25Smrg if (crtc->rotatedData != NULL) 287f29dbc25Smrg vg_set_display_offset((unsigned int)((char *)crtc->rotatedData - 288f29dbc25Smrg (char *)pGeode->FBBase)); 289f29dbc25Smrg else 290f29dbc25Smrg vg_set_display_offset(0); 291f29dbc25Smrg 292f29dbc25Smrg /* FIXME: Whats up with X and Y? Does that come into play 293f29dbc25Smrg * here? */ 294f29dbc25Smrg 295f29dbc25Smrg df_configure_video_source(&vs_odd, &vs_even); 296f29dbc25Smrg 297f29dbc25Smrg vg_wait_vertical_blank(); 298f29dbc25Smrg} 299f29dbc25Smrg 300f29dbc25Smrgstatic void 301f29dbc25Smrglx_crtc_commit(xf86CrtcPtr crtc) 302f29dbc25Smrg{ 303f29dbc25Smrg LXCrtcPrivatePtr lx_crtc = crtc->driver_private; 304f29dbc25Smrg ScrnInfoPtr pScrni = crtc->scrn; 305f29dbc25Smrg GeodeRec *pGeode = GEODEPTR(pScrni); 306f29dbc25Smrg 307f29dbc25Smrg /* Turn back on the sreen */ 308f29dbc25Smrg crtc->funcs->dpms(crtc, DPMSModeOn); 309f29dbc25Smrg 310f29dbc25Smrg /* Turn on compression */ 311f29dbc25Smrg 312f29dbc25Smrg if (pGeode->Compression) { 313f29dbc25Smrg vg_configure_compression(&(pGeode->CBData)); 314f29dbc25Smrg vg_set_compression_enable(1); 315f29dbc25Smrg } 316f29dbc25Smrg 317f29dbc25Smrg /* Load the cursor */ 318f29dbc25Smrg if (crtc->scrn->pScreen != NULL) { 319f29dbc25Smrg xf86_reload_cursors(crtc->scrn->pScreen); 320f29dbc25Smrg crtc->funcs->hide_cursor(crtc); 321f29dbc25Smrg crtc->cursor_shown = FALSE; 322f29dbc25Smrg } 323f29dbc25Smrg 324f29dbc25Smrg /* Renable the video */ 325f29dbc25Smrg 326f29dbc25Smrg if (lx_crtc->video_enable) 327f29dbc25Smrg df_set_video_enable(lx_crtc->video_enable, lx_crtc->video_flags); 328f29dbc25Smrg 329f29dbc25Smrg lx_crtc->video_enable = 0; 330f29dbc25Smrg lx_crtc->video_flags = 0; 331f29dbc25Smrg} 332f29dbc25Smrg 333f29dbc25Smrgstatic void 334f29dbc25Smrglx_crtc_gamma_set(xf86CrtcPtr crtc, CARD16 * red, CARD16 * green, 335f29dbc25Smrg CARD16 * blue, int size) 336f29dbc25Smrg{ 337f29dbc25Smrg unsigned int dcfg; 338f29dbc25Smrg int i; 339f29dbc25Smrg 340f29dbc25Smrg assert(size == 256); 341f29dbc25Smrg 342f29dbc25Smrg for (i = 0; i < 256; i++) { 343f29dbc25Smrg unsigned int val = (*red << 8) | *green | (*blue >> 8); 344f29dbc25Smrg 345f29dbc25Smrg df_set_video_palette_entry(i, val); 346f29dbc25Smrg } 347f29dbc25Smrg 348f29dbc25Smrg /* df_set_video_palette_entry automatically turns on 349f29dbc25Smrg * gamma for video - if this gets called, we assume that 350f29dbc25Smrg * RandR wants it set for graphics, so reverse cimarron 351f29dbc25Smrg */ 352f29dbc25Smrg 353f29dbc25Smrg dcfg = READ_VID32(DF_DISPLAY_CONFIG); 354f29dbc25Smrg dcfg &= ~DF_DCFG_GV_PAL_BYP; 355f29dbc25Smrg WRITE_VID32(DF_DISPLAY_CONFIG, dcfg); 356f29dbc25Smrg} 357f29dbc25Smrg 358f29dbc25Smrgstatic void * 359f29dbc25Smrglx_crtc_shadow_allocate(xf86CrtcPtr crtc, int width, int height) 360f29dbc25Smrg{ 361f29dbc25Smrg ScrnInfoPtr pScrni = crtc->scrn; 362f29dbc25Smrg GeodePtr pGeode = GEODEPTR(pScrni); 363f29dbc25Smrg LXCrtcPrivatePtr lx_crtc = crtc->driver_private; 364f29dbc25Smrg unsigned int rpitch, size; 365f29dbc25Smrg 366f29dbc25Smrg rpitch = pScrni->displayWidth * (pScrni->bitsPerPixel / 8); 367f29dbc25Smrg size = rpitch * height; 368f29dbc25Smrg 369f29dbc25Smrg lx_crtc->rotate_mem = GeodeAllocOffscreen(pGeode, size, 4); 370f29dbc25Smrg 371f29dbc25Smrg if (lx_crtc->rotate_mem == NULL) { 372f29dbc25Smrg xf86DrvMsg(pScrni->scrnIndex, X_ERROR, 373f29dbc25Smrg "Couldn't allocate the shadow memory for rotation\n"); 374f29dbc25Smrg xf86DrvMsg(pScrni->scrnIndex, X_ERROR, 375f29dbc25Smrg " You need 0x%x bytes, but only 0x%x bytes are available\n", 376f29dbc25Smrg size, GeodeOffscreenFreeSize(pGeode)); 377f29dbc25Smrg 378f29dbc25Smrg return NULL; 379f29dbc25Smrg } 380f29dbc25Smrg 381f29dbc25Smrg memset(pGeode->FBBase + lx_crtc->rotate_mem->offset, 0, size); 382f29dbc25Smrg return pGeode->FBBase + lx_crtc->rotate_mem->offset; 383f29dbc25Smrg} 384f29dbc25Smrg 385f29dbc25Smrgstatic PixmapPtr 386f29dbc25Smrglx_crtc_shadow_create(xf86CrtcPtr crtc, void *data, int width, int height) 387f29dbc25Smrg{ 388f29dbc25Smrg ScrnInfoPtr pScrni = crtc->scrn; 389f29dbc25Smrg GeodeRec *pGeode = GEODEPTR(pScrni); 390f29dbc25Smrg PixmapPtr rpixmap; 391f29dbc25Smrg 392f29dbc25Smrg if (!data) 393f29dbc25Smrg data = lx_crtc_shadow_allocate(crtc, width, height); 394f29dbc25Smrg 395f29dbc25Smrg rpixmap = GetScratchPixmapHeader(pScrni->pScreen, 396f29dbc25Smrg width, height, pScrni->depth, pScrni->bitsPerPixel, pGeode->Pitch, 397f29dbc25Smrg data); 398f29dbc25Smrg 399f29dbc25Smrg if (rpixmap == NULL) { 400f29dbc25Smrg xf86DrvMsg(pScrni->scrnIndex, X_ERROR, 401f29dbc25Smrg "Couldn't allocate shadow pixmap for rotated CRTC\n"); 402f29dbc25Smrg } 403f29dbc25Smrg 404f29dbc25Smrg return rpixmap; 405f29dbc25Smrg} 406f29dbc25Smrg 407f29dbc25Smrgstatic void 408f29dbc25Smrglx_crtc_shadow_destroy(xf86CrtcPtr crtc, PixmapPtr rpixmap, void *data) 409f29dbc25Smrg{ 410f29dbc25Smrg ScrnInfoPtr pScrni = crtc->scrn; 411f29dbc25Smrg GeodeRec *pGeode = GEODEPTR(pScrni); 412f29dbc25Smrg LXCrtcPrivatePtr lx_crtc = crtc->driver_private; 413f29dbc25Smrg 414f29dbc25Smrg if (rpixmap) 415f29dbc25Smrg FreeScratchPixmapHeader(rpixmap); 416f29dbc25Smrg 417f29dbc25Smrg if (data) { 418f29dbc25Smrg gp_wait_until_idle(); 419f29dbc25Smrg GeodeFreeOffscreen(pGeode, lx_crtc->rotate_mem); 420f29dbc25Smrg lx_crtc->rotate_mem = NULL; 421f29dbc25Smrg } 422f29dbc25Smrg} 423f29dbc25Smrg 424f29dbc25Smrgstatic void 425f29dbc25Smrglx_crtc_set_cursor_colors(xf86CrtcPtr crtc, int bg, int fg) 426f29dbc25Smrg{ 427f29dbc25Smrg vg_set_mono_cursor_colors(bg, fg); 428f29dbc25Smrg} 429f29dbc25Smrg 430f29dbc25Smrgstatic void 431f29dbc25Smrglx_crtc_set_cursor_position(xf86CrtcPtr crtc, int x, int y) 432f29dbc25Smrg{ 433f29dbc25Smrg VG_PANNING_COORDINATES panning; 434f29dbc25Smrg vg_set_cursor_position(x, y, &panning); 435f29dbc25Smrg} 436f29dbc25Smrg 437f29dbc25Smrgstatic void 438f29dbc25Smrglx_crtc_show_cursor(xf86CrtcPtr crtc) 439f29dbc25Smrg{ 440f29dbc25Smrg vg_set_cursor_enable(1); 441f29dbc25Smrg} 442f29dbc25Smrg 443f29dbc25Smrgstatic void 444f29dbc25Smrglx_crtc_hide_cursor(xf86CrtcPtr crtc) 445f29dbc25Smrg{ 446f29dbc25Smrg vg_set_cursor_enable(0); 447f29dbc25Smrg} 448f29dbc25Smrg 449f29dbc25Smrgstatic void 450f29dbc25Smrglx_crtc_load_cursor_argb(xf86CrtcPtr crtc, CARD32 *image) 451f29dbc25Smrg{ 452f29dbc25Smrg LXLoadARGBCursorImage(crtc->scrn, (unsigned char *) image); 453f29dbc25Smrg} 454f29dbc25Smrg 455f29dbc25Smrgstatic const xf86CrtcFuncsRec lx_crtc_funcs = { 456f29dbc25Smrg .dpms = lx_crtc_dpms, 457f29dbc25Smrg .lock = lx_crtc_lock, 458f29dbc25Smrg .unlock = lx_crtc_unlock, 459f29dbc25Smrg .mode_fixup = lx_crtc_mode_fixup, 460f29dbc25Smrg .prepare = lx_crtc_prepare, 461f29dbc25Smrg .mode_set = lx_crtc_mode_set, 462f29dbc25Smrg .commit = lx_crtc_commit, 463f29dbc25Smrg .gamma_set = lx_crtc_gamma_set, 464f29dbc25Smrg .shadow_create = lx_crtc_shadow_create, 465f29dbc25Smrg .shadow_allocate = lx_crtc_shadow_allocate, 466f29dbc25Smrg .shadow_destroy = lx_crtc_shadow_destroy, 467f29dbc25Smrg .set_cursor_colors = lx_crtc_set_cursor_colors, 468f29dbc25Smrg .set_cursor_position = lx_crtc_set_cursor_position, 469f29dbc25Smrg .show_cursor = lx_crtc_show_cursor, 470f29dbc25Smrg .hide_cursor = lx_crtc_hide_cursor, 471f29dbc25Smrg .load_cursor_argb = lx_crtc_load_cursor_argb, 472f29dbc25Smrg}; 473f29dbc25Smrg 474f29dbc25Smrgvoid 475f29dbc25SmrgLXSetupCrtc(ScrnInfoPtr pScrni) 476f29dbc25Smrg{ 477f29dbc25Smrg xf86CrtcPtr crtc; 478f29dbc25Smrg LXCrtcPrivatePtr lxpriv; 479f29dbc25Smrg 480f29dbc25Smrg crtc = xf86CrtcCreate(pScrni, &lx_crtc_funcs); 481f29dbc25Smrg 482f29dbc25Smrg if (crtc == NULL) { 483f29dbc25Smrg ErrorF("ERROR - failed to create a CRTC\n"); 484f29dbc25Smrg return; 485f29dbc25Smrg } 486f29dbc25Smrg 487f29dbc25Smrg lxpriv = xnfcalloc(sizeof(LXCrtcPrivateRec), 1); 488f29dbc25Smrg 489f29dbc25Smrg if (!lxpriv) { 490f29dbc25Smrg xf86CrtcDestroy(crtc); 491f29dbc25Smrg ErrorF("unable to allocate memory for lxpriv\n"); 492f29dbc25Smrg return; 493f29dbc25Smrg } 494f29dbc25Smrg 495f29dbc25Smrg crtc->driver_private = lxpriv; 496f29dbc25Smrg} 497