diff options
Diffstat (limited to 'src/panel/dora9211.c')
-rw-r--r-- | src/panel/dora9211.c | 607 |
1 files changed, 607 insertions, 0 deletions
diff --git a/src/panel/dora9211.c b/src/panel/dora9211.c new file mode 100644 index 0000000..ea52e95 --- /dev/null +++ b/src/panel/dora9211.c @@ -0,0 +1,607 @@ +/* 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); +} |