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