summaryrefslogtreecommitdiff
path: root/firmware/target/arm/imx233/lcdif-imx233.c
diff options
context:
space:
mode:
authorAmaury Pouly <pamaury@rockbox.org>2011-05-01 13:02:46 +0000
committerAmaury Pouly <pamaury@rockbox.org>2011-05-01 13:02:46 +0000
commit08fb3f65745a237e2c1eae55d856ff27702246e5 (patch)
treea56ce11ac20e4df0e36de9195306c10b71752538 /firmware/target/arm/imx233/lcdif-imx233.c
parentc0838cbfd8e45621fe3450aee1bf9458ff420d16 (diff)
downloadrockbox-08fb3f65745a237e2c1eae55d856ff27702246e5.tar.gz
rockbox-08fb3f65745a237e2c1eae55d856ff27702246e5.zip
Sansa Fuze+: initial commit (bootloader only, LCD basically working)
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@29808 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/target/arm/imx233/lcdif-imx233.c')
-rw-r--r--firmware/target/arm/imx233/lcdif-imx233.c171
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
23static unsigned lcdif_word_length = 0;
24static unsigned lcdif_byte_packing = 0;
25
26void 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
34void 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
42void 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
58void 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
67void 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
73void 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
80unsigned 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
93void 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
100void 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
116void imx233_lcdif_wait_ready(void)
117{
118 while(HW_LCDIF_CTRL & HW_LCDIF_CTRL__RUN);
119}
120
121void 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
163void 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}