]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - board/amcc/taihu/lcd.c
Merge branch 'u-boot/master' into u-boot-arm/master
[karo-tx-uboot.git] / board / amcc / taihu / lcd.c
1 /*
2  * SPDX-License-Identifier:     GPL-2.0+
3  */
4
5 #include <config.h>
6 #include <common.h>
7 #include <command.h>
8 #include <asm/io.h>
9 #include <asm/ppc4xx-gpio.h>
10
11 #define LCD_CMD_ADDR    0x50100002
12 #define LCD_DATA_ADDR   0x50100003
13 #define LCD_BLK_CTRL    CPLD_REG1_ADDR
14
15 static char *amcc_logo = "AMCC 405EP TAIHU EVALUATION KIT";
16 static int addr_flag = 0x80;
17
18 static void lcd_bl_ctrl(char val)
19 {
20         out_8((u8 *) LCD_BLK_CTRL, in_8((u8 *) LCD_BLK_CTRL) | val);
21 }
22
23 static 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
53 static 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
75 static 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
98 int 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
116 static int do_lcd_clear (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
117 {
118         out_8((u8 *) LCD_CMD_ADDR, 0x01);
119         udelay(2000);
120
121         return 0;
122 }
123
124 static int do_lcd_puts (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
125 {
126         if (argc < 2)
127                 return cmd_usage(cmdtp);
128
129         lcd_puts(argv[1]);
130
131         return 0;
132 }
133
134 static int do_lcd_putc (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
135 {
136         if (argc < 2)
137                 return cmd_usage(cmdtp);
138
139         lcd_putc((char)argv[1][0]);
140
141         return 0;
142 }
143
144 static int do_lcd_cur (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
145 {
146         ulong count;
147         ulong dir;
148         char cur_addr;
149
150         if (argc < 3)
151                 return cmd_usage(cmdtp);
152
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
213 U_BOOT_CMD(
214         lcd_cls, 1, 1, do_lcd_clear,
215         "lcd clear display",
216         ""
217 );
218
219 U_BOOT_CMD(
220         lcd_puts, 2, 1, do_lcd_puts,
221         "display string on lcd",
222         "<string> - <string> to be displayed"
223 );
224
225 U_BOOT_CMD(
226         lcd_putc, 2, 1, do_lcd_putc,
227         "display char on lcd",
228         "<char> - <char> to be displayed"
229 );
230
231 U_BOOT_CMD(
232         lcd_cur, 3, 1, do_lcd_cur,
233         "shift cursor on lcd",
234         "<count> <dir> - shift cursor on lcd <count> times, direction is <dir> \n"
235         " <count> - 0..31\n"
236         " <dir>   - 0=backward 1=forward"
237 );