blob: 3d042dfa736977ea5efbe15009945e9bc92c1202 [file] [log] [blame]
John Otkend4024bb2007-07-26 17:49:11 +02001/*
2 * See file CREDITS for list of people who contributed to this
3 * project.
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 <config.h>
22#include <common.h>
23#include <command.h>
24#include <asm/io.h>
25#include <asm/gpio.h>
26
27#define LCD_CMD_ADDR 0x50100002
28#define LCD_DATA_ADDR 0x50100003
29#define LCD_BLK_CTRL CPLD_REG1_ADDR
30
31static char *amcc_logo = "AMCC 405EP TAIHU EVALUATION KIT";
32static int addr_flag = 0x80;
33
34static void lcd_bl_ctrl(char val)
35{
36 out_8((u8 *) LCD_BLK_CTRL, in_8((u8 *) LCD_BLK_CTRL) | val);
37}
38
39static void lcd_putc(int val)
40{
41 int i = 100;
42 char addr;
43
44 while (i--) {
45 if ((in_8((u8 *) LCD_CMD_ADDR) & 0x80) != 0x80) { /*BF = 1 ?*/
46 udelay(50);
47 break;
48 }
49 udelay(50);
50 }
51
52 if (in_8((u8 *) LCD_CMD_ADDR) & 0x80) {
53 printf("LCD is busy\n");
54 return;
55 }
56
57 addr = in_8((u8 *) LCD_CMD_ADDR);
58 udelay(50);
59 if ((addr != 0) && (addr % 0x10 == 0)) {
60 addr_flag ^= 0x40;
61 out_8((u8 *) LCD_CMD_ADDR, addr_flag);
62 }
63
64 udelay(50);
65 out_8((u8 *) LCD_DATA_ADDR, val);
66 udelay(50);
67}
68
69static void lcd_puts(char *s)
70{
71 char *p = s;
72 int i = 100;
73
74 while (i--) {
75 if ((in_8((u8 *) LCD_CMD_ADDR) & 0x80) != 0x80) { /*BF = 1 ?*/
76 udelay(50);
77 break;
78 }
79 udelay(50);
80 }
81
82 if (in_8((u8 *) LCD_CMD_ADDR) & 0x80) {
83 printf("LCD is busy\n");
84 return;
85 }
86
87 while (*p)
88 lcd_putc(*p++);
89}
90
91static void lcd_put_logo(void)
92{
93 int i = 100;
94 char *p = amcc_logo;
95
96 while (i--) {
97 if ((in_8((u8 *) LCD_CMD_ADDR) & 0x80) != 0x80) { /*BF = 1 ?*/
98 udelay(50);
99 break;
100 }
101 udelay(50);
102 }
103
104 if (in_8((u8 *) LCD_CMD_ADDR) & 0x80) {
105 printf("LCD is busy\n");
106 return;
107 }
108
109 out_8((u8 *) LCD_CMD_ADDR, 0x80);
110 while (*p)
111 lcd_putc(*p++);
112}
113
114int lcd_init(void)
115{
116 puts("LCD: ");
117 out_8((u8 *) LCD_CMD_ADDR, 0x38); /* set function:8-bit,2-line,5x7 font type */
118 udelay(50);
119 out_8((u8 *) LCD_CMD_ADDR, 0x0f); /* set display on,cursor on,blink on */
120 udelay(50);
121 out_8((u8 *) LCD_CMD_ADDR, 0x01); /* display clear */
122 udelay(2000);
123 out_8((u8 *) LCD_CMD_ADDR, 0x06); /* set entry */
124 udelay(50);
125 lcd_bl_ctrl(0x02); /* set backlight on */
126 lcd_put_logo();
127 puts("ready\n");
128
129 return 0;
130}
131
132static int do_lcd_clear (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
133{
134 out_8((u8 *) LCD_CMD_ADDR, 0x01);
135 udelay(2000);
136
137 return 0;
138}
139
140static int do_lcd_puts (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
141{
142 if (argc < 2) {
143 printf("%s", cmdtp->usage);
144 return 1;
145 }
146 lcd_puts(argv[1]);
147
148 return 0;
149}
150
151static int do_lcd_putc (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
152{
153 if (argc < 2) {
154 printf("%s", cmdtp->usage);
155 return 1;
156 }
157 lcd_putc((char)argv[1][0]);
158
159 return 0;
160}
161
162static int do_lcd_cur (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
163{
164 ulong count;
165 ulong dir;
166 char cur_addr;
167
168 if (argc < 3) {
169 printf("%s", cmdtp->usage);
170 return 1;
171 }
172
173 count = simple_strtoul(argv[1], NULL, 16);
174 if (count > 31) {
175 printf("unable to shift > 0x20\n");
176 count = 0;
177 }
178
179 dir = simple_strtoul(argv[2], NULL, 16);
180 cur_addr = in_8((u8 *) LCD_CMD_ADDR);
181 udelay(50);
182
183 if (dir == 0x0) {
184 if (addr_flag == 0x80) {
185 if (count >= (cur_addr & 0xf)) {
186 out_8((u8 *) LCD_CMD_ADDR, 0x80);
187 udelay(50);
188 count = 0;
189 }
190 } else {
191 if (count >= ((cur_addr & 0x0f) + 0x0f)) {
192 out_8((u8 *) LCD_CMD_ADDR, 0x80);
193 addr_flag = 0x80;
194 udelay(50);
195 count = 0x0;
196 } else if (count >= ( cur_addr & 0xf)) {
197 count -= cur_addr & 0xf ;
198 out_8((u8 *) LCD_CMD_ADDR, 0x80 | 0xf);
199 addr_flag = 0x80;
200 udelay(50);
201 }
202 }
203 } else {
204 if (addr_flag == 0x80) {
205 if (count >= (0x1f - (cur_addr & 0xf))) {
206 count = 0x0;
207 addr_flag = 0xc0;
208 out_8((u8 *) LCD_CMD_ADDR, 0xc0 | 0xf);
209 udelay(50);
210 } else if ((count + (cur_addr & 0xf ))>= 0x0f) {
211 count = count + (cur_addr & 0xf) - 0x0f;
212 addr_flag = 0xc0;
213 out_8((u8 *) LCD_CMD_ADDR, 0xc0);
214 udelay(50);
215 }
216 } else if ((count + (cur_addr & 0xf )) >= 0x0f) {
217 count = 0x0;
218 out_8((u8 *) LCD_CMD_ADDR, 0xC0 | 0x0F);
219 udelay(50);
220 }
221 }
222 while (count--) {
223 if (dir == 0)
224 out_8((u8 *) LCD_CMD_ADDR, 0x10);
225 else
226 out_8((u8 *) LCD_CMD_ADDR, 0x14);
227 udelay(50);
228 }
229
230 return 0;
231}
232
233U_BOOT_CMD(
234 lcd_cls, 1, 1, do_lcd_clear,
235 "lcd_cls - lcd clear display\n",
236 NULL
237 );
238
239U_BOOT_CMD(
240 lcd_puts, 2, 1, do_lcd_puts,
241 "lcd_puts - display string on lcd\n",
242 "<string> - <string> to be displayed\n"
243 );
244
245U_BOOT_CMD(
246 lcd_putc, 2, 1, do_lcd_putc,
247 "lcd_putc - display char on lcd\n",
248 "<char> - <char> to be displayed\n"
249 );
250
251U_BOOT_CMD(
252 lcd_cur, 3, 1, do_lcd_cur,
253 "lcd_cur - shift cursor on lcd\n",
254 "<count> <dir> - shift cursor on lcd <count> times, direction is <dir> \n"
255 " <count> - 0..31\n"
256 " <dir> - 0=backward 1=forward\n"
257 );