summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--firmware/target/arm/tms320dm320/sansa-connect/lcd-sansaconnect.c124
-rw-r--r--firmware/target/arm/tms320dm320/sansa-connect/lcd-target.h8
2 files changed, 132 insertions, 0 deletions
diff --git a/firmware/target/arm/tms320dm320/sansa-connect/lcd-sansaconnect.c b/firmware/target/arm/tms320dm320/sansa-connect/lcd-sansaconnect.c
index ad417663fe..d4d5b97ca7 100644
--- a/firmware/target/arm/tms320dm320/sansa-connect/lcd-sansaconnect.c
+++ b/firmware/target/arm/tms320dm320/sansa-connect/lcd-sansaconnect.c
@@ -153,6 +153,130 @@ void lcd_init_device(void)
153 lcd_on = true; 153 lcd_on = true;
154} 154}
155 155
156#ifdef LCD_USE_DMA
157static void dma_lcd_copy_buffer_rect(int x, int y, int width, int height)
158{
159 char *dst, *src;
160
161 /* Image buffer A is 4KW, every pixel is one Word */
162 /* lines is maximum number of lines we can transfer in single run */
163 int lines = 4096/width;
164 if (lines > height)
165 lines = height;
166
167 /* Set source and destination addresses */
168 dst = (char*)(FRAME + LCD_WIDTH*y + x);
169 src = (char*)(&lcd_framebuffer[y][x]);
170
171 /* Flush cache to memory */
172 commit_dcache();
173
174 /* Addresses are relative to start of SDRAM */
175 src -= CONFIG_SDRAM_START;
176 dst -= CONFIG_SDRAM_START;
177
178 /* Enable Image Buffer clock */
179 bitset16(&IO_CLK_MOD1, CLK_MOD1_IMGBUF);
180
181 /* Use Image Buffer A for DMA */
182 COP_BUF_MUX0 = (COP_BUF_MUX0 & 0xFFF0) | 0x0003;
183
184 /* Setup buffer offsets and transfer width/height */
185 COP_BUF_LOFST = width;
186 COP_DMA_XNUM = width;
187 COP_DMA_YNUM = lines;
188
189 /* DMA: No byte SWAP, no transformation, data bus shift down 0 bit */
190 COP_IMG_MODE &= 0xC0;
191
192 /* Set the start address of buffer */
193 COP_BUF_ADDR = 0x0000;
194
195 /* Setup SDRAM stride */
196 COP_SDEM_LOFST = LCD_WIDTH;
197
198 do {
199 int addr;
200
201 addr = (int)src;
202 addr >>= 1; /* Addresses are in 16-bit words */
203
204 /* Setup the registers to initiate the read from SDRAM */
205 COP_SDEM_ADDRH = addr >> 16;
206 COP_SDEM_ADDRL = addr & 0xFFFF;
207
208 /* Set direction and start */
209 COP_DMA_CTRL = 0x0001;
210 COP_DMA_CTRL |= 0x0002;
211
212 /* Wait for read to finish */
213 while (COP_DMA_CTRL & 0x02) {};
214
215 addr = (int)dst;
216 addr >>= 1;
217
218 COP_SDEM_ADDRH = addr >> 16;
219 COP_SDEM_ADDRL = addr & 0xFFFF;
220
221 /* Set direction and start transfer */
222 COP_DMA_CTRL = 0x0000;
223 COP_DMA_CTRL |= 0x0002;
224
225 /* Wait for the transfer to complete */
226 while (COP_DMA_CTRL & 0x02) {};
227
228 /* Decrease height, update pointers */
229 src += (LCD_WIDTH << 1)*lines;
230 dst += (LCD_WIDTH << 1)*lines;
231
232 height -= lines;
233 if (height < lines)
234 {
235 lines = height;
236 COP_DMA_YNUM = height;
237 }
238 } while (height > 0);
239
240 /* Disable Image Buffer clock */
241 bitclr16(&IO_CLK_MOD1, CLK_MOD1_IMGBUF);
242}
243
244/* Update a fraction of the display. */
245void lcd_update_rect(int x, int y, int width, int height)
246 __attribute__ ((section(".icode")));
247void lcd_update_rect(int x, int y, int width, int height)
248{
249 if (!lcd_on)
250 return;
251
252 if ((width | height) < 0)
253 return; /* Nothing left to do */
254
255 if (x + width > LCD_WIDTH)
256 width = LCD_WIDTH - x; /* Clip right */
257 if (x < 0)
258 width += x, x = 0; /* Clip left */
259
260 if (y + height > LCD_HEIGHT)
261 height = LCD_HEIGHT - y; /* Clip bottom */
262 if (y < 0)
263 height += y, y = 0; /* Clip top */
264
265 dma_lcd_copy_buffer_rect(x, y, width, height);
266}
267
268/* Update the display.
269 This must be called after all other LCD functions that change the display. */
270void lcd_update(void) __attribute__ ((section(".icode")));
271void lcd_update(void)
272{
273 if (!lcd_on)
274 return;
275
276 lcd_update_rect(0, 0, LCD_WIDTH, LCD_HEIGHT);
277}
278#endif
279
156void lcd_set_contrast(int val) { 280void lcd_set_contrast(int val) {
157 (void) val; 281 (void) val;
158 // TODO: 282 // TODO:
diff --git a/firmware/target/arm/tms320dm320/sansa-connect/lcd-target.h b/firmware/target/arm/tms320dm320/sansa-connect/lcd-target.h
index 60d5df69c8..6a62140b27 100644
--- a/firmware/target/arm/tms320dm320/sansa-connect/lcd-target.h
+++ b/firmware/target/arm/tms320dm320/sansa-connect/lcd-target.h
@@ -24,6 +24,14 @@
24 24
25#define LCD_FRAMEBUF_ADDR(col, row) ((fb_data *)FRAME + (row)*LCD_WIDTH + (col)) 25#define LCD_FRAMEBUF_ADDR(col, row) ((fb_data *)FRAME + (row)*LCD_WIDTH + (col))
26 26
27/* Comment this to remove Image Buffer DMA usage */
28#define LCD_USE_DMA
29
30#ifdef LCD_USE_DMA
31#define LCD_OPTIMIZED_UPDATE
32#define LCD_OPTIMIZED_UPDATE_RECT
33#endif
34
27void lcd_awake(void); 35void lcd_awake(void);
28 36
29#endif /* LCD_TARGET_H */ 37#endif /* LCD_TARGET_H */