1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (c) 2011 by Amaury Pouly
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.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
21 #include "lcdif-imx233.h"
23 static unsigned lcdif_word_length
= 0;
24 static unsigned lcdif_byte_packing
= 0;
26 void imx233_lcdif_enable_bus_master(bool enable
)
29 __REG_SET(HW_LCDIF_CTRL
) = HW_LCDIF_CTRL__LCDIF_MASTER
;
31 __REG_CLR(HW_LCDIF_CTRL
) = HW_LCDIF_CTRL__LCDIF_MASTER
;
34 void imx233_lcdif_enable(bool enable
)
37 __REG_CLR(HW_LCDIF_CTRL
) = __BLOCK_CLKGATE
;
39 __REG_SET(HW_LCDIF_CTRL
) = __BLOCK_CLKGATE
;
42 void imx233_lcdif_reset(void)
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
;
58 void imx233_lcdif_set_timings(unsigned data_setup
, unsigned data_hold
,
59 unsigned cmd_setup
, unsigned cmd_hold
)
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
);
67 void imx233_lcdif_set_lcd_databus_width(unsigned width
)
69 __REG_CLR(HW_LCDIF_CTRL
) = HW_LCDIF_CTRL__LCD_DATABUS_WIDTH_BM
;
70 __REG_SET(HW_LCDIF_CTRL
) = width
;
73 void imx233_lcdif_set_word_length(unsigned word_length
)
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
;
80 unsigned imx233_lcdif_enable_irqs(unsigned irq_bm
)
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
;
86 __REG_CLR(HW_LCDIF_CTRL1
) = HW_LCDIF_CTRL1__IRQ_EN_BM
;
88 __REG_SET(HW_LCDIF_CTRL1
) = irq_bm
<< HW_LCDIF_CTRL1__IRQ_EN_BP
;
93 void imx233_lcdif_set_byte_packing_format(unsigned byte_packing
)
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
;
100 void imx233_lcdif_set_data_format(bool data_fmt_16
, bool data_fmt_18
, bool data_fmt_24
)
103 __REG_SET(HW_LCDIF_CTRL
) = HW_LCDIF_CTRL__DATA_FORMAT_16_BIT
;
105 __REG_CLR(HW_LCDIF_CTRL
) = HW_LCDIF_CTRL__DATA_FORMAT_16_BIT
;
107 __REG_SET(HW_LCDIF_CTRL
) = HW_LCDIF_CTRL__DATA_FORMAT_18_BIT
;
109 __REG_CLR(HW_LCDIF_CTRL
) = HW_LCDIF_CTRL__DATA_FORMAT_18_BIT
;
111 __REG_SET(HW_LCDIF_CTRL
) = HW_LCDIF_CTRL__DATA_FORMAT_24_BIT
;
113 __REG_CLR(HW_LCDIF_CTRL
) = HW_LCDIF_CTRL__DATA_FORMAT_24_BIT
;
116 void imx233_lcdif_wait_ready(void)
118 while(HW_LCDIF_CTRL
& HW_LCDIF_CTRL__RUN
);
121 void imx233_lcdif_pio_send(bool data_mode
, unsigned len
, uint32_t *buf
)
123 unsigned max_xfer_size
= 0xffff;
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);
134 unsigned burst
= MIN(len
, max_xfer_size
);
136 unsigned count
= burst
;
137 if(lcdif_word_length
!= HW_LCDIF_CTRL__WORD_LENGTH_8_BIT
)
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
;
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;
154 while(HW_LCDIF_STAT
& HW_LCDIF_STAT__LFIFO_FULL
);
155 HW_LCDIF_DATA
= *buf
++;
157 while(HW_LCDIF_CTRL
& HW_LCDIF_CTRL__RUN
);
159 imx233_lcdif_enable_bus_master(true);
160 imx233_lcdif_enable_irqs(msk
);
163 void imx233_lcdif_dma_send(void *buf
, unsigned width
, unsigned height
)
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
;