Index: firmware/target/arm/as3525/sansa-e200v2/lcd-e200v2.c =================================================================== --- firmware/target/arm/as3525/sansa-e200v2/lcd-e200v2.c (Revision 21184) +++ firmware/target/arm/as3525/sansa-e200v2/lcd-e200v2.c (Arbeitskopie) @@ -91,6 +91,12 @@ #define R_ENTRY_MODE_SOLID_VERT 0x1038 #define R_ENTRY_MODE_VIDEO 0x7020 +volatile int full_empty = 0; +void INT_DBOP(void) +{ + full_empty = 1; + DBOP_CTRL &= ~(1<<11|1<<5|1<<8); +} /* Reverse Flag */ #define R_DISP_CONTROL_NORMAL 0x0004 @@ -121,6 +127,8 @@ DBOP_CTRL = (1<<18)|(1<<16)|(1<<12)|(8<<0);/* short count,write enable, 16bit write, read-timing =8 */ DBOP_TIMPOL_01 = 0x6e167; DBOP_TIMPOL_23 = 0xa167e06f; + + VIC_INT_ENABLE |= INTERRUPT_DBOP; /* TODO: The OF calls some other functions here, but maybe not important */ } @@ -139,21 +147,41 @@ while ((DBOP_STAT & (1<<10)) == 0); /* Fuze OF has this loop and it seems to help us now also */ - int delay=8; - while(delay--); + int x = 0; + do { + asm volatile ("nop\n"); + } while (x++ < 8); DBOP_TIMPOL_23 = 0xa167e06f; } void lcd_write_data(const fb_data* p_bytes, int count) { - while (count--) + /* Interrupts seem to be faster than polling the status register */ +start: + full_empty = 0; + DBOP_CTRL |= (1<<11|1<<5); + while (!full_empty && count--) { DBOP_DOUT = *p_bytes++; + } + if (count > 0) + { + // yield(); // yield() doesn't seem to make it any slower! + goto start; + } + /* While push fifo is not empty */ +#if 0 + full_empty = 0; + DBOP_CTRL |= (1<<11|1<<8); + if (DBOP_STAT & (1<<10)) + return; + while(!full_empty); +#else + /* this is slightly faster */ + while ((DBOP_STAT & (1<<10)) == 0); +#endif - /* Wait for fifo to empty */ - while ((DBOP_STAT & (1<<10)) == 0); - } } static void lcd_write_reg(int reg, int value) Index: firmware/target/arm/as3525/system-as3525.c =================================================================== --- firmware/target/arm/as3525/system-as3525.c (Revision 21184) +++ firmware/target/arm/as3525/system-as3525.c (Arbeitskopie) @@ -85,7 +85,9 @@ while((status >>= 1)) irq_no++; +/* panicf("Unhandled IRQ %02X: %s", irq_no, irqname[irq_no]); +*/ } struct vec_int_src @@ -104,6 +106,7 @@ { INT_SRC_MCI0, INT_MCI0 }, { INT_SRC_GPIOA, INT_GPIOA, }, { INT_SRC_GPIOB, INT_GPIOB, }, + { INT_SRC_DBOP, INT_DBOP, }, }; static void setup_vic(void) Index: firmware/target/arm/as3525/sansa-fuze/button-fuze.c =================================================================== --- firmware/target/arm/as3525/sansa-fuze/button-fuze.c (Revision 21184) +++ firmware/target/arm/as3525/sansa-fuze/button-fuze.c (Arbeitskopie) @@ -150,7 +150,7 @@ static void button_delay(void) { - int i = 24; + int i = 45; while(i--) asm volatile ("nop\n"); } Index: firmware/target/arm/as3525/sansa-fuze/lcd-fuze.c =================================================================== --- firmware/target/arm/as3525/sansa-fuze/lcd-fuze.c (Revision 21184) +++ firmware/target/arm/as3525/sansa-fuze/lcd-fuze.c (Arbeitskopie) @@ -39,6 +39,14 @@ #define R_ENTRY_MODE_HORZ 0x7030 #define R_ENTRY_MODE_VERT 0x7038 + +volatile int full_empty = 0; +void INT_DBOP(void) +{ + full_empty = 1; + DBOP_CTRL &= ~(1<<11|1<<5|1<<8); +} + static unsigned lcd_yuv_options = 0; static bool display_on = false; /* is the display turned on? */ static bool display_flipped = false; @@ -59,11 +67,14 @@ GPIOB_AFSEL = 0xfc; GPIOC_AFSEL = 0xff; + DBOP_TIMPOL_23 = 0x6000e; DBOP_CTRL = 0x51008; DBOP_TIMPOL_01 = 0x6e167; DBOP_TIMPOL_23 = 0xa167e06f; + VIC_INT_ENABLE |= INTERRUPT_DBOP; + /* TODO: The OF calls some other functions here, but maybe not important */ } @@ -93,13 +104,31 @@ void lcd_write_data(const fb_data* p_bytes, int count) { - while (count--) + /* Interrupts seem to be faster than polling the status register */ +start: + full_empty = 0; + DBOP_CTRL |= (1<<11|1<<5); + while (!full_empty && count--) { DBOP_DOUT = *p_bytes++; + } + if (count > 0) + { + // yield(); // yield() doesn't seem to make it any slower! + goto start; + } + /* While push fifo is not empty */ +#if 0 + full_empty = 0; + DBOP_CTRL |= (1<<11|1<<8); + if (DBOP_STAT & (1<<10)) + return; + while(!full_empty); +#else + /* this is slightly faster */ + while ((DBOP_STAT & (1<<10)) == 0); +#endif - /* Wait for fifo to empty */ - while ((DBOP_STAT & (1<<10)) == 0); - } } static void lcd_write_reg(int reg, int value)