diff options
Diffstat (limited to 'firmware/target/arm/imx233/lcdif-imx233.c')
-rw-r--r-- | firmware/target/arm/imx233/lcdif-imx233.c | 171 |
1 files changed, 171 insertions, 0 deletions
diff --git a/firmware/target/arm/imx233/lcdif-imx233.c b/firmware/target/arm/imx233/lcdif-imx233.c new file mode 100644 index 0000000000..0b96cbf2bc --- /dev/null +++ b/firmware/target/arm/imx233/lcdif-imx233.c | |||
@@ -0,0 +1,171 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (c) 2011 by Amaury Pouly | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | #include "lcdif-imx233.h" | ||
22 | |||
23 | static unsigned lcdif_word_length = 0; | ||
24 | static unsigned lcdif_byte_packing = 0; | ||
25 | |||
26 | void imx233_lcdif_enable_bus_master(bool enable) | ||
27 | { | ||
28 | if(enable) | ||
29 | __REG_SET(HW_LCDIF_CTRL) = HW_LCDIF_CTRL__LCDIF_MASTER; | ||
30 | else | ||
31 | __REG_CLR(HW_LCDIF_CTRL) = HW_LCDIF_CTRL__LCDIF_MASTER; | ||
32 | } | ||
33 | |||
34 | void imx233_lcdif_enable(bool enable) | ||
35 | { | ||
36 | if(enable) | ||
37 | __REG_CLR(HW_LCDIF_CTRL) = __BLOCK_CLKGATE; | ||
38 | else | ||
39 | __REG_SET(HW_LCDIF_CTRL) = __BLOCK_CLKGATE; | ||
40 | } | ||
41 | |||
42 | void imx233_lcdif_reset(void) | ||
43 | { | ||
44 | //imx233_reset_block(&HW_LCDIF_CTRL);// doesn't work | ||
45 | while(HW_LCDIF_CTRL & __BLOCK_CLKGATE) | ||
46 | HW_LCDIF_CTRL &= ~__BLOCK_CLKGATE; | ||
47 | while(!(HW_LCDIF_CTRL & __BLOCK_SFTRST)) | ||
48 | HW_LCDIF_CTRL |= __BLOCK_SFTRST; | ||
49 | while(HW_LCDIF_CTRL & __BLOCK_CLKGATE) | ||
50 | HW_LCDIF_CTRL &= ~__BLOCK_CLKGATE; | ||
51 | while(HW_LCDIF_CTRL & __BLOCK_SFTRST) | ||
52 | HW_LCDIF_CTRL &= ~__BLOCK_SFTRST; | ||
53 | while(HW_LCDIF_CTRL & __BLOCK_CLKGATE) | ||
54 | HW_LCDIF_CTRL &= ~__BLOCK_CLKGATE; | ||
55 | __REG_SET(HW_LCDIF_CTRL1) = HW_LCDIF_CTRL1__RESET; | ||
56 | } | ||
57 | |||
58 | void imx233_lcdif_set_timings(unsigned data_setup, unsigned data_hold, | ||
59 | unsigned cmd_setup, unsigned cmd_hold) | ||
60 | { | ||
61 | HW_LCDIF_TIMING = (data_setup << HW_LCDIF_TIMING__DATA_SETUP_BP) | | ||
62 | (data_hold << HW_LCDIF_TIMING__DATA_HOLD_BP) | | ||
63 | (cmd_setup << HW_LCDIF_TIMING__CMD_SETUP_BP) | | ||
64 | (cmd_hold << HW_LCDIF_TIMING__CMD_HOLD_BP); | ||
65 | } | ||
66 | |||
67 | void imx233_lcdif_set_lcd_databus_width(unsigned width) | ||
68 | { | ||
69 | __REG_CLR(HW_LCDIF_CTRL) = HW_LCDIF_CTRL__LCD_DATABUS_WIDTH_BM; | ||
70 | __REG_SET(HW_LCDIF_CTRL) = width; | ||
71 | } | ||
72 | |||
73 | void imx233_lcdif_set_word_length(unsigned word_length) | ||
74 | { | ||
75 | __REG_CLR(HW_LCDIF_CTRL) = HW_LCDIF_CTRL__WORD_LENGTH_BM; | ||
76 | __REG_SET(HW_LCDIF_CTRL) = word_length; | ||
77 | lcdif_word_length = word_length; | ||
78 | } | ||
79 | |||
80 | unsigned imx233_lcdif_enable_irqs(unsigned irq_bm) | ||
81 | { | ||
82 | unsigned old_msk = (HW_LCDIF_CTRL1 & HW_LCDIF_CTRL1__IRQ_EN_BM) >>HW_LCDIF_CTRL1__IRQ_EN_BP ; | ||
83 | /* clear irq status */ | ||
84 | __REG_CLR(HW_LCDIF_CTRL1) = irq_bm << HW_LCDIF_CTRL1__IRQ_BP; | ||
85 | /* disable irqs */ | ||
86 | __REG_CLR(HW_LCDIF_CTRL1) = HW_LCDIF_CTRL1__IRQ_EN_BM; | ||
87 | /* enable irqs */ | ||
88 | __REG_SET(HW_LCDIF_CTRL1) = irq_bm << HW_LCDIF_CTRL1__IRQ_EN_BP; | ||
89 | |||
90 | return old_msk; | ||
91 | } | ||
92 | |||
93 | void imx233_lcdif_set_byte_packing_format(unsigned byte_packing) | ||
94 | { | ||
95 | __REG_CLR(HW_LCDIF_CTRL1) = HW_LCDIF_CTRL1__BYTE_PACKING_FORMAT_BM; | ||
96 | __REG_SET(HW_LCDIF_CTRL1) = byte_packing << HW_LCDIF_CTRL1__BYTE_PACKING_FORMAT_BP; | ||
97 | lcdif_byte_packing = byte_packing; | ||
98 | } | ||
99 | |||
100 | void imx233_lcdif_set_data_format(bool data_fmt_16, bool data_fmt_18, bool data_fmt_24) | ||
101 | { | ||
102 | if(data_fmt_16) | ||
103 | __REG_SET(HW_LCDIF_CTRL) = HW_LCDIF_CTRL__DATA_FORMAT_16_BIT; | ||
104 | else | ||
105 | __REG_CLR(HW_LCDIF_CTRL) = HW_LCDIF_CTRL__DATA_FORMAT_16_BIT; | ||
106 | if(data_fmt_18) | ||
107 | __REG_SET(HW_LCDIF_CTRL) = HW_LCDIF_CTRL__DATA_FORMAT_18_BIT; | ||
108 | else | ||
109 | __REG_CLR(HW_LCDIF_CTRL) = HW_LCDIF_CTRL__DATA_FORMAT_18_BIT; | ||
110 | if(data_fmt_24) | ||
111 | __REG_SET(HW_LCDIF_CTRL) = HW_LCDIF_CTRL__DATA_FORMAT_24_BIT; | ||
112 | else | ||
113 | __REG_CLR(HW_LCDIF_CTRL) = HW_LCDIF_CTRL__DATA_FORMAT_24_BIT; | ||
114 | } | ||
115 | |||
116 | void imx233_lcdif_wait_ready(void) | ||
117 | { | ||
118 | while(HW_LCDIF_CTRL & HW_LCDIF_CTRL__RUN); | ||
119 | } | ||
120 | |||
121 | void imx233_lcdif_pio_send(bool data_mode, unsigned len, uint32_t *buf) | ||
122 | { | ||
123 | unsigned max_xfer_size = 0xffff; | ||
124 | if(len == 0) | ||
125 | return; | ||
126 | if(lcdif_word_length == HW_LCDIF_CTRL__WORD_LENGTH_16_BIT) | ||
127 | max_xfer_size = 0x1fffe; | ||
128 | imx233_lcdif_wait_ready(); | ||
129 | unsigned msk = imx233_lcdif_enable_irqs(0); | ||
130 | imx233_lcdif_enable_bus_master(false); | ||
131 | |||
132 | do | ||
133 | { | ||
134 | unsigned burst = MIN(len, max_xfer_size); | ||
135 | len -= burst; | ||
136 | unsigned count = burst; | ||
137 | if(lcdif_word_length != HW_LCDIF_CTRL__WORD_LENGTH_8_BIT) | ||
138 | { | ||
139 | if(burst & 1) | ||
140 | burst++; | ||
141 | count = burst / 2; | ||
142 | } | ||
143 | else | ||
144 | count = burst; | ||
145 | HW_LCDIF_TRANSFER_COUNT = 0; | ||
146 | HW_LCDIF_TRANSFER_COUNT = 0x10000 | count; | ||
147 | __REG_CLR(HW_LCDIF_CTRL) = HW_LCDIF_CTRL__DATA_SELECT | HW_LCDIF_CTRL__RUN; | ||
148 | if(data_mode) | ||
149 | __REG_SET(HW_LCDIF_CTRL) = HW_LCDIF_CTRL__DATA_SELECT; | ||
150 | __REG_SET(HW_LCDIF_CTRL) = HW_LCDIF_CTRL__RUN; | ||
151 | burst = (burst + 3) / 4; | ||
152 | while(burst-- > 0) | ||
153 | { | ||
154 | while(HW_LCDIF_STAT & HW_LCDIF_STAT__LFIFO_FULL); | ||
155 | HW_LCDIF_DATA = *buf++; | ||
156 | } | ||
157 | while(HW_LCDIF_CTRL & HW_LCDIF_CTRL__RUN); | ||
158 | }while(len > 0); | ||
159 | imx233_lcdif_enable_bus_master(true); | ||
160 | imx233_lcdif_enable_irqs(msk); | ||
161 | } | ||
162 | |||
163 | void imx233_lcdif_dma_send(void *buf, unsigned width, unsigned height) | ||
164 | { | ||
165 | HW_LCDIF_CUR_BUF = (uint32_t)buf; | ||
166 | HW_LCDIF_TRANSFER_COUNT = 0; | ||
167 | HW_LCDIF_TRANSFER_COUNT = (height << 16) | width; | ||
168 | __REG_CLR(HW_LCDIF_CTRL) = HW_LCDIF_CTRL__RUN; | ||
169 | __REG_SET(HW_LCDIF_CTRL) = HW_LCDIF_CTRL__DATA_SELECT; | ||
170 | __REG_SET(HW_LCDIF_CTRL) = HW_LCDIF_CTRL__RUN; | ||
171 | } | ||