pnl_bios.c revision 79d5fcd7
1/* Copyright (c) 2005 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/*
27 * File Contents:   This file panel functions which query for the BIOS for
28 *                  current FP Parameters.
29 *
30 * SubModule:       Geode FlatPanel library
31 * */
32
33#include "panel.h"
34
35#if defined(_WIN32)             /* windows */
36extern unsigned long gfx_cpu_version;
37extern void gfx_outw(unsigned short port, unsigned short data);
38extern unsigned short gfx_inw(unsigned short port);
39#endif
40
41#define SOFTVGA_DISPLAY_ENABLE   0x50
42#define SOFTVGA_FPRESOLUTION     0x52
43#define SOFTVGA_FPCLOCKFREQUENCY 0x54
44
45/* SOFTVG VIRTUAL REGISTER DEFINITIONS */
46
47#define VR_INDEX                0xAC1C
48#define VR_DATA                 0xAC1E
49#define VR_UNLOCK               0xFC53
50#define VRC_VG                  0x0002  /* SoftVG Virtual Register Class    */
51#define VG_MEM_SIZE             0x0000  /* MemSize Virtual Register             */
52#define FP_DETECT_MASK          0x8000
53
54#define VG_FP_TYPE      0x0002  /* Flat Panel Info Virtual Register */
55
56#define FP_DEV_MASK     0x0003  /* Flat Panel type                                      */
57#define FP_TYPE_SSTN	0x0000  /* SSTN panel type value                        */
58#define FP_TYPE_DSTN	0x0001  /* DSTN panel type value                        */
59#define FP_TYPE_TFT		0x0002  /* TFT panel type value                         */
60#define FP_TYPE_LVDS	0x0003  /* LVDS panel type value                        */
61
62#define FP_RESOLUTION_MASK      0x0038
63#define FP_RES_6X4		0x0000  /* 640x480 resolution value             */
64#define FP_RES_8X6		0x0008  /* 800x600 resolution value             */
65#define FP_RES_10X7		0x0010  /* 1024x768 resolution value            */
66#define FP_RES_11X8	0x0018  /* 1152x864 resolution value            */
67#define FP_RES_12X10	0x0020  /* 1280x1024 resolution value           */
68#define FP_RES_16X12	0x0028  /* 1600x1200 resolution value           */
69
70#define FP_WIDTH_MASK   0x01C0
71#define FP_WIDTH_8		0x0000  /* 8 bit data bus width                         */
72#define FP_WIDTH_9		0x0040  /* 9 bit data bus width                         */
73#define FP_WIDTH_12		0x0080  /* 12 bit data bus width                        */
74#define FP_WIDTH_18		0x00C0  /* 18 bit data bus width                        */
75#define FP_WIDTH_24		0x0100  /* 24 bit data bus width                        */
76#define FP_WIDTH_16		0x0140  /* 16 bit data bus width - 16 bit
77                                         * Mono DSTN only                                       */
78
79#define FP_COLOR_MASK   0x0200
80#define FP_COLOR_COLOR	0x0000  /* Color panel                                          */
81#define FP_COLOR_MONO	0x0200  /* Mono Panel                                           */
82
83#define FP_PPC_MASK     0x0400
84#define FP_PPC_1PPC		0x0000  /* One pixel per clock                          */
85#define FP_PPC_2PPC		0x0400  /* Two pixels per clock                         */
86
87#define FP_HPOL_MASK    0x0800
88#define	FP_H_POL_LGH	0x0000  /* HSync at panel, normally low,
89                                 * active high                                          */
90#define FP_H_POL_HGL	0x0800  /* HSync at panel, normally high,
91                                 * active low                                           */
92
93#define FP_VPOL_MASK    0x1000
94#define FP_V_POL_LGH	0x0000  /* VSync at panel, normally low,
95                                 * active high                                          */
96#define FP_V_POL_HGL	0x1000  /* VSync at panel, normally high,
97                                 * active low                                           */
98
99#define FP_REF_MASK     0xE000
100#define FP_REF_60		0x0000  /* 60Hz refresh rate                            */
101#define FP_REF_70		0x2000  /* 70Hz refresh rate                            */
102#define FP_REF_72		0x4000  /* 72Hz refresh rate                            */
103#define FP_REF_75		0x6000  /* 75Hz refresh rate                            */
104#define FP_REF_85		0x8000  /* 85Hz refresh rate                            */
105#define FP_REF_90		0xA000  /* 90Hz refresh rate                            */
106#define FP_REF_100		0xC000  /* 100Hz refresh rate                           */
107
108/*-----------------------------------------------------------------
109 * Pnl_IsPanelEnabledInBIOS
110 *
111 * Description:	This function specifies whether the panel is enabled
112 *				by the BIOS or not.
113 *  parameters: none.
114 *      return: 1 - Enabled, 0 - Disabled
115 *-----------------------------------------------------------------*/
116int
117Pnl_IsPanelEnabledInBIOS(void)
118{
119    unsigned char ret = 0;
120
121    if ((gfx_cpu_version & 0xFF) == GFX_CPU_REDCLOUD) {
122        unsigned short data;
123
124        gfx_outw(VR_INDEX, VR_UNLOCK);
125        gfx_outw(VR_INDEX, (VRC_VG << 8) | VG_MEM_SIZE);
126        data = gfx_inw(VR_DATA);
127        if (data & FP_DETECT_MASK)
128            ret = 1;
129    }
130    else {
131        unsigned short crtcindex, crtcdata;
132
133        crtcindex = (gfx_inb(0x3CC) & 0x01) ? 0x3D4 : 0x3B4;
134        crtcdata = crtcindex + 1;
135
136        /* CHECK DisplayEnable Reg in SoftVGA */
137
138        gfx_outb(crtcindex, (unsigned char) SOFTVGA_DISPLAY_ENABLE);
139        ret = gfx_inb(crtcdata);
140    }
141
142    return (ret & 0x1);
143}
144
145/*-----------------------------------------------------------------
146 * Pnl_GetPanelInfoFromBIOS
147 *
148 * Description:	This function queries the panel information from
149 *              the BIOS.
150 *  parameters:
151 *        xres: width of the panel configured
152 *        yres: height of the panel configured
153 *         bpp: depth of the panel configured
154 *          hz: vertical frequency of the panel configured
155 *      return: none
156 *-----------------------------------------------------------------*/
157void
158Pnl_GetPanelInfoFromBIOS(int *xres, int *yres, int *bpp, int *hz)
159{
160    unsigned short crtcindex, crtcdata;
161    unsigned short ret;
162
163    if ((gfx_cpu_version & 0xFF) == GFX_CPU_REDCLOUD) {
164        gfx_outw(VR_INDEX, VR_UNLOCK);
165        gfx_outw(VR_INDEX, (VRC_VG << 8) | VG_FP_TYPE);
166        ret = gfx_inw(VR_DATA);
167        switch (ret & FP_RESOLUTION_MASK) {
168        case FP_RES_6X4:
169            *xres = 640;
170            *yres = 480;
171            break;
172        case FP_RES_8X6:
173            *xres = 800;
174            *yres = 600;
175            break;
176        case FP_RES_10X7:
177            *xres = 1024;
178            *yres = 768;
179            break;
180        case FP_RES_11X8:
181            *xres = 1152;
182            *yres = 864;
183            break;
184        case FP_RES_12X10:
185            *xres = 1280;
186            *yres = 1024;
187            break;
188        case FP_RES_16X12:
189            *xres = 1600;
190            *yres = 1200;
191            break;
192        }
193
194        switch (ret & FP_WIDTH_MASK) {
195        case FP_WIDTH_8:
196            *bpp = 8;
197            break;
198        case FP_WIDTH_9:
199            *bpp = 9;
200            break;
201        case FP_WIDTH_12:
202            *bpp = 12;
203            break;
204        case FP_WIDTH_18:
205            *bpp = 18;
206            break;
207        case FP_WIDTH_24:
208            *bpp = 24;
209            break;
210        case FP_WIDTH_16:
211            *bpp = 16;
212            break;
213        }
214
215        switch (ret & FP_REF_MASK) {
216        case FP_REF_60:
217            *hz = 60;
218            break;
219        case FP_REF_70:
220            *hz = 70;
221            break;
222        case FP_REF_72:
223            *hz = 72;
224            break;
225        case FP_REF_75:
226            *hz = 75;
227            break;
228        case FP_REF_85:
229            *hz = 85;
230            break;
231        case FP_REF_90:
232            *hz = 90;
233            break;
234        case FP_REF_100:
235            *hz = 100;
236            break;
237        }
238
239    }
240    else {
241        crtcindex = (gfx_inb(0x3CC) & 0x01) ? 0x3D4 : 0x3B4;
242        crtcdata = crtcindex + 1;
243
244        /* CHECK FPResolution Reg in SoftVGA */
245
246        gfx_outb(crtcindex, (unsigned char) SOFTVGA_FPRESOLUTION);
247        ret = gfx_inb(crtcdata);
248
249        switch (ret & 0x3) {
250        case 0:
251            *xres = 640;
252            *yres = 480;
253            break;
254        case 1:
255            *xres = 800;
256            *yres = 600;
257            break;
258        case 2:
259            *xres = 1024;
260            *yres = 768;
261            break;
262        }
263
264        switch ((ret >> 4) & 0x3) {
265        case 0:
266            *bpp = 12;
267            break;
268        case 1:
269            *bpp = 18;
270            break;
271        case 2:
272            *bpp = 16;
273            break;
274        case 3:
275            *bpp = 8;
276            break;
277        }
278
279        /* CHECK FPClockFrequency Reg in SoftVGA */
280
281        gfx_outb(crtcindex, (unsigned char) SOFTVGA_FPCLOCKFREQUENCY);
282        *hz = gfx_inb(crtcdata);
283    }
284}
285