1/* Copyright (c) 2008 Advanced Micro Devices, Inc. 2 * 3 * Permission is hereby granted, free of charge, to any person obtaining a copy 4 * of this software and associated documentation files (the "Software"), to 5 * deal in the Software without restriction, including without limitation the 6 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7 * sell copies of the Software, and to permit persons to whom the Software is 8 * furnished to do so, subject to the following conditions: 9 * 10 * The above copyright notice and this permission notice shall be included in 11 * all copies or substantial portions of the Software. 12 * 13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19 * IN THE SOFTWARE. 20 * 21 * Neither the name of the Advanced Micro Devices, Inc. nor the names of its 22 * contributors may be used to endorse or promote products derived from this 23 * software without specific prior written permission. 24 */ 25 26/* Reference: Video Graphics Suite Specification: 27 * VG Config Register (0x00) page 16 28 * VG FP Register (0x02) page 18 29 */ 30 31#ifdef HAVE_CONFIG_H 32#include "config.h" 33#endif 34 35#include <stdio.h> 36 37#include "xorg-server.h" 38 39#include "xf86.h" 40#include "compiler.h" 41#include "xf86Modes.h" 42#include "geode.h" 43 44#define LX_READ_VG(reg) \ 45 (outw(0xAC1C,0xFC53), outw(0xAC1C,0x0200|(reg)), inw(0xAC1E)) 46 47/* This is borrowed from xerver/hw/xfree86/modes */ 48 49#define MODEPREFIX NULL, NULL, NULL, 0, M_T_DRIVER 50#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 51 52DisplayModeRec lx_panel_modes[] = { 53 {MODEPREFIX, 31200, 320, 354, 384, 400, 0, 240, 249, 253, 260, 0, 54 V_NHSYNC | V_NVSYNC, MODESUFFIX} 55 , /* 320x200@75 */ 56 {MODEPREFIX, 25175, 640, 656, 744, 800, 0, 480, 490, 492, 525, 0, 57 V_NHSYNC | V_NVSYNC, MODESUFFIX} 58 , /* 640x480@60 */ 59 {MODEPREFIX, 40000, 800, 840, 968, 1056, 0, 600, 601, 605, 628, 0, 60 V_NHSYNC | V_NVSYNC, MODESUFFIX} 61 , /* 880x600@60 */ 62 {MODEPREFIX, 65000, 1024, 1048, 1184, 1344, 0, 768, 771, 777, 806, 0, 63 V_NHSYNC | V_NVSYNC, MODESUFFIX} 64 , /* 1024x768@60 */ 65 {MODEPREFIX, 81600, 1152, 1216, 1336, 1520, 0, 864, 865, 868, 895, 0, 66 V_NHSYNC | V_NVSYNC, MODESUFFIX} 67 , /* 1152x864@60 */ 68 {MODEPREFIX, 108000, 1280, 1328, 1440, 1688, 0, 1024, 1025, 1028, 1066, 0, 69 V_NHSYNC | V_NVSYNC, MODESUFFIX} 70 , /* 1280x1024@60 */ 71 {MODEPREFIX, 162000, 1600, 1664, 1856, 2160, 0, 1200, 1201, 1204, 1250, 0, 72 V_NHSYNC | V_NVSYNC, MODESUFFIX} 73 , /* 1600x1200@60 */ 74 {MODEPREFIX, 48960, 1024, 1064, 1168, 1312, 0, 600, 601, 604, 622, 0, 75 V_NHSYNC | V_NVSYNC, MODESUFFIX} 76 , /* 1024x600@60 wide panels */ 77}; 78 79/* Get the legacy panel size from VSA, and return the associated mode rec */ 80 81DisplayModePtr 82LXGetLegacyPanelMode(ScrnInfoPtr pScrni) 83{ 84 unsigned short reg = LX_READ_VG(0x00); 85 unsigned char ret = (reg >> 8) & 0x07; 86 87 if ((ret == 1 || ret == 5)) { 88 89 reg = LX_READ_VG(0x02); 90 ret = (reg >> 3) & 0x07; 91 92 /* FIXME: 7 is reserved in default. We use this value to support 93 * wide screen resolution 1024x600@80 now for panel. If you want to use 94 * that resolution, please assign ret to 7 manually here: 95 * "reg = 7" 96 * The user can use this entry for other wide screen resolutions. 97 */ 98 99 if (ret < 8) { 100 xf86DrvMsg(pScrni->scrnIndex, X_INFO, 101 " VSA Panel Mode is: %dx%d, pixel clock freq(kHz) is %d\n", 102 lx_panel_modes[ret].HDisplay, 103 lx_panel_modes[ret].VDisplay, lx_panel_modes[ret].Clock); 104 return &lx_panel_modes[ret]; 105 } 106 107 } 108 109 return NULL; 110} 111 112/* Construct a moderec from the specified panel mode */ 113 114DisplayModePtr 115LXGetManualPanelMode(const char *modestr) 116{ 117 int clock; 118 int hactive, hsstart, hsend, htotal; 119 int vactive, vsstart, vsend, vtotal; 120 DisplayModePtr mode; 121 char sname[32]; 122 123 int ret = sscanf(modestr, "%d %d %d %d %d %d %d %d %d", 124 &clock, 125 &hactive, &hsstart, &hsend, &htotal, 126 &vactive, &vsstart, &vsend, &vtotal); 127 128 if (ret != 9) 129 return NULL; 130 131 mode = xnfcalloc(1, sizeof(DisplayModeRec)); 132 133 if (mode == NULL) 134 return NULL; 135 136 sprintf(sname, "%dx%d", hactive, vactive); 137 138 mode->name = xnfalloc(strlen(sname) + 1); 139 strcpy(mode->name, sname); 140 141 mode->type = M_T_DRIVER | M_T_PREFERRED; 142 mode->Clock = clock; 143 mode->HDisplay = hactive; 144 mode->HSyncStart = hsstart; 145 mode->HSyncEnd = hsend; 146 mode->HTotal = htotal; 147 mode->VDisplay = vactive; 148 mode->VSyncStart = vsstart; 149 mode->VSyncEnd = vsend; 150 mode->VTotal = vtotal; 151 152 mode->prev = mode->next = NULL; 153 154 return mode; 155} 156