]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - board/karo/common/splashimage.c
Unified codebase for TX28, TX48, TX51, TX53
[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
33         debug("Initializing mtd_parts\n");
34         ret = mtdparts_init();
35         if (ret)
36                 return ret;
37
38         debug("Trying to find NAND partition '%s'\n", part);
39         ret = find_dev_and_part(part, &dev, &part_num,
40                                 &part_info);
41         if (ret) {
42                 printf("Failed to find flash partition '%s': %d\n",
43                         part, ret);
44
45                 return ret;
46         }
47         debug("Found partition '%s': offset=%08x size=%08x\n",
48                 part, part_info->offset, part_info->size);
49         if (part_info->size < len) {
50                 printf("Warning: partition '%s' smaller than requested size: %u; truncating data to %u byte\n",
51                         part, len, part_info->size);
52                 len = part_info->size;
53         }
54         debug("Reading NAND partition '%s' to %p\n", part, addr);
55         ret = nand_read_skip_bad(&nand_info[0], part_info->offset, &len, addr);
56         if (ret) {
57                 printf("Failed to load partition '%s' to %p\n", part, addr);
58                 return ret;
59         }
60         debug("Read %u byte from partition '%s' @ offset %08x\n",
61                 len, part, part_info->offset);
62         return 0;
63 }
64
65 static ulong calc_fbsize(void)
66 {
67         return panel_info.vl_row * panel_info.vl_col *
68                 NBITS(panel_info.vl_bpix) / 8;
69 }
70
71 int karo_load_splashimage(int mode)
72 {
73         int ret;
74         int do_nand(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]);
75         unsigned long la = gd->fb_base;
76         char *splashimage = getenv("splashimage");
77         ulong fbsize = calc_fbsize();
78         char *end;
79
80         if (!la || !splashimage)
81                 return 0;
82
83         if ((simple_strtoul(splashimage, &end, 16) != 0) &&
84                 *end == '\0') {
85                 if (mode)
86                         return 0;
87                 la = simple_strtoul(splashimage, NULL, 16);
88                 splashimage = "logo.bmp";
89         } else if (!mode) {
90                 return 0;
91         }
92
93         if (tstc())
94                 return -ENODEV;
95
96         ret = karo_load_part(splashimage, (void *)la, fbsize);
97         if (ret) {
98                 printf("Failed to load logo from '%s': %d\n", splashimage, ret);
99                 return ret;
100         }
101         return 0;
102 }
103
104 static int erase_flash(loff_t offs, size_t len)
105 {
106         nand_erase_options_t nand_erase_options;
107
108         memset(&nand_erase_options, 0, sizeof(nand_erase_options));
109         nand_erase_options.length = len;
110         nand_erase_options.offset = offs;
111
112         return nand_erase_opts(&nand_info[0], &nand_erase_options);
113 }
114
115 int do_fbdump(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
116 {
117         int ret;
118         size_t fbsize = calc_fbsize();
119         const char *part = "logo";
120         struct mtd_device *dev;
121         struct part_info *part_info;
122         u8 part_num;
123         u_char *addr = (u_char *)gd->fb_base;
124
125         if (argc > 2)
126                 return CMD_RET_USAGE;
127
128         if (argc == 2)
129                 part = argv[1];
130
131         if (!addr) {
132                 printf("fb address unknown\n");
133                 return CMD_RET_FAILURE;
134         }
135
136         debug("Initializing mtd_parts\n");
137         ret = mtdparts_init();
138         if (ret)
139                 return ret;
140
141         debug("Trying to find NAND partition '%s'\n", part);
142         ret = find_dev_and_part(part, &dev, &part_num,
143                                 &part_info);
144         if (ret) {
145                 printf("Failed to find flash partition '%s': %d\n",
146                         part, ret);
147
148                 return ret;
149         }
150         debug("Found partition '%s': offset=%08x size=%08x\n",
151                 part, part_info->offset, part_info->size);
152         if (part_info->size < fbsize) {
153                 printf("Error: partition '%s' smaller than frame buffer size: %u\n",
154                         part, fbsize);
155                 return CMD_RET_FAILURE;
156         }
157         debug("Writing framebuffer %p to NAND partition '%s'\n",
158                 addr, part);
159
160         ret = erase_flash(part_info->offset, fbsize);
161         if (ret) {
162                 printf("Failed to erase partition '%s'\n", part);
163                 return CMD_RET_FAILURE;
164         }
165
166         ret = nand_write_skip_bad(&nand_info[0], part_info->offset,
167                                 &fbsize, addr, WITH_DROP_FFS);
168         if (ret) {
169                 printf("Failed to write partition '%s'\n", part);
170                 return ret;
171         }
172         debug("Wrote %u byte from %p to partition '%s' @ offset %08x\n",
173                 fbsize, addr, part, part_info->offset);
174
175         return CMD_RET_SUCCESS;
176 }
177
178 U_BOOT_CMD(fbdump, 2, 0, do_fbdump, "dump framebuffer contents to flash",
179         "[partition name]\n"
180         "       default partition name: 'logo'\n");