Sansa Fuze+: initial commit (bootloader only, LCD basically working)
[kugel-rb.git] / firmware / target / arm / imx233 / lcdif-imx233.c
blob0b96cbf2bc8b99d7611435c37a62d6a5be3086a5
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
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)
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;
34 void imx233_lcdif_enable(bool enable)
36 if(enable)
37 __REG_CLR(HW_LCDIF_CTRL) = __BLOCK_CLKGATE;
38 else
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;
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;
90 return old_msk;
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)
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;
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;
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);
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)
139 if(burst & 1)
140 burst++;
141 count = burst / 2;
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)
154 while(HW_LCDIF_STAT & HW_LCDIF_STAT__LFIFO_FULL);
155 HW_LCDIF_DATA = *buf++;
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);
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;