diff options
Diffstat (limited to 'firmware')
-rw-r--r-- | firmware/target/arm/s3c2440/gigabeat-fx/lcd-meg-fx.c | 178 |
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 9b066d61d0..dcf028b06d 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) | |||
42 | return (address & ((1 << 22)-1)) >> 1; | 42 | return (address & ((1 << 22)-1)) >> 1; |
43 | } | 43 | } |
44 | 44 | ||
45 | inline void delay_cycles(volatile int delay) | ||
46 | { | ||
47 | while(delay>0) delay--; | ||
48 | } | ||
49 | |||
50 | void SPI_LCD_CS(bool select) | ||
51 | { | ||
52 | delay_cycles(0x4FFF); | ||
53 | |||
54 | GPBCON&=~0x30000; | ||
55 | GPBCON|=0x10000; | ||
56 | |||
57 | if(select) | ||
58 | GPBDAT|=0x100; | ||
59 | else | ||
60 | GPBDAT&=~0x100; | ||
61 | } | ||
62 | |||
63 | void reset_LCD(bool reset) | ||
64 | { | ||
65 | GPBCON&=~0xC000; | ||
66 | GPBCON|=0x4000; | ||
67 | if(reset) | ||
68 | GPBDAT|=0x80; | ||
69 | else | ||
70 | GPBDAT&=~0x80; | ||
71 | } | ||
72 | |||
73 | void SPI_Send_Bytes(unsigned char *array, int count) | ||
74 | { | ||
75 | while (count--) | ||
76 | { | ||
77 | while ((SPSTA0&0x01)==0){}; | ||
78 | SPTDAT0=*array++; | ||
79 | } | ||
80 | } | ||
81 | |||
82 | void Setup_LCD_SPI(void) | ||
83 | { | ||
84 | CLKCON|=0x40000; | ||
85 | SPI_LCD_CS(false); | ||
86 | SPCON0=0x3E; | ||
87 | SPPRE0=24; | ||
88 | } | ||
89 | |||
90 | void Setup_LCD_CTRL(void) | ||
91 | { | ||
92 | /* ENVID = 0, BPPMODE = 16 bpp, PNRMODE = TFT, MMODE = Each Frame, CLKVAL = 8 */ | ||
93 | LCDCON1 = 0x878; | ||
94 | |||
95 | /* VCPW = 1, VFPD = 5, LINEVAL = 319, VBPD = 7 */ | ||
96 | LCDCON2 = 0x74FC141; | ||
97 | |||
98 | /* HFPD = 9, HOZVAL = 239, HBPD = 7 */ | ||
99 | LCDCON3 = 0x38EF09; | ||
100 | |||
101 | /* HSPW = 7 */ | ||
102 | LCDCON4 = 7; | ||
103 | |||
104 | /* HWSWP = 1, INVVFRAM = 1, INVVLINE = 1, FRM565 = 1, All others = 0 */ | ||
105 | LCDCON5 = 0xB01; | ||
106 | |||
107 | LCDSADDR1 = (LCDBANK((unsigned)FRAME) << 21) | (LCDBASEU((unsigned)FRAME)); | ||
108 | LCDSADDR2 = LCDBASEL((unsigned)FRAME); | ||
109 | LCDSADDR3 = 0x000000F0; | ||
110 | } | ||
111 | |||
45 | /* LCD init */ | 112 | /* LCD init */ |
46 | void lcd_init_device(void) | 113 | void lcd_init_device(void) |
47 | { | 114 | { |
48 | int i; | ||
49 | #ifdef BOOTLOADER | 115 | #ifdef BOOTLOADER |
50 | /* When the Rockbox bootloader starts, we are changing framebuffer address, | 116 | /* When the Rockbox bootloader starts, we are changing framebuffer address, |
51 | but we don't want what's shown on the LCD to change until we do an | 117 | 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) | |||
62 | } | 128 | } |
63 | #endif | 129 | #endif |
64 | 130 | ||
65 | LCDSADDR1 = (LCDBANK((unsigned)FRAME) << 21) | (LCDBASEU((unsigned)FRAME)); | 131 | /* Set pins up */ |
66 | LCDSADDR2 = LCDBASEL((unsigned)FRAME); | 132 | GPCCON |= 0xAAA000A8; |
67 | LCDSADDR3 = 0x000000F0; | 133 | GPCUP |= 0xFC0E; |
134 | |||
135 | GPDCON |= 0xAAA0AAA0; | ||
136 | GPDUP |= 0xFCFC; | ||
137 | |||
138 | GPHUP &= 0x600; | ||
139 | |||
140 | GPECON |= 0x0A800000; | ||
141 | GPEUP |= 0x3800; | ||
142 | |||
143 | GPBUP |= 0x181; | ||
68 | 144 | ||
69 | #if !defined(BOOTLOADER) | 145 | #if !defined(BOOTLOADER) |
70 | lcd_poweroff = false; | 146 | lcd_poweroff = false; |
71 | #endif | 147 | #endif |
72 | |||
73 | /* ENVID = 1, BPPMODE = 16 bpp, PNRMODE = TFT, MMODE = Each Frame, CLKVAL = 8 */ | ||
74 | LCDCON1 = 0x879; | ||
75 | |||
76 | /* VCPW = 1, VFPD = 5, LINEVAL = 319, VBPD = 7 */ | ||
77 | LCDCON2 = 0x74FC141; | ||
78 | 148 | ||
79 | /* HFPD = 9, HOZVAL = 239, HBPD = 7 */ | 149 | CLKCON |= 0x20; /* enable LCD clock */ |
80 | LCDCON3 = 0x38EF09; | ||
81 | 150 | ||
82 | /* HSPW = 7 */ | 151 | Setup_LCD_SPI(); |
83 | LCDCON4 = 7; | ||
84 | |||
85 | /* HWSWP = 1, INVVFRAM = 1, INVVLINE = 1, FRM565 = 1, All others = 0 */ | ||
86 | LCDCON5 = 0xB01; | ||
87 | 152 | ||
88 | /* LCD controller reset */ | 153 | Setup_LCD_CTRL(); |
89 | GPBCON = (GPBCON & ~((1<<15)|(1<<17))) | (1<<16)|(1<<14); /* GPB7=OUT, GPB8=OUT */ | ||
90 | GPBDAT |= (1<<7); /* LCD reset */ | ||
91 | GPBUP |= (1<<8) | (1<<7) | 1; /* pullup GPB8, GPB7, GPB0(?) */ | ||
92 | CLKCON |= (1<<5); /* enable LCD clock */ | ||
93 | 154 | ||
94 | /* SPI bus transfer */ | 155 | delay_cycles(0xA000); |
95 | GPBDAT &= ~(1<<8); /* LCD CS off */ | ||
96 | 156 | ||
97 | /* Start the SPI interface */ | 157 | reset_LCD(true); |
98 | CLKCON |= 1<<18; /* enable SPI clock */ | 158 | LCDCON1|=0x01; |
99 | SPCON0 = 0x3E; /* enable iterrupt mode, master,active low,format B */ | ||
100 | SPPRE0 = 0x18; /* Baud rate = PCLK(50MHz) / 2 / (Prescaler value + 1) */ | ||
101 | 159 | ||
160 | delay_cycles(0x80000); | ||
161 | |||
162 | #if 0 | ||
163 | /* Setup the appropriate screen modes */ | ||
164 | TCONSEL= 0xCE6; | ||
165 | #endif | ||
166 | |||
102 | /* SPI data - Right now we are not sure what each of these SPI writes is actually | 167 | /* SPI data - Right now we are not sure what each of these SPI writes is actually |
103 | * telling the lcd. Many thanks to Alex Gerchanovsky for discovering them. | 168 | * telling the lcd. Many thanks to Alex Gerchanovsky for discovering them. |
169 | * | ||
170 | * This looks like a register, data combination, 0 denoting a register address, | ||
171 | * 1 denoting data. Addr 0x04 is used more than once and may be an enable. | ||
104 | */ | 172 | */ |
105 | const unsigned char initbuf[] = { | 173 | const unsigned char initbuf[] = |
106 | 0,0x0F,1,0x01, 0,0x09,1,0x06, 0,0x16,1,0xA6, 0,0x1E,1,0x49, 0,0x1F,1,0x26, | ||
107 | 0,0x0B,1,0x2F, 0,0x0C,1,0x2B, 0,0x19,1,0x5E, 0,0x1A,1,0x15, 0,0x1B,1,0x15, | ||
108 | 0,0x1D,1,0x01, 0,0x00,1,0x03, 0,0x01,1,0x10, 0,0x02,1,0x0A, 0,0x06,1,0x04, | ||
109 | 0,0x08,1,0x2E, 0,0x24,1,0x12, 0,0x25,1,0x3F, 0,0x26,1,0x0B, 0,0x27,1,0x00, | ||
110 | 0,0x28,1,0x00, 0,0x29,1,0xF6, 0,0x2A,1,0x03, 0,0x2B,1,0x0A, 0,0x04,1,0x01}; | ||
111 | |||
112 | /* Send the SPI data */ | ||
113 | for (i=0;i<(int)sizeof(initbuf);i++) | ||
114 | { | 174 | { |
115 | while ((SPSTA0&1)==0); | 175 | 0,0x0F,1,0x01, |
116 | SPRDAT0 = initbuf[i]; | 176 | 0,0x09,1,0x06, |
117 | do{int x;for(x=1000*51/2;x;x--);} while (0); | 177 | 0,0x16,1,0xA6, |
118 | } | 178 | 0,0x1E,1,0x49, |
119 | 179 | 0,0x1F,1,0x26, | |
120 | /* Stop the SPI interface */ | 180 | 0,0x0B,1,0x2F, |
121 | SPPRE0 = 0; | 181 | 0,0x0C,1,0x2B, |
122 | SPCON0 = 0; | 182 | 0,0x19,1,0x5E, |
123 | CLKCON &= ~(1<<18); /* disable SPI clock */ | 183 | 0,0x1A,1,0x15, |
124 | GPBDAT |= (1<<8); /* LCD CS on */ | 184 | 0,0x1B,1,0x15, |
185 | 0,0x1D,1,0x01, | ||
186 | 0,0x00,1,0x03, | ||
187 | 0,0x01,1,0x10, | ||
188 | 0,0x02,1,0x0A, | ||
189 | 0,0x06,1,0x04, | ||
190 | 0,0x08,1,0x2E, | ||
191 | 0,0x24,1,0x12, | ||
192 | 0,0x25,1,0x3F, | ||
193 | 0,0x26,1,0x0B, | ||
194 | 0,0x27,1,0x00, | ||
195 | 0,0x28,1,0x00, | ||
196 | 0,0x29,1,0xF6, | ||
197 | 0,0x2A,1,0x03, | ||
198 | 0,0x2B,1,0x0A, | ||
199 | 0,0x04,1,0x01, | ||
200 | }; | ||
201 | |||
202 | SPI_LCD_CS(true); | ||
203 | SPI_Send_Bytes(initbuf, sizeof(initbuf)); | ||
204 | SPI_LCD_CS(false); | ||
205 | |||
206 | CLKCON &= ~0x40000; /* disable SPI clock */ | ||
125 | } | 207 | } |
126 | 208 | ||
127 | /* Update a fraction of the display. */ | 209 | /* Update a fraction of the display. */ |