blob: c7c7fa44397a6f13c84d709cfcdf4493e4bc3f20 [file] [log] [blame]
John Otkend4024bb2007-07-26 17:49:11 +02001/*
Wolfgang Denk1a459662013-07-08 09:37:19 +02002 * SPDX-License-Identifier: GPL-2.0+
John Otkend4024bb2007-07-26 17:49:11 +02003 */
4
5#include <config.h>
6#include <common.h>
7#include <command.h>
8#include <asm/io.h>
Stefan Roese09887762010-09-16 14:30:37 +02009#include <asm/ppc4xx-gpio.h>
John Otkend4024bb2007-07-26 17:49:11 +020010
11#define LCD_CMD_ADDR 0x50100002
12#define LCD_DATA_ADDR 0x50100003
13#define LCD_BLK_CTRL CPLD_REG1_ADDR
14
15static char *amcc_logo = "AMCC 405EP TAIHU EVALUATION KIT";
16static int addr_flag = 0x80;
17
18static void lcd_bl_ctrl(char val)
19{
20 out_8((u8 *) LCD_BLK_CTRL, in_8((u8 *) LCD_BLK_CTRL) | val);
21}
22
23static void lcd_putc(int val)
24{
25 int i = 100;
26 char addr;
27
28 while (i--) {
29 if ((in_8((u8 *) LCD_CMD_ADDR) & 0x80) != 0x80) { /*BF = 1 ?*/
30 udelay(50);
31 break;
32 }
33 udelay(50);
34 }
35
36 if (in_8((u8 *) LCD_CMD_ADDR) & 0x80) {
37 printf("LCD is busy\n");
38 return;
39 }
40
41 addr = in_8((u8 *) LCD_CMD_ADDR);
42 udelay(50);
43 if ((addr != 0) && (addr % 0x10 == 0)) {
44 addr_flag ^= 0x40;
45 out_8((u8 *) LCD_CMD_ADDR, addr_flag);
46 }
47
48 udelay(50);
49 out_8((u8 *) LCD_DATA_ADDR, val);
50 udelay(50);
51}
52
53static void lcd_puts(char *s)
54{
55 char *p = s;
56 int i = 100;
57
58 while (i--) {
59 if ((in_8((u8 *) LCD_CMD_ADDR) & 0x80) != 0x80) { /*BF = 1 ?*/
60 udelay(50);
61 break;
62 }
63 udelay(50);
64 }
65
66 if (in_8((u8 *) LCD_CMD_ADDR) & 0x80) {
67 printf("LCD is busy\n");
68 return;
69 }
70
71 while (*p)
72 lcd_putc(*p++);
73}
74
75static void lcd_put_logo(void)
76{
77 int i = 100;
78 char *p = amcc_logo;
79
80 while (i--) {
81 if ((in_8((u8 *) LCD_CMD_ADDR) & 0x80) != 0x80) { /*BF = 1 ?*/
82 udelay(50);
83 break;
84 }
85 udelay(50);
86 }
87
88 if (in_8((u8 *) LCD_CMD_ADDR) & 0x80) {
89 printf("LCD is busy\n");
90 return;
91 }
92
93 out_8((u8 *) LCD_CMD_ADDR, 0x80);
94 while (*p)
95 lcd_putc(*p++);
96}
97
98int lcd_init(void)
99{
100 puts("LCD: ");
101 out_8((u8 *) LCD_CMD_ADDR, 0x38); /* set function:8-bit,2-line,5x7 font type */
102 udelay(50);
103 out_8((u8 *) LCD_CMD_ADDR, 0x0f); /* set display on,cursor on,blink on */
104 udelay(50);
105 out_8((u8 *) LCD_CMD_ADDR, 0x01); /* display clear */
106 udelay(2000);
107 out_8((u8 *) LCD_CMD_ADDR, 0x06); /* set entry */
108 udelay(50);
109 lcd_bl_ctrl(0x02); /* set backlight on */
110 lcd_put_logo();
111 puts("ready\n");
112
113 return 0;
114}
115
Wolfgang Denk54841ab2010-06-28 22:00:46 +0200116static int do_lcd_clear (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
John Otkend4024bb2007-07-26 17:49:11 +0200117{
118 out_8((u8 *) LCD_CMD_ADDR, 0x01);
119 udelay(2000);
120
121 return 0;
122}
123
Wolfgang Denk54841ab2010-06-28 22:00:46 +0200124static int do_lcd_puts (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
John Otkend4024bb2007-07-26 17:49:11 +0200125{
Wolfgang Denk47e26b12010-07-17 01:06:04 +0200126 if (argc < 2)
127 return cmd_usage(cmdtp);
128
John Otkend4024bb2007-07-26 17:49:11 +0200129 lcd_puts(argv[1]);
130
131 return 0;
132}
133
Wolfgang Denk54841ab2010-06-28 22:00:46 +0200134static int do_lcd_putc (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
John Otkend4024bb2007-07-26 17:49:11 +0200135{
Wolfgang Denk47e26b12010-07-17 01:06:04 +0200136 if (argc < 2)
137 return cmd_usage(cmdtp);
138
John Otkend4024bb2007-07-26 17:49:11 +0200139 lcd_putc((char)argv[1][0]);
140
141 return 0;
142}
143
Wolfgang Denk54841ab2010-06-28 22:00:46 +0200144static int do_lcd_cur (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
John Otkend4024bb2007-07-26 17:49:11 +0200145{
146 ulong count;
147 ulong dir;
148 char cur_addr;
149
Wolfgang Denk47e26b12010-07-17 01:06:04 +0200150 if (argc < 3)
151 return cmd_usage(cmdtp);
John Otkend4024bb2007-07-26 17:49:11 +0200152
153 count = simple_strtoul(argv[1], NULL, 16);
154 if (count > 31) {
155 printf("unable to shift > 0x20\n");
156 count = 0;
157 }
158
159 dir = simple_strtoul(argv[2], NULL, 16);
160 cur_addr = in_8((u8 *) LCD_CMD_ADDR);
161 udelay(50);
162
163 if (dir == 0x0) {
164 if (addr_flag == 0x80) {
165 if (count >= (cur_addr & 0xf)) {
166 out_8((u8 *) LCD_CMD_ADDR, 0x80);
167 udelay(50);
168 count = 0;
169 }
170 } else {
171 if (count >= ((cur_addr & 0x0f) + 0x0f)) {
172 out_8((u8 *) LCD_CMD_ADDR, 0x80);
173 addr_flag = 0x80;
174 udelay(50);
175 count = 0x0;
176 } else if (count >= ( cur_addr & 0xf)) {
177 count -= cur_addr & 0xf ;
178 out_8((u8 *) LCD_CMD_ADDR, 0x80 | 0xf);
179 addr_flag = 0x80;
180 udelay(50);
181 }
182 }
183 } else {
184 if (addr_flag == 0x80) {
185 if (count >= (0x1f - (cur_addr & 0xf))) {
186 count = 0x0;
187 addr_flag = 0xc0;
188 out_8((u8 *) LCD_CMD_ADDR, 0xc0 | 0xf);
189 udelay(50);
190 } else if ((count + (cur_addr & 0xf ))>= 0x0f) {
191 count = count + (cur_addr & 0xf) - 0x0f;
192 addr_flag = 0xc0;
193 out_8((u8 *) LCD_CMD_ADDR, 0xc0);
194 udelay(50);
195 }
196 } else if ((count + (cur_addr & 0xf )) >= 0x0f) {
197 count = 0x0;
198 out_8((u8 *) LCD_CMD_ADDR, 0xC0 | 0x0F);
199 udelay(50);
200 }
201 }
202 while (count--) {
203 if (dir == 0)
204 out_8((u8 *) LCD_CMD_ADDR, 0x10);
205 else
206 out_8((u8 *) LCD_CMD_ADDR, 0x14);
207 udelay(50);
208 }
209
210 return 0;
211}
212
213U_BOOT_CMD(
214 lcd_cls, 1, 1, do_lcd_clear,
Peter Tyser2fb26042009-01-27 18:03:12 -0600215 "lcd clear display",
Wolfgang Denka89c33d2009-05-24 17:06:54 +0200216 ""
217);
John Otkend4024bb2007-07-26 17:49:11 +0200218
219U_BOOT_CMD(
220 lcd_puts, 2, 1, do_lcd_puts,
Peter Tyser2fb26042009-01-27 18:03:12 -0600221 "display string on lcd",
Wolfgang Denka89c33d2009-05-24 17:06:54 +0200222 "<string> - <string> to be displayed"
223);
John Otkend4024bb2007-07-26 17:49:11 +0200224
225U_BOOT_CMD(
226 lcd_putc, 2, 1, do_lcd_putc,
Peter Tyser2fb26042009-01-27 18:03:12 -0600227 "display char on lcd",
Wolfgang Denka89c33d2009-05-24 17:06:54 +0200228 "<char> - <char> to be displayed"
229);
John Otkend4024bb2007-07-26 17:49:11 +0200230
231U_BOOT_CMD(
232 lcd_cur, 3, 1, do_lcd_cur,
Peter Tyser2fb26042009-01-27 18:03:12 -0600233 "shift cursor on lcd",
John Otkend4024bb2007-07-26 17:49:11 +0200234 "<count> <dir> - shift cursor on lcd <count> times, direction is <dir> \n"
235 " <count> - 0..31\n"
Wolfgang Denka89c33d2009-05-24 17:06:54 +0200236 " <dir> - 0=backward 1=forward"
237);