pnl_bios.c revision f29dbc25
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 Paramters.
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    } else {
130        unsigned short crtcindex, crtcdata;
131
132        crtcindex = (gfx_inb(0x3CC) & 0x01) ? 0x3D4 : 0x3B4;
133        crtcdata = crtcindex + 1;
134
135        /* CHECK DisplayEnable Reg in SoftVGA */
136
137        gfx_outb(crtcindex, (unsigned char)SOFTVGA_DISPLAY_ENABLE);
138        ret = gfx_inb(crtcdata);
139    }
140
141    return (ret & 0x1);
142}
143
144/*-----------------------------------------------------------------
145 * Pnl_GetPanelInfoFromBIOS
146 *
147 * Description:	This function queries the panel information from
148 *              the BIOS.
149 *  parameters:
150 *        xres: width of the panel configured
151 *        yres: height of the panel configured
152 *         bpp: depth of the panel configured
153 *          hz: vertical frequency of the panel configured
154 *      return: none
155 *-----------------------------------------------------------------*/
156void
157Pnl_GetPanelInfoFromBIOS(int *xres, int *yres, int *bpp, int *hz)
158{
159    unsigned short crtcindex, crtcdata;
160    unsigned short ret;
161
162    if ((gfx_cpu_version & 0xFF) == GFX_CPU_REDCLOUD) {
163        gfx_outw(VR_INDEX, VR_UNLOCK);
164        gfx_outw(VR_INDEX, (VRC_VG << 8) | VG_FP_TYPE);
165        ret = gfx_inw(VR_DATA);
166        switch (ret & FP_RESOLUTION_MASK) {
167        case FP_RES_6X4:
168            *xres = 640;
169            *yres = 480;
170            break;
171        case FP_RES_8X6:
172            *xres = 800;
173            *yres = 600;
174            break;
175        case FP_RES_10X7:
176            *xres = 1024;
177            *yres = 768;
178            break;
179        case FP_RES_11X8:
180            *xres = 1152;
181            *yres = 864;
182            break;
183        case FP_RES_12X10:
184            *xres = 1280;
185            *yres = 1024;
186            break;
187        case FP_RES_16X12:
188            *xres = 1600;
189            *yres = 1200;
190            break;
191        }
192
193        switch (ret & FP_WIDTH_MASK) {
194        case FP_WIDTH_8:
195            *bpp = 8;
196            break;
197        case FP_WIDTH_9:
198            *bpp = 9;
199            break;
200        case FP_WIDTH_12:
201            *bpp = 12;
202            break;
203        case FP_WIDTH_18:
204            *bpp = 18;
205            break;
206        case FP_WIDTH_24:
207            *bpp = 24;
208            break;
209        case FP_WIDTH_16:
210            *bpp = 16;
211            break;
212        }
213
214        switch (ret & FP_REF_MASK) {
215        case FP_REF_60:
216            *hz = 60;
217            break;
218        case FP_REF_70:
219            *hz = 70;
220            break;
221        case FP_REF_72:
222            *hz = 72;
223            break;
224        case FP_REF_75:
225            *hz = 75;
226            break;
227        case FP_REF_85:
228            *hz = 85;
229            break;
230        case FP_REF_90:
231            *hz = 90;
232            break;
233        case FP_REF_100:
234            *hz = 100;
235            break;
236        }
237
238    } else {
239        crtcindex = (gfx_inb(0x3CC) & 0x01) ? 0x3D4 : 0x3B4;
240        crtcdata = crtcindex + 1;
241
242        /* CHECK FPResolution Reg in SoftVGA */
243
244        gfx_outb(crtcindex, (unsigned char)SOFTVGA_FPRESOLUTION);
245        ret = gfx_inb(crtcdata);
246
247        switch (ret & 0x3) {
248        case 0:
249            *xres = 640;
250            *yres = 480;
251            break;
252        case 1:
253            *xres = 800;
254            *yres = 600;
255            break;
256        case 2:
257            *xres = 1024;
258            *yres = 768;
259            break;
260        }
261
262        switch ((ret >> 4) & 0x3) {
263        case 0:
264            *bpp = 12;
265            break;
266        case 1:
267            *bpp = 18;
268            break;
269        case 2:
270            *bpp = 16;
271            break;
272        case 3:
273            *bpp = 8;
274            break;
275        }
276
277        /* CHECK FPClockFrequency Reg in SoftVGA */
278
279        gfx_outb(crtcindex, (unsigned char)SOFTVGA_FPCLOCKFREQUENCY);
280        *hz = gfx_inb(crtcdata);
281    }
282}
283