dora9211.c revision 04007eba
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 functions to interface 28 * the dorado platform. 29 * 30 * SubModule: Geode FlatPanel library 31 * */ 32 33#include "dora9211.h" 34 35void 36Dorado_Get_9211_Details(unsigned long flags, Pnl_PanelParams * pParam) 37{ 38 unsigned long DPanelType; 39 int i; 40 41 for (i = 0; i < 0x7fff; i++) { 42 } 43 44 Dorado9211GpioInit(); 45 46 for (i = 0; i < 5; i++) 47 toggle_Centaurus_9211_clock(); 48 49 if (flags & PNL_PANELCHIP) { 50 DPanelType = Dorado9211ReadReg(0x430); 51 52 if ((DPanelType & 0xFFFF0000) == 0x92110000) { /* found 9211 */ 53 /* check the values for revision ID */ 54 if (DPanelType >= 0x92110301) 55 pParam->PanelChip = PNL_9211_C; 56 else if ((DPanelType >= 0x92110101) && (DPanelType < 0x92110301)) 57 pParam->PanelChip = PNL_9211_A; 58 else 59 pParam->PanelChip = PNL_UNKNOWN_CHIP; 60 } 61 else { /* no 9211 present */ 62 pParam->PanelChip = PNL_UNKNOWN_CHIP; 63 } 64 } 65 66 if ((pParam->PanelChip != PNL_UNKNOWN_CHIP) && (flags & PNL_PANELSTAT)) { 67 unsigned long PanelTypeOrg; 68 unsigned char Panel_2Byte; 69 70 DPanelType = Dorado9211ReadReg(0x438); 71 DPanelType &= 0x00e8e8e8; 72 DPanelType |= 0x00170000; 73 Dorado9211WriteReg(0x438, DPanelType); 74 DPanelType = 0; 75 76 DPanelType = Dorado9211ReadReg(0x434); 77 DPanelType = (DPanelType >> (DRD_LCDRESGPIO1 + 1)); 78 PanelTypeOrg = DPanelType >> 8; 79 Panel_2Byte = (unsigned char) PanelTypeOrg; 80 Panel_2Byte = (Panel_2Byte >> (DRD_LCDRESGPIO2 - DRD_LCDRESGPIO1 - 1)); 81 DPanelType = (DPanelType | ((unsigned int) Panel_2Byte << 8)); 82 DPanelType = DPanelType >> 1; 83 PanelTypeOrg = DPanelType >> 8; 84 Panel_2Byte = (unsigned char) PanelTypeOrg; 85 Panel_2Byte = (Panel_2Byte >> (DRD_LCDRESGPIO3 - DRD_LCDRESGPIO2 - 1)); 86 DPanelType = (DPanelType | ((unsigned int) Panel_2Byte << 8)); 87 DPanelType = DPanelType >> 1; 88 PanelTypeOrg = DPanelType >> 8; 89 Panel_2Byte = (unsigned char) PanelTypeOrg; 90 Panel_2Byte = (Panel_2Byte >> (DRD_LCDRESGPIO4 - DRD_LCDRESGPIO3 - 1)); 91 DPanelType = (DPanelType | ((unsigned int) Panel_2Byte << 8)); 92 DPanelType = DPanelType >> 5; 93 DPanelType &= 0xf; 94 95 switch (DPanelType) { 96 case 8: 97 pParam->PanelStat.XRes = 800; 98 pParam->PanelStat.YRes = 600; 99 pParam->PanelStat.Depth = 18; 100 pParam->PanelStat.MonoColor = PNL_COLOR_PANEL; 101 pParam->PanelStat.Type = PNL_TFT; 102 break; 103 104 case 9: 105 pParam->PanelStat.XRes = 640; 106 pParam->PanelStat.YRes = 480; 107 pParam->PanelStat.Depth = 8; 108 pParam->PanelStat.MonoColor = PNL_COLOR_PANEL; 109 pParam->PanelStat.Type = PNL_SSTN; 110 break; 111 112 case 10: 113 pParam->PanelStat.XRes = 1024; 114 pParam->PanelStat.YRes = 768; 115 pParam->PanelStat.Depth = 18; 116 pParam->PanelStat.MonoColor = PNL_COLOR_PANEL; 117 pParam->PanelStat.Type = PNL_TFT; 118 break; 119 case 0: 120 case 1: 121 case 2: 122 case 3: 123 case 4: 124 case 5: 125 case 6: 126 case 7: 127 case 11: 128 pParam->PanelStat.XRes = 640; 129 pParam->PanelStat.YRes = 480; 130 pParam->PanelStat.Depth = 16; 131 pParam->PanelStat.MonoColor = PNL_COLOR_PANEL; 132 pParam->PanelStat.Type = PNL_DSTN; 133 break; 134 case 12: 135 pParam->PanelStat.XRes = 640; 136 pParam->PanelStat.YRes = 480; 137 pParam->PanelStat.Depth = 18; 138 pParam->PanelStat.MonoColor = PNL_COLOR_PANEL; 139 pParam->PanelStat.Type = PNL_TFT; 140 break; 141 case 13: 142 pParam->PanelStat.XRes = 1024; 143 pParam->PanelStat.YRes = 768; 144 pParam->PanelStat.Depth = 24; 145 pParam->PanelStat.MonoColor = PNL_COLOR_PANEL; 146 pParam->PanelStat.Type = PNL_DSTN; 147 break; 148 case 14: 149 pParam->PanelStat.XRes = 640; 150 pParam->PanelStat.YRes = 480; 151 pParam->PanelStat.Depth = 8; 152 pParam->PanelStat.MonoColor = PNL_MONO_PANEL; 153 pParam->PanelStat.Type = PNL_DSTN; 154 break; 155 case 15: 156 pParam->PanelStat.XRes = 800; 157 pParam->PanelStat.YRes = 600; 158 pParam->PanelStat.Depth = 16; 159 pParam->PanelStat.MonoColor = PNL_COLOR_PANEL; 160 pParam->PanelStat.Type = PNL_DSTN; 161 break; 162 default: 163 break; 164 } 165 } 166 /* if block end */ 167} 168 169void 170Dorado9211Init(Pnl_PanelStat * pstat) 171{ 172 int mode; 173 unsigned long orig_value, pm_value; 174 175 gfx_delay_milliseconds(100); 176 Dorado9211GpioInit(); 177 178 Dorado9211ToggleClock(); 179 Dorado9211ToggleClock(); 180 Dorado9211ToggleClock(); 181 Dorado9211ToggleClock(); 182 Dorado9211ToggleClock(); 183 184 gfx_delay_milliseconds(100); 185 186 Dorado9211ToggleClock(); 187 Dorado9211ToggleClock(); 188 Dorado9211ToggleClock(); 189 Dorado9211ToggleClock(); 190 Dorado9211ToggleClock(); 191 192 Dorado9211WriteReg(CS92xx_LCD_PWR_MAN, 0x0); 193 194 gfx_delay_milliseconds(100); 195 gfx_delay_milliseconds(100); 196 197 /* LOOP THROUGH THE AVAILABLE MODES TO FIND A MATCH */ 198 for (mode = 0; mode < NUM_92XX_MODES; mode++) { 199 if ((FPModeParams[mode].xres == pstat->XRes) && 200 (FPModeParams[mode].yres == pstat->YRes) && 201 (FPModeParams[mode].bpp == pstat->Depth) && 202 (FPModeParams[mode].panel_type == pstat->Type) && 203 (FPModeParams[mode].color_type == pstat->MonoColor)) { 204 205 /* SET THE 92xx FOR THE SELECTED MODE */ 206 CS92xx_MODE *pMode = &FPModeParams[mode]; 207 208 Dorado9211WriteReg(CS92xx_LCD_PAN_TIMING1, pMode->panel_timing1); 209 Dorado9211WriteReg(CS92xx_LCD_PAN_TIMING2, pMode->panel_timing2); 210 Dorado9211WriteReg(CS92xx_LCD_DITH_FR_CNTRL, 211 pMode->rev_C_dither_frc); 212 Dorado9211WriteReg(CS92xx_BLUE_LSFR_SEED, pMode->blue_lsfr_seed); 213 Dorado9211WriteReg(CS92xx_RED_GREEN_LSFR_SEED, 214 pMode->red_green_lsfr_seed); 215 DoradoProgramFRMload(); 216 Dorado9211WriteReg(CS92xx_LCD_MEM_CNTRL, pMode->memory_control); 217 Dorado9211WriteReg(CS92xx_LCD_PWR_MAN, pMode->power_management); 218 gfx_delay_milliseconds(100); 219 gfx_delay_milliseconds(100); 220 Dorado9211ClearCS(); 221 222 /* This code is added to take care of Panel initialization. 223 * Irrespective of Xpressrom is enabling the panel or not. 224 */ 225 orig_value = READ_VID32(0X04); 226 WRITE_VID32(0x04, 0x00200141); 227 gfx_delay_milliseconds(21); 228 pm_value = gfx_ind(0x9030); 229 230 pm_value |= 0x400; 231 gfx_outd(0x9030, pm_value); 232 gfx_delay_milliseconds(4); 233 orig_value &= 0xfff1ffff; 234 WRITE_VID32(0X4, orig_value); 235 return; 236 } /*end if() */ 237 } /*end for() */ 238 239} 240 241void 242Dorado9211SetCS(void) 243{ 244 unsigned long value; 245 246 value = gfx_ind(DRD_CSP9211IN); 247 gfx_outd(DRD_CSP9211OUT, value | DRD_CS9211); 248} 249 250void 251Dorado9211ClearCS(void) 252{ 253 unsigned long value; 254 255 value = gfx_ind(DRD_CSP9211IN); 256 gfx_outd(DRD_CSP9211OUT, value & (~DRD_CS9211)); 257} 258 259void 260Dorado9211SetDataOut(void) 261{ 262 unsigned long value; 263 264 value = gfx_ind(DRD_DATAOUTP9211IN); 265 gfx_outd(DRD_DATAOUTP9211OUT, value | DRD_DATAIN9211); 266} 267 268void 269Dorado9211ClearDataOut(void) 270{ 271 unsigned long value; 272 273 value = gfx_ind(DRD_DATAOUTP9211IN); 274 gfx_outd(DRD_DATAOUTP9211OUT, value & (~DRD_DATAIN9211)); 275} 276 277unsigned char 278Dorado9211ReadDataIn(void) 279{ 280 unsigned char readdata = 0; 281 unsigned long value; 282 283 /* why to read 4 times ??? */ 284 value = gfx_ind(DRD_DATAINP9211IN); 285 value = gfx_ind(DRD_DATAINP9211IN); 286 value = gfx_ind(DRD_DATAINP9211IN); 287 value = gfx_ind(DRD_DATAINP9211IN); 288 if (value & DRD_DATAOUT9211) 289 readdata = 1; 290 return (readdata); 291} 292 293void 294Dorado9211ToggleClock(void) 295{ 296 Dorado9211SetClock(); 297 Dorado9211ClearClock(); 298} 299 300void 301Dorado9211SetClock(void) 302{ 303 unsigned long value; 304 305 value = gfx_ind(DRD_CLOCKP9211IN); 306 gfx_outd(DRD_CLOCKP9211OUT, value | DRD_CLOCK9211); 307} 308 309void 310Dorado9211ClearClock(void) 311{ 312 unsigned long value; 313 314 value = gfx_ind(DRD_CLOCKP9211IN); 315 gfx_outd(DRD_CLOCKP9211OUT, value & (~DRD_CLOCK9211)); 316} 317 318void 319Dorado9211GpioInit(void) 320{ 321 unsigned long value; 322 323 /* set output enable on gpio 7, 9, 11 */ 324 gfx_outd((DRD_GEODE_GPIO_BASE + DRD_GEODE_GPPIN_SEL), DRD_CLOCK9211CFG); 325 gfx_outd((DRD_GEODE_GPIO_BASE + DRD_GEODE_GPPIN_CFG), 3); 326 /* set output enable on gpio 7, 9, 11 */ 327 gfx_outd((DRD_GEODE_GPIO_BASE + DRD_GEODE_GPPIN_SEL), DRD_CS9211CFG); 328 gfx_outd((DRD_GEODE_GPIO_BASE + DRD_GEODE_GPPIN_CFG), 3); 329 /* set output enable on gpio 7, 9, 18 */ 330 gfx_outd((DRD_GEODE_GPIO_BASE + DRD_GEODE_GPPIN_SEL), DRD_DATAIN9211CFG); 331 gfx_outd((DRD_GEODE_GPIO_BASE + DRD_GEODE_GPPIN_CFG), 3); 332 /* disable on gpio 11 - This is the output from the 9211 */ 333 gfx_outd((DRD_GEODE_GPIO_BASE + DRD_GEODE_GPPIN_SEL), DRD_DATAOUT9211CFG); 334 gfx_outd((DRD_GEODE_GPIO_BASE + DRD_GEODE_GPPIN_CFG), 0); 335 /* Set all PINS low */ 336 value = gfx_ind(DRD_GEODE_GPIO_BASE + DRD_GEODE_GPDI0); 337 value &= ~(DRD_CS9211 | DRD_CLOCK9211 | DRD_DATAIN9211); 338 gfx_outd((DRD_GEODE_GPIO_BASE + DRD_GEODE_GPDO0), value); 339} 340 341unsigned long 342Dorado9211ReadReg(unsigned short index) 343{ 344 345 unsigned char i, readbit; 346 unsigned long data; 347 348 Dorado9211ClearDataOut(); 349 350 Dorado9211SetCS(); 351 Dorado9211ToggleClock(); 352 353 Dorado9211SetDataOut(); 354 Dorado9211ToggleClock(); 355 356 for (i = 0; i < 12; i++) { 357 if (index & 0x1) { 358 Dorado9211SetDataOut(); 359 } 360 else { 361 Dorado9211ClearDataOut(); 362 } 363 Dorado9211ToggleClock(); 364 index >>= 1; 365 } 366 367 Dorado9211ClearDataOut(); 368 Dorado9211ToggleClock(); 369 370 /* Idle clock, 7 clocks, no data set */ 371 372 Dorado9211ToggleClock(); 373 Dorado9211ToggleClock(); 374 Dorado9211ToggleClock(); 375 Dorado9211ToggleClock(); 376 Dorado9211ToggleClock(); 377 Dorado9211ToggleClock(); 378 Dorado9211ToggleClock(); 379 380 data = 0; 381 for (i = 0; i < 32; i++) { 382 Dorado9211ToggleClock(); 383 readbit = Dorado9211ReadDataIn(); 384 data |= (((unsigned long) readbit) << i); 385 } 386 387 Dorado9211ClearCS(); 388 Dorado9211ToggleClock(); 389 return (data); 390 391} 392 393void 394Dorado9211WriteReg(unsigned short index, unsigned long data) 395{ 396 397 unsigned char i; 398 399 Dorado9211ClearDataOut(); 400 Dorado9211SetDataOut(); 401 Dorado9211SetCS(); 402 Dorado9211ToggleClock(); 403 Dorado9211SetDataOut(); 404 Dorado9211ToggleClock(); 405 406 for (i = 0; i < 12; i++) { 407 if (index & 0x1) { 408 Dorado9211SetDataOut(); 409 } 410 else { 411 Dorado9211ClearDataOut(); 412 } 413 Dorado9211ToggleClock(); 414 index >>= 1; 415 } 416 417 Dorado9211SetDataOut(); 418 Dorado9211ToggleClock(); 419 420 for (i = 0; i < 32; i++) { 421 if (data & 0x1) { 422 Dorado9211SetDataOut(); 423 } 424 else { 425 Dorado9211ClearDataOut(); 426 } 427 Dorado9211ToggleClock(); 428 data >>= 1; 429 } 430 431 Dorado9211ClearCS(); 432 433 Dorado9211ToggleClock(); 434 Dorado9211ToggleClock(); 435 Dorado9211ToggleClock(); 436 Dorado9211ToggleClock(); 437} 438 439void 440DoradoProgramFRMload(void) 441{ 442 unsigned long DoradoFRMtable[] = { 443 444 0x00000000, 445 0x00000000, 446 0x01000100, 447 0x01000100, 448 0x01010101, 449 0x01010101, 450 0x02081041, 451 0x02081041, 452 0x10111111, 453 0x11111101, 454 0x49249241, 455 0x12412492, 456 0x92244891, 457 0x92244891, 458 0x22252525, 459 0x22252525, 460 0x528294a5, 461 0x2528494a, 462 0x294a5295, 463 0x294a5295, 464 0x54a54a95, 465 0x2952a52a, 466 0x2a552a55, 467 0x2a552a55, 468 0x554aa955, 469 0x2a9552aa, 470 0x2aaa5555, 471 0x2aaa5555, 472 0x55555555, 473 0x2aaaaaaa, 474 0x55555555, 475 0x55555555, 476 0xaaaaaaab, 477 0x55555555, 478 0x5555aaab, 479 0x5555aaab, 480 0xaab556ab, 481 0x556aad55, 482 0x55ab55ab, 483 0x55ab55ab, 484 0xab5ab56b, 485 0x56ad5ad5, 486 0x56b5ad6b, 487 0x56b5ad6b, 488 0xad6d6b5b, 489 0x5ad6b6b6, 490 0x5b5b5b5b, 491 0x5b5b5b5b, 492 0x5F6db6db, 493 0x5F6db6db, 494 0xF776F776, 495 0xF776F776, 496 0xFBDEFBDE, 497 0xFBDEFBDE, 498 0x7eFFBFF7, 499 0x7eFFBFF7, 500 0xFF7FF7F7, 501 0xFF7FF7F7, 502 0xFF7FFF7F, 503 0xFF7FFF7F, 504 0xFFF7FFFF, 505 0xFFF7FFFF, 506 0xFFFFFFFF, 507 0xFFFFFFFF, 508 }; 509 510 unsigned char i; 511 unsigned short index; 512 unsigned long data; 513 514 Dorado9211WriteReg(CS92xx_FRM_MEMORY_INDEX, 0); 515 index = CS92xx_FRM_MEMORY_DATA; 516 for (i = 0; i < 64; i += 2) { 517 data = DoradoFRMtable[i]; 518 Dorado9211WriteReg(index, data); 519 data = DoradoFRMtable[i + 1]; 520 Dorado9211WriteReg(index, data); 521 } 522 523/* 524 * The first FRM location (64 bits) does not program correctly. 525 * This location always reads back with the last value programmed. 526 * ie. If 32 64-bit values are programmed, location 0 reads back as the 32nd 527 * If 30 locations are programmed, location 0 reads back as the 30th, etc. 528 * Fix this by re-writing location 0 after programming all 64 in the writeFRM 529 * loop in RevCFrmload() in CS9211. 530 */ 531 532 Dorado9211WriteReg(CS92xx_FRM_MEMORY_INDEX, 0); 533 Dorado9211WriteReg(CS92xx_FRM_MEMORY_DATA, 0); 534 Dorado9211WriteReg(CS92xx_FRM_MEMORY_DATA, 0); 535 536} 537 538/***************************************************************************** 539 * void Dorado_Enable_Power((void); 540 * Enables the power of the CX9211 on Dorado board. 541 ***************************************************************************** 542 */ 543 544void 545Dorado_Power_Up(void) 546{ 547 Dorado9211WriteReg(CS92xx_LCD_PWR_MAN, 0x01000000); 548 return; 549 550} /* disable_Centaurus_Power */ 551 552/***************************************************************************** 553 * void Dorado_Disable_Power((void); 554 * Disables the power of the CX9211 on Dorado board. 555 ***************************************************************************** 556 */ 557 558void 559Dorado_Power_Down(void) 560{ 561 Dorado9211WriteReg(CS92xx_LCD_PWR_MAN, 0x0); 562 return; 563 564} /* disable_Centaurus_Power */ 565 566void 567Dorado_Save_Panel_State(void) 568{ 569 570 /* set 9211 registers using the desired panel settings */ 571 cs9211_regs.panel_timing1 = Dorado9211ReadReg(CS92xx_LCD_PAN_TIMING1); 572 cs9211_regs.panel_timing2 = Dorado9211ReadReg(CS92xx_LCD_PAN_TIMING2); 573 574 cs9211_regs.dither_frc_ctrl = Dorado9211ReadReg(CS92xx_LCD_DITH_FR_CNTRL); 575 cs9211_regs.blue_lsfr_seed = Dorado9211ReadReg(CS92xx_BLUE_LSFR_SEED); 576 cs9211_regs.red_green_lsfr_seed = 577 Dorado9211ReadReg(CS92xx_RED_GREEN_LSFR_SEED); 578 579 /* CentaurusProgramFRMload(); */ 580 cs9211_regs.memory_control = Dorado9211ReadReg(CS92xx_LCD_MEM_CNTRL); 581 582 /* Set the power register last. This will turn the panel on at the 9211 */ 583 cs9211_regs.power_management = Dorado9211ReadReg(CS92xx_LCD_PWR_MAN); 584 cs9211_regs.panel_state = cs9211_regs.power_management; 585} 586 587void 588Dorado_Restore_Panel_State(void) 589{ 590 unsigned long off_data = 0; 591 592 /* Before restoring the 9211 registers, power off the 9211. */ 593 594 Dorado9211WriteReg(CS92xx_LCD_PWR_MAN, off_data); 595 596 /* set 9211 registers using the desired panel settings */ 597 Dorado9211WriteReg(CS92xx_LCD_PAN_TIMING1, cs9211_regs.panel_timing1); 598 Dorado9211WriteReg(CS92xx_LCD_PAN_TIMING2, cs9211_regs.panel_timing2); 599 /* load the LSFR seeds */ 600 Dorado9211WriteReg(CS92xx_LCD_DITH_FR_CNTRL, cs9211_regs.dither_frc_ctrl); 601 Dorado9211WriteReg(CS92xx_BLUE_LSFR_SEED, cs9211_regs.blue_lsfr_seed); 602 Dorado9211WriteReg(CS92xx_RED_GREEN_LSFR_SEED, 603 cs9211_regs.red_green_lsfr_seed); 604 605 Dorado9211WriteReg(CS92xx_LCD_MEM_CNTRL, cs9211_regs.memory_control); 606 /* Set the power register last. This will turn the panel on at the 9211 */ 607 Dorado9211WriteReg(CS92xx_LCD_PWR_MAN, cs9211_regs.power_management); 608} 609