diff options
Diffstat (limited to 'firmware/target/arm/imx233/lcdif-imx233.c')
-rw-r--r-- | firmware/target/arm/imx233/lcdif-imx233.c | 366 |
1 files changed, 294 insertions, 72 deletions
diff --git a/firmware/target/arm/imx233/lcdif-imx233.c b/firmware/target/arm/imx233/lcdif-imx233.c index f947fa69f1..da58270498 100644 --- a/firmware/target/arm/imx233/lcdif-imx233.c +++ b/firmware/target/arm/imx233/lcdif-imx233.c | |||
@@ -19,36 +19,62 @@ | |||
19 | * | 19 | * |
20 | ****************************************************************************/ | 20 | ****************************************************************************/ |
21 | #include "lcdif-imx233.h" | 21 | #include "lcdif-imx233.h" |
22 | #include "pinctrl-imx233.h" | ||
23 | #include "icoll-imx233.h" | ||
22 | 24 | ||
23 | static unsigned lcdif_word_length = 0; | 25 | #if IMX233_SUBTARGET >= 3700 |
26 | static lcdif_irq_cb_t g_cur_frame_cb = NULL; | ||
27 | static lcdif_irq_cb_t g_vsync_edge_cb = NULL; | ||
28 | #endif | ||
24 | 29 | ||
25 | void imx233_lcdif_enable_underflow_recover(bool enable) | 30 | /* for some crazy reason, all "non-dma" interrupts are routed to the ERROR irq */ |
31 | #if IMX233_SUBTARGET >= 3700 | ||
32 | void INT_LCDIF_ERROR(void) | ||
26 | { | 33 | { |
27 | if(enable) | 34 | if(BF_RD(LCDIF_CTRL1, CUR_FRAME_DONE_IRQ)) |
28 | BF_SET(LCDIF_CTRL1, RECOVER_ON_UNDERFLOW); | 35 | { |
29 | else | 36 | if(g_cur_frame_cb) |
30 | BF_CLR(LCDIF_CTRL1, RECOVER_ON_UNDERFLOW); | 37 | g_cur_frame_cb(); |
38 | BF_CLR(LCDIF_CTRL1, CUR_FRAME_DONE_IRQ); | ||
39 | } | ||
40 | if(BF_RD(LCDIF_CTRL1, VSYNC_EDGE_IRQ)) | ||
41 | { | ||
42 | if(g_vsync_edge_cb) | ||
43 | g_vsync_edge_cb(); | ||
44 | BF_CLR(LCDIF_CTRL1, VSYNC_EDGE_IRQ); | ||
45 | } | ||
31 | } | 46 | } |
47 | #endif | ||
32 | 48 | ||
33 | void imx233_lcdif_enable_bus_master(bool enable) | 49 | void imx233_lcdif_enable(bool enable) |
34 | { | 50 | { |
35 | if(enable) | 51 | if(enable) |
36 | BF_SET(LCDIF_CTRL, LCDIF_MASTER); | 52 | BF_CLR(LCDIF_CTRL, CLKGATE); |
37 | else | 53 | else |
38 | BF_CLR(LCDIF_CTRL, LCDIF_MASTER); | 54 | BF_SET(LCDIF_CTRL, CLKGATE); |
39 | } | 55 | } |
40 | 56 | ||
41 | void imx233_lcdif_enable(bool enable) | 57 | void imx233_lcdif_reset_lcd(bool enable) |
42 | { | 58 | { |
59 | #if IMX233_SUBTARGET < 3700 | ||
43 | if(enable) | 60 | if(enable) |
44 | BF_CLR(LCDIF_CTRL, CLKGATE); | 61 | BF_SET(LCDIF_CTRL, RESET); |
45 | else | 62 | else |
46 | BF_SET(LCDIF_CTRL, CLKGATE); | 63 | BF_CLR(LCDIF_CTRL, RESET); |
64 | #else | ||
65 | if(enable) | ||
66 | BF_SET(LCDIF_CTRL1, RESET); | ||
67 | else | ||
68 | BF_CLR(LCDIF_CTRL1, RESET); | ||
69 | #endif | ||
47 | } | 70 | } |
48 | 71 | ||
49 | void imx233_lcdif_reset(void) | 72 | void imx233_lcdif_init(void) |
50 | { | 73 | { |
51 | imx233_reset_block(&HW_LCDIF_CTRL); | 74 | imx233_reset_block(&HW_LCDIF_CTRL); |
75 | #if IMX233_SUBTARGET >= 3700 | ||
76 | imx233_icoll_enable_interrupt(INT_SRC_LCDIF_ERROR, true); | ||
77 | #endif | ||
52 | } | 78 | } |
53 | 79 | ||
54 | void imx233_lcdif_set_timings(unsigned data_setup, unsigned data_hold, | 80 | void imx233_lcdif_set_timings(unsigned data_setup, unsigned data_hold, |
@@ -58,90 +84,286 @@ void imx233_lcdif_set_timings(unsigned data_setup, unsigned data_hold, | |||
58 | DATA_HOLD(data_hold), CMD_SETUP(cmd_setup), CMD_HOLD(cmd_hold)); | 84 | DATA_HOLD(data_hold), CMD_SETUP(cmd_setup), CMD_HOLD(cmd_hold)); |
59 | } | 85 | } |
60 | 86 | ||
61 | void imx233_lcdif_set_lcd_databus_width(unsigned width) | 87 | void imx233_lcdif_set_word_length(unsigned word_length) |
62 | { | 88 | { |
63 | BF_WR(LCDIF_CTRL, LCD_DATABUS_WIDTH, width); | 89 | switch(word_length) |
90 | { | ||
91 | case 8: BF_WR_V(LCDIF_CTRL, WORD_LENGTH, 8_BIT); break; | ||
92 | case 16: BF_WR_V(LCDIF_CTRL, WORD_LENGTH, 16_BIT); break; | ||
93 | #if IMX233_SUBTARGET >= 3780 | ||
94 | case 18: BF_WR_V(LCDIF_CTRL, WORD_LENGTH, 18_BIT); break; | ||
95 | case 24: BF_WR_V(LCDIF_CTRL, WORD_LENGTH, 24_BIT); break; | ||
96 | #endif | ||
97 | default: | ||
98 | panicf("this chip cannot handle a lcd word length of %d", word_length); | ||
99 | break; | ||
100 | } | ||
64 | } | 101 | } |
65 | 102 | ||
66 | void imx233_lcdif_set_word_length(unsigned word_length) | 103 | void imx233_lcdif_wait_ready(void) |
67 | { | 104 | { |
68 | BF_WR(LCDIF_CTRL, WORD_LENGTH, word_length); | 105 | while(BF_RD(LCDIF_CTRL, RUN)); |
69 | lcdif_word_length = word_length; | ||
70 | } | 106 | } |
71 | 107 | ||
72 | void imx233_lcdif_set_byte_packing_format(unsigned byte_packing) | 108 | void imx233_lcdif_set_data_swizzle(unsigned swizzle) |
73 | { | 109 | { |
74 | BF_WR(LCDIF_CTRL1, BYTE_PACKING_FORMAT, byte_packing); | 110 | #if IMX233_SUBTARGET >= 3780 |
111 | BF_WR(LCDIF_CTRL, INPUT_DATA_SWIZZLE, swizzle); | ||
112 | #else | ||
113 | BF_WR(LCDIF_CTRL, DATA_SWIZZLE, swizzle); | ||
114 | #endif | ||
75 | } | 115 | } |
76 | 116 | ||
77 | void imx233_lcdif_set_data_format(bool data_fmt_16, bool data_fmt_18, bool data_fmt_24) | 117 | void imx233_lcdif_wait_fifo(void) |
78 | { | 118 | { |
79 | if(data_fmt_16) | 119 | #if IMX233_SUBTARGET >= 3700 |
80 | BF_SET(LCDIF_CTRL, DATA_FORMAT_16_BIT); | 120 | while(BF_RD(LCDIF_STAT, TXFIFO_FULL)); |
81 | else | 121 | #else |
82 | BF_CLR(LCDIF_CTRL, DATA_FORMAT_16_BIT); | 122 | while(!BF_RD(LCDIF_CTRL, FIFO_STATUS)); |
83 | if(data_fmt_18) | 123 | #endif |
84 | BF_SET(LCDIF_CTRL, DATA_FORMAT_18_BIT); | ||
85 | else | ||
86 | BF_CLR(LCDIF_CTRL, DATA_FORMAT_18_BIT); | ||
87 | if(data_fmt_24) | ||
88 | BF_SET(LCDIF_CTRL, DATA_FORMAT_24_BIT); | ||
89 | else | ||
90 | BF_CLR(LCDIF_CTRL, DATA_FORMAT_24_BIT); | ||
91 | } | 124 | } |
92 | 125 | ||
93 | void imx233_lcdif_wait_ready(void) | 126 | /* The following function set byte packing often, ifdefing everytime is painful */ |
127 | #if IMX233_SUBTARGET < 3700 | ||
128 | #define imx233_lcdif_set_byte_packing_format(a) | ||
129 | #endif | ||
130 | |||
131 | // bbp = bytes per pixel | ||
132 | static void pio_send(unsigned len, unsigned bpp, uint8_t *buf) | ||
94 | { | 133 | { |
95 | while(BF_RD(LCDIF_CTRL, RUN)); | 134 | /* WARNING: the imx233 has a limitation on count wrt to byte packing, the |
135 | * count must be a multiple of 2 with maximum packing when word-length is | ||
136 | * 16-bit! | ||
137 | * On the other hand, 8-bit word length doesn't seem to have any limitations, | ||
138 | * for example one can send 3 bytes with a packing format of 0xf | ||
139 | * WARNING for this function to work properly with any swizzle, we have to | ||
140 | * make sure we pack as many 32-bits as possible even when the data is not | ||
141 | * word-aligned */ | ||
142 | imx233_lcdif_set_byte_packing_format(0xf); | ||
143 | /* compute shift between buf and next word-aligned pointer */ | ||
144 | int shift = 0; | ||
145 | uint32_t temp_buf = 0; | ||
146 | int count = len * bpp; // number of bytes | ||
147 | while(0x3 & (intptr_t)buf) | ||
148 | { | ||
149 | temp_buf = temp_buf | *buf++ << shift; | ||
150 | shift += 8; | ||
151 | count--; | ||
152 | } | ||
153 | /* starting from now, all read are 32-bit */ | ||
154 | uint32_t *wbuf = (void *)buf; | ||
155 | #if IMX233_SUBTARGET >= 3780 | ||
156 | HW_LCDIF_TRANSFER_COUNT = BF_OR2(LCDIF_TRANSFER_COUNT, V_COUNT(1), H_COUNT(len)); | ||
157 | #else | ||
158 | BF_WR(LCDIF_CTRL, COUNT, len); | ||
159 | #endif | ||
160 | BF_SET(LCDIF_CTRL, RUN); | ||
161 | while(count > 0) | ||
162 | { | ||
163 | uint32_t val = *wbuf++; | ||
164 | imx233_lcdif_wait_fifo(); | ||
165 | HW_LCDIF_DATA = temp_buf | val << shift; | ||
166 | if(shift != 0) | ||
167 | temp_buf = val >> (32 - shift); | ||
168 | count -= 4; | ||
169 | } | ||
170 | /* send remaining bytes if any */ | ||
171 | if(shift != 0) | ||
172 | { | ||
173 | imx233_lcdif_wait_fifo(); | ||
174 | HW_LCDIF_DATA = temp_buf; | ||
175 | } | ||
176 | imx233_lcdif_wait_ready(); | ||
96 | } | 177 | } |
97 | 178 | ||
98 | void imx233_lcdif_pio_send(bool data_mode, unsigned len, uint32_t *buf) | 179 | void imx233_lcdif_pio_send(bool data_mode, unsigned len, void *buf) |
99 | { | 180 | { |
100 | unsigned max_xfer_size = 0xffff; | ||
101 | if(len == 0) | ||
102 | return; | ||
103 | if(lcdif_word_length == BV_LCDIF_CTRL_WORD_LENGTH__16_BIT) | ||
104 | max_xfer_size = 0x1fffe; | ||
105 | imx233_lcdif_wait_ready(); | 181 | imx233_lcdif_wait_ready(); |
182 | #if IMX233_SUBTARGET >= 3780 | ||
106 | imx233_lcdif_enable_bus_master(false); | 183 | imx233_lcdif_enable_bus_master(false); |
184 | #endif | ||
185 | if(data_mode) | ||
186 | BF_SET(LCDIF_CTRL, DATA_SELECT); | ||
187 | else | ||
188 | BF_CLR(LCDIF_CTRL, DATA_SELECT); | ||
107 | 189 | ||
108 | do | 190 | switch(BF_RD(LCDIF_CTRL, WORD_LENGTH)) |
109 | { | 191 | { |
110 | unsigned burst = MIN(len, max_xfer_size); | 192 | case BV_LCDIF_CTRL_WORD_LENGTH__8_BIT: pio_send(len, 1, buf); break; |
111 | len -= burst; | 193 | case BV_LCDIF_CTRL_WORD_LENGTH__16_BIT: pio_send(len, 2, buf); break; |
112 | unsigned count = burst; | 194 | #if IMX233_SUBTARGET >= 3780 |
113 | if(lcdif_word_length != BV_LCDIF_CTRL_WORD_LENGTH__8_BIT) | 195 | case BV_LCDIF_CTRL_WORD_LENGTH__18_BIT: pio_send(len, 4, buf); break; |
114 | { | 196 | #endif |
115 | if(burst & 1) | 197 | default: panicf("Don't know how to handle this word length"); |
116 | burst++; | 198 | } |
117 | count = burst / 2; | ||
118 | } | ||
119 | else | ||
120 | count = burst; | ||
121 | HW_LCDIF_TRANSFER_COUNT = 0; | ||
122 | HW_LCDIF_TRANSFER_COUNT = 0x10000 | count; | ||
123 | BF_CLR(LCDIF_CTRL, DATA_SELECT); | ||
124 | BF_CLR(LCDIF_CTRL, RUN); | ||
125 | if(data_mode) | ||
126 | BF_SET(LCDIF_CTRL, DATA_SELECT); | ||
127 | BF_SET(LCDIF_CTRL, RUN); | ||
128 | burst = (burst + 3) / 4; | ||
129 | while(burst-- > 0) | ||
130 | { | ||
131 | while(BF_RD(LCDIF_STAT, LFIFO_FULL)); | ||
132 | HW_LCDIF_DATA = *buf++; | ||
133 | } | ||
134 | imx233_lcdif_wait_ready(); | ||
135 | }while(len > 0); | ||
136 | imx233_lcdif_enable_bus_master(true); | ||
137 | } | 199 | } |
138 | 200 | ||
139 | void imx233_lcdif_dma_send(void *buf, unsigned width, unsigned height) | 201 | void imx233_lcdif_dma_send(void *buf, unsigned width, unsigned height) |
140 | { | 202 | { |
203 | #if IMX233_SUBTARGET >= 3780 | ||
204 | imx233_lcdif_enable_bus_master(true); | ||
141 | HW_LCDIF_CUR_BUF = (uint32_t)buf; | 205 | HW_LCDIF_CUR_BUF = (uint32_t)buf; |
142 | HW_LCDIF_TRANSFER_COUNT = 0; | 206 | HW_LCDIF_TRANSFER_COUNT = BF_OR2(LCDIF_TRANSFER_COUNT, V_COUNT(height), H_COUNT(width)); |
143 | HW_LCDIF_TRANSFER_COUNT = (height << 16) | width; | ||
144 | BF_CLR(LCDIF_CTRL, RUN); | ||
145 | BF_SET(LCDIF_CTRL, DATA_SELECT); | 207 | BF_SET(LCDIF_CTRL, DATA_SELECT); |
146 | BF_SET(LCDIF_CTRL, RUN); | 208 | BF_SET(LCDIF_CTRL, RUN); |
209 | #endif | ||
210 | } | ||
211 | |||
212 | static void setup_data_pins(unsigned bus_width) | ||
213 | { | ||
214 | imx233_pinctrl_setup_vpin(VPIN_LCD_D0, "lcd d0", PINCTRL_DRIVE_4mA, false); | ||
215 | imx233_pinctrl_setup_vpin(VPIN_LCD_D1, "lcd d1", PINCTRL_DRIVE_4mA, false); | ||
216 | imx233_pinctrl_setup_vpin(VPIN_LCD_D2, "lcd d2", PINCTRL_DRIVE_4mA, false); | ||
217 | imx233_pinctrl_setup_vpin(VPIN_LCD_D3, "lcd d3", PINCTRL_DRIVE_4mA, false); | ||
218 | imx233_pinctrl_setup_vpin(VPIN_LCD_D4, "lcd d4", PINCTRL_DRIVE_4mA, false); | ||
219 | imx233_pinctrl_setup_vpin(VPIN_LCD_D5, "lcd d5", PINCTRL_DRIVE_4mA, false); | ||
220 | imx233_pinctrl_setup_vpin(VPIN_LCD_D6, "lcd d6", PINCTRL_DRIVE_4mA, false); | ||
221 | imx233_pinctrl_setup_vpin(VPIN_LCD_D7, "lcd d7", PINCTRL_DRIVE_4mA, false); | ||
222 | if(bus_width >= 16) | ||
223 | { | ||
224 | imx233_pinctrl_setup_vpin(VPIN_LCD_D8, "lcd d8", PINCTRL_DRIVE_4mA, false); | ||
225 | imx233_pinctrl_setup_vpin(VPIN_LCD_D9, "lcd d9", PINCTRL_DRIVE_4mA, false); | ||
226 | imx233_pinctrl_setup_vpin(VPIN_LCD_D10, "lcd d10", PINCTRL_DRIVE_4mA, false); | ||
227 | imx233_pinctrl_setup_vpin(VPIN_LCD_D11, "lcd d11", PINCTRL_DRIVE_4mA, false); | ||
228 | imx233_pinctrl_setup_vpin(VPIN_LCD_D12, "lcd d12", PINCTRL_DRIVE_4mA, false); | ||
229 | imx233_pinctrl_setup_vpin(VPIN_LCD_D13, "lcd d13", PINCTRL_DRIVE_4mA, false); | ||
230 | imx233_pinctrl_setup_vpin(VPIN_LCD_D14, "lcd d14", PINCTRL_DRIVE_4mA, false); | ||
231 | imx233_pinctrl_setup_vpin(VPIN_LCD_D15, "lcd d15", PINCTRL_DRIVE_4mA, false); | ||
232 | } | ||
233 | #if IMX233_SUBTARGET >= 3780 | ||
234 | if(bus_width >= 18) | ||
235 | { | ||
236 | imx233_pinctrl_setup_vpin(VPIN_LCD_D16, "lcd d16", PINCTRL_DRIVE_4mA, false); | ||
237 | imx233_pinctrl_setup_vpin(VPIN_LCD_D17, "lcd d17", PINCTRL_DRIVE_4mA, false); | ||
238 | } | ||
239 | #endif | ||
240 | } | ||
241 | |||
242 | void imx233_lcdif_setup_system_pins(unsigned bus_width) | ||
243 | { | ||
244 | imx233_pinctrl_setup_vpin(VPIN_LCD_RESET, "lcd reset", PINCTRL_DRIVE_4mA, false); | ||
245 | imx233_pinctrl_setup_vpin(VPIN_LCD_RS, "lcd rs", PINCTRL_DRIVE_4mA, false); | ||
246 | imx233_pinctrl_setup_vpin(VPIN_LCD_WR, "lcd wr", PINCTRL_DRIVE_4mA, false); | ||
247 | #ifdef VPIN_LCD_RD | ||
248 | imx233_pinctrl_setup_vpin(VPIN_LCD_RD, "lcd rd", PINCTRL_DRIVE_4mA, false); | ||
249 | #endif | ||
250 | imx233_pinctrl_setup_vpin(VPIN_LCD_CS, "lcd cs", PINCTRL_DRIVE_4mA, false); | ||
251 | |||
252 | setup_data_pins(bus_width); | ||
253 | } | ||
254 | |||
255 | #if IMX233_SUBTARGET >= 3700 | ||
256 | void imx233_lcdif_setup_dotclk_pins(unsigned bus_width, bool have_enable) | ||
257 | { | ||
258 | if(have_enable) | ||
259 | imx233_pinctrl_setup_vpin(VPIN_LCD_ENABLE, "lcd enable", PINCTRL_DRIVE_4mA, false); | ||
260 | imx233_pinctrl_setup_vpin(VPIN_LCD_RESET, "lcd reset", PINCTRL_DRIVE_4mA, false); | ||
261 | imx233_pinctrl_setup_vpin(VPIN_LCD_HSYNC, "lcd hsync", PINCTRL_DRIVE_4mA, false); | ||
262 | imx233_pinctrl_setup_vpin(VPIN_LCD_VSYNC, "lcd vsync", PINCTRL_DRIVE_4mA, false); | ||
263 | imx233_pinctrl_setup_vpin(VPIN_LCD_DOTCLK, "lcd dotclk", PINCTRL_DRIVE_4mA, false); | ||
264 | |||
265 | setup_data_pins(bus_width); | ||
266 | } | ||
267 | |||
268 | void imx233_lcdif_set_byte_packing_format(unsigned byte_packing) | ||
269 | { | ||
270 | BF_WR(LCDIF_CTRL1, BYTE_PACKING_FORMAT, byte_packing); | ||
271 | } | ||
272 | #endif | ||
273 | |||
274 | #if IMX233_SUBTARGET >= 3700 && IMX233_SUBTARGET < 3780 | ||
275 | void imx233_lcdif_enable_sync_signals(bool en) | ||
276 | { | ||
277 | BF_WR(LCDIF_VDCTRL3, SYNC_SIGNALS_ON, en); | ||
278 | } | ||
279 | |||
280 | void imx233_lcdif_setup_dotclk(unsigned v_pulse_width, unsigned v_period, | ||
281 | unsigned v_wait_cnt, unsigned v_active, unsigned h_pulse_width, | ||
282 | unsigned h_period, unsigned h_wait_cnt, unsigned h_active, bool enable_present) | ||
283 | { | ||
284 | HW_LCDIF_VDCTRL0 = BF_OR4(LCDIF_VDCTRL0, ENABLE_PRESENT(enable_present), | ||
285 | VSYNC_PERIOD_UNIT(1), VSYNC_PULSE_WIDTH_UNIT(1), | ||
286 | DOTCLK_V_VALID_DATA_CNT(v_active)); | ||
287 | HW_LCDIF_VDCTRL1 = BF_OR2(LCDIF_VDCTRL1, VSYNC_PERIOD(v_period), | ||
288 | VSYNC_PULSE_WIDTH(v_pulse_width)); | ||
289 | HW_LCDIF_VDCTRL2 = BF_OR3(LCDIF_VDCTRL2, HSYNC_PULSE_WIDTH(h_pulse_width), | ||
290 | HSYNC_PERIOD(h_period), DOTCLK_H_VALID_DATA_CNT(h_active)); | ||
291 | HW_LCDIF_VDCTRL3 = BF_OR2(LCDIF_VDCTRL3, VERTICAL_WAIT_CNT(v_wait_cnt), | ||
292 | HORIZONTAL_WAIT_CNT(h_wait_cnt)); | ||
293 | // setup dotclk mode, always bypass count, apparently data select is needed | ||
294 | HW_LCDIF_CTRL_SET = BM_OR3(LCDIF_CTRL, DOTCLK_MODE, BYPASS_COUNT, DATA_SELECT); | ||
295 | } | ||
296 | |||
297 | void imx233_lcdif_setup_dotclk_ex(unsigned v_pulse_width, unsigned v_back_porch, | ||
298 | unsigned v_front_porch, unsigned h_pulse_width, unsigned h_back_porch, | ||
299 | unsigned h_front_porch, unsigned width, unsigned height, unsigned clk_per_pix, | ||
300 | bool enable_present) | ||
301 | { | ||
302 | unsigned h_active = clk_per_pix * width; | ||
303 | unsigned h_period = h_active + h_back_porch + h_front_porch; | ||
304 | unsigned v_active = height; | ||
305 | unsigned v_period = v_active + v_back_porch + v_front_porch; | ||
306 | imx233_lcdif_setup_dotclk(v_pulse_width, v_period, v_back_porch, v_active, | ||
307 | h_pulse_width, h_period, h_back_porch, h_active, enable_present); | ||
308 | } | ||
309 | |||
310 | void imx233_lcdif_enable_frame_done_irq(bool en) | ||
311 | { | ||
312 | if(en) | ||
313 | BF_SET(LCDIF_CTRL1, CUR_FRAME_DONE_IRQ_EN); | ||
314 | else | ||
315 | BF_CLR(LCDIF_CTRL1, CUR_FRAME_DONE_IRQ_EN); | ||
316 | BF_CLR(LCDIF_CTRL1, CUR_FRAME_DONE_IRQ); | ||
317 | } | ||
318 | |||
319 | void imx233_lcdif_set_frame_done_cb(lcdif_irq_cb_t cb) | ||
320 | { | ||
321 | g_cur_frame_cb = cb; | ||
322 | } | ||
323 | |||
324 | void imx233_lcdif_enable_vsync_edge_irq(bool en) | ||
325 | { | ||
326 | if(en) | ||
327 | BF_SET(LCDIF_CTRL1, VSYNC_EDGE_IRQ_EN); | ||
328 | else | ||
329 | BF_CLR(LCDIF_CTRL1, VSYNC_EDGE_IRQ_EN); | ||
330 | BF_CLR(LCDIF_CTRL1, VSYNC_EDGE_IRQ); | ||
331 | } | ||
332 | |||
333 | void imx233_lcdif_set_vsync_edge_cb(lcdif_irq_cb_t cb) | ||
334 | { | ||
335 | g_vsync_edge_cb = cb; | ||
336 | } | ||
337 | #endif | ||
338 | |||
339 | #if IMX233_SUBTARGET >= 3780 | ||
340 | void imx233_lcdif_set_lcd_databus_width(unsigned width) | ||
341 | { | ||
342 | switch(width) | ||
343 | { | ||
344 | case 8: BF_WR_V(LCDIF_CTRL, LCD_DATABUS_WIDTH, 8_BIT); break; | ||
345 | case 16: BF_WR_V(LCDIF_CTRL, LCD_DATABUS_WIDTH, 16_BIT); break; | ||
346 | case 18: BF_WR_V(LCDIF_CTRL, LCD_DATABUS_WIDTH, 18_BIT); break; | ||
347 | case 24: BF_WR_V(LCDIF_CTRL, LCD_DATABUS_WIDTH, 24_BIT); break; | ||
348 | default: | ||
349 | panicf("this chip cannot handle a lcd bus width of %d", width); | ||
350 | break; | ||
351 | } | ||
352 | } | ||
353 | |||
354 | void imx233_lcdif_enable_underflow_recover(bool enable) | ||
355 | { | ||
356 | if(enable) | ||
357 | BF_SET(LCDIF_CTRL1, RECOVER_ON_UNDERFLOW); | ||
358 | else | ||
359 | BF_CLR(LCDIF_CTRL1, RECOVER_ON_UNDERFLOW); | ||
360 | } | ||
361 | |||
362 | void imx233_lcdif_enable_bus_master(bool enable) | ||
363 | { | ||
364 | if(enable) | ||
365 | BF_SET(LCDIF_CTRL, LCDIF_MASTER); | ||
366 | else | ||
367 | BF_CLR(LCDIF_CTRL, LCDIF_MASTER); | ||
147 | } | 368 | } |
369 | #endif \ No newline at end of file | ||