summaryrefslogtreecommitdiff
path: root/src/panel/dora9211.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/panel/dora9211.c')
-rw-r--r--src/panel/dora9211.c607
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);
+}