summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKarl Kurbjun <kkurbjun@gmail.com>2008-02-13 05:46:04 +0000
committerKarl Kurbjun <kkurbjun@gmail.com>2008-02-13 05:46:04 +0000
commit94bd1f74a77a35ac968b2a9623fe9e6ae10a4de3 (patch)
treef5fb5fdf2b362513ac2840b1303e80b650fccab4
parent086aab3235c9636a9689684d759518ffe3665ac6 (diff)
downloadrockbox-94bd1f74a77a35ac968b2a9623fe9e6ae10a4de3.zip
rockbox-94bd1f74a77a35ac968b2a9623fe9e6ae10a4de3.tar.gz
rockbox-94bd1f74a77a35ac968b2a9623fe9e6ae10a4de3.tar.bz2
rockbox-94bd1f74a77a35ac968b2a9623fe9e6ae10a4de3.tar.xz
Make the gigabeat LCD initialization work properly without the original firmware.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@16298 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--firmware/target/arm/s3c2440/gigabeat-fx/lcd-meg-fx.c178
1 files changed, 130 insertions, 48 deletions
diff --git a/firmware/target/arm/s3c2440/gigabeat-fx/lcd-meg-fx.c b/firmware/target/arm/s3c2440/gigabeat-fx/lcd-meg-fx.c
index 9b066d6..dcf028b 100644
--- a/firmware/target/arm/s3c2440/gigabeat-fx/lcd-meg-fx.c
+++ b/firmware/target/arm/s3c2440/gigabeat-fx/lcd-meg-fx.c
@@ -42,10 +42,76 @@ unsigned int LCDBASEL(unsigned int address)
return (address & ((1 << 22)-1)) >> 1;
}
+inline void delay_cycles(volatile int delay)
+{
+ while(delay>0) delay--;
+}
+
+void SPI_LCD_CS(bool select)
+{
+ delay_cycles(0x4FFF);
+
+ GPBCON&=~0x30000;
+ GPBCON|=0x10000;
+
+ if(select)
+ GPBDAT|=0x100;
+ else
+ GPBDAT&=~0x100;
+}
+
+void reset_LCD(bool reset)
+{
+ GPBCON&=~0xC000;
+ GPBCON|=0x4000;
+ if(reset)
+ GPBDAT|=0x80;
+ else
+ GPBDAT&=~0x80;
+}
+
+void SPI_Send_Bytes(unsigned char *array, int count)
+{
+ while (count--)
+ {
+ while ((SPSTA0&0x01)==0){};
+ SPTDAT0=*array++;
+ }
+}
+
+void Setup_LCD_SPI(void)
+{
+ CLKCON|=0x40000;
+ SPI_LCD_CS(false);
+ SPCON0=0x3E;
+ SPPRE0=24;
+}
+
+void Setup_LCD_CTRL(void)
+{
+ /* ENVID = 0, BPPMODE = 16 bpp, PNRMODE = TFT, MMODE = Each Frame, CLKVAL = 8 */
+ LCDCON1 = 0x878;
+
+ /* VCPW = 1, VFPD = 5, LINEVAL = 319, VBPD = 7 */
+ LCDCON2 = 0x74FC141;
+
+ /* HFPD = 9, HOZVAL = 239, HBPD = 7 */
+ LCDCON3 = 0x38EF09;
+
+ /* HSPW = 7 */
+ LCDCON4 = 7;
+
+ /* HWSWP = 1, INVVFRAM = 1, INVVLINE = 1, FRM565 = 1, All others = 0 */
+ LCDCON5 = 0xB01;
+
+ LCDSADDR1 = (LCDBANK((unsigned)FRAME) << 21) | (LCDBASEU((unsigned)FRAME));
+ LCDSADDR2 = LCDBASEL((unsigned)FRAME);
+ LCDSADDR3 = 0x000000F0;
+}
+
/* LCD init */
void lcd_init_device(void)
{
- int i;
#ifdef BOOTLOADER
/* When the Rockbox bootloader starts, we are changing framebuffer address,
but we don't want what's shown on the LCD to change until we do an
@@ -62,66 +128,82 @@ void lcd_init_device(void)
}
#endif
- LCDSADDR1 = (LCDBANK((unsigned)FRAME) << 21) | (LCDBASEU((unsigned)FRAME));
- LCDSADDR2 = LCDBASEL((unsigned)FRAME);
- LCDSADDR3 = 0x000000F0;
+ /* Set pins up */
+ GPCCON |= 0xAAA000A8;
+ GPCUP |= 0xFC0E;
+
+ GPDCON |= 0xAAA0AAA0;
+ GPDUP |= 0xFCFC;
+
+ GPHUP &= 0x600;
+
+ GPECON |= 0x0A800000;
+ GPEUP |= 0x3800;
+
+ GPBUP |= 0x181;
#if !defined(BOOTLOADER)
lcd_poweroff = false;
#endif
-
- /* ENVID = 1, BPPMODE = 16 bpp, PNRMODE = TFT, MMODE = Each Frame, CLKVAL = 8 */
- LCDCON1 = 0x879;
-
- /* VCPW = 1, VFPD = 5, LINEVAL = 319, VBPD = 7 */
- LCDCON2 = 0x74FC141;
- /* HFPD = 9, HOZVAL = 239, HBPD = 7 */
- LCDCON3 = 0x38EF09;
+ CLKCON |= 0x20; /* enable LCD clock */
- /* HSPW = 7 */
- LCDCON4 = 7;
-
- /* HWSWP = 1, INVVFRAM = 1, INVVLINE = 1, FRM565 = 1, All others = 0 */
- LCDCON5 = 0xB01;
+ Setup_LCD_SPI();
- /* LCD controller reset */
- GPBCON = (GPBCON & ~((1<<15)|(1<<17))) | (1<<16)|(1<<14); /* GPB7=OUT, GPB8=OUT */
- GPBDAT |= (1<<7); /* LCD reset */
- GPBUP |= (1<<8) | (1<<7) | 1; /* pullup GPB8, GPB7, GPB0(?) */
- CLKCON |= (1<<5); /* enable LCD clock */
+ Setup_LCD_CTRL();
- /* SPI bus transfer */
- GPBDAT &= ~(1<<8); /* LCD CS off */
+ delay_cycles(0xA000);
- /* Start the SPI interface */
- CLKCON |= 1<<18; /* enable SPI clock */
- SPCON0 = 0x3E; /* enable iterrupt mode, master,active low,format B */
- SPPRE0 = 0x18; /* Baud rate = PCLK(50MHz) / 2 / (Prescaler value + 1) */
+ reset_LCD(true);
+ LCDCON1|=0x01;
+ delay_cycles(0x80000);
+
+#if 0
+ /* Setup the appropriate screen modes */
+ TCONSEL= 0xCE6;
+#endif
+
/* SPI data - Right now we are not sure what each of these SPI writes is actually
- * telling the lcd. Many thanks to Alex Gerchanovsky for discovering them.
+ * telling the lcd. Many thanks to Alex Gerchanovsky for discovering them.
+ *
+ * This looks like a register, data combination, 0 denoting a register address,
+ * 1 denoting data. Addr 0x04 is used more than once and may be an enable.
*/
- const unsigned char initbuf[] = {
- 0,0x0F,1,0x01, 0,0x09,1,0x06, 0,0x16,1,0xA6, 0,0x1E,1,0x49, 0,0x1F,1,0x26,
- 0,0x0B,1,0x2F, 0,0x0C,1,0x2B, 0,0x19,1,0x5E, 0,0x1A,1,0x15, 0,0x1B,1,0x15,
- 0,0x1D,1,0x01, 0,0x00,1,0x03, 0,0x01,1,0x10, 0,0x02,1,0x0A, 0,0x06,1,0x04,
- 0,0x08,1,0x2E, 0,0x24,1,0x12, 0,0x25,1,0x3F, 0,0x26,1,0x0B, 0,0x27,1,0x00,
- 0,0x28,1,0x00, 0,0x29,1,0xF6, 0,0x2A,1,0x03, 0,0x2B,1,0x0A, 0,0x04,1,0x01};
-
- /* Send the SPI data */
- for (i=0;i<(int)sizeof(initbuf);i++)
+ const unsigned char initbuf[] =
{
- while ((SPSTA0&1)==0);
- SPRDAT0 = initbuf[i];
- do{int x;for(x=1000*51/2;x;x--);} while (0);
- }
-
- /* Stop the SPI interface */
- SPPRE0 = 0;
- SPCON0 = 0;
- CLKCON &= ~(1<<18); /* disable SPI clock */
- GPBDAT |= (1<<8); /* LCD CS on */
+ 0,0x0F,1,0x01,
+ 0,0x09,1,0x06,
+ 0,0x16,1,0xA6,
+ 0,0x1E,1,0x49,
+ 0,0x1F,1,0x26,
+ 0,0x0B,1,0x2F,
+ 0,0x0C,1,0x2B,
+ 0,0x19,1,0x5E,
+ 0,0x1A,1,0x15,
+ 0,0x1B,1,0x15,
+ 0,0x1D,1,0x01,
+ 0,0x00,1,0x03,
+ 0,0x01,1,0x10,
+ 0,0x02,1,0x0A,
+ 0,0x06,1,0x04,
+ 0,0x08,1,0x2E,
+ 0,0x24,1,0x12,
+ 0,0x25,1,0x3F,
+ 0,0x26,1,0x0B,
+ 0,0x27,1,0x00,
+ 0,0x28,1,0x00,
+ 0,0x29,1,0xF6,
+ 0,0x2A,1,0x03,
+ 0,0x2B,1,0x0A,
+ 0,0x04,1,0x01,
+ };
+
+ SPI_LCD_CS(true);
+ SPI_Send_Bytes(initbuf, sizeof(initbuf));
+ SPI_LCD_CS(false);
+
+ CLKCON &= ~0x40000; /* disable SPI clock */
}
/* Update a fraction of the display. */