]>
Commit | Line | Data |
---|---|---|
e8143e72 WD |
1 | /* |
2 | * (C) Copyright 2006 | |
3 | * Wolfgang Denk, DENX Software Engineering, wd@denx.de. | |
4 | * | |
5 | * This program is free software; you can redistribute it and/or | |
6 | * modify it under the terms of the GNU General Public License as | |
7 | * published by the Free Software Foundation; either version 2 of | |
8 | * the License, or (at your option) any later version. | |
9 | * | |
10 | * This program is distributed in the hope that it will be useful, | |
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13 | * GNU General Public License for more details. | |
14 | * | |
15 | * You should have received a copy of the GNU General Public License | |
16 | * along with this program; if not, write to the Free Software | |
17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, | |
18 | * MA 02111-1307 USA | |
19 | */ | |
20 | ||
21 | #include <common.h> | |
22 | #include <lcd.h> | |
23 | #include <mpc5xxx.h> | |
24 | ||
25 | #ifdef CONFIG_LCD | |
26 | ||
638dd145 | 27 | #undef SWAPPED_LCD /* For the previous h/w version */ |
e8143e72 WD |
28 | /* |
29 | * The name of the device used for communication | |
30 | * with the PSoC. | |
31 | */ | |
32 | #define PSOC_PSC MPC5XXX_PSC2 | |
638dd145 | 33 | #define PSOC_BAUD 230400UL |
e8143e72 WD |
34 | |
35 | #define RTS_ASSERT 1 | |
36 | #define RTS_NEGATE 0 | |
37 | #define CTS_ASSERT 1 | |
38 | #define CTS_NEGATE 0 | |
39 | ||
40 | /* | |
41 | * Dimensions in pixels | |
42 | */ | |
43 | #define LCD_WIDTH 160 | |
44 | #define LCD_HEIGHT 100 | |
45 | ||
46 | /* | |
47 | * Dimensions in bytes | |
48 | */ | |
49 | #define LCD_BUF_SIZE ((LCD_WIDTH*LCD_HEIGHT)>>3) | |
50 | ||
51 | #if LCD_BPP != LCD_MONOCHROME | |
52 | #error "MCC200 support only monochrome displays (1 bpp)!" | |
53 | #endif | |
54 | ||
55 | #define PSOC_RETRIES 10 /* each of PSOC_WAIT_TIME */ | |
56 | #define PSOC_WAIT_TIME 10 /* usec */ | |
57 | ||
58 | DECLARE_GLOBAL_DATA_PTR; | |
59 | ||
60 | /* | |
61 | * LCD information | |
62 | */ | |
63 | vidinfo_t panel_info = { | |
64 | LCD_WIDTH, LCD_HEIGHT, LCD_BPP | |
65 | }; | |
66 | ||
67 | int lcd_line_length; | |
68 | ||
69 | int lcd_color_fg; | |
70 | int lcd_color_bg; | |
71 | ||
72 | /* | |
73 | * Frame buffer memory information | |
74 | */ | |
75 | void *lcd_base; /* Start of framebuffer memory */ | |
76 | void *lcd_console_address; /* Start of console buffer */ | |
77 | ||
78 | short console_col = 0; | |
79 | short console_row = 0; | |
80 | ||
81 | /* | |
82 | * The device we use to communicate with PSoC | |
83 | */ | |
84 | int serial_inited = 0; | |
85 | ||
86 | /* | |
87 | * Exported functions | |
88 | */ | |
89 | void lcd_initcolregs (void); | |
90 | void lcd_ctrl_init (void *lcdbase); | |
91 | void lcd_enable (void); | |
92 | ||
93 | /* | |
94 | * Imported functions to support the PSoC protocol | |
95 | */ | |
96 | extern int serial_init_dev (unsigned long dev_base); | |
97 | extern void serial_setrts_dev (unsigned long dev_base, int s); | |
98 | extern int serial_getcts_dev (unsigned long dev_base); | |
99 | extern void serial_putc_raw_dev(unsigned long dev_base, const char c); | |
100 | ||
101 | /* | |
102 | * Just stubs for our driver, needed for compiling compabilty with | |
103 | * the common LCD driver code. | |
104 | */ | |
105 | void lcd_initcolregs (void) | |
106 | { | |
107 | } | |
108 | ||
109 | void lcd_ctrl_init (void *lcdbase) | |
110 | { | |
111 | } | |
112 | ||
113 | /* | |
114 | * Function sends the contents of the frame-buffer to the LCD | |
115 | */ | |
116 | void lcd_enable (void) | |
117 | { | |
118 | int i, retries, fb_size; | |
119 | ||
120 | if (!serial_inited) { | |
121 | unsigned long baud; | |
122 | ||
123 | baud = gd->baudrate; | |
124 | gd->baudrate = PSOC_BAUD; | |
125 | serial_init_dev(PSOC_PSC); | |
126 | gd->baudrate = baud; | |
127 | serial_setrts_dev (PSOC_PSC, RTS_ASSERT); | |
128 | serial_inited = 1; | |
129 | } | |
130 | ||
131 | /* | |
132 | * Implement PSoC communication protocol: | |
133 | * 1. Assert RTS, wait CTS assertion | |
134 | * 2. Transmit data | |
135 | * 3. Negate RTS, wait CTS negation | |
136 | */ | |
137 | ||
138 | /* 1 */ | |
139 | serial_setrts_dev (PSOC_PSC, RTS_ASSERT); | |
140 | for (retries = PSOC_RETRIES; retries; retries--) { | |
141 | if (serial_getcts_dev(PSOC_PSC) == CTS_ASSERT) | |
142 | break; | |
143 | udelay (PSOC_WAIT_TIME); | |
144 | } | |
145 | if (!retries) { | |
146 | printf ("%s Error: PSoC doesn't respond on " | |
147 | "RTS ASSERT\n", __FUNCTION__); | |
148 | } | |
149 | ||
150 | /* 2 */ | |
151 | fb_size = panel_info.vl_row * (panel_info.vl_col >> 3); | |
152 | ||
153 | #if !defined(SWAPPED_LCD) | |
154 | for (i=0; i<fb_size; i++) { | |
155 | serial_putc_raw_dev (PSOC_PSC, ((char *)lcd_base)[i]); | |
156 | } | |
157 | #else | |
158 | { | |
159 | int x, y, pwidth; | |
160 | char *p = (char *)lcd_base; | |
161 | ||
162 | pwidth = ((panel_info.vl_col+7) >> 3); | |
163 | for (y=0; y<panel_info.vl_row; y++) { | |
164 | i = y * pwidth; | |
165 | for (x=0; x<pwidth; x+=5) { | |
166 | serial_putc_raw_dev (PSOC_PSC, (p[i+x+2]<<4 & 0xF0) | (p[i+x+3]>>4 & 0x0F)); | |
167 | serial_putc_raw_dev (PSOC_PSC, (p[i+x+3]<<4 & 0xF0) | (p[i+x+4]>>4 & 0x0F)); | |
168 | serial_putc_raw_dev (PSOC_PSC, (p[i+x+4]<<4 & 0xF0) | (p[i+x]>>4 & 0x0F)); | |
169 | serial_putc_raw_dev (PSOC_PSC, (p[i+x]<<4 & 0xF0) | (p[i+x+1]>>4 & 0x0F)); | |
170 | serial_putc_raw_dev (PSOC_PSC, (p[i+x+1]<<4 & 0xF0) | (p[i+x+2]>>4 & 0x0F)); | |
171 | } | |
172 | } | |
173 | } | |
174 | #endif | |
175 | ||
176 | /* 3 */ | |
177 | serial_setrts_dev (PSOC_PSC, RTS_NEGATE); | |
178 | for (retries = PSOC_RETRIES; retries; retries--) { | |
179 | if (serial_getcts_dev(PSOC_PSC) == CTS_NEGATE) | |
180 | break; | |
181 | udelay (PSOC_WAIT_TIME); | |
182 | } | |
e8143e72 WD |
183 | |
184 | return; | |
185 | } | |
638dd145 SP |
186 | #ifdef CONFIG_PROGRESSBAR |
187 | ||
188 | #define FONT_WIDTH 8 /* the same as VIDEO_FONT_WIDTH in video_font.h */ | |
189 | void show_progress (int size, int tot) | |
190 | { | |
191 | int cnt; | |
192 | int i; | |
193 | static int rc = 0; | |
194 | ||
195 | rc += size; | |
196 | ||
197 | cnt = ((LCD_WIDTH/FONT_WIDTH) * rc) / tot; | |
198 | ||
199 | rc -= (cnt * tot) / (LCD_WIDTH/FONT_WIDTH); | |
200 | ||
201 | for (i = 0; i < cnt; i++) { | |
202 | lcd_putc(0xdc); | |
203 | } | |
204 | ||
205 | if (cnt) { | |
206 | lcd_enable(); /* MCC200-specific - send the framebuffer to PSoC */ | |
207 | } | |
208 | } | |
209 | ||
210 | #endif | |
e8143e72 | 211 | #endif /* CONFIG_LCD */ |