diff options
-rw-r--r-- | firmware/target/arm/as3525/dbop-as3525.c | 48 | ||||
-rw-r--r-- | firmware/target/arm/as3525/dbop-as3525.h | 12 | ||||
-rw-r--r-- | firmware/target/arm/as3525/sansa-e200v2/lcd-e200v2.c | 50 | ||||
-rw-r--r-- | firmware/target/arm/as3525/sansa-fuze/lcd-fuze.c | 59 |
4 files changed, 76 insertions, 93 deletions
diff --git a/firmware/target/arm/as3525/dbop-as3525.c b/firmware/target/arm/as3525/dbop-as3525.c index 938eee2fb1..b54ad17a6c 100644 --- a/firmware/target/arm/as3525/dbop-as3525.c +++ b/firmware/target/arm/as3525/dbop-as3525.c | |||
@@ -20,6 +20,7 @@ | |||
20 | ****************************************************************************/ | 20 | ****************************************************************************/ |
21 | 21 | ||
22 | #include "config.h" | 22 | #include "config.h" |
23 | #include <inttypes.h> | ||
23 | #include "as3525.h" | 24 | #include "as3525.h" |
24 | #include "dbop-as3525.h" | 25 | #include "dbop-as3525.h" |
25 | 26 | ||
@@ -75,3 +76,50 @@ unsigned short dbop_debug(void) | |||
75 | { | 76 | { |
76 | return dbop_input_value; | 77 | return dbop_input_value; |
77 | } | 78 | } |
79 | |||
80 | static inline void dbop_set_mode(int mode) | ||
81 | { | ||
82 | int delay = 10; | ||
83 | if (mode == 32 && (!(DBOP_CTRL & (1<<13|1<<14)))) | ||
84 | DBOP_CTRL |= (1<<13|1<<14); | ||
85 | else if (mode == 16 && (DBOP_CTRL & (1<<13|1<<14))) | ||
86 | DBOP_CTRL &= ~(1<<14|1<<13); | ||
87 | else | ||
88 | return; | ||
89 | while(delay--) asm volatile("nop"); | ||
90 | } | ||
91 | |||
92 | void dbop_write_data(const int16_t* p_bytes, int count) | ||
93 | { | ||
94 | |||
95 | const int32_t *data; | ||
96 | if ((intptr_t)p_bytes & 0x3 || count == 1) | ||
97 | { /* need to do a single 16bit write beforehand if the address is | ||
98 | * not word aligned or count is 1, switch to 16bit mode if needed */ | ||
99 | dbop_set_mode(16); | ||
100 | DBOP_DOUT16 = *p_bytes++; | ||
101 | if (!(--count)) | ||
102 | return; | ||
103 | } | ||
104 | /* from here, 32bit transfers are save | ||
105 | * set it to transfer 4*(outputwidth) units at a time, | ||
106 | * if bit 12 is set it only does 2 halfwords though (we never set it) | ||
107 | * switch to 32bit output if needed */ | ||
108 | dbop_set_mode(32); | ||
109 | data = (int32_t*)p_bytes; | ||
110 | while (count > 1) | ||
111 | { | ||
112 | DBOP_DOUT32 = *data++; | ||
113 | count -= 2; | ||
114 | |||
115 | /* Wait if push fifo is full */ | ||
116 | while ((DBOP_STAT & (1<<6)) != 0); | ||
117 | } | ||
118 | /* While push fifo is not empty */ | ||
119 | while ((DBOP_STAT & (1<<10)) == 0); | ||
120 | |||
121 | /* due to the 32bit alignment requirement or uneven count, | ||
122 | * we possibly need to do a 16bit transfer at the end also */ | ||
123 | if (count > 0) | ||
124 | dbop_write_data((int16_t*)data, 1); | ||
125 | } | ||
diff --git a/firmware/target/arm/as3525/dbop-as3525.h b/firmware/target/arm/as3525/dbop-as3525.h index 63156031c4..3db62bd3e1 100644 --- a/firmware/target/arm/as3525/dbop-as3525.h +++ b/firmware/target/arm/as3525/dbop-as3525.h | |||
@@ -19,5 +19,17 @@ | |||
19 | * | 19 | * |
20 | ****************************************************************************/ | 20 | ****************************************************************************/ |
21 | 21 | ||
22 | |||
23 | #ifndef __DBOP_AS3525_H__ | ||
24 | #define __DBOP_AS3525_H__ | ||
25 | #include <inttypes.h> | ||
22 | unsigned short int dbop_read_input(void); | 26 | unsigned short int dbop_read_input(void); |
23 | unsigned short dbop_debug(void); | 27 | unsigned short dbop_debug(void); |
28 | |||
29 | /* | ||
30 | * Write any data to dbop | ||
31 | * switches to 32bit transfers if possible, | ||
32 | * for best performance pre-align count and data | ||
33 | **/ | ||
34 | void dbop_write_data(const int16_t *data, int count); | ||
35 | #endif | ||
diff --git a/firmware/target/arm/as3525/sansa-e200v2/lcd-e200v2.c b/firmware/target/arm/as3525/sansa-e200v2/lcd-e200v2.c index f4d1a7cf56..54aa22e398 100644 --- a/firmware/target/arm/as3525/sansa-e200v2/lcd-e200v2.c +++ b/firmware/target/arm/as3525/sansa-e200v2/lcd-e200v2.c | |||
@@ -120,19 +120,11 @@ static void as3525_dbop_init(void) | |||
120 | /* TODO: The OF calls some other functions here, but maybe not important */ | 120 | /* TODO: The OF calls some other functions here, but maybe not important */ |
121 | } | 121 | } |
122 | 122 | ||
123 | static void lcd_write_value16(unsigned short value) | 123 | static void lcd_write_cmd(short cmd) |
124 | { | ||
125 | DBOP_CTRL &= ~(1<<14|1<<13); | ||
126 | lcd_delay(10); | ||
127 | DBOP_DOUT16 = value; | ||
128 | while ((DBOP_STAT & (1<<10)) == 0); | ||
129 | } | ||
130 | |||
131 | static void lcd_write_cmd(int cmd) | ||
132 | { | 124 | { |
133 | /* Write register */ | 125 | /* Write register */ |
134 | DBOP_TIMPOL_23 = 0xa167006e; | 126 | DBOP_TIMPOL_23 = 0xa167006e; |
135 | lcd_write_value16(cmd); | 127 | dbop_write_data(&cmd, 1); |
136 | 128 | ||
137 | /* Wait for fifo to empty */ | 129 | /* Wait for fifo to empty */ |
138 | while ((DBOP_STAT & (1<<10)) == 0); | 130 | while ((DBOP_STAT & (1<<10)) == 0); |
@@ -144,43 +136,13 @@ static void lcd_write_cmd(int cmd) | |||
144 | DBOP_TIMPOL_23 = 0xa167e06f; | 136 | DBOP_TIMPOL_23 = 0xa167e06f; |
145 | } | 137 | } |
146 | 138 | ||
147 | void lcd_write_data(const fb_data* p_bytes, int count) | ||
148 | { | ||
149 | const long *data; | ||
150 | if ((int)p_bytes & 0x3) | ||
151 | { /* need to do a single 16bit write beforehand if the address is | ||
152 | * not word aligned */ | ||
153 | lcd_write_value16(*p_bytes); | ||
154 | count--;p_bytes++; | ||
155 | } | ||
156 | /* from here, 32bit transfers are save | ||
157 | * set it to transfer 4*(outputwidth) units at a time, | ||
158 | * if bit 12 is set it only does 2 halfwords though */ | ||
159 | DBOP_CTRL |= (1<<13|1<<14); | ||
160 | data = (long*)p_bytes; | ||
161 | while (count > 1) | ||
162 | { | ||
163 | DBOP_DOUT32 = *data++; | ||
164 | count -= 2; | ||
165 | |||
166 | /* Wait if push fifo is full */ | ||
167 | while ((DBOP_STAT & (1<<6)) != 0); | ||
168 | } | ||
169 | /* While push fifo is not empty */ | ||
170 | while ((DBOP_STAT & (1<<10)) == 0); | ||
171 | |||
172 | /* due to the 32bit alignment requirement or uneven count, | ||
173 | * we possibly need to do a 16bit transfer at the end also */ | ||
174 | if (count > 0) | ||
175 | lcd_write_value16(*(fb_data*)data); | ||
176 | } | ||
177 | 139 | ||
178 | static void lcd_write_reg(int reg, int value) | 140 | static void lcd_write_reg(int reg, int value) |
179 | { | 141 | { |
180 | fb_data data = value; | 142 | unsigned short data = value; |
181 | 143 | ||
182 | lcd_write_cmd(reg); | 144 | lcd_write_cmd(reg); |
183 | lcd_write_value16(data); | 145 | dbop_write_data(&data, 1); |
184 | } | 146 | } |
185 | 147 | ||
186 | /*** hardware configuration ***/ | 148 | /*** hardware configuration ***/ |
@@ -486,7 +448,7 @@ void lcd_update(void) | |||
486 | 448 | ||
487 | lcd_write_cmd(R_WRITE_DATA_2_GRAM); | 449 | lcd_write_cmd(R_WRITE_DATA_2_GRAM); |
488 | 450 | ||
489 | lcd_write_data((fb_data*)lcd_framebuffer, LCD_WIDTH*LCD_HEIGHT); | 451 | dbop_write_data((fb_data*)lcd_framebuffer, LCD_WIDTH*LCD_HEIGHT); |
490 | } | 452 | } |
491 | 453 | ||
492 | /* Update a fraction of the display. */ | 454 | /* Update a fraction of the display. */ |
@@ -526,7 +488,7 @@ void lcd_update_rect(int x, int y, int width, int height) | |||
526 | 488 | ||
527 | do | 489 | do |
528 | { | 490 | { |
529 | lcd_write_data(ptr, width); | 491 | dbop_write_data(ptr, width); |
530 | ptr += LCD_WIDTH; | 492 | ptr += LCD_WIDTH; |
531 | } | 493 | } |
532 | while (--height > 0); | 494 | while (--height > 0); |
diff --git a/firmware/target/arm/as3525/sansa-fuze/lcd-fuze.c b/firmware/target/arm/as3525/sansa-fuze/lcd-fuze.c index 3332e0c78c..bdf1c704e0 100644 --- a/firmware/target/arm/as3525/sansa-fuze/lcd-fuze.c +++ b/firmware/target/arm/as3525/sansa-fuze/lcd-fuze.c | |||
@@ -124,66 +124,23 @@ static void as3525_dbop_init(void) | |||
124 | /* TODO: The OF calls some other functions here, but maybe not important */ | 124 | /* TODO: The OF calls some other functions here, but maybe not important */ |
125 | } | 125 | } |
126 | 126 | ||
127 | static void lcd_write_value16(unsigned short value) | 127 | static void lcd_write_cmd(short cmd) |
128 | { | ||
129 | DBOP_CTRL &= ~(1<<14|1<<13); | ||
130 | lcd_delay(10); | ||
131 | DBOP_DOUT16 = value; | ||
132 | while ((DBOP_STAT & (1<<10)) == 0); | ||
133 | } | ||
134 | |||
135 | static void lcd_write_cmd(int cmd) | ||
136 | { | 128 | { |
137 | /* Write register */ | 129 | /* Write register */ |
138 | DBOP_TIMPOL_23 = 0xa167006e; | 130 | DBOP_TIMPOL_23 = 0xa167006e; |
139 | lcd_write_value16(cmd); | 131 | dbop_write_data(&cmd, 1); |
140 | |||
141 | /* Wait for fifo to empty */ | ||
142 | while ((DBOP_STAT & (1<<10)) == 0); | ||
143 | 132 | ||
144 | lcd_delay(4); | 133 | lcd_delay(4); |
145 | 134 | ||
146 | DBOP_TIMPOL_23 = 0xa167e06f; | 135 | DBOP_TIMPOL_23 = 0xa167e06f; |
147 | } | 136 | } |
148 | 137 | ||
149 | void lcd_write_data(const fb_data* p_bytes, int count) | ||
150 | { | ||
151 | const long *data; | ||
152 | if ((int)p_bytes & 0x3) | ||
153 | { /* need to do a single 16bit write beforehand if the address is | ||
154 | * not word aligned */ | ||
155 | lcd_write_value16(*p_bytes); | ||
156 | count--;p_bytes++; | ||
157 | } | ||
158 | /* from here, 32bit transfers are save | ||
159 | * set it to transfer 4*(outputwidth) units at a time, | ||
160 | * if bit 12 is set it only does 2 halfwords though */ | ||
161 | DBOP_CTRL |= (1<<13|1<<14); | ||
162 | lcd_delay(10); | ||
163 | data = (long*)p_bytes; | ||
164 | while (count > 1) | ||
165 | { | ||
166 | DBOP_DOUT32 = *data++; | ||
167 | count -= 2; | ||
168 | |||
169 | /* Wait if push fifo is full */ | ||
170 | while ((DBOP_STAT & (1<<6)) != 0); | ||
171 | } | ||
172 | /* While push fifo is not empty */ | ||
173 | while ((DBOP_STAT & (1<<10)) == 0); | ||
174 | |||
175 | /* due to the 32bit alignment requirement or uneven count, | ||
176 | * we possibly need to do a 16bit transfer at the end also */ | ||
177 | if (count > 0) | ||
178 | lcd_write_value16(*(fb_data*)data); | ||
179 | } | ||
180 | |||
181 | static void lcd_write_reg(int reg, int value) | 138 | static void lcd_write_reg(int reg, int value) |
182 | { | 139 | { |
183 | fb_data data = value; | 140 | int16_t data = value; |
184 | 141 | ||
185 | lcd_write_cmd(reg); | 142 | lcd_write_cmd(reg); |
186 | lcd_write_value16(data); | 143 | dbop_write_data(&data, 1); |
187 | } | 144 | } |
188 | 145 | ||
189 | /*** hardware configuration ***/ | 146 | /*** hardware configuration ***/ |
@@ -437,7 +394,7 @@ void lcd_update(void) | |||
437 | 394 | ||
438 | lcd_write_cmd(R_WRITE_DATA_2_GRAM); | 395 | lcd_write_cmd(R_WRITE_DATA_2_GRAM); |
439 | 396 | ||
440 | lcd_write_data((fb_data*)lcd_framebuffer, LCD_WIDTH*LCD_HEIGHT); | 397 | dbop_write_data((fb_data*)lcd_framebuffer, LCD_WIDTH*LCD_HEIGHT); |
441 | } | 398 | } |
442 | 399 | ||
443 | /* Update a fraction of the display. */ | 400 | /* Update a fraction of the display. */ |
@@ -470,6 +427,10 @@ void lcd_update_rect(int x, int y, int width, int height) | |||
470 | 427 | ||
471 | lcd_write_reg(R_ENTRY_MODE, r_entry_mode); | 428 | lcd_write_reg(R_ENTRY_MODE, r_entry_mode); |
472 | 429 | ||
430 | /* we need to make x and width even to enable 32bit transfers */ | ||
431 | width = (width + (x & 1) + 1) & ~1; | ||
432 | x &= ~1; | ||
433 | |||
473 | lcd_window_x(x, x + width - 1); | 434 | lcd_window_x(x, x + width - 1); |
474 | lcd_window_y(y, y + height -1); | 435 | lcd_window_y(y, y + height -1); |
475 | 436 | ||
@@ -479,7 +440,7 @@ void lcd_update_rect(int x, int y, int width, int height) | |||
479 | 440 | ||
480 | do | 441 | do |
481 | { | 442 | { |
482 | lcd_write_data(ptr, width); | 443 | dbop_write_data(ptr, width); |
483 | ptr += LCD_WIDTH; | 444 | ptr += LCD_WIDTH; |
484 | } | 445 | } |
485 | while (--height > 0); | 446 | while (--height > 0); |