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/* Reference: Video Graphics Suite Specification: 27f29dbc25Smrg * VG Config Register (0x00) page 16 28f29dbc25Smrg * VG FP Register (0x02) page 18 29f29dbc25Smrg */ 30f29dbc25Smrg 31f29dbc25Smrg#ifdef HAVE_CONFIG_H 32f29dbc25Smrg#include "config.h" 33f29dbc25Smrg#endif 34f29dbc25Smrg 35f29dbc25Smrg#include <stdio.h> 36f29dbc25Smrg 3700be8644Schristos#include "xorg-server.h" 3800be8644Schristos 39f29dbc25Smrg#include "xf86.h" 40f29dbc25Smrg#include "compiler.h" 41f29dbc25Smrg#include "xf86Modes.h" 42f29dbc25Smrg#include "geode.h" 43f29dbc25Smrg 44f29dbc25Smrg#define LX_READ_VG(reg) \ 45f29dbc25Smrg (outw(0xAC1C,0xFC53), outw(0xAC1C,0x0200|(reg)), inw(0xAC1E)) 46f29dbc25Smrg 47f29dbc25Smrg/* This is borrowed from xerver/hw/xfree86/modes */ 48f29dbc25Smrg 49f29dbc25Smrg#define MODEPREFIX NULL, NULL, NULL, 0, M_T_DRIVER 50f29dbc25Smrg#define MODESUFFIX 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,FALSE,FALSE,0,NULL,0,0.0,0.0 51f29dbc25Smrg 52f29dbc25SmrgDisplayModeRec lx_panel_modes[] = { 53f29dbc25Smrg {MODEPREFIX, 31200, 320, 354, 384, 400, 0, 240, 249, 253, 260, 0, 5404007ebaSmrg V_NHSYNC | V_NVSYNC, MODESUFFIX} 5504007ebaSmrg , /* 320x200@75 */ 56f29dbc25Smrg {MODEPREFIX, 25175, 640, 656, 744, 800, 0, 480, 490, 492, 525, 0, 5704007ebaSmrg V_NHSYNC | V_NVSYNC, MODESUFFIX} 5804007ebaSmrg , /* 640x480@60 */ 59f29dbc25Smrg {MODEPREFIX, 40000, 800, 840, 968, 1056, 0, 600, 601, 605, 628, 0, 6004007ebaSmrg V_NHSYNC | V_NVSYNC, MODESUFFIX} 6104007ebaSmrg , /* 880x600@60 */ 62f29dbc25Smrg {MODEPREFIX, 65000, 1024, 1048, 1184, 1344, 0, 768, 771, 777, 806, 0, 6304007ebaSmrg V_NHSYNC | V_NVSYNC, MODESUFFIX} 6404007ebaSmrg , /* 1024x768@60 */ 65f29dbc25Smrg {MODEPREFIX, 81600, 1152, 1216, 1336, 1520, 0, 864, 865, 868, 895, 0, 6604007ebaSmrg V_NHSYNC | V_NVSYNC, MODESUFFIX} 6704007ebaSmrg , /* 1152x864@60 */ 68170d5fdcSmrg {MODEPREFIX, 108000, 1280, 1328, 1440, 1688, 0, 1024, 1025, 1028, 1066, 0, 6904007ebaSmrg V_NHSYNC | V_NVSYNC, MODESUFFIX} 7004007ebaSmrg , /* 1280x1024@60 */ 71f29dbc25Smrg {MODEPREFIX, 162000, 1600, 1664, 1856, 2160, 0, 1200, 1201, 1204, 1250, 0, 7204007ebaSmrg V_NHSYNC | V_NVSYNC, MODESUFFIX} 7304007ebaSmrg , /* 1600x1200@60 */ 747aef237fSmrg {MODEPREFIX, 48960, 1024, 1064, 1168, 1312, 0, 600, 601, 604, 622, 0, 7504007ebaSmrg V_NHSYNC | V_NVSYNC, MODESUFFIX} 7604007ebaSmrg , /* 1024x600@60 wide panels */ 77f29dbc25Smrg}; 78f29dbc25Smrg 79f29dbc25Smrg/* Get the legacy panel size from VSA, and return the associated mode rec */ 80f29dbc25Smrg 81f29dbc25SmrgDisplayModePtr 827aef237fSmrgLXGetLegacyPanelMode(ScrnInfoPtr pScrni) 83f29dbc25Smrg{ 84f29dbc25Smrg unsigned short reg = LX_READ_VG(0x00); 85f29dbc25Smrg unsigned char ret = (reg >> 8) & 0x07; 8604007ebaSmrg 87f29dbc25Smrg if ((ret == 1 || ret == 5)) { 88f29dbc25Smrg 8904007ebaSmrg reg = LX_READ_VG(0x02); 9004007ebaSmrg ret = (reg >> 3) & 0x07; 91f29dbc25Smrg 9204007ebaSmrg /* FIXME: 7 is reserved in default. We use this value to support 9304007ebaSmrg * wide screen resolution 1024x600@80 now for panel. If you want to use 9404007ebaSmrg * that resolution, please assign ret to 7 manually here: 9504007ebaSmrg * "reg = 7" 9604007ebaSmrg * The user can use this entry for other wide screen resolutions. 9704007ebaSmrg */ 98f29dbc25Smrg 9904007ebaSmrg if (ret < 8) { 10004007ebaSmrg xf86DrvMsg(pScrni->scrnIndex, X_INFO, 10104007ebaSmrg " VSA Panel Mode is: %dx%d, pixel clock freq(kHz) is %d\n", 10204007ebaSmrg lx_panel_modes[ret].HDisplay, 10304007ebaSmrg lx_panel_modes[ret].VDisplay, lx_panel_modes[ret].Clock); 10404007ebaSmrg return &lx_panel_modes[ret]; 10504007ebaSmrg } 106f29dbc25Smrg 107f29dbc25Smrg } 108f29dbc25Smrg 109f29dbc25Smrg return NULL; 110f29dbc25Smrg} 111f29dbc25Smrg 112f29dbc25Smrg/* Construct a moderec from the specified panel mode */ 113f29dbc25Smrg 114f29dbc25SmrgDisplayModePtr 115861b9feeSmrgLXGetManualPanelMode(const char *modestr) 116f29dbc25Smrg{ 117f29dbc25Smrg int clock; 118f29dbc25Smrg int hactive, hsstart, hsend, htotal; 119f29dbc25Smrg int vactive, vsstart, vsend, vtotal; 120f29dbc25Smrg DisplayModePtr mode; 121f29dbc25Smrg char sname[32]; 122f29dbc25Smrg 123f29dbc25Smrg int ret = sscanf(modestr, "%d %d %d %d %d %d %d %d %d", 12404007ebaSmrg &clock, 12504007ebaSmrg &hactive, &hsstart, &hsend, &htotal, 12604007ebaSmrg &vactive, &vsstart, &vsend, &vtotal); 127f29dbc25Smrg 128f29dbc25Smrg if (ret != 9) 12904007ebaSmrg return NULL; 130f29dbc25Smrg 131f29dbc25Smrg mode = xnfcalloc(1, sizeof(DisplayModeRec)); 132f29dbc25Smrg 133f29dbc25Smrg if (mode == NULL) 13404007ebaSmrg return NULL; 135f29dbc25Smrg 136f29dbc25Smrg sprintf(sname, "%dx%d", hactive, vactive); 137f29dbc25Smrg 138f29dbc25Smrg mode->name = xnfalloc(strlen(sname) + 1); 139170d5fdcSmrg strcpy(mode->name, sname); 140f29dbc25Smrg 141f29dbc25Smrg mode->type = M_T_DRIVER | M_T_PREFERRED; 142f29dbc25Smrg mode->Clock = clock; 143f29dbc25Smrg mode->HDisplay = hactive; 144f29dbc25Smrg mode->HSyncStart = hsstart; 145f29dbc25Smrg mode->HSyncEnd = hsend; 146f29dbc25Smrg mode->HTotal = htotal; 147f29dbc25Smrg mode->VDisplay = vactive; 148f29dbc25Smrg mode->VSyncStart = vsstart; 149f29dbc25Smrg mode->VSyncEnd = vsend; 150f29dbc25Smrg mode->VTotal = vtotal; 151f29dbc25Smrg 152f29dbc25Smrg mode->prev = mode->next = NULL; 153f29dbc25Smrg 154f29dbc25Smrg return mode; 155f29dbc25Smrg} 156