lx_panel.c revision 7aef237f
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
37f29dbc25Smrg#include "xf86.h"
38f29dbc25Smrg#include "compiler.h"
39f29dbc25Smrg#include "xf86Modes.h"
40f29dbc25Smrg#include "geode.h"
41f29dbc25Smrg
42f29dbc25Smrg#define LX_READ_VG(reg) \
43f29dbc25Smrg                (outw(0xAC1C,0xFC53), outw(0xAC1C,0x0200|(reg)), inw(0xAC1E))
44f29dbc25Smrg
45f29dbc25Smrg/* This is borrowed from xerver/hw/xfree86/modes */
46f29dbc25Smrg
47f29dbc25Smrg#define MODEPREFIX NULL, NULL, NULL, 0, M_T_DRIVER
48f29dbc25Smrg#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
49f29dbc25Smrg
50f29dbc25SmrgDisplayModeRec lx_panel_modes[] = {
51f29dbc25Smrg    {MODEPREFIX, 31200, 320, 354, 384, 400, 0, 240, 249, 253, 260, 0,
52f29dbc25Smrg	V_NHSYNC | V_NVSYNC, MODESUFFIX}
53f29dbc25Smrg    ,				       /* 320x200@75 */
54f29dbc25Smrg    {MODEPREFIX, 25175, 640, 656, 744, 800, 0, 480, 490, 492, 525, 0,
55f29dbc25Smrg	V_NHSYNC | V_NVSYNC, MODESUFFIX}
56f29dbc25Smrg    ,				       /* 640x480@60 */
57f29dbc25Smrg    {MODEPREFIX, 40000, 800, 840, 968, 1056, 0, 600, 601, 605, 628, 0,
58f29dbc25Smrg	V_NHSYNC | V_NVSYNC, MODESUFFIX}
59f29dbc25Smrg    ,				       /* 880x600@60 */
60f29dbc25Smrg    {MODEPREFIX, 65000, 1024, 1048, 1184, 1344, 0, 768, 771, 777, 806, 0,
61f29dbc25Smrg	V_NHSYNC | V_NVSYNC, MODESUFFIX}
62f29dbc25Smrg    ,				       /* 1024x768@60 */
63f29dbc25Smrg    {MODEPREFIX, 81600, 1152, 1216, 1336, 1520, 0, 864, 865, 868, 895, 0,
64f29dbc25Smrg	V_NHSYNC | V_NVSYNC, MODESUFFIX}
65f29dbc25Smrg    ,				       /* 1152x864@60 */
66170d5fdcSmrg    {MODEPREFIX, 108000, 1280, 1328, 1440, 1688, 0, 1024, 1025, 1028, 1066, 0,
67f29dbc25Smrg	V_NHSYNC | V_NVSYNC, MODESUFFIX}
68f29dbc25Smrg    ,				       /* 1280x1024@60 */
69f29dbc25Smrg    {MODEPREFIX, 162000, 1600, 1664, 1856, 2160, 0, 1200, 1201, 1204, 1250, 0,
70f29dbc25Smrg	V_NHSYNC | V_NVSYNC, MODESUFFIX}
71f29dbc25Smrg    ,				       /* 1600x1200@60 */
727aef237fSmrg    {MODEPREFIX, 48960, 1024, 1064, 1168, 1312, 0, 600, 601, 604, 622, 0,
737aef237fSmrg        V_NHSYNC | V_NVSYNC, MODESUFFIX}
747aef237fSmrg    ,				       /* 1024x600@60 wide panels */
75f29dbc25Smrg};
76f29dbc25Smrg
77f29dbc25Smrg/* Get the legacy panel size from VSA, and return the associated mode rec */
78f29dbc25Smrg
79f29dbc25SmrgDisplayModePtr
807aef237fSmrgLXGetLegacyPanelMode(ScrnInfoPtr pScrni)
81f29dbc25Smrg{
82f29dbc25Smrg    unsigned short reg = LX_READ_VG(0x00);
83f29dbc25Smrg    unsigned char ret = (reg >> 8) & 0x07;
84f29dbc25Smrg    if ((ret == 1 || ret == 5)) {
85f29dbc25Smrg
86f29dbc25Smrg	reg = LX_READ_VG(0x02);
87f29dbc25Smrg	ret = (reg >> 3) & 0x07;
88f29dbc25Smrg
89170d5fdcSmrg	/* FIXME: 7 is reserved in default. We use this value to support
90170d5fdcSmrg 	 * wide screen resolution 1024x600@80 now for panel. If you want to use
91170d5fdcSmrg 	 * that resolution, please assign ret to 7 manually here:
92170d5fdcSmrg 	 * "reg = 7"
93170d5fdcSmrg 	 * The user can use this entry for other wide screen resolutions.
94f29dbc25Smrg	 */
95f29dbc25Smrg
967aef237fSmrg	if (ret < 8) {
977aef237fSmrg	    xf86DrvMsg(pScrni->scrnIndex, X_INFO,
987aef237fSmrg		" VSA Panel Mode is: %dx%d, pixel clock freq(kHz) is %d\n",
997aef237fSmrg		lx_panel_modes[ret].HDisplay, lx_panel_modes[ret].VDisplay,
1007aef237fSmrg		lx_panel_modes[ret].Clock);
101f29dbc25Smrg	    return &lx_panel_modes[ret];
1027aef237fSmrg	}
103f29dbc25Smrg
104f29dbc25Smrg    }
105f29dbc25Smrg
106f29dbc25Smrg    return NULL;
107f29dbc25Smrg}
108f29dbc25Smrg
109f29dbc25Smrg/* Construct a moderec from the specified panel mode */
110f29dbc25Smrg
111f29dbc25SmrgDisplayModePtr
112f29dbc25SmrgLXGetManualPanelMode(char *modestr)
113f29dbc25Smrg{
114f29dbc25Smrg    int clock;
115f29dbc25Smrg    int hactive, hsstart, hsend, htotal;
116f29dbc25Smrg    int vactive, vsstart, vsend, vtotal;
117f29dbc25Smrg    DisplayModePtr mode;
118f29dbc25Smrg    char sname[32];
119f29dbc25Smrg
120f29dbc25Smrg    int ret = sscanf(modestr, "%d %d %d %d %d %d %d %d %d",
121f29dbc25Smrg	&clock,
122f29dbc25Smrg	&hactive, &hsstart, &hsend, &htotal,
123f29dbc25Smrg	&vactive, &vsstart, &vsend, &vtotal);
124f29dbc25Smrg
125f29dbc25Smrg    if (ret != 9)
126f29dbc25Smrg	return NULL;
127f29dbc25Smrg
128f29dbc25Smrg    mode = xnfcalloc(1, sizeof(DisplayModeRec));
129f29dbc25Smrg
130f29dbc25Smrg    if (mode == NULL)
131f29dbc25Smrg	return NULL;
132f29dbc25Smrg
133f29dbc25Smrg    sprintf(sname, "%dx%d", hactive, vactive);
134f29dbc25Smrg
135f29dbc25Smrg    mode->name = xnfalloc(strlen(sname) + 1);
136170d5fdcSmrg    strcpy(mode->name, sname);
137f29dbc25Smrg
138f29dbc25Smrg    mode->type = M_T_DRIVER | M_T_PREFERRED;
139f29dbc25Smrg    mode->Clock = clock;
140f29dbc25Smrg    mode->HDisplay = hactive;
141f29dbc25Smrg    mode->HSyncStart = hsstart;
142f29dbc25Smrg    mode->HSyncEnd = hsend;
143f29dbc25Smrg    mode->HTotal = htotal;
144f29dbc25Smrg    mode->VDisplay = vactive;
145f29dbc25Smrg    mode->VSyncStart = vsstart;
146f29dbc25Smrg    mode->VSyncEnd = vsend;
147f29dbc25Smrg    mode->VTotal = vtotal;
148f29dbc25Smrg
149f29dbc25Smrg    mode->prev = mode->next = NULL;
150f29dbc25Smrg
151f29dbc25Smrg    return mode;
152f29dbc25Smrg}
153