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 } 178 else { 179 write_video_reg64_low(address, *data); 180 } 181 182} /* End of Redcloud_fp_reg() */ 183 184/*------------------------------------------------------------------- 185 * 186 * SET_92XX_MODE_PARAMS 187 * This routine sets the 9211 mode parameters. 188 * 189 *-------------------------------------------------------------------*/ 190 191void 192set_Redcloud_92xx_mode_params(int mode) 193{ 194 CS92xx_MODE *pMode = &FPModeParams[mode]; 195 unsigned long temp_data = 0; 196 unsigned long base_data; 197 QQ_WORD msrValue; 198 199 /* on a Redcloud, we need to set up the DF pad select MSR */ 200 if (gfx_msr_read(RC_ID_DF, GX2_VP_MSR_PAD_SELECT, &msrValue) == FOUND) { 201 msrValue.low &= ~GX2_VP_PAD_SELECT_MASK; 202 if (pMode->panel_type == PNL_TFT || pMode->panel_type == PNL_TWOP) { 203 msrValue.low = GX2_VP_PAD_SELECT_TFT; 204 } 205 else { 206 msrValue.low = GX2_VP_PAD_SELECT_DSTN; 207 } 208 gfx_msr_write(RC_ID_DF, GX2_VP_MSR_PAD_SELECT, &msrValue); 209 } 210 211 /* Turn the 92xx power off before setting any new parameters. */ 212 temp_data = pMode->power_management & ~GX2_FP_PM_PWR_ON; 213 Redcloud_fp_reg(GX2_WRITE, GX2_FP_PWR_MAN, (unsigned long *) &temp_data); 214 215 /* Set 9211 registers using the desired panel settings */ 216 217 Redcloud_fp_reg(GX2_WRITE, GX2_FP_PAN_TIMING1, 218 (unsigned long *) &pMode->panel_timing1); 219 220 /* On Redcloud, bit 31 is now reserved. */ 221 temp_data = pMode->panel_timing2 & 0x7FFFFFFF; 222 Redcloud_fp_reg(GX2_WRITE, GX2_FP_PAN_TIMING2, 223 (unsigned long *) &temp_data); 224 225 /* On Redcloud TFT parts, set this to 0x70 so all 8 bits per color run 226 * thru fp crc but only non-TFT parts. Otherwise, set it to be 0x50. 227 * (source: Larry G.). 228 */ 229 if (pMode->panel_type == PNL_TFT || pMode->panel_type == PNL_TWOP) { 230 temp_data = GX2_FP_CRC_PASS_THRU_MASK; 231 } 232 else { 233 temp_data = pMode->rev_C_dither_frc; 234 } 235 Redcloud_fp_reg(GX2_WRITE, GX2_FP_DITH_FR_CNTRL, 236 (unsigned long *) &temp_data); 237 Redcloud_fp_reg(GX2_WRITE, GX2_FP_BLFSR, 238 (unsigned long *) &pMode->blue_lsfr_seed); 239 Redcloud_fp_reg(GX2_WRITE, GX2_FP_RLFSR, 240 (unsigned long *) &pMode->red_green_lsfr_seed); 241 242 /* Set the memory information, then the power register last. 243 * This will turn the panel on at the 9211. 244 */ 245 246 Redcloud_fp_reg(GX2_READ, GX2_FP_FBB, (unsigned long *) &base_data); 247 if (base_data != 0x41780000) { 248 base_data = 0x41780000; 249 Redcloud_fp_reg(GX2_WRITE, GX2_FP_FBB, (unsigned long *) &base_data); 250 } 251 252 Redcloud_fp_reg(GX2_WRITE, GX2_FP_PWR_MAN, 253 (unsigned long *) &pMode->power_management); 254 255} /*end set_92xx_mode_params() */ 256 257/* ----------------------------------------------------------------------- 258 * SET_FLAT_PANEL_MODE 259 * 260 * This routine sets the specified flat panel moden parameters in 261 * the 9211. 262 * Returns PASS if successful, FAIL if the mode parameters could 263 * not be set. 264 *------------------------------------------------------------------------*/ 265 266unsigned char 267set_Redcloud_92xx_mode(Pnl_PanelStat * pstat) 268{ 269 int mode; 270 271 /* LOOP THROUGH THE AVAILABLE MODES TO FIND A MATCH */ 272 273 for (mode = 0; mode < NUM_92XX_MODES; mode++) { 274 if ((FPModeParams[mode].xres == pstat->XRes) && 275 (FPModeParams[mode].yres == pstat->YRes) && 276 (FPModeParams[mode].bpp == pstat->Depth) && 277 (FPModeParams[mode].panel_type == pstat->Type) && 278 (FPModeParams[mode].color_type == pstat->MonoColor)) { 279 280 /* SET THE 92xx FOR THE SELECTED MODE */ 281 set_Redcloud_92xx_mode_params(mode); 282 return TRUE; 283 } /* end if() */ 284 } /* end for() */ 285 return FALSE; 286 287} /* end set_Centaurus_92xx_mode() */ 288 289void 290Redcloud_9211init(Pnl_PanelStat * pstat) 291{ 292 293 set_Redcloud_92xx_mode(pstat); 294 295} 296