/* Copyright (c) 2005 Advanced Micro Devices, Inc. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to * deal in the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. * * Neither the name of the Advanced Micro Devices, Inc. nor the names of its * contributors may be used to endorse or promote products derived from this * software without specific prior written permission. * */ /* * File Contents: This file contains the panel functions to interface * the dorado platform. * * SubModule: Geode FlatPanel library * */ #include "dora9211.h" void Dorado_Get_9211_Details(unsigned long flags, Pnl_PanelParams * pParam) { unsigned long DPanelType; int i; for (i = 0; i < 0x7fff; i++) { } Dorado9211GpioInit(); for (i = 0; i < 5; i++) toggle_Centaurus_9211_clock(); if (flags & PNL_PANELCHIP) { DPanelType = Dorado9211ReadReg(0x430); if ((DPanelType & 0xFFFF0000) == 0x92110000) { /* found 9211 */ /* check the values for revision ID */ if (DPanelType >= 0x92110301) pParam->PanelChip = PNL_9211_C; else if ((DPanelType >= 0x92110101) && (DPanelType < 0x92110301)) pParam->PanelChip = PNL_9211_A; else pParam->PanelChip = PNL_UNKNOWN_CHIP; } else { /* no 9211 present */ pParam->PanelChip = PNL_UNKNOWN_CHIP; } } if ((pParam->PanelChip != PNL_UNKNOWN_CHIP) && (flags & PNL_PANELSTAT)) { unsigned long PanelTypeOrg; unsigned char Panel_2Byte; DPanelType = Dorado9211ReadReg(0x438); DPanelType &= 0x00e8e8e8; DPanelType |= 0x00170000; Dorado9211WriteReg(0x438, DPanelType); DPanelType = 0; DPanelType = Dorado9211ReadReg(0x434); DPanelType = (DPanelType >> (DRD_LCDRESGPIO1 + 1)); PanelTypeOrg = DPanelType >> 8; Panel_2Byte = (unsigned char) PanelTypeOrg; Panel_2Byte = (Panel_2Byte >> (DRD_LCDRESGPIO2 - DRD_LCDRESGPIO1 - 1)); DPanelType = (DPanelType | ((unsigned int) Panel_2Byte << 8)); DPanelType = DPanelType >> 1; PanelTypeOrg = DPanelType >> 8; Panel_2Byte = (unsigned char) PanelTypeOrg; Panel_2Byte = (Panel_2Byte >> (DRD_LCDRESGPIO3 - DRD_LCDRESGPIO2 - 1)); DPanelType = (DPanelType | ((unsigned int) Panel_2Byte << 8)); DPanelType = DPanelType >> 1; PanelTypeOrg = DPanelType >> 8; Panel_2Byte = (unsigned char) PanelTypeOrg; Panel_2Byte = (Panel_2Byte >> (DRD_LCDRESGPIO4 - DRD_LCDRESGPIO3 - 1)); DPanelType = (DPanelType | ((unsigned int) Panel_2Byte << 8)); DPanelType = DPanelType >> 5; DPanelType &= 0xf; switch (DPanelType) { case 8: pParam->PanelStat.XRes = 800; pParam->PanelStat.YRes = 600; pParam->PanelStat.Depth = 18; pParam->PanelStat.MonoColor = PNL_COLOR_PANEL; pParam->PanelStat.Type = PNL_TFT; break; case 9: pParam->PanelStat.XRes = 640; pParam->PanelStat.YRes = 480; pParam->PanelStat.Depth = 8; pParam->PanelStat.MonoColor = PNL_COLOR_PANEL; pParam->PanelStat.Type = PNL_SSTN; break; case 10: pParam->PanelStat.XRes = 1024; pParam->PanelStat.YRes = 768; pParam->PanelStat.Depth = 18; pParam->PanelStat.MonoColor = PNL_COLOR_PANEL; pParam->PanelStat.Type = PNL_TFT; break; case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 11: pParam->PanelStat.XRes = 640; pParam->PanelStat.YRes = 480; pParam->PanelStat.Depth = 16; pParam->PanelStat.MonoColor = PNL_COLOR_PANEL; pParam->PanelStat.Type = PNL_DSTN; break; case 12: pParam->PanelStat.XRes = 640; pParam->PanelStat.YRes = 480; pParam->PanelStat.Depth = 18; pParam->PanelStat.MonoColor = PNL_COLOR_PANEL; pParam->PanelStat.Type = PNL_TFT; break; case 13: pParam->PanelStat.XRes = 1024; pParam->PanelStat.YRes = 768; pParam->PanelStat.Depth = 24; pParam->PanelStat.MonoColor = PNL_COLOR_PANEL; pParam->PanelStat.Type = PNL_DSTN; break; case 14: pParam->PanelStat.XRes = 640; pParam->PanelStat.YRes = 480; pParam->PanelStat.Depth = 8; pParam->PanelStat.MonoColor = PNL_MONO_PANEL; pParam->PanelStat.Type = PNL_DSTN; break; case 15: pParam->PanelStat.XRes = 800; pParam->PanelStat.YRes = 600; pParam->PanelStat.Depth = 16; pParam->PanelStat.MonoColor = PNL_COLOR_PANEL; pParam->PanelStat.Type = PNL_DSTN; break; default: break; } } /* if block end */ } void Dorado9211Init(Pnl_PanelStat * pstat) { int mode; unsigned long orig_value, pm_value; gfx_delay_milliseconds(100); Dorado9211GpioInit(); Dorado9211ToggleClock(); Dorado9211ToggleClock(); Dorado9211ToggleClock(); Dorado9211ToggleClock(); Dorado9211ToggleClock(); gfx_delay_milliseconds(100); Dorado9211ToggleClock(); Dorado9211ToggleClock(); Dorado9211ToggleClock(); Dorado9211ToggleClock(); Dorado9211ToggleClock(); Dorado9211WriteReg(CS92xx_LCD_PWR_MAN, 0x0); gfx_delay_milliseconds(100); gfx_delay_milliseconds(100); /* LOOP THROUGH THE AVAILABLE MODES TO FIND A MATCH */ for (mode = 0; mode < NUM_92XX_MODES; mode++) { if ((FPModeParams[mode].xres == pstat->XRes) && (FPModeParams[mode].yres == pstat->YRes) && (FPModeParams[mode].bpp == pstat->Depth) && (FPModeParams[mode].panel_type == pstat->Type) && (FPModeParams[mode].color_type == pstat->MonoColor)) { /* SET THE 92xx FOR THE SELECTED MODE */ CS92xx_MODE *pMode = &FPModeParams[mode]; Dorado9211WriteReg(CS92xx_LCD_PAN_TIMING1, pMode->panel_timing1); Dorado9211WriteReg(CS92xx_LCD_PAN_TIMING2, pMode->panel_timing2); Dorado9211WriteReg(CS92xx_LCD_DITH_FR_CNTRL, pMode->rev_C_dither_frc); Dorado9211WriteReg(CS92xx_BLUE_LSFR_SEED, pMode->blue_lsfr_seed); Dorado9211WriteReg(CS92xx_RED_GREEN_LSFR_SEED, pMode->red_green_lsfr_seed); DoradoProgramFRMload(); Dorado9211WriteReg(CS92xx_LCD_MEM_CNTRL, pMode->memory_control); Dorado9211WriteReg(CS92xx_LCD_PWR_MAN, pMode->power_management); gfx_delay_milliseconds(100); gfx_delay_milliseconds(100); Dorado9211ClearCS(); /* This code is added to take care of Panel initialization. * Irrespective of Xpressrom is enabling the panel or not. */ orig_value = READ_VID32(0X04); WRITE_VID32(0x04, 0x00200141); gfx_delay_milliseconds(21); pm_value = gfx_ind(0x9030); pm_value |= 0x400; gfx_outd(0x9030, pm_value); gfx_delay_milliseconds(4); orig_value &= 0xfff1ffff; WRITE_VID32(0X4, orig_value); return; } /*end if() */ } /*end for() */ } void Dorado9211SetCS(void) { unsigned long value; value = gfx_ind(DRD_CSP9211IN); gfx_outd(DRD_CSP9211OUT, value | DRD_CS9211); } void Dorado9211ClearCS(void) { unsigned long value; value = gfx_ind(DRD_CSP9211IN); gfx_outd(DRD_CSP9211OUT, value & (~DRD_CS9211)); } void Dorado9211SetDataOut(void) { unsigned long value; value = gfx_ind(DRD_DATAOUTP9211IN); gfx_outd(DRD_DATAOUTP9211OUT, value | DRD_DATAIN9211); } void Dorado9211ClearDataOut(void) { unsigned long value; value = gfx_ind(DRD_DATAOUTP9211IN); gfx_outd(DRD_DATAOUTP9211OUT, value & (~DRD_DATAIN9211)); } unsigned char Dorado9211ReadDataIn(void) { unsigned char readdata = 0; unsigned long value; /* why to read 4 times ??? */ value = gfx_ind(DRD_DATAINP9211IN); value = gfx_ind(DRD_DATAINP9211IN); value = gfx_ind(DRD_DATAINP9211IN); value = gfx_ind(DRD_DATAINP9211IN); if (value & DRD_DATAOUT9211) readdata = 1; return (readdata); } void Dorado9211ToggleClock(void) { Dorado9211SetClock(); Dorado9211ClearClock(); } void Dorado9211SetClock(void) { unsigned long value; value = gfx_ind(DRD_CLOCKP9211IN); gfx_outd(DRD_CLOCKP9211OUT, value | DRD_CLOCK9211); } void Dorado9211ClearClock(void) { unsigned long value; value = gfx_ind(DRD_CLOCKP9211IN); gfx_outd(DRD_CLOCKP9211OUT, value & (~DRD_CLOCK9211)); } void Dorado9211GpioInit(void) { unsigned long value; /* set output enable on gpio 7, 9, 11 */ gfx_outd((DRD_GEODE_GPIO_BASE + DRD_GEODE_GPPIN_SEL), DRD_CLOCK9211CFG); gfx_outd((DRD_GEODE_GPIO_BASE + DRD_GEODE_GPPIN_CFG), 3); /* set output enable on gpio 7, 9, 11 */ gfx_outd((DRD_GEODE_GPIO_BASE + DRD_GEODE_GPPIN_SEL), DRD_CS9211CFG); gfx_outd((DRD_GEODE_GPIO_BASE + DRD_GEODE_GPPIN_CFG), 3); /* set output enable on gpio 7, 9, 18 */ gfx_outd((DRD_GEODE_GPIO_BASE + DRD_GEODE_GPPIN_SEL), DRD_DATAIN9211CFG); gfx_outd((DRD_GEODE_GPIO_BASE + DRD_GEODE_GPPIN_CFG), 3); /* disable on gpio 11 - This is the output from the 9211 */ gfx_outd((DRD_GEODE_GPIO_BASE + DRD_GEODE_GPPIN_SEL), DRD_DATAOUT9211CFG); gfx_outd((DRD_GEODE_GPIO_BASE + DRD_GEODE_GPPIN_CFG), 0); /* Set all PINS low */ value = gfx_ind(DRD_GEODE_GPIO_BASE + DRD_GEODE_GPDI0); value &= ~(DRD_CS9211 | DRD_CLOCK9211 | DRD_DATAIN9211); gfx_outd((DRD_GEODE_GPIO_BASE + DRD_GEODE_GPDO0), value); } unsigned long Dorado9211ReadReg(unsigned short index) { unsigned char i, readbit; unsigned long data; Dorado9211ClearDataOut(); Dorado9211SetCS(); Dorado9211ToggleClock(); Dorado9211SetDataOut(); Dorado9211ToggleClock(); for (i = 0; i < 12; i++) { if (index & 0x1) { Dorado9211SetDataOut(); } else { Dorado9211ClearDataOut(); } Dorado9211ToggleClock(); index >>= 1; } Dorado9211ClearDataOut(); Dorado9211ToggleClock(); /* Idle clock, 7 clocks, no data set */ Dorado9211ToggleClock(); Dorado9211ToggleClock(); Dorado9211ToggleClock(); Dorado9211ToggleClock(); Dorado9211ToggleClock(); Dorado9211ToggleClock(); Dorado9211ToggleClock(); data = 0; for (i = 0; i < 32; i++) { Dorado9211ToggleClock(); readbit = Dorado9211ReadDataIn(); data |= (((unsigned long) readbit) << i); } Dorado9211ClearCS(); Dorado9211ToggleClock(); return (data); } void Dorado9211WriteReg(unsigned short index, unsigned long data) { unsigned char i; Dorado9211ClearDataOut(); Dorado9211SetDataOut(); Dorado9211SetCS(); Dorado9211ToggleClock(); Dorado9211SetDataOut(); Dorado9211ToggleClock(); for (i = 0; i < 12; i++) { if (index & 0x1) { Dorado9211SetDataOut(); } else { Dorado9211ClearDataOut(); } Dorado9211ToggleClock(); index >>= 1; } Dorado9211SetDataOut(); Dorado9211ToggleClock(); for (i = 0; i < 32; i++) { if (data & 0x1) { Dorado9211SetDataOut(); } else { Dorado9211ClearDataOut(); } Dorado9211ToggleClock(); data >>= 1; } Dorado9211ClearCS(); Dorado9211ToggleClock(); Dorado9211ToggleClock(); Dorado9211ToggleClock(); Dorado9211ToggleClock(); } void DoradoProgramFRMload(void) { unsigned long DoradoFRMtable[] = { 0x00000000, 0x00000000, 0x01000100, 0x01000100, 0x01010101, 0x01010101, 0x02081041, 0x02081041, 0x10111111, 0x11111101, 0x49249241, 0x12412492, 0x92244891, 0x92244891, 0x22252525, 0x22252525, 0x528294a5, 0x2528494a, 0x294a5295, 0x294a5295, 0x54a54a95, 0x2952a52a, 0x2a552a55, 0x2a552a55, 0x554aa955, 0x2a9552aa, 0x2aaa5555, 0x2aaa5555, 0x55555555, 0x2aaaaaaa, 0x55555555, 0x55555555, 0xaaaaaaab, 0x55555555, 0x5555aaab, 0x5555aaab, 0xaab556ab, 0x556aad55, 0x55ab55ab, 0x55ab55ab, 0xab5ab56b, 0x56ad5ad5, 0x56b5ad6b, 0x56b5ad6b, 0xad6d6b5b, 0x5ad6b6b6, 0x5b5b5b5b, 0x5b5b5b5b, 0x5F6db6db, 0x5F6db6db, 0xF776F776, 0xF776F776, 0xFBDEFBDE, 0xFBDEFBDE, 0x7eFFBFF7, 0x7eFFBFF7, 0xFF7FF7F7, 0xFF7FF7F7, 0xFF7FFF7F, 0xFF7FFF7F, 0xFFF7FFFF, 0xFFF7FFFF, 0xFFFFFFFF, 0xFFFFFFFF, }; unsigned char i; unsigned short index; unsigned long data; Dorado9211WriteReg(CS92xx_FRM_MEMORY_INDEX, 0); index = CS92xx_FRM_MEMORY_DATA; for (i = 0; i < 64; i += 2) { data = DoradoFRMtable[i]; Dorado9211WriteReg(index, data); data = DoradoFRMtable[i + 1]; Dorado9211WriteReg(index, data); } /* * The first FRM location (64 bits) does not program correctly. * This location always reads back with the last value programmed. * ie. If 32 64-bit values are programmed, location 0 reads back as the 32nd * If 30 locations are programmed, location 0 reads back as the 30th, etc. * Fix this by re-writing location 0 after programming all 64 in the writeFRM * loop in RevCFrmload() in CS9211. */ Dorado9211WriteReg(CS92xx_FRM_MEMORY_INDEX, 0); Dorado9211WriteReg(CS92xx_FRM_MEMORY_DATA, 0); Dorado9211WriteReg(CS92xx_FRM_MEMORY_DATA, 0); } /***************************************************************************** * void Dorado_Enable_Power((void); * Enables the power of the CX9211 on Dorado board. ***************************************************************************** */ void Dorado_Power_Up(void) { Dorado9211WriteReg(CS92xx_LCD_PWR_MAN, 0x01000000); return; } /* disable_Centaurus_Power */ /***************************************************************************** * void Dorado_Disable_Power((void); * Disables the power of the CX9211 on Dorado board. ***************************************************************************** */ void Dorado_Power_Down(void) { Dorado9211WriteReg(CS92xx_LCD_PWR_MAN, 0x0); return; } /* disable_Centaurus_Power */ void Dorado_Save_Panel_State(void) { /* set 9211 registers using the desired panel settings */ cs9211_regs.panel_timing1 = Dorado9211ReadReg(CS92xx_LCD_PAN_TIMING1); cs9211_regs.panel_timing2 = Dorado9211ReadReg(CS92xx_LCD_PAN_TIMING2); cs9211_regs.dither_frc_ctrl = Dorado9211ReadReg(CS92xx_LCD_DITH_FR_CNTRL); cs9211_regs.blue_lsfr_seed = Dorado9211ReadReg(CS92xx_BLUE_LSFR_SEED); cs9211_regs.red_green_lsfr_seed = Dorado9211ReadReg(CS92xx_RED_GREEN_LSFR_SEED); /* CentaurusProgramFRMload(); */ cs9211_regs.memory_control = Dorado9211ReadReg(CS92xx_LCD_MEM_CNTRL); /* Set the power register last. This will turn the panel on at the 9211 */ cs9211_regs.power_management = Dorado9211ReadReg(CS92xx_LCD_PWR_MAN); cs9211_regs.panel_state = cs9211_regs.power_management; } void Dorado_Restore_Panel_State(void) { unsigned long off_data = 0; /* Before restoring the 9211 registers, power off the 9211. */ Dorado9211WriteReg(CS92xx_LCD_PWR_MAN, off_data); /* set 9211 registers using the desired panel settings */ Dorado9211WriteReg(CS92xx_LCD_PAN_TIMING1, cs9211_regs.panel_timing1); Dorado9211WriteReg(CS92xx_LCD_PAN_TIMING2, cs9211_regs.panel_timing2); /* load the LSFR seeds */ Dorado9211WriteReg(CS92xx_LCD_DITH_FR_CNTRL, cs9211_regs.dither_frc_ctrl); Dorado9211WriteReg(CS92xx_BLUE_LSFR_SEED, cs9211_regs.blue_lsfr_seed); Dorado9211WriteReg(CS92xx_RED_GREEN_LSFR_SEED, cs9211_regs.red_green_lsfr_seed); Dorado9211WriteReg(CS92xx_LCD_MEM_CNTRL, cs9211_regs.memory_control); /* Set the power register last. This will turn the panel on at the 9211 */ Dorado9211WriteReg(CS92xx_LCD_PWR_MAN, cs9211_regs.power_management); }