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