]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - board/karo/common/splashimage.c
bd1b64c8aafd0d7d08a88409ba4da4bfa7ed9fb9
[karo-tx-uboot.git] / board / karo / common / splashimage.c
1 /*
2  * (C) Copyright 2012 Lothar Waßmann <LW@KARO-electronics.de>
3  *
4  * See file CREDITS for list of people who contributed to this
5  * project.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * version 2 as published by the Free Software Foundation.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  */
17
18 #include <common.h>
19 #include <errno.h>
20 #include <lcd.h>
21 #include <nand.h>
22 #include <jffs2/load_kernel.h>
23
24 DECLARE_GLOBAL_DATA_PTR;
25
26 static int karo_load_part(const char *part, void *addr, size_t len)
27 {
28         int ret;
29         struct mtd_device *dev;
30         struct part_info *part_info;
31         u8 part_num;
32         size_t actual;
33
34         debug("Initializing mtd_parts\n");
35         ret = mtdparts_init();
36         if (ret)
37                 return ret;
38
39         debug("Trying to find NAND partition '%s'\n", part);
40         ret = find_dev_and_part(part, &dev, &part_num,
41                                 &part_info);
42         if (ret) {
43                 printf("Failed to find flash partition '%s': %d\n",
44                         part, ret);
45
46                 return ret;
47         }
48         debug("Found partition '%s': offset=%08x size=%08x\n",
49                 part, part_info->offset, part_info->size);
50         if (part_info->size < len) {
51                 printf("Warning: partition '%s' smaller than requested size: %u; truncating data to %u byte\n",
52                         part, len, part_info->size);
53                 len = part_info->size;
54         }
55         debug("Reading NAND partition '%s' to %p\n", part, addr);
56         ret = nand_read_skip_bad(&nand_info[0], part_info->offset, &len,
57                                 &actual, len, addr);
58         if (ret) {
59                 printf("Failed to load partition '%s' to %p\n", part, addr);
60                 return ret;
61         }
62         if (actual < len)
63                 printf("Read only %u of %u bytes due to bad blocks\n",
64                         actual, len);
65
66         debug("Read %u byte from partition '%s' @ offset %08x\n",
67                 len, part, part_info->offset);
68         return 0;
69 }
70
71 static ulong calc_fbsize(void)
72 {
73         return panel_info.vl_row * panel_info.vl_col *
74                 NBITS(panel_info.vl_bpix) / 8;
75 }
76
77 int karo_load_splashimage(int mode)
78 {
79         int ret;
80         int do_nand(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]);
81         unsigned long la = gd->fb_base;
82         char *splashimage = getenv("splashimage");
83         ulong fbsize = calc_fbsize();
84         char *end;
85
86         if (!la || !splashimage)
87                 return 0;
88
89         if ((simple_strtoul(splashimage, &end, 16) != 0) &&
90                 *end == '\0') {
91                 if (mode)
92                         return 0;
93                 la = simple_strtoul(splashimage, NULL, 16);
94                 splashimage = "logo.bmp";
95         } else if (!mode) {
96                 return 0;
97         }
98
99         if (tstc())
100                 return -ENODEV;
101
102         ret = karo_load_part(splashimage, (void *)la, fbsize);
103         if (ret) {
104                 printf("Failed to load logo from '%s': %d\n", splashimage, ret);
105                 return ret;
106         }
107         return 0;
108 }
109
110 static int erase_flash(loff_t offs, size_t len)
111 {
112         nand_erase_options_t nand_erase_options;
113
114         memset(&nand_erase_options, 0, sizeof(nand_erase_options));
115         nand_erase_options.length = len;
116         nand_erase_options.offset = offs;
117
118         return nand_erase_opts(&nand_info[0], &nand_erase_options);
119 }
120
121 int do_fbdump(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
122 {
123         int ret;
124         size_t fbsize = calc_fbsize();
125         const char *part = "logo";
126         struct mtd_device *dev;
127         struct part_info *part_info;
128         u8 part_num;
129         u_char *addr = (u_char *)gd->fb_base;
130         size_t actual;
131
132         if (argc > 2)
133                 return CMD_RET_USAGE;
134
135         if (argc == 2)
136                 part = argv[1];
137
138         if (!addr) {
139                 printf("fb address unknown\n");
140                 return CMD_RET_FAILURE;
141         }
142
143         debug("Initializing mtd_parts\n");
144         ret = mtdparts_init();
145         if (ret)
146                 return ret;
147
148         debug("Trying to find NAND partition '%s'\n", part);
149         ret = find_dev_and_part(part, &dev, &part_num,
150                                 &part_info);
151         if (ret) {
152                 printf("Failed to find flash partition '%s': %d\n",
153                         part, ret);
154
155                 return ret;
156         }
157         debug("Found partition '%s': offset=%08x size=%08x\n",
158                 part, part_info->offset, part_info->size);
159         if (part_info->size < fbsize) {
160                 printf("Error: partition '%s' smaller than frame buffer size: %u\n",
161                         part, fbsize);
162                 return CMD_RET_FAILURE;
163         }
164         debug("Writing framebuffer %p to NAND partition '%s'\n",
165                 addr, part);
166
167         ret = erase_flash(part_info->offset, fbsize);
168         if (ret) {
169                 printf("Failed to erase partition '%s'\n", part);
170                 return CMD_RET_FAILURE;
171         }
172
173         ret = nand_write_skip_bad(&nand_info[0], part_info->offset,
174                                 &fbsize, &actual, part_info->size,
175                                 addr, WITH_DROP_FFS);
176         if (ret) {
177                 printf("Failed to write partition '%s'\n", part);
178                 return ret;
179         }
180         if (actual < fbsize)
181                 printf("Wrote only %u of %u bytes due to bad blocks\n",
182                         actual, fbsize);
183
184         debug("Wrote %u byte from %p to partition '%s' @ offset %08x\n",
185                 fbsize, addr, part, part_info->offset);
186
187         return CMD_RET_SUCCESS;
188 }
189
190 U_BOOT_CMD(fbdump, 2, 0, do_fbdump, "dump framebuffer contents to flash",
191         "[partition name]\n"
192         "       default partition name: 'logo'\n");