gx2_9211.c revision 170d5fdc
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 contains the panel library files to the
28 *                  GX2 platforms with 9211 support.
29 *
30 * SubModule:       Geode FlatPanel library
31 * */
32
33#include "92xx.h"
34#include "gx2_9211.h"
35#include "pnl_defs.h"
36
37#if defined(_WIN32)                    /* windows */
38#include "gfx_defs.h"
39
40extern DEV_STATUS gfx_msr_read(unsigned int device, unsigned int msrRegister,
41    Q_WORD * msrValue);
42extern DEV_STATUS gfx_msr_write(unsigned int device, unsigned int msrRegister,
43    Q_WORD * msrValue);
44#endif
45
46static unsigned long FPBaseAddr;
47
48void
49SetFPBaseAddr(unsigned long addr)
50{
51
52    FPBaseAddr = addr;
53}
54
55/****************************************************************************
56 * protected_mode_access( unsigned long mode, unsigned long width,
57 * 		unsigned long addr, unsigned char* pdata )
58 * This function provides access to physical memory at the requested address.
59 *
60 * mode is:
61 *        GX2_READ or GX2_WRITE (accesses a single byte, word or double word
62 *        	depending on the value of "width".  Only 1, 2 or 4 supported).
63 *        READ_BYTES, WRITE_BYTES accesses "width" number of bytes (8 bits)
64 *        READ_WORDS, WRITE_WORDS accesses "width" number of words (16 bits)
65 *        READ_DWORDS, WRITE_DWORDS accesses "width" number of dwords (32
66 *        	bits)
67 *
68 * width is:
69 * 		  The size of the access.  For READ or WRITE, only 1, 2 and 4 are
70 *        	supported.  For other modes, width is not limited but will cause
71 *        	paging if the block traverses page boundaries.
72 *
73 * addr is:
74 * 		  The physical address being accessed
75 *
76 * pdata is:
77 * 		  A pointer to the data to be read or written into.
78 *
79 * NOTE! WORD or DWORD accesses can only be made on WORD or DWORD boundaries!
80 ****************************************************************************/
81void
82protected_mode_access(unsigned long mode,
83    unsigned long width, unsigned long addr, char *pdata)
84{
85    void *ptr = (void *)(FPBaseAddr + addr);
86
87    /* type specific buffer pointers */
88    char *byte_data = (char *)pdata;
89    unsigned long *word_data = (unsigned long *)pdata;
90    unsigned long *dword_data = (unsigned long *)pdata;
91
92    if (mode == GX2_READ) {
93        switch (width) {
94        case FOUR_BYTES:
95            *(dword_data) = (unsigned long)(*(unsigned long *)ptr);
96            break;
97        case TWO_BYTES:
98            *(word_data) = (unsigned long)(*(unsigned long *)ptr);
99            break;
100        default:
101            *(byte_data) = (char)(*(char *)ptr);
102            break;
103        }
104    } /* end  GX2_READ */
105    else if (mode == GX2_WRITE) {
106        switch (width) {
107        case FOUR_BYTES:
108            *(unsigned long *)ptr = *dword_data;
109            break;
110        case TWO_BYTES:
111            *(unsigned long *)ptr = *word_data;
112            break;
113        default:
114            *(char *)ptr = *byte_data;
115            break;
116        }                              /* end switch(mode) */
117    }
118    /* end case GX2_WRITE */
119    return;
120
121}                                      /* End of protected_mode_access. */
122
123/*************************************************************************
124 * void write_video_reg64_low( unsigned long offset, unsigned long value )
125 *
126 * Writes value to the low 32 bits of the 64 bit memory mapped video
127 * register indicated by offset.
128 * This function uses Sys_info.video_reg_base as the base address, so
129 * the value of offset should be with respect to this base.
130 *************************************************************************/
131void
132write_video_reg64_low(unsigned long offset, unsigned long value)
133{
134    protected_mode_access(GX2_WRITE, FOUR_BYTES,
135        FPBaseAddr + offset, (char *)&value);
136}                                      /*end write_video_reg64_low() */
137
138/*************************************************************************
139 * unsigned long read_video_reg64_low( unsigned long offset )
140 *
141 * Returns the contents of the low 32 bits of the 64 bit memory mapped
142 * video register indicated by offset.
143 * This function uses Sys_info.video_reg_base as the base address, so
144 * the value of offset should be with respect to this base.
145 *************************************************************************/
146unsigned long
147read_video_reg64_low(unsigned long offset)
148{
149    unsigned long data;
150
151    protected_mode_access(GX2_READ, FOUR_BYTES,
152        FPBaseAddr + offset, (char *)&data);
153    return (data);
154}                                      /*end read_video_reg64_low() */
155
156/*****************************************************************************
157 * void Redcloud_fp_reg(int mode, unsigned long address, unsigned long *data)
158 *
159 * Writes and reads dwords to the Redcloud flat panel registers in the
160 * Redcloud Display Filter.  There's no clock control, chip select or timing
161 * to deal with.
162 * This routine expects the actual GX2 macro definitions for the address.
163 *
164 * Parameters:
165 *			mode:		An integer value for a GX2_READ or GX2_WRITE operation
166 *						0 = GX2_Read and 1 = GX2_Write
167 *			address:	A dword value representing the offset of the register.
168 *			data:		A pointer to a dword value that is to be written in to
169 *						the required register.  In case of a Read operation
170 *						this will point to the result of the Read operation.
171 ****************************************************************************/
172void
173Redcloud_fp_reg(int mode, unsigned long address, unsigned long *data)
174{
175    if (mode == GX2_READ) {
176        *data = read_video_reg64_low(address);
177    } else {
178        write_video_reg64_low(address, *data);
179    }
180
181}                                      /* End of Redcloud_fp_reg() */
182
183/*-------------------------------------------------------------------
184 *
185 * SET_92XX_MODE_PARAMS
186 * This routine sets the 9211 mode parameters.
187 *
188 *-------------------------------------------------------------------*/
189
190void
191set_Redcloud_92xx_mode_params(int mode)
192{
193    CS92xx_MODE *pMode = &FPModeParams[mode];
194    unsigned long temp_data = 0;
195    unsigned long base_data;
196    QQ_WORD msrValue;
197
198    /* on a Redcloud, we need to set up the DF pad select MSR */
199    if (gfx_msr_read(RC_ID_DF, GX2_VP_MSR_PAD_SELECT, &msrValue) == FOUND) {
200        msrValue.low &= ~GX2_VP_PAD_SELECT_MASK;
201        if (pMode->panel_type == PNL_TFT || pMode->panel_type == PNL_TWOP) {
202            msrValue.low = GX2_VP_PAD_SELECT_TFT;
203        } else {
204            msrValue.low = GX2_VP_PAD_SELECT_DSTN;
205        }
206        gfx_msr_write(RC_ID_DF, GX2_VP_MSR_PAD_SELECT, &msrValue);
207    }
208
209    /* Turn the 92xx power off before setting any new parameters. */
210    temp_data = pMode->power_management & ~GX2_FP_PM_PWR_ON;
211    Redcloud_fp_reg(GX2_WRITE, GX2_FP_PWR_MAN, (unsigned long *)&temp_data);
212
213    /* Set 9211 registers using the desired panel settings */
214
215    Redcloud_fp_reg(GX2_WRITE, GX2_FP_PAN_TIMING1,
216        (unsigned long *)&pMode->panel_timing1);
217
218    /* On Redcloud, bit 31 is now reserved. */
219    temp_data = pMode->panel_timing2 & 0x7FFFFFFF;
220    Redcloud_fp_reg(GX2_WRITE, GX2_FP_PAN_TIMING2,
221        (unsigned long *)&temp_data);
222
223    /* On Redcloud TFT parts, set this to 0x70 so all 8 bits per color run
224     * thru fp crc but only non-TFT parts.  Otherwise, set it to be 0x50.
225     * (source: Larry G.).
226     */
227    if (pMode->panel_type == PNL_TFT || pMode->panel_type == PNL_TWOP) {
228        temp_data = GX2_FP_CRC_PASS_THRU_MASK;
229    } else {
230        temp_data = pMode->rev_C_dither_frc;
231    }
232    Redcloud_fp_reg(GX2_WRITE, GX2_FP_DITH_FR_CNTRL,
233        (unsigned long *)&temp_data);
234    Redcloud_fp_reg(GX2_WRITE, GX2_FP_BLFSR,
235        (unsigned long *)&pMode->blue_lsfr_seed);
236    Redcloud_fp_reg(GX2_WRITE, GX2_FP_RLFSR,
237        (unsigned long *)&pMode->red_green_lsfr_seed);
238
239    /* Set the memory information, then the power register last.
240     * This will turn the panel on at the 9211.
241     */
242
243    Redcloud_fp_reg(GX2_READ, GX2_FP_FBB, (unsigned long *)&base_data);
244    if (base_data != 0x41780000) {
245        base_data = 0x41780000;
246        Redcloud_fp_reg(GX2_WRITE, GX2_FP_FBB, (unsigned long *)&base_data);
247    }
248
249    Redcloud_fp_reg(GX2_WRITE, GX2_FP_PWR_MAN,
250        (unsigned long *)&pMode->power_management);
251
252}                                      /*end set_92xx_mode_params() */
253
254/* -----------------------------------------------------------------------
255 * SET_FLAT_PANEL_MODE
256 *
257 * This routine sets the specified flat panel moden parameters in
258 * the 9211.
259 * Returns PASS if successful, FAIL if the mode parameters could
260 * not be set.
261 *------------------------------------------------------------------------*/
262
263unsigned char
264set_Redcloud_92xx_mode(Pnl_PanelStat * pstat)
265{
266    int mode;
267
268    /* LOOP THROUGH THE AVAILABLE MODES TO FIND A MATCH */
269
270    for (mode = 0; mode < NUM_92XX_MODES; mode++) {
271        if ((FPModeParams[mode].xres == pstat->XRes) &&
272            (FPModeParams[mode].yres == pstat->YRes) &&
273            (FPModeParams[mode].bpp == pstat->Depth) &&
274            (FPModeParams[mode].panel_type == pstat->Type) &&
275            (FPModeParams[mode].color_type == pstat->MonoColor)) {
276
277            /* SET THE 92xx FOR THE SELECTED MODE */
278            set_Redcloud_92xx_mode_params(mode);
279            return TRUE;
280        }                              /* end if() */
281    }                                  /* end for() */
282    return FALSE;
283
284}                                      /* end set_Centaurus_92xx_mode() */
285
286void
287Redcloud_9211init(Pnl_PanelStat * pstat)
288{
289
290    set_Redcloud_92xx_mode(pstat);
291
292}
293