blob: 643f957a543a4712de6868eb455cb60b6881beab [file] [log] [blame]
Przemyslaw Marczak679549d2014-01-22 11:24:12 +01001/*
2 * Copyright (C) 2013 Samsung Electronics
3 * Przemyslaw Marczak <p.marczak@samsung.com>
4 *
5 * SPDX-License-Identifier: GPL-2.0+
6 */
7
8#include <common.h>
9#include <lcd.h>
10#include <libtizen.h>
11#include <samsung/misc.h>
Przemyslaw Marczak9d29a682014-01-22 11:24:17 +010012#include <errno.h>
13#include <version.h>
14#include <asm/sizes.h>
15#include <asm/arch/cpu.h>
16#include <asm/arch/gpio.h>
17#include <asm/gpio.h>
18#include <linux/input.h>
19#include <power/pmic.h>
20#include <mmc.h>
21
22DECLARE_GLOBAL_DATA_PTR;
23
24#ifdef CONFIG_LCD_MENU
25static int power_key_pressed(u32 reg)
26{
27 struct pmic *pmic;
28 u32 status;
29 u32 mask;
30
31 pmic = pmic_get(KEY_PWR_PMIC_NAME);
32 if (!pmic) {
33 printf("%s: Not found\n", KEY_PWR_PMIC_NAME);
34 return 0;
35 }
36
37 if (pmic_probe(pmic))
38 return 0;
39
40 if (reg == KEY_PWR_STATUS_REG)
41 mask = KEY_PWR_STATUS_MASK;
42 else
43 mask = KEY_PWR_INTERRUPT_MASK;
44
45 if (pmic_reg_read(pmic, reg, &status))
46 return 0;
47
48 return !!(status & mask);
49}
50
51static int key_pressed(int key)
52{
53 int value;
54
55 switch (key) {
56 case KEY_POWER:
57 value = power_key_pressed(KEY_PWR_INTERRUPT_REG);
58 break;
59 case KEY_VOLUMEUP:
60 value = !gpio_get_value(KEY_VOL_UP_GPIO);
61 break;
62 case KEY_VOLUMEDOWN:
63 value = !gpio_get_value(KEY_VOL_DOWN_GPIO);
64 break;
65 default:
66 value = 0;
67 break;
68 }
69
70 return value;
71}
72
73static int check_keys(void)
74{
75 int keys = 0;
76
77 if (key_pressed(KEY_POWER))
78 keys += KEY_POWER;
79 if (key_pressed(KEY_VOLUMEUP))
80 keys += KEY_VOLUMEUP;
81 if (key_pressed(KEY_VOLUMEDOWN))
82 keys += KEY_VOLUMEDOWN;
83
84 return keys;
85}
86
87/*
88 * 0 BOOT_MODE_INFO
89 * 1 BOOT_MODE_THOR
90 * 2 BOOT_MODE_UMS
91 * 3 BOOT_MODE_DFU
92 * 4 BOOT_MODE_EXIT
93 */
94static char *
95mode_name[BOOT_MODE_EXIT + 1] = {
96 "DEVICE",
97 "THOR",
98 "UMS",
99 "DFU",
100 "EXIT"
101};
102
103static char *
104mode_info[BOOT_MODE_EXIT + 1] = {
105 "info",
106 "downloader",
107 "mass storage",
108 "firmware update",
109 "and run normal boot"
110};
111
112#define MODE_CMD_ARGC 4
113
114static char *
115mode_cmd[BOOT_MODE_EXIT + 1][MODE_CMD_ARGC] = {
116 {"", "", "", ""},
117 {"thor", "0", "mmc", "0"},
118 {"ums", "0", "mmc", "0"},
119 {"dfu", "0", "mmc", "0"},
120 {"", "", "", ""},
121};
122
123static void display_board_info(void)
124{
125#ifdef CONFIG_GENERIC_MMC
126 struct mmc *mmc = find_mmc_device(0);
127#endif
128 vidinfo_t *vid = &panel_info;
129
130 lcd_position_cursor(4, 4);
131
132 lcd_printf("%s\n\t", U_BOOT_VERSION);
133 lcd_puts("\n\t\tBoard Info:\n");
134#ifdef CONFIG_SYS_BOARD
135 lcd_printf("\tBoard name: %s\n", CONFIG_SYS_BOARD);
136#endif
137#ifdef CONFIG_REVISION_TAG
138 lcd_printf("\tBoard rev: %u\n", get_board_rev());
139#endif
140 lcd_printf("\tDRAM banks: %u\n", CONFIG_NR_DRAM_BANKS);
141 lcd_printf("\tDRAM size: %u MB\n", gd->ram_size / SZ_1M);
142
143#ifdef CONFIG_GENERIC_MMC
144 if (mmc) {
145 if (!mmc->capacity)
146 mmc_init(mmc);
147
148 lcd_printf("\teMMC size: %llu MB\n", mmc->capacity / SZ_1M);
149 }
150#endif
151 if (vid)
152 lcd_printf("\tDisplay resolution: %u x % u\n",
153 vid->vl_col, vid->vl_row);
154
155 lcd_printf("\tDisplay BPP: %u\n", 1 << vid->vl_bpix);
156}
157
158static int mode_leave_menu(int mode)
159{
160 char *exit_option;
161 char *exit_boot = "boot";
162 char *exit_back = "back";
163 cmd_tbl_t *cmd;
164 int cmd_result;
165 int cmd_repeatable;
166 int leave;
167
168 lcd_clear();
169
170 switch (mode) {
171 case BOOT_MODE_EXIT:
172 return 1;
173 case BOOT_MODE_INFO:
174 display_board_info();
175 exit_option = exit_back;
176 leave = 0;
177 break;
178 default:
179 cmd = find_cmd(mode_cmd[mode][0]);
180 if (cmd) {
181 printf("Enter: %s %s\n", mode_name[mode],
182 mode_info[mode]);
183 lcd_printf("\n\n\t%s %s\n", mode_name[mode],
184 mode_info[mode]);
185 lcd_puts("\n\tDo not turn off device before finish!\n");
186
187 cmd_result = cmd_process(0, MODE_CMD_ARGC,
188 *(mode_cmd + mode),
189 &cmd_repeatable, NULL);
190
191 if (cmd_result == CMD_RET_SUCCESS) {
192 printf("Command finished\n");
193 lcd_clear();
194 lcd_printf("\n\n\t%s finished\n",
195 mode_name[mode]);
196
197 exit_option = exit_boot;
198 leave = 1;
199 } else {
200 printf("Command error\n");
201 lcd_clear();
202 lcd_printf("\n\n\t%s command error\n",
203 mode_name[mode]);
204
205 exit_option = exit_back;
206 leave = 0;
207 }
208 } else {
209 lcd_puts("\n\n\tThis mode is not supported.\n");
210 exit_option = exit_back;
211 leave = 0;
212 }
213 }
214
215 lcd_printf("\n\n\tPress POWER KEY to %s\n", exit_option);
216
217 /* Clear PWR button Rising edge interrupt status flag */
218 power_key_pressed(KEY_PWR_INTERRUPT_REG);
219
220 /* Wait for PWR key */
221 while (!key_pressed(KEY_POWER))
222 mdelay(1);
223
224 lcd_clear();
225 return leave;
226}
227
228static void display_download_menu(int mode)
229{
230 char *selection[BOOT_MODE_EXIT + 1];
231 int i;
232
233 for (i = 0; i <= BOOT_MODE_EXIT; i++)
234 selection[i] = "[ ]";
235
236 selection[mode] = "[=>]";
237
238 lcd_clear();
239 lcd_printf("\n\t\tDownload Mode Menu\n");
240
241 for (i = 0; i <= BOOT_MODE_EXIT; i++)
242 lcd_printf("\t%s %s - %s\n\n", selection[i],
243 mode_name[i],
244 mode_info[i]);
245}
246
247static void download_menu(void)
248{
249 int mode = 0;
250 int last_mode = 0;
251 int run;
252 int key;
253
254 display_download_menu(mode);
255
256 while (1) {
257 run = 0;
258
259 if (mode != last_mode)
260 display_download_menu(mode);
261
262 last_mode = mode;
263 mdelay(100);
264
265 key = check_keys();
266 switch (key) {
267 case KEY_POWER:
268 run = 1;
269 break;
270 case KEY_VOLUMEUP:
271 if (mode > 0)
272 mode--;
273 break;
274 case KEY_VOLUMEDOWN:
275 if (mode < BOOT_MODE_EXIT)
276 mode++;
277 break;
278 default:
279 break;
280 }
281
282 if (run) {
283 if (mode_leave_menu(mode))
284 break;
285
286 display_download_menu(mode);
287 }
288 }
289
290 lcd_clear();
291}
292
293static void display_mode_info(void)
294{
295 lcd_position_cursor(4, 4);
296 lcd_printf("%s\n", U_BOOT_VERSION);
297 lcd_puts("\nDownload Mode Menu\n");
298#ifdef CONFIG_SYS_BOARD
299 lcd_printf("Board name: %s\n", CONFIG_SYS_BOARD);
300#endif
301 lcd_printf("Press POWER KEY to display MENU options.");
302}
303
304static int boot_menu(void)
305{
306 int key = 0;
307 int timeout = 10;
308
309 display_mode_info();
310
311 while (timeout--) {
312 lcd_printf("\rNormal boot will start in: %d seconds.", timeout);
313 mdelay(1000);
314
315 key = key_pressed(KEY_POWER);
316 if (key)
317 break;
318 }
319
320 lcd_clear();
321
322 /* If PWR pressed - show download menu */
323 if (key) {
324 printf("Power pressed - go to download menu\n");
325 download_menu();
326 printf("Download mode exit.\n");
327 }
328
329 return 0;
330}
331
332void check_boot_mode(void)
333{
334 int pwr_key;
335
336 pwr_key = power_key_pressed(KEY_PWR_STATUS_REG);
337 if (!pwr_key)
338 return;
339
340 /* Clear PWR button Rising edge interrupt status flag */
341 power_key_pressed(KEY_PWR_INTERRUPT_REG);
342
343 if (key_pressed(KEY_VOLUMEUP))
344 boot_menu();
345 else if (key_pressed(KEY_VOLUMEDOWN))
346 mode_leave_menu(BOOT_MODE_THOR);
347}
348
349void keys_init(void)
350{
351 /* Set direction to input */
352 gpio_direction_input(KEY_VOL_UP_GPIO);
353 gpio_direction_input(KEY_VOL_DOWN_GPIO);
354}
355#endif /* CONFIG_LCD_MENU */
Przemyslaw Marczak679549d2014-01-22 11:24:12 +0100356
357#ifdef CONFIG_CMD_BMP
358void draw_logo(void)
359{
360 int x, y;
361 ulong addr;
362
363 addr = panel_info.logo_addr;
364 if (!addr) {
365 error("There is no logo data.");
366 return;
367 }
368
369 if (panel_info.vl_width >= panel_info.logo_width) {
370 x = ((panel_info.vl_width - panel_info.logo_width) >> 1);
Przemyslaw Marczak903afe12013-11-29 18:30:43 +0100371 x += panel_info.logo_x_offset; /* For X center align */
Przemyslaw Marczak679549d2014-01-22 11:24:12 +0100372 } else {
373 x = 0;
374 printf("Warning: image width is bigger than display width\n");
375 }
376
377 if (panel_info.vl_height >= panel_info.logo_height) {
378 y = ((panel_info.vl_height - panel_info.logo_height) >> 1);
Przemyslaw Marczak903afe12013-11-29 18:30:43 +0100379 y += panel_info.logo_y_offset; /* For Y center align */
Przemyslaw Marczak679549d2014-01-22 11:24:12 +0100380 } else {
381 y = 0;
382 printf("Warning: image height is bigger than display height\n");
383 }
384
385 bmp_display(addr, x, y);
386}
387#endif /* CONFIG_CMD_BMP */