]> git.kernelconcepts.de Git - karo-tx-redboot.git/blob - packages/hal/arm/mx51/3stack/v2_0/src/epson_lcd.c
TX51 pre-release
[karo-tx-redboot.git] / packages / hal / arm / mx51 / 3stack / v2_0 / src / epson_lcd.c
1 //==========================================================================
2 //
3 //      epson_lcd.c
4 //
5 //      LCD Display Implementation
6 //
7 //==========================================================================
8 //####ECOSGPLCOPYRIGHTBEGIN####
9 // -------------------------------------------
10 // This file is part of eCos, the Embedded Configurable Operating System.
11 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
12 //
13 // eCos is free software; you can redistribute it and/or modify it under
14 // the terms of the GNU General Public License as published by the Free
15 // Software Foundation; either version 2 or (at your option) any later version.
16 //
17 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
18 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
20 // for more details.
21 //
22 // You should have received a copy of the GNU General Public License along
23 // with eCos; if not, write to the Free Software Foundation, Inc.,
24 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
25 //
26 // As a special exception, if other files instantiate templates or use macros
27 // or inline functions from this file, or you compile this file and link it
28 // with other works to produce a work based on this file, this file does not
29 // by itself cause the resulting work to be covered by the GNU General Public
30 // License. However the source code for this file must still be made available
31 // in accordance with section (3) of the GNU General Public License.
32 //
33 // This exception does not invalidate any other reasons why a work based on
34 // this file might be covered by the GNU General Public License.
35 //
36 // Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
37 // at http://sources.redhat.com/ecos/ecos-license/
38 // -------------------------------------------
39 //####ECOSGPLCOPYRIGHTEND####
40 //==========================================================================
41
42 #include <cyg/io/ipu_common.h>
43 #include <cyg/io/mxc_i2c.h>
44
45 #define MX51_ATLAS_PMIC_ADDRESS 0x8
46
47 static int pmic_read_reg(unsigned int reg_addr, unsigned char *data, unsigned int count)
48 {
49     struct mxc_i2c_request rq;
50
51     rq.dev_addr = MX51_ATLAS_PMIC_ADDRESS;  // dev_addr of Atlas PMIC
52     rq.reg_addr = reg_addr;     // addr of LEC Control0 Reg
53     rq.reg_addr_sz = 1;
54     rq.buffer_sz = count;           // send 3 data in a series
55     rq.buffer = data;
56     i2c_xfer(1, &rq, 1);
57
58     return 1;
59 }
60
61 static int pmic_write_reg(unsigned int reg_addr, unsigned char *data, unsigned int count)
62 {
63     struct mxc_i2c_request rq;
64
65     rq.dev_addr = MX51_ATLAS_PMIC_ADDRESS;  // dev_addr of Atlas PMIC
66     rq.reg_addr = reg_addr;     // addr of LEC Control0 Reg
67     rq.reg_addr_sz = 1;
68     rq.buffer_sz = count;           // send 3 data in a series
69     rq.buffer = data;
70     i2c_xfer(1, &rq, 0);
71
72     return 1;
73 }
74
75 /*this function use common pins of IPU to simulate a cspi interface*/
76 static void epson_lcd_spi_simulate(void)
77 {
78     dc_microcode_t microcode = { 0 };
79     microcode.addr = 0x24;
80     microcode.stop = 1;
81     microcode.opcode = "WROD";
82     microcode.lf = 0;
83     microcode.af = 0;
84     microcode.operand = 0;
85     microcode.mapping = 5;
86     microcode.waveform = 7;
87     microcode.gluelogic = 0;
88     microcode.sync = 0;
89     ipu_dc_microcode_config(microcode);
90
91     ipu_write_field(IPU_DC_RL3_CH_8__COD_NEW_DATA_START_CHAN_W_8_1, 0x24);  //address of second region
92     ipu_write_field(IPU_DC_RL3_CH_8__COD_NEW_DATA_START_CHAN_W_8_0, 0x24);  //address of first region
93     ipu_write_field(IPU_DC_RL3_CH_8__COD_NEW_DATA_PRIORITY_CHAN_8, 1);  //MEDIUM PRIORITY FOR DATA
94
95     /*  Data Mapping of 24-bit new data
96        |23..16|15..8|7..0| ==>> bit[15..0]&(0x1FF), just keep the last 17bit for LCD configuration */
97     ipu_write_field(IPU_DC_MAP_CONF_2__MAPPING_PNTR_BYTE2_4, 3);
98     ipu_write_field(IPU_DC_MAP_CONF_2__MAPPING_PNTR_BYTE1_4, 4);
99     ipu_write_field(IPU_DC_MAP_CONF_2__MAPPING_PNTR_BYTE0_4, 5);
100     ipu_write_field(IPU_DC_MAP_CONF_16__MD_OFFSET_3, 0);
101     ipu_write_field(IPU_DC_MAP_CONF_16__MD_MASK_3, 0x00);
102     ipu_write_field(IPU_DC_MAP_CONF_17__MD_OFFSET_4, 15);
103     ipu_write_field(IPU_DC_MAP_CONF_17__MD_MASK_4, 0x01);
104     ipu_write_field(IPU_DC_MAP_CONF_17__MD_OFFSET_5, 7);
105     ipu_write_field(IPU_DC_MAP_CONF_17__MD_MASK_5, 0xFF);
106
107     /*set clock and cs signal for command.
108        sclk should be more than 90ns interval, derived from base clock. */
109     ipu_di_waveform_config(0, 6, 0, 0, 11);
110     ipu_di_waveform_config(0, 6, 1, 1, 2);
111     ipu_di_waveform_config(0, 6, 2, 0, 0);
112     ipu_write_field(IPU_DI0_DW_GEN_6__DI0_SERIAL_PERIOD_6, 3);  //base clock, 133MHz/div
113     ipu_write_field(IPU_DI0_DW_GEN_6__DI0_START_PERIOD_6, 0);   //start immediatly
114     ipu_write_field(IPU_DI0_DW_GEN_6__DI0_CST_6, 0);    //pointer for CS
115     ipu_write_field(IPU_DI0_DW_GEN_6__DI0_SERIAL_VALID_BITS_6, 8);  //8+1 bit, should be more than or equal with 9
116     ipu_write_field(IPU_DI0_DW_GEN_6__DI0_SERIAL_RS_6, 2);  //RS=0
117     ipu_write_field(IPU_DI0_DW_GEN_6__DI0_SERIAL_CLK_6, 1); //SCLK for command, should be less than 11MHz
118     ipu_write_field(IPU_DI0_SER_CONF__DI0_SER_CLK_POLARITY, 1);
119     ipu_write_field(IPU_IPU_DISP_GEN__MCU_DI_ID_8, 0);  //MCU accesses DC's channel #8 via DI0.
120
121     /* T VALUE, seperate into two parts */
122     ipu_write_field(IPU_IPU_DISP_GEN__MCU_T, T_VALUE);  //diffrenciate
123
124     ipu_write_field(IPU_DC_WR_CH_CONF1_8__MCU_DISP_ID_8, 1);    //display 1
125     ipu_write_field(IPU_DC_WR_CH_CONF1_8__W_SIZE_8, 3); //32 bits are used (RGB)
126
127     ipu_write_field(IPU_DC_DISP_CONF1_1__DISP_TYP_1, 0);    //serial display
128
129     ipu_write_field(IPU_IPU_CONF__DI0_EN, 1);
130     ipu_write_field(IPU_IPU_CONF__DP_EN, 0);
131     ipu_write_field(IPU_IPU_CONF__DC_EN, 1);
132     ipu_write_field(IPU_IPU_CONF__DMFC_EN, 1);
133 }
134
135 static void epson_lcd_rst(void)
136 {
137     ipu_write_field(IPU_DI1_GENERAL__DI1_POLARITY_4, 1);
138     hal_delay_us(1000);
139     ipu_write_field(IPU_DI1_GENERAL__DI1_POLARITY_4, 0);
140 }
141
142 void lcd_backlit_on(void)
143 {
144     struct mxc_i2c_request rq;
145     unsigned char data[3];
146     unsigned char dataCheck[3];
147     int timeout = 0;
148     int ret = 0xFF;
149     /*duty cycle = (mainDispDutyCycle % 32) / 32; */
150     unsigned char mainDispDutyCycle = 0x20;
151     /*current = mainDispCurrentSet * 3 * 2^mainDispHiCurMode
152        current should be no more than 15 */
153     unsigned char mainDispCurrentSet = 3;
154     unsigned char mainDispHiCurMode = 0;
155
156 #ifndef CYGPKG_REDBOOT
157     mxc_i2c2_clock_gate(1);
158 #endif
159     if (i2c_init(I2C2_BASE_ADDR, 170000) == 0) {
160         while (timeout < 5) {
161             data[0] = 0x0;
162             data[1] = ((mainDispCurrentSet << 1) & 0xE) | ((mainDispDutyCycle >> 5) & 0x1);
163             data[2] = ((mainDispHiCurMode << 1) & 0x2) | ((mainDispDutyCycle << 3) & 0xF8);
164             pmic_write_reg(0x33, data, 3);
165             dataCheck[0] = 0x0;
166             dataCheck[1] = 0x0;
167             dataCheck[2] = 0x0;
168             pmic_read_reg(0x33, dataCheck, 3);
169
170             if ((dataCheck[0] == data[0]) && (dataCheck[1] == data[1]) && (dataCheck[2] == data[2])) {
171                 break;
172             }
173             timeout++;
174             hal_delay_us(20);
175         }
176     } else {
177         diag_printf("ERROR:I2C initialization failed\n");
178     }
179 #ifndef CYGPKG_REDBOOT
180     mxc_i2c2_clock_gate(0);
181 #endif
182 }
183
184 void lcd_config(void)
185 {
186     /* set these regs to conpensate color. */
187     writel((readl(MIPI_HSC_BASE_ADDR + 0x800) | (1<<16)), MIPI_HSC_BASE_ADDR + 0x800);
188     writel((readl(MIPI_HSC_BASE_ADDR + 0x0) | (1<<10)), MIPI_HSC_BASE_ADDR + 0x0);
189
190     /* simulate spi interface to access LCD regs */
191     epson_lcd_spi_simulate();
192     epson_lcd_rst();
193
194     /* enable chip select */
195     gpio_dir_config(GPIO_PORT3, 4, GPIO_GDIR_OUTPUT);
196     gpio_write_data(GPIO_PORT3, 4, 0);
197     hal_delay_us(300);
198
199     writel(MADCTL, IPU_CTRL_BASE_ADDR);
200     writel(0x0100, IPU_CTRL_BASE_ADDR);
201
202     writel(GAMSET, IPU_CTRL_BASE_ADDR);
203     writel(0x0101, IPU_CTRL_BASE_ADDR);
204
205     writel(COLMOD, IPU_CTRL_BASE_ADDR);
206     writel(0x0160, IPU_CTRL_BASE_ADDR);
207
208     writel(SLPOUT, IPU_CTRL_BASE_ADDR); // SLEEP OUT
209     hal_delay_us(300);
210
211     writel(DISON, IPU_CTRL_BASE_ADDR);  // Display ON
212     hal_delay_us(300);
213
214     /* disable chip select */
215     gpio_dir_config(GPIO_PORT3, 4, GPIO_GDIR_OUTPUT);
216     gpio_write_data(GPIO_PORT3, 4, 1);
217
218     ipu_write_field(IPU_IPU_CONF__DI0_EN, 0);
219     ipu_write_field(IPU_IPU_CONF__DP_EN, 0);
220     ipu_write_field(IPU_IPU_CONF__DC_EN, 0);
221     ipu_write_field(IPU_IPU_CONF__DMFC_EN, 0);
222     hal_delay_us(300);
223 }