summaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
Diffstat (limited to 'common')
-rw-r--r--common/Makefile2
-rw-r--r--common/board_f.c8
-rw-r--r--common/bootm.c150
-rw-r--r--common/bootm_os.c29
-rw-r--r--common/cmd_mmc.c205
-rw-r--r--common/cmd_sandbox.c2
-rw-r--r--common/cmd_usb.c48
-rw-r--r--common/console.c46
-rw-r--r--common/edid.c12
-rw-r--r--common/image-fit.c10
-rw-r--r--common/image.c4
-rw-r--r--common/lcd.c313
-rw-r--r--common/lcd_console.c211
-rw-r--r--common/memsize.c31
-rw-r--r--common/spl/spl_nor.c64
-rw-r--r--common/usb.c11
-rw-r--r--common/usb_kbd.c10
17 files changed, 738 insertions, 418 deletions
diff --git a/common/Makefile b/common/Makefile
index c668a2f..94554f2 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -196,7 +196,7 @@ obj-$(CONFIG_CMD_KGDB) += kgdb.o kgdb_stubs.o
obj-$(CONFIG_I2C_EDID) += edid.o
obj-$(CONFIG_KALLSYMS) += kallsyms.o
obj-y += splash.o
-obj-$(CONFIG_LCD) += lcd.o
+obj-$(CONFIG_LCD) += lcd.o lcd_console.o
obj-$(CONFIG_LYNXKDI) += lynxkdi.o
obj-$(CONFIG_MENU) += menu.o
obj-$(CONFIG_MODEM_SUPPORT) += modem.o
diff --git a/common/board_f.c b/common/board_f.c
index cfd77f8..3a4b32c 100644
--- a/common/board_f.c
+++ b/common/board_f.c
@@ -985,6 +985,11 @@ static init_fnc_t init_sequence_f[] = {
INIT_FUNC_WATCHDOG_RESET
reloc_fdt,
setup_reloc,
+#ifdef CONFIG_X86
+ copy_uboot_to_ram,
+ clear_bss,
+ do_elf_reloc_fixups,
+#endif
#if !defined(CONFIG_ARM) && !defined(CONFIG_SANDBOX)
jump_to_copy,
#endif
@@ -1044,9 +1049,6 @@ void board_init_f(ulong boot_flags)
*/
static init_fnc_t init_sequence_f_r[] = {
init_cache_f_r,
- copy_uboot_to_ram,
- clear_bss,
- do_elf_reloc_fixups,
NULL,
};
diff --git a/common/bootm.c b/common/bootm.c
index 6b3ea8c..e2dc164 100644
--- a/common/bootm.c
+++ b/common/bootm.c
@@ -264,103 +264,122 @@ static int bootm_find_other(cmd_tbl_t *cmdtp, int flag, int argc,
return 0;
}
-#endif /* USE_HOSTCC */
+#endif /* USE_HOSTC */
/**
- * decomp_image() - decompress the operating system
+ * print_decomp_msg() - Print a suitable decompression/loading message
*
- * @comp: Compression algorithm that is used (IH_COMP_...)
- * @load: Destination load address in U-Boot memory
- * @image_start Image start address (where we are decompressing from)
* @type: OS type (IH_OS_...)
- * @load_bug: Place to decompress to
- * @image_buf: Address to decompress from
- * @return 0 if OK, -ve on error (BOOTM_ERR_...)
+ * @comp_type: Compression type being used (IH_COMP_...)
+ * @is_xip: true if the load address matches the image start
*/
-static int decomp_image(int comp, ulong load, ulong image_start, int type,
- void *load_buf, void *image_buf, ulong image_len,
- ulong *load_end)
+static void print_decomp_msg(int comp_type, int type, bool is_xip)
{
- const char *type_name = genimg_get_type_name(type);
- __attribute__((unused)) uint unc_len = CONFIG_SYS_BOOTM_LEN;
+ const char *name = genimg_get_type_name(type);
+
+ if (comp_type == IH_COMP_NONE)
+ printf(" %s %s ... ", is_xip ? "XIP" : "Loading", name);
+ else
+ printf(" Uncompressing %s ... ", name);
+}
+
+/**
+ * handle_decomp_error() - display a decompression error
+ *
+ * This function tries to produce a useful message. In the case where the
+ * uncompressed size is the same as the available space, we can assume that
+ * the image is too large for the buffer.
+ *
+ * @comp_type: Compression type being used (IH_COMP_...)
+ * @uncomp_size: Number of bytes uncompressed
+ * @unc_len: Amount of space available for decompression
+ * @ret: Error code to report
+ * @return BOOTM_ERR_RESET, indicating that the board must be reset
+ */
+static int handle_decomp_error(int comp_type, size_t uncomp_size,
+ size_t unc_len, int ret)
+{
+ const char *name = genimg_get_comp_name(comp_type);
+
+ if (uncomp_size >= unc_len)
+ printf("Image too large: increase CONFIG_SYS_BOOTM_LEN\n");
+ else
+ printf("%s: uncompress error %d\n", name, ret);
+
+ /*
+ * The decompression routines are now safe, so will not write beyond
+ * their bounds. Probably it is not necessary to reset, but maintain
+ * the current behaviour for now.
+ */
+ printf("Must RESET board to recover\n");
+#ifndef USE_HOSTCC
+ bootstage_error(BOOTSTAGE_ID_DECOMP_IMAGE);
+#endif
+
+ return BOOTM_ERR_RESET;
+}
+
+int bootm_decomp_image(int comp, ulong load, ulong image_start, int type,
+ void *load_buf, void *image_buf, ulong image_len,
+ uint unc_len, ulong *load_end)
+{
+ int ret = 0;
*load_end = load;
+ print_decomp_msg(comp, type, load == image_start);
+
+ /*
+ * Load the image to the right place, decompressing if needed. After
+ * this, image_len will be set to the number of uncompressed bytes
+ * loaded, ret will be non-zero on error.
+ */
switch (comp) {
case IH_COMP_NONE:
- if (load == image_start) {
- printf(" XIP %s ... ", type_name);
- } else {
- printf(" Loading %s ... ", type_name);
+ if (load == image_start)
+ break;
+ if (image_len <= unc_len)
memmove_wd(load_buf, image_buf, image_len, CHUNKSZ);
- }
- *load_end = load + image_len;
+ else
+ ret = 1;
break;
#ifdef CONFIG_GZIP
- case IH_COMP_GZIP:
- printf(" Uncompressing %s ... ", type_name);
- if (gunzip(load_buf, unc_len, image_buf, &image_len) != 0) {
- puts("GUNZIP: uncompress, out-of-mem or overwrite error - must RESET board to recover\n");
- return BOOTM_ERR_RESET;
- }
-
- *load_end = load + image_len;
+ case IH_COMP_GZIP: {
+ ret = gunzip(load_buf, unc_len, image_buf, &image_len);
break;
+ }
#endif /* CONFIG_GZIP */
#ifdef CONFIG_BZIP2
- case IH_COMP_BZIP2:
- printf(" Uncompressing %s ... ", type_name);
+ case IH_COMP_BZIP2: {
+ uint size = unc_len;
+
/*
* If we've got less than 4 MB of malloc() space,
* use slower decompression algorithm which requires
* at most 2300 KB of memory.
*/
- int i = BZ2_bzBuffToBuffDecompress(load_buf, &unc_len,
+ ret = BZ2_bzBuffToBuffDecompress(load_buf, &size,
image_buf, image_len,
CONFIG_SYS_MALLOC_LEN < (4096 * 1024), 0);
- if (i != BZ_OK) {
- printf("BUNZIP2: uncompress or overwrite error %d - must RESET board to recover\n",
- i);
- return BOOTM_ERR_RESET;
- }
-
- *load_end = load + unc_len;
+ image_len = size;
break;
+ }
#endif /* CONFIG_BZIP2 */
#ifdef CONFIG_LZMA
case IH_COMP_LZMA: {
SizeT lzma_len = unc_len;
- int ret;
-
- printf(" Uncompressing %s ... ", type_name);
ret = lzmaBuffToBuffDecompress(load_buf, &lzma_len,
image_buf, image_len);
- unc_len = lzma_len;
- if (ret != SZ_OK) {
- printf("LZMA: uncompress or overwrite error %d - must RESET board to recover\n",
- ret);
- bootstage_error(BOOTSTAGE_ID_DECOMP_IMAGE);
- return BOOTM_ERR_RESET;
- }
- *load_end = load + unc_len;
+ image_len = lzma_len;
break;
}
#endif /* CONFIG_LZMA */
#ifdef CONFIG_LZO
case IH_COMP_LZO: {
size_t size = unc_len;
- int ret;
-
- printf(" Uncompressing %s ... ", type_name);
ret = lzop_decompress(image_buf, image_len, load_buf, &size);
- if (ret != LZO_E_OK) {
- printf("LZO: uncompress or overwrite error %d - must RESET board to recover\n",
- ret);
- return BOOTM_ERR_RESET;
- }
-
- *load_end = load + size;
+ image_len = size;
break;
}
#endif /* CONFIG_LZO */
@@ -369,6 +388,10 @@ static int decomp_image(int comp, ulong load, ulong image_start, int type,
return BOOTM_ERR_UNIMPLEMENTED;
}
+ if (ret)
+ return handle_decomp_error(comp, image_len, unc_len, ret);
+ *load_end = load + image_len;
+
puts("OK\n");
return 0;
@@ -390,8 +413,9 @@ static int bootm_load_os(bootm_headers_t *images, unsigned long *load_end,
load_buf = map_sysmem(load, 0);
image_buf = map_sysmem(os.image_start, image_len);
- err = decomp_image(os.comp, load, os.image_start, os.type, load_buf,
- image_buf, image_len, load_end);
+ err = bootm_decomp_image(os.comp, load, os.image_start, os.type,
+ load_buf, image_buf, image_len,
+ CONFIG_SYS_BOOTM_LEN, load_end);
if (err) {
bootstage_error(BOOTSTAGE_ID_DECOMP_IMAGE);
return err;
@@ -882,9 +906,11 @@ static int bootm_host_load_image(const void *fit, int req_image_type)
/* Allow the image to expand by a factor of 4, should be safe */
load_buf = malloc((1 << 20) + len * 4);
- ret = decomp_image(imape_comp, 0, data, image_type, load_buf,
- (void *)data, len, &load_end);
+ ret = bootm_decomp_image(imape_comp, 0, data, image_type, load_buf,
+ (void *)data, len, CONFIG_SYS_BOOTM_LEN,
+ &load_end);
free(load_buf);
+
if (ret && ret != BOOTM_ERR_UNIMPLEMENTED)
return ret;
diff --git a/common/bootm_os.c b/common/bootm_os.c
index 5be4467..72477f0 100644
--- a/common/bootm_os.c
+++ b/common/bootm_os.c
@@ -404,6 +404,32 @@ static int do_bootm_integrity(int flag, int argc, char * const argv[],
}
#endif
+#ifdef CONFIG_BOOTM_OPENRTOS
+static int do_bootm_openrtos(int flag, int argc, char * const argv[],
+ bootm_headers_t *images)
+{
+ void (*entry_point)(void);
+
+ if (flag != BOOTM_STATE_OS_GO)
+ return 0;
+
+ entry_point = (void (*)(void))images->ep;
+
+ printf("## Transferring control to OpenRTOS (at address %08lx) ...\n",
+ (ulong)entry_point);
+
+ bootstage_mark(BOOTSTAGE_ID_RUN_OS);
+
+ /*
+ * OpenRTOS Parameters:
+ * None
+ */
+ (*entry_point)();
+
+ return 1;
+}
+#endif
+
static boot_os_fn *boot_os[] = {
[IH_OS_U_BOOT] = do_bootm_standalone,
#ifdef CONFIG_BOOTM_LINUX
@@ -434,6 +460,9 @@ static boot_os_fn *boot_os[] = {
#ifdef CONFIG_INTEGRITY
[IH_OS_INTEGRITY] = do_bootm_integrity,
#endif
+#ifdef CONFIG_BOOTM_OPENRTOS
+ [IH_OS_OPENRTOS] = do_bootm_openrtos,
+#endif
};
/* Allow for arch specific config before we boot */
diff --git a/common/cmd_mmc.c b/common/cmd_mmc.c
index 96478e4..4e28c9d 100644
--- a/common/cmd_mmc.c
+++ b/common/cmd_mmc.c
@@ -73,6 +73,8 @@ U_BOOT_CMD(
static void print_mmcinfo(struct mmc *mmc)
{
+ int i;
+
printf("Device: %s\n", mmc->cfg->name);
printf("Manufacturer ID: %x\n", mmc->cid[0] >> 24);
printf("OEM: %x\n", (mmc->cid[0] >> 8) & 0xffff);
@@ -92,6 +94,48 @@ static void print_mmcinfo(struct mmc *mmc)
printf("Bus Width: %d-bit%s\n", mmc->bus_width,
mmc->ddr_mode ? " DDR" : "");
+
+ puts("Erase Group Size: ");
+ print_size(((u64)mmc->erase_grp_size) << 9, "\n");
+
+ if (!IS_SD(mmc) && mmc->version >= MMC_VERSION_4_41) {
+ bool has_enh = (mmc->part_support & ENHNCD_SUPPORT) != 0;
+ bool usr_enh = has_enh && (mmc->part_attr & EXT_CSD_ENH_USR);
+
+ puts("HC WP Group Size: ");
+ print_size(((u64)mmc->hc_wp_grp_size) << 9, "\n");
+
+ puts("User Capacity: ");
+ print_size(mmc->capacity_user, usr_enh ? " ENH" : "");
+ if (mmc->wr_rel_set & EXT_CSD_WR_DATA_REL_USR)
+ puts(" WRREL\n");
+ else
+ putc('\n');
+ if (usr_enh) {
+ puts("User Enhanced Start: ");
+ print_size(mmc->enh_user_start, "\n");
+ puts("User Enhanced Size: ");
+ print_size(mmc->enh_user_size, "\n");
+ }
+ puts("Boot Capacity: ");
+ print_size(mmc->capacity_boot, has_enh ? " ENH\n" : "\n");
+ puts("RPMB Capacity: ");
+ print_size(mmc->capacity_rpmb, has_enh ? " ENH\n" : "\n");
+
+ for (i = 0; i < ARRAY_SIZE(mmc->capacity_gp); i++) {
+ bool is_enh = has_enh &&
+ (mmc->part_attr & EXT_CSD_ENH_GP(i));
+ if (mmc->capacity_gp[i]) {
+ printf("GP%i Capacity: ", i+1);
+ print_size(mmc->capacity_gp[i],
+ is_enh ? " ENH" : "");
+ if (mmc->wr_rel_set & EXT_CSD_WR_DATA_REL_GP(i))
+ puts(" WRREL\n");
+ else
+ putc('\n');
+ }
+ }
+ }
}
static struct mmc *init_mmc_device(int dev, bool force_init)
{
@@ -444,6 +488,157 @@ static int do_mmc_list(cmd_tbl_t *cmdtp, int flag,
print_mmc_devices('\n');
return CMD_RET_SUCCESS;
}
+
+static int parse_hwpart_user(struct mmc_hwpart_conf *pconf,
+ int argc, char * const argv[])
+{
+ int i = 0;
+
+ memset(&pconf->user, 0, sizeof(pconf->user));
+
+ while (i < argc) {
+ if (!strcmp(argv[i], "enh")) {
+ if (i + 2 >= argc)
+ return -1;
+ pconf->user.enh_start =
+ simple_strtoul(argv[i+1], NULL, 10);
+ pconf->user.enh_size =
+ simple_strtoul(argv[i+2], NULL, 10);
+ i += 3;
+ } else if (!strcmp(argv[i], "wrrel")) {
+ if (i + 1 >= argc)
+ return -1;
+ pconf->user.wr_rel_change = 1;
+ if (!strcmp(argv[i+1], "on"))
+ pconf->user.wr_rel_set = 1;
+ else if (!strcmp(argv[i+1], "off"))
+ pconf->user.wr_rel_set = 0;
+ else
+ return -1;
+ i += 2;
+ } else {
+ break;
+ }
+ }
+ return i;
+}
+
+static int parse_hwpart_gp(struct mmc_hwpart_conf *pconf, int pidx,
+ int argc, char * const argv[])
+{
+ int i;
+
+ memset(&pconf->gp_part[pidx], 0, sizeof(pconf->gp_part[pidx]));
+
+ if (1 >= argc)
+ return -1;
+ pconf->gp_part[pidx].size = simple_strtoul(argv[0], NULL, 10);
+
+ i = 1;
+ while (i < argc) {
+ if (!strcmp(argv[i], "enh")) {
+ pconf->gp_part[pidx].enhanced = 1;
+ i += 1;
+ } else if (!strcmp(argv[i], "wrrel")) {
+ if (i + 1 >= argc)
+ return -1;
+ pconf->gp_part[pidx].wr_rel_change = 1;
+ if (!strcmp(argv[i+1], "on"))
+ pconf->gp_part[pidx].wr_rel_set = 1;
+ else if (!strcmp(argv[i+1], "off"))
+ pconf->gp_part[pidx].wr_rel_set = 0;
+ else
+ return -1;
+ i += 2;
+ } else {
+ break;
+ }
+ }
+ return i;
+}
+
+static int do_mmc_hwpartition(cmd_tbl_t *cmdtp, int flag,
+ int argc, char * const argv[])
+{
+ struct mmc *mmc;
+ struct mmc_hwpart_conf pconf = { };
+ enum mmc_hwpart_conf_mode mode = MMC_HWPART_CONF_CHECK;
+ int i, r, pidx;
+
+ mmc = init_mmc_device(curr_device, false);
+ if (!mmc)
+ return CMD_RET_FAILURE;
+
+ if (argc < 1)
+ return CMD_RET_USAGE;
+ i = 1;
+ while (i < argc) {
+ if (!strcmp(argv[i], "user")) {
+ i++;
+ r = parse_hwpart_user(&pconf, argc-i, &argv[i]);
+ if (r < 0)
+ return CMD_RET_USAGE;
+ i += r;
+ } else if (!strncmp(argv[i], "gp", 2) &&
+ strlen(argv[i]) == 3 &&
+ argv[i][2] >= '1' && argv[i][2] <= '4') {
+ pidx = argv[i][2] - '1';
+ i++;
+ r = parse_hwpart_gp(&pconf, pidx, argc-i, &argv[i]);
+ if (r < 0)
+ return CMD_RET_USAGE;
+ i += r;
+ } else if (!strcmp(argv[i], "check")) {
+ mode = MMC_HWPART_CONF_CHECK;
+ i++;
+ } else if (!strcmp(argv[i], "set")) {
+ mode = MMC_HWPART_CONF_SET;
+ i++;
+ } else if (!strcmp(argv[i], "complete")) {
+ mode = MMC_HWPART_CONF_COMPLETE;
+ i++;
+ } else {
+ return CMD_RET_USAGE;
+ }
+ }
+
+ puts("Partition configuration:\n");
+ if (pconf.user.enh_size) {
+ puts("\tUser Enhanced Start: ");
+ print_size(((u64)pconf.user.enh_start) << 9, "\n");
+ puts("\tUser Enhanced Size: ");
+ print_size(((u64)pconf.user.enh_size) << 9, "\n");
+ } else {
+ puts("\tNo enhanced user data area\n");
+ }
+ if (pconf.user.wr_rel_change)
+ printf("\tUser partition write reliability: %s\n",
+ pconf.user.wr_rel_set ? "on" : "off");
+ for (pidx = 0; pidx < 4; pidx++) {
+ if (pconf.gp_part[pidx].size) {
+ printf("\tGP%i Capacity: ", pidx+1);
+ print_size(((u64)pconf.gp_part[pidx].size) << 9,
+ pconf.gp_part[pidx].enhanced ?
+ " ENH\n" : "\n");
+ } else {
+ printf("\tNo GP%i partition\n", pidx+1);
+ }
+ if (pconf.gp_part[pidx].wr_rel_change)
+ printf("\tGP%i write reliability: %s\n", pidx+1,
+ pconf.gp_part[pidx].wr_rel_set ? "on" : "off");
+ }
+
+ if (!mmc_hwpart_config(mmc, &pconf, mode)) {
+ if (mode == MMC_HWPART_CONF_COMPLETE)
+ puts("Partitioning successful, "
+ "power-cycle to make effective\n");
+ return CMD_RET_SUCCESS;
+ } else {
+ puts("Failed!\n");
+ return CMD_RET_FAILURE;
+ }
+}
+
#ifdef CONFIG_SUPPORT_EMMC_BOOT
static int do_mmc_bootbus(cmd_tbl_t *cmdtp, int flag,
int argc, char * const argv[])
@@ -601,6 +796,7 @@ static cmd_tbl_t cmd_mmc[] = {
U_BOOT_CMD_MKENT(part, 1, 1, do_mmc_part, "", ""),
U_BOOT_CMD_MKENT(dev, 3, 0, do_mmc_dev, "", ""),
U_BOOT_CMD_MKENT(list, 1, 1, do_mmc_list, "", ""),
+ U_BOOT_CMD_MKENT(hwpartition, 28, 0, do_mmc_hwpartition, "", ""),
#ifdef CONFIG_SUPPORT_EMMC_BOOT
U_BOOT_CMD_MKENT(bootbus, 5, 0, do_mmc_bootbus, "", ""),
U_BOOT_CMD_MKENT(bootpart-resize, 4, 0, do_mmc_boot_resize, "", ""),
@@ -640,7 +836,7 @@ static int do_mmcops(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
}
U_BOOT_CMD(
- mmc, 7, 1, do_mmcops,
+ mmc, 29, 1, do_mmcops,
"MMC sub system",
"info - display info of the current MMC device\n"
"mmc read addr blk# cnt\n"
@@ -650,6 +846,13 @@ U_BOOT_CMD(
"mmc part - lists available partition on current mmc device\n"
"mmc dev [dev] [part] - show or set current mmc device [partition]\n"
"mmc list - lists available devices\n"
+ "mmc hwpartition [args...] - does hardware partitioning\n"
+ " arguments (sizes in 512-byte blocks):\n"
+ " [user [enh start cnt] [wrrel {on|off}]] - sets user data area attributes\n"
+ " [gp1|gp2|gp3|gp4 cnt [enh] [wrrel {on|off}]] - general purpose partition\n"
+ " [check|set|complete] - mode, complete set partitioning completed\n"
+ " WARNING: Partitioning is a write-once setting once it is set to complete.\n"
+ " Power cycling is required to initialize partitions after set to complete.\n"
#ifdef CONFIG_SUPPORT_EMMC_BOOT
"mmc bootbus dev boot_bus_width reset_boot_bus_width boot_mode\n"
" - Set the BOOT_BUS_WIDTH field of the specified device\n"
diff --git a/common/cmd_sandbox.c b/common/cmd_sandbox.c
index 3d9fce7..4286969 100644
--- a/common/cmd_sandbox.c
+++ b/common/cmd_sandbox.c
@@ -117,7 +117,7 @@ U_BOOT_CMD(
"load hostfs - <addr> <filename> [<bytes> <offset>] - "
"load a file from host\n"
"sb ls hostfs - <filename> - list files on host\n"
- "sb save hostfs - <filename> <addr> <bytes> [<offset>] - "
+ "sb save hostfs - <addr> <filename> <bytes> [<offset>] - "
"save a file to host\n"
"sb bind <dev> [<filename>] - bind \"host\" device to file\n"
"sb info [<dev>] - show device binding & info\n"
diff --git a/common/cmd_usb.c b/common/cmd_usb.c
index c192498..27813f0 100644
--- a/common/cmd_usb.c
+++ b/common/cmd_usb.c
@@ -441,6 +441,26 @@ static int do_usb_stop_keyboard(int force)
return 0;
}
+static void do_usb_start(void)
+{
+ bootstage_mark_name(BOOTSTAGE_ID_USB_START, "usb_start");
+
+ if (usb_init() < 0)
+ return;
+
+#ifdef CONFIG_USB_STORAGE
+ /* try to recognize storage devices immediately */
+ usb_stor_curr_dev = usb_stor_scan(1);
+#endif
+#ifdef CONFIG_USB_HOST_ETHER
+ /* try to recognize ethernet devices immediately */
+ usb_ether_curr_dev = usb_host_eth_scan(1);
+#endif
+#ifdef CONFIG_USB_KEYBOARD
+ drv_usb_kbd_init();
+#endif
+}
+
/******************************************************************************
* usb command intepreter
*/
@@ -457,26 +477,20 @@ static int do_usb(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
if (argc < 2)
return CMD_RET_USAGE;
- if ((strncmp(argv[1], "reset", 5) == 0) ||
- (strncmp(argv[1], "start", 5) == 0)) {
- bootstage_mark_name(BOOTSTAGE_ID_USB_START, "usb_start");
+ if (strncmp(argv[1], "start", 5) == 0) {
+ if (usb_started)
+ return 0; /* Already started */
+ printf("starting USB...\n");
+ do_usb_start();
+ return 0;
+ }
+
+ if (strncmp(argv[1], "reset", 5) == 0) {
+ printf("resetting USB...\n");
if (do_usb_stop_keyboard(1) != 0)
return 1;
usb_stop();
- printf("(Re)start USB...\n");
- if (usb_init() >= 0) {
-#ifdef CONFIG_USB_STORAGE
- /* try to recognize storage devices immediately */
- usb_stor_curr_dev = usb_stor_scan(1);
-#endif
-#ifdef CONFIG_USB_HOST_ETHER
- /* try to recognize ethernet devices immediately */
- usb_ether_curr_dev = usb_host_eth_scan(1);
-#endif
-#ifdef CONFIG_USB_KEYBOARD
- drv_usb_kbd_init();
-#endif
- }
+ do_usb_start();
return 0;
}
if (strncmp(argv[1], "stop", 4) == 0) {
diff --git a/common/console.c b/common/console.c
index 29560c3..fc1963b 100644
--- a/common/console.c
+++ b/common/console.c
@@ -199,6 +199,20 @@ static void console_putc(int file, const char c)
}
}
+#ifdef CONFIG_PRE_CONSOLE_BUFFER
+static void console_putc_noserial(int file, const char c)
+{
+ int i;
+ struct stdio_dev *dev;
+
+ for (i = 0; i < cd_count[file]; i++) {
+ dev = console_devices[file][i];
+ if (dev->putc != NULL && strcmp(dev->name, "serial") != 0)
+ dev->putc(dev, c);
+ }
+}
+#endif
+
static void console_puts(int file, const char *s)
{
int i;
@@ -236,6 +250,14 @@ static inline void console_putc(int file, const char c)
stdio_devices[file]->putc(stdio_devices[file], c);
}
+#ifdef CONFIG_PRE_CONSOLE_BUFFER
+static inline void console_putc_noserial(int file, const char c)
+{
+ if (strcmp(stdio_devices[file]->name, "serial") != 0)
+ stdio_devices[file]->putc(stdio_devices[file], c);
+}
+#endif
+
static inline void console_puts(int file, const char *s)
{
stdio_devices[file]->puts(stdio_devices[file], s);
@@ -382,6 +404,9 @@ int tstc(void)
return serial_tstc();
}
+#define PRE_CONSOLE_FLUSHPOINT1_SERIAL 0
+#define PRE_CONSOLE_FLUSHPOINT2_EVERYTHING_BUT_SERIAL 1
+
#ifdef CONFIG_PRE_CONSOLE_BUFFER
#define CIRC_BUF_IDX(idx) ((idx) % (unsigned long)CONFIG_PRE_CON_BUF_SZ)
@@ -398,7 +423,7 @@ static void pre_console_puts(const char *s)
pre_console_putc(*s++);
}
-static void print_pre_console_buffer(void)
+static void print_pre_console_buffer(int flushpoint)
{
unsigned long i = 0;
char *buffer = (char *)CONFIG_PRE_CON_BUF_ADDR;
@@ -407,12 +432,20 @@ static void print_pre_console_buffer(void)
i = gd->precon_buf_idx - CONFIG_PRE_CON_BUF_SZ;
while (i < gd->precon_buf_idx)
- putc(buffer[CIRC_BUF_IDX(i++)]);
+ switch (flushpoint) {
+ case PRE_CONSOLE_FLUSHPOINT1_SERIAL:
+ putc(buffer[CIRC_BUF_IDX(i++)]);
+ break;
+ case PRE_CONSOLE_FLUSHPOINT2_EVERYTHING_BUT_SERIAL:
+ console_putc_noserial(stdout,
+ buffer[CIRC_BUF_IDX(i++)]);
+ break;
+ }
}
#else
static inline void pre_console_putc(const char c) {}
static inline void pre_console_puts(const char *s) {}
-static inline void print_pre_console_buffer(void) {}
+static inline void print_pre_console_buffer(int flushpoint) {}
#endif
void putc(const char c)
@@ -441,6 +474,7 @@ void putc(const char c)
fputc(stdout, c);
} else {
/* Send directly to the handler */
+ pre_console_putc(c);
serial_putc(c);
}
}
@@ -472,6 +506,7 @@ void puts(const char *s)
fputs(stdout, s);
} else {
/* Send directly to the handler */
+ pre_console_puts(s);
serial_puts(s);
}
}
@@ -679,7 +714,7 @@ int console_init_f(void)
gd->flags |= GD_FLG_SILENT;
#endif
- print_pre_console_buffer();
+ print_pre_console_buffer(PRE_CONSOLE_FLUSHPOINT1_SERIAL);
return 0;
}
@@ -794,6 +829,7 @@ done:
if ((stdio_devices[stdin] == NULL) && (stdio_devices[stdout] == NULL))
return 0;
#endif
+ print_pre_console_buffer(PRE_CONSOLE_FLUSHPOINT2_EVERYTHING_BUT_SERIAL);
return 0;
}
@@ -869,7 +905,7 @@ int console_init_r(void)
if ((stdio_devices[stdin] == NULL) && (stdio_devices[stdout] == NULL))
return 0;
#endif
-
+ print_pre_console_buffer(PRE_CONSOLE_FLUSHPOINT2_EVERYTHING_BUT_SERIAL);
return 0;
}
diff --git a/common/edid.c b/common/edid.c
index e66108f..df797fc 100644
--- a/common/edid.c
+++ b/common/edid.c
@@ -12,6 +12,7 @@
#include <common.h>
#include <edid.h>
+#include <errno.h>
#include <linux/ctype.h>
#include <linux/string.h>
@@ -29,6 +30,17 @@ int edid_check_info(struct edid1_info *edid_info)
return 0;
}
+int edid_check_checksum(u8 *edid_block)
+{
+ u8 checksum = 0;
+ int i;
+
+ for (i = 0; i < 128; i++)
+ checksum += edid_block[i];
+
+ return (checksum == 0) ? 0 : -EINVAL;
+}
+
int edid_get_ranges(struct edid1_info *edid, unsigned int *hmin,
unsigned int *hmax, unsigned int *vmin,
unsigned int *vmax)
diff --git a/common/image-fit.c b/common/image-fit.c
index 4ffc5aa..1589ee3 100644
--- a/common/image-fit.c
+++ b/common/image-fit.c
@@ -1518,6 +1518,7 @@ int fit_image_load(bootm_headers_t *images, ulong addr,
size_t size;
int type_ok, os_ok;
ulong load, data, len;
+ uint8_t os;
const char *prop_name;
int ret;
@@ -1612,10 +1613,15 @@ int fit_image_load(bootm_headers_t *images, ulong addr,
(image_type == IH_TYPE_KERNEL &&
fit_image_check_type(fit, noffset,
IH_TYPE_KERNEL_NOLOAD));
+
os_ok = image_type == IH_TYPE_FLATDT ||
- fit_image_check_os(fit, noffset, IH_OS_LINUX);
+ fit_image_check_os(fit, noffset, IH_OS_LINUX) ||
+ fit_image_check_os(fit, noffset, IH_OS_OPENRTOS);
if (!type_ok || !os_ok) {
- printf("No Linux %s %s Image\n", genimg_get_arch_name(arch),
+ fit_image_get_os(fit, noffset, &os);
+ printf("No %s %s %s Image\n",
+ genimg_get_os_name(os),
+ genimg_get_arch_name(arch),
genimg_get_type_name(image_type));
bootstage_error(bootstage_id + BOOTSTAGE_SUB_CHECK_ALL);
return -EIO;
diff --git a/common/image.c b/common/image.c
index e691a51..ad7a46d 100644
--- a/common/image.c
+++ b/common/image.c
@@ -120,6 +120,10 @@ static const table_entry_t uimage_os[] = {
{ IH_OS_SOLARIS, "solaris", "Solaris", },
{ IH_OS_SVR4, "svr4", "SVR4", },
#endif
+#if defined(CONFIG_BOOTM_OPENRTOS) || defined(USE_HOSTCC)
+ { IH_OS_OPENRTOS, "openrtos", "OpenRTOS", },
+#endif
+
{ -1, "", "", },
};
diff --git a/common/lcd.c b/common/lcd.c
index 3ed504d..cc34b8a 100644
--- a/common/lcd.c
+++ b/common/lcd.c
@@ -73,45 +73,13 @@
#define CONFIG_LCD_ALIGNMENT PAGE_SIZE
#endif
-/* By default we scroll by a single line */
-#ifndef CONFIG_CONSOLE_SCROLL_LINES
-#define CONFIG_CONSOLE_SCROLL_LINES 1
-#endif
-
-/************************************************************************/
-/* ** CONSOLE DEFINITIONS & FUNCTIONS */
-/************************************************************************/
-#if defined(CONFIG_LCD_LOGO) && !defined(CONFIG_LCD_INFO_BELOW_LOGO)
-# define CONSOLE_ROWS ((panel_info.vl_row-BMP_LOGO_HEIGHT) \
- / VIDEO_FONT_HEIGHT)
-#else
-# define CONSOLE_ROWS (panel_info.vl_row / VIDEO_FONT_HEIGHT)
-#endif
-
-#define CONSOLE_COLS (panel_info.vl_col / VIDEO_FONT_WIDTH)
-#define CONSOLE_ROW_SIZE (VIDEO_FONT_HEIGHT * lcd_line_length)
-#define CONSOLE_ROW_FIRST lcd_console_address
-#define CONSOLE_ROW_SECOND (lcd_console_address + CONSOLE_ROW_SIZE)
-#define CONSOLE_ROW_LAST (lcd_console_address + CONSOLE_SIZE \
- - CONSOLE_ROW_SIZE)
-#define CONSOLE_SIZE (CONSOLE_ROW_SIZE * CONSOLE_ROWS)
-#define CONSOLE_SCROLL_SIZE (CONSOLE_SIZE - CONSOLE_ROW_SIZE)
-
-#if LCD_BPP == LCD_MONOCHROME
-# define COLOR_MASK(c) ((c) | (c) << 1 | (c) << 2 | (c) << 3 | \
- (c) << 4 | (c) << 5 | (c) << 6 | (c) << 7)
-#elif (LCD_BPP == LCD_COLOR8) || (LCD_BPP == LCD_COLOR16) || \
- (LCD_BPP == LCD_COLOR32)
-# define COLOR_MASK(c) (c)
-#else
+#if (LCD_BPP != LCD_COLOR8) && (LCD_BPP != LCD_COLOR16) && \
+ (LCD_BPP != LCD_COLOR32)
# error Unsupported LCD BPP.
#endif
DECLARE_GLOBAL_DATA_PTR;
-static void lcd_drawchars(ushort x, ushort y, uchar *str, int count);
-static inline void lcd_putc_xy(ushort x, ushort y, uchar c);
-
static int lcd_init(void *lcdbase);
static void *lcd_logo(void);
@@ -125,10 +93,6 @@ int lcd_line_length;
char lcd_is_enabled = 0;
-static short console_col;
-static short console_row;
-
-static void *lcd_console_address;
static void *lcd_base; /* Start of framebuffer memory */
static char lcd_flush_dcache; /* 1 to flush dcache after each lcd update */
@@ -166,217 +130,16 @@ void lcd_set_flush_dcache(int flush)
/*----------------------------------------------------------------------*/
-static void console_scrollup(void)
-{
- const int rows = CONFIG_CONSOLE_SCROLL_LINES;
-
- /* Copy up rows ignoring those that will be overwritten */
- memcpy(CONSOLE_ROW_FIRST,
- lcd_console_address + CONSOLE_ROW_SIZE * rows,
- CONSOLE_SIZE - CONSOLE_ROW_SIZE * rows);
-
- /* Clear the last rows */
-#if (LCD_BPP != LCD_COLOR32)
- memset(lcd_console_address + CONSOLE_SIZE - CONSOLE_ROW_SIZE * rows,
- COLOR_MASK(lcd_color_bg),
- CONSOLE_ROW_SIZE * rows);
-#else
- u32 *ppix = lcd_console_address +
- CONSOLE_SIZE - CONSOLE_ROW_SIZE * rows;
- u32 i;
- for (i = 0;
- i < (CONSOLE_ROW_SIZE * rows) / NBYTES(panel_info.vl_bpix);
- i++) {
- *ppix++ = COLOR_MASK(lcd_color_bg);
- }
-#endif
- lcd_sync();
- console_row -= rows;
-}
-
-/*----------------------------------------------------------------------*/
-
-static inline void console_back(void)
-{
- if (--console_col < 0) {
- console_col = CONSOLE_COLS-1 ;
- if (--console_row < 0)
- console_row = 0;
- }
-
- lcd_putc_xy(console_col * VIDEO_FONT_WIDTH,
- console_row * VIDEO_FONT_HEIGHT, ' ');
-}
-
-/*----------------------------------------------------------------------*/
-
-static inline void console_newline(void)
-{
- console_col = 0;
-
- /* Check if we need to scroll the terminal */
- if (++console_row >= CONSOLE_ROWS)
- console_scrollup();
- else
- lcd_sync();
-}
-
-/*----------------------------------------------------------------------*/
-
static void lcd_stub_putc(struct stdio_dev *dev, const char c)
{
lcd_putc(c);
}
-void lcd_putc(const char c)
-{
- if (!lcd_is_enabled) {
- serial_putc(c);
-
- return;
- }
-
- switch (c) {
- case '\r':
- console_col = 0;
-
- return;
- case '\n':
- console_newline();
-
- return;
- case '\t': /* Tab (8 chars alignment) */
- console_col += 8;
- console_col &= ~7;
-
- if (console_col >= CONSOLE_COLS)
- console_newline();
-
- return;
- case '\b':
- console_back();
-
- return;
- default:
- lcd_putc_xy(console_col * VIDEO_FONT_WIDTH,
- console_row * VIDEO_FONT_HEIGHT, c);
- if (++console_col >= CONSOLE_COLS)
- console_newline();
- }
-}
-
-/*----------------------------------------------------------------------*/
-
static void lcd_stub_puts(struct stdio_dev *dev, const char *s)
{
lcd_puts(s);
}
-void lcd_puts(const char *s)
-{
- if (!lcd_is_enabled) {
- serial_puts(s);
-
- return;
- }
-
- while (*s)
- lcd_putc(*s++);
-
- lcd_sync();
-}
-
-/*----------------------------------------------------------------------*/
-
-void lcd_printf(const char *fmt, ...)
-{
- va_list args;
- char buf[CONFIG_SYS_PBSIZE];
-
- va_start(args, fmt);
- vsprintf(buf, fmt, args);
- va_end(args);
-
- lcd_puts(buf);
-}
-
-/************************************************************************/
-/* ** Low-Level Graphics Routines */
-/************************************************************************/
-
-static void lcd_drawchars(ushort x, ushort y, uchar *str, int count)
-{
- uchar *dest;
- ushort row;
-
-#if defined(CONFIG_LCD_LOGO) && !defined(CONFIG_LCD_INFO_BELOW_LOGO)
- y += BMP_LOGO_HEIGHT;
-#endif
-
-#if LCD_BPP == LCD_MONOCHROME
- ushort off = x * (1 << LCD_BPP) % 8;
-#endif
-
- dest = (uchar *)(lcd_base + y * lcd_line_length + x * NBITS(LCD_BPP)/8);
-
- for (row = 0; row < VIDEO_FONT_HEIGHT; ++row, dest += lcd_line_length) {
- uchar *s = str;
- int i;
-#if LCD_BPP == LCD_COLOR16
- ushort *d = (ushort *)dest;
-#elif LCD_BPP == LCD_COLOR32
- u32 *d = (u32 *)dest;
-#else
- uchar *d = dest;
-#endif
-
-#if LCD_BPP == LCD_MONOCHROME
- uchar rest = *d & -(1 << (8 - off));
- uchar sym;
-#endif
- for (i = 0; i < count; ++i) {
- uchar c, bits;
-
- c = *s++;
- bits = video_fontdata[c * VIDEO_FONT_HEIGHT + row];
-
-#if LCD_BPP == LCD_MONOCHROME
- sym = (COLOR_MASK(lcd_color_fg) & bits) |
- (COLOR_MASK(lcd_color_bg) & ~bits);
-
- *d++ = rest | (sym >> off);
- rest = sym << (8-off);
-#elif LCD_BPP == LCD_COLOR8
- for (c = 0; c < 8; ++c) {
- *d++ = (bits & 0x80) ?
- lcd_color_fg : lcd_color_bg;
- bits <<= 1;
- }
-#elif LCD_BPP == LCD_COLOR16
- for (c = 0; c < 8; ++c) {
- *d++ = (bits & 0x80) ?
- lcd_color_fg : lcd_color_bg;
- bits <<= 1;
- }
-#elif LCD_BPP == LCD_COLOR32
- for (c = 0; c < 8; ++c) {
- *d++ = (bits & 0x80) ?
- lcd_color_fg : lcd_color_bg;
- bits <<= 1;
- }
-#endif
- }
-#if LCD_BPP == LCD_MONOCHROME
- *d = rest | (*d & ((1 << (8 - off)) - 1));
-#endif
- }
-}
-
-static inline void lcd_putc_xy(ushort x, ushort y, uchar c)
-{
- lcd_drawchars(x, y, &c, 1);
-}
-
/************************************************************************/
/** Small utility to check that you got the colours right */
/************************************************************************/
@@ -455,11 +218,9 @@ int drv_lcd_init(void)
/*----------------------------------------------------------------------*/
void lcd_clear(void)
{
-#if LCD_BPP == LCD_MONOCHROME
- /* Setting the palette */
- lcd_initcolregs();
-
-#elif LCD_BPP == LCD_COLOR8
+ short console_rows, console_cols;
+ int bg_color;
+#if LCD_BPP == LCD_COLOR8
/* Setting the palette */
lcd_setcolreg(CONSOLE_COLOR_BLACK, 0, 0, 0);
lcd_setcolreg(CONSOLE_COLOR_RED, 0xFF, 0, 0);
@@ -475,9 +236,11 @@ void lcd_clear(void)
#ifndef CONFIG_SYS_WHITE_ON_BLACK
lcd_setfgcolor(CONSOLE_COLOR_BLACK);
lcd_setbgcolor(CONSOLE_COLOR_WHITE);
+ bg_color = CONSOLE_COLOR_WHITE;
#else
lcd_setfgcolor(CONSOLE_COLOR_WHITE);
lcd_setbgcolor(CONSOLE_COLOR_BLACK);
+ bg_color = CONSOLE_COLOR_BLACK;
#endif /* CONFIG_SYS_WHITE_ON_BLACK */
#ifdef LCD_TEST_PATTERN
@@ -485,25 +248,27 @@ void lcd_clear(void)
#else
/* set framebuffer to background color */
#if (LCD_BPP != LCD_COLOR32)
- memset((char *)lcd_base,
- COLOR_MASK(lcd_color_bg),
- lcd_line_length * panel_info.vl_row);
+ memset((char *)lcd_base, bg_color, lcd_line_length * panel_info.vl_row);
#else
u32 *ppix = lcd_base;
u32 i;
for (i = 0;
i < (lcd_line_length * panel_info.vl_row)/NBYTES(panel_info.vl_bpix);
i++) {
- *ppix++ = COLOR_MASK(lcd_color_bg);
+ *ppix++ = bg_color;
}
#endif
#endif
/* Paint the logo and retrieve LCD base address */
debug("[LCD] Drawing the logo...\n");
- lcd_console_address = lcd_logo();
-
- console_col = 0;
- console_row = 0;
+#if defined(CONFIG_LCD_LOGO) && !defined(CONFIG_LCD_INFO_BELOW_LOGO)
+ console_rows = (panel_info.vl_row - BMP_LOGO_HEIGHT);
+ console_rows /= VIDEO_FONT_HEIGHT;
+#else
+ console_rows = panel_info.vl_row / VIDEO_FONT_HEIGHT;
+#endif
+ console_cols = panel_info.vl_col / VIDEO_FONT_WIDTH;
+ lcd_init_console(lcd_logo(), console_rows, console_cols);
lcd_sync();
}
@@ -546,11 +311,11 @@ static int lcd_init(void *lcdbase)
lcd_enable();
/* Initialize the console */
- console_col = 0;
+ lcd_set_col(0);
#ifdef CONFIG_LCD_INFO_BELOW_LOGO
- console_row = 7 + BMP_LOGO_HEIGHT / VIDEO_FONT_HEIGHT;
+ lcd_set_row(7 + BMP_LOGO_HEIGHT / VIDEO_FONT_HEIGHT);
#else
- console_row = 1; /* leave 1 blank line below logo */
+ lcd_set_row(1); /* leave 1 blank line below logo */
#endif
return 0;
@@ -597,6 +362,11 @@ static void lcd_setfgcolor(int color)
lcd_color_fg = color;
}
+int lcd_getfgcolor(void)
+{
+ return lcd_color_fg;
+}
+
/*----------------------------------------------------------------------*/
static void lcd_setbgcolor(int color)
@@ -604,6 +374,11 @@ static void lcd_setbgcolor(int color)
lcd_color_bg = color;
}
+int lcd_getbgcolor(void)
+{
+ return lcd_color_bg;
+}
+
/************************************************************************/
/* ** Chipset depending Bitmap / Logo stuff... */
/************************************************************************/
@@ -685,11 +460,7 @@ void bitmap_plot(int x, int y)
*(cmap + BMP_LOGO_OFFSET) = lut_entry;
cmap++;
#else /* !CONFIG_ATMEL_LCD */
-#ifdef CONFIG_SYS_INVERT_COLORS
- *cmap++ = 0xffff - colreg;
-#else
*cmap++ = colreg;
-#endif
#endif /* CONFIG_ATMEL_LCD */
}
@@ -967,11 +738,7 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y)
( ((cte.red) << 8) & 0xf800) |
( ((cte.green) << 3) & 0x07e0) |
( ((cte.blue) >> 3) & 0x001f) ;
-#ifdef CONFIG_SYS_INVERT_COLORS
- *cmap = 0xffff - colreg;
-#else
*cmap = colreg;
-#endif
#if defined(CONFIG_MPC823)
cmap--;
#else
@@ -1108,8 +875,8 @@ static void *lcd_logo(void)
bitmap_plot(0, 0);
#ifdef CONFIG_LCD_INFO
- console_col = LCD_INFO_X / VIDEO_FONT_WIDTH;
- console_row = LCD_INFO_Y / VIDEO_FONT_HEIGHT;
+ lcd_set_col(LCD_INFO_X / VIDEO_FONT_WIDTH);
+ lcd_set_row(LCD_INFO_Y / VIDEO_FONT_HEIGHT);
lcd_show_board_info();
#endif /* CONFIG_LCD_INFO */
@@ -1144,12 +911,6 @@ static int on_splashimage(const char *name, const char *value, enum env_op op,
U_BOOT_ENV_CALLBACK(splashimage, on_splashimage);
#endif
-void lcd_position_cursor(unsigned col, unsigned row)
-{
- console_col = min_t(short, col, CONSOLE_COLS - 1);
- console_row = min_t(short, row, CONSOLE_ROWS - 1);
-}
-
int lcd_get_pixel_width(void)
{
return panel_info.vl_col;
@@ -1160,16 +921,6 @@ int lcd_get_pixel_height(void)
return panel_info.vl_row;
}
-int lcd_get_screen_rows(void)
-{
- return CONSOLE_ROWS;
-}
-
-int lcd_get_screen_columns(void)
-{
- return CONSOLE_COLS;
-}
-
#if defined(CONFIG_LCD_DT_SIMPLEFB)
static int lcd_dt_simplefb_configure_node(void *blob, int off)
{
diff --git a/common/lcd_console.c b/common/lcd_console.c
new file mode 100644
index 0000000..74c388a
--- /dev/null
+++ b/common/lcd_console.c
@@ -0,0 +1,211 @@
+/*
+ * (C) Copyright 2001-2014
+ * DENX Software Engineering -- wd@denx.de
+ * Compulab Ltd - http://compulab.co.il/
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <lcd.h>
+#include <video_font.h> /* Get font data, width and height */
+
+#define CONSOLE_ROW_SIZE (VIDEO_FONT_HEIGHT * lcd_line_length)
+#define CONSOLE_ROW_FIRST lcd_console_address
+#define CONSOLE_SIZE (CONSOLE_ROW_SIZE * console_rows)
+
+static short console_curr_col;
+static short console_curr_row;
+static short console_cols;
+static short console_rows;
+static void *lcd_console_address;
+
+void lcd_init_console(void *address, int rows, int cols)
+{
+ console_curr_col = 0;
+ console_curr_row = 0;
+ console_cols = cols;
+ console_rows = rows;
+ lcd_console_address = address;
+}
+
+void lcd_set_col(short col)
+{
+ console_curr_col = col;
+}
+
+void lcd_set_row(short row)
+{
+ console_curr_row = row;
+}
+
+void lcd_position_cursor(unsigned col, unsigned row)
+{
+ console_curr_col = min_t(short, col, console_cols - 1);
+ console_curr_row = min_t(short, row, console_rows - 1);
+}
+
+int lcd_get_screen_rows(void)
+{
+ return console_rows;
+}
+
+int lcd_get_screen_columns(void)
+{
+ return console_cols;
+}
+
+static void lcd_drawchars(ushort x, ushort y, uchar *str, int count)
+{
+ uchar *dest;
+ ushort row;
+ int fg_color, bg_color;
+
+ dest = (uchar *)(lcd_console_address +
+ y * lcd_line_length + x * NBITS(LCD_BPP) / 8);
+
+ for (row = 0; row < VIDEO_FONT_HEIGHT; ++row, dest += lcd_line_length) {
+ uchar *s = str;
+ int i;
+#if LCD_BPP == LCD_COLOR16
+ ushort *d = (ushort *)dest;
+#elif LCD_BPP == LCD_COLOR32
+ u32 *d = (u32 *)dest;
+#else
+ uchar *d = dest;
+#endif
+
+ fg_color = lcd_getfgcolor();
+ bg_color = lcd_getbgcolor();
+ for (i = 0; i < count; ++i) {
+ uchar c, bits;
+
+ c = *s++;
+ bits = video_fontdata[c * VIDEO_FONT_HEIGHT + row];
+
+ for (c = 0; c < 8; ++c) {
+ *d++ = (bits & 0x80) ? fg_color : bg_color;
+ bits <<= 1;
+ }
+ }
+ }
+}
+
+static inline void lcd_putc_xy(ushort x, ushort y, uchar c)
+{
+ lcd_drawchars(x, y, &c, 1);
+}
+
+static void console_scrollup(void)
+{
+ const int rows = CONFIG_CONSOLE_SCROLL_LINES;
+ int bg_color = lcd_getbgcolor();
+
+ /* Copy up rows ignoring those that will be overwritten */
+ memcpy(CONSOLE_ROW_FIRST,
+ lcd_console_address + CONSOLE_ROW_SIZE * rows,
+ CONSOLE_SIZE - CONSOLE_ROW_SIZE * rows);
+
+ /* Clear the last rows */
+#if (LCD_BPP != LCD_COLOR32)
+ memset(lcd_console_address + CONSOLE_SIZE - CONSOLE_ROW_SIZE * rows,
+ bg_color, CONSOLE_ROW_SIZE * rows);
+#else
+ u32 *ppix = lcd_console_address +
+ CONSOLE_SIZE - CONSOLE_ROW_SIZE * rows;
+ u32 i;
+ for (i = 0;
+ i < (CONSOLE_ROW_SIZE * rows) / NBYTES(panel_info.vl_bpix);
+ i++) {
+ *ppix++ = bg_color;
+ }
+#endif
+ lcd_sync();
+ console_curr_row -= rows;
+}
+
+static inline void console_back(void)
+{
+ if (--console_curr_col < 0) {
+ console_curr_col = console_cols - 1;
+ if (--console_curr_row < 0)
+ console_curr_row = 0;
+ }
+
+ lcd_putc_xy(console_curr_col * VIDEO_FONT_WIDTH,
+ console_curr_row * VIDEO_FONT_HEIGHT, ' ');
+}
+
+static inline void console_newline(void)
+{
+ console_curr_col = 0;
+
+ /* Check if we need to scroll the terminal */
+ if (++console_curr_row >= console_rows)
+ console_scrollup();
+ else
+ lcd_sync();
+}
+
+void lcd_putc(const char c)
+{
+ if (!lcd_is_enabled) {
+ serial_putc(c);
+
+ return;
+ }
+
+ switch (c) {
+ case '\r':
+ console_curr_col = 0;
+
+ return;
+ case '\n':
+ console_newline();
+
+ return;
+ case '\t': /* Tab (8 chars alignment) */
+ console_curr_col += 8;
+ console_curr_col &= ~7;
+
+ if (console_curr_col >= console_cols)
+ console_newline();
+
+ return;
+ case '\b':
+ console_back();
+
+ return;
+ default:
+ lcd_putc_xy(console_curr_col * VIDEO_FONT_WIDTH,
+ console_curr_row * VIDEO_FONT_HEIGHT, c);
+ if (++console_curr_col >= console_cols)
+ console_newline();
+ }
+}
+
+void lcd_puts(const char *s)
+{
+ if (!lcd_is_enabled) {
+ serial_puts(s);
+
+ return;
+ }
+
+ while (*s)
+ lcd_putc(*s++);
+
+ lcd_sync();
+}
+
+void lcd_printf(const char *fmt, ...)
+{
+ va_list args;
+ char buf[CONFIG_SYS_PBSIZE];
+
+ va_start(args, fmt);
+ vsprintf(buf, fmt, args);
+ va_end(args);
+
+ lcd_puts(buf);
+}
diff --git a/common/memsize.c b/common/memsize.c
index 589400d..0fb9ba5 100644
--- a/common/memsize.c
+++ b/common/memsize.c
@@ -33,43 +33,46 @@ long get_ram_size(long *base, long maxsize)
long size;
int i = 0;
- for (cnt = (maxsize / sizeof (long)) >> 1; cnt > 0; cnt >>= 1) {
+ for (cnt = (maxsize / sizeof(long)) >> 1; cnt > 0; cnt >>= 1) {
addr = base + cnt; /* pointer arith! */
- sync ();
+ sync();
save[i++] = *addr;
- sync ();
+ sync();
*addr = ~cnt;
}
addr = base;
- sync ();
+ sync();
save[i] = *addr;
- sync ();
+ sync();
*addr = 0;
- sync ();
+ sync();
if ((val = *addr) != 0) {
- /* Restore the original data before leaving the function.
- */
- sync ();
+ /* Restore the original data before leaving the function. */
+ sync();
*addr = save[i];
for (cnt = 1; cnt < maxsize / sizeof(long); cnt <<= 1) {
addr = base + cnt;
- sync ();
+ sync();
*addr = save[--i];
}
return (0);
}
- for (cnt = 1; cnt < maxsize / sizeof (long); cnt <<= 1) {
+ for (cnt = 1; cnt < maxsize / sizeof(long); cnt <<= 1) {
addr = base + cnt; /* pointer arith! */
val = *addr;
*addr = save[--i];
if (val != ~cnt) {
- size = cnt * sizeof (long);
- /* Restore the original data before leaving the function.
+ size = cnt * sizeof(long);
+ /*
+ * Restore the original data
+ * before leaving the function.
*/
- for (cnt <<= 1; cnt < maxsize / sizeof (long); cnt <<= 1) {
+ for (cnt <<= 1;
+ cnt < maxsize / sizeof(long);
+ cnt <<= 1) {
addr = base + cnt;
*addr = save[--i];
}
diff --git a/common/spl/spl_nor.c b/common/spl/spl_nor.c
index b444a3e..2c0e8e0 100644
--- a/common/spl/spl_nor.c
+++ b/common/spl/spl_nor.c
@@ -15,37 +15,51 @@ void spl_nor_load_image(void)
*/
spl_image.flags |= SPL_COPY_PAYLOAD_ONLY;
- if (spl_start_uboot()) {
- /*
- * Load real U-Boot from its location in NOR flash to its
- * defined location in SDRAM
- */
- spl_parse_image_header(
- (const struct image_header *)CONFIG_SYS_UBOOT_BASE);
+#ifdef CONFIG_SPL_OS_BOOT
+ if (!spl_start_uboot()) {
+ struct image_header *header;
- memcpy((void *)spl_image.load_addr,
- (void *)(CONFIG_SYS_UBOOT_BASE +
- sizeof(struct image_header)),
- spl_image.size);
- } else {
/*
* Load Linux from its location in NOR flash to its defined
* location in SDRAM
*/
- spl_parse_image_header(
- (const struct image_header *)CONFIG_SYS_OS_BASE);
+ header = (const struct image_header *)CONFIG_SYS_OS_BASE;
- memcpy((void *)spl_image.load_addr,
- (void *)(CONFIG_SYS_OS_BASE +
- sizeof(struct image_header)),
- spl_image.size);
+ if (image_get_os(header) == IH_OS_LINUX) {
+ /* happy - was a Linux */
- /*
- * Copy DT blob (fdt) to SDRAM. Passing pointer to flash
- * doesn't work (16 KiB should be enough for DT)
- */
- memcpy((void *)CONFIG_SYS_SPL_ARGS_ADDR,
- (void *)(CONFIG_SYS_FDT_BASE),
- (16 << 10));
+ spl_parse_image_header(header);
+
+ memcpy((void *)spl_image.load_addr,
+ (void *)(CONFIG_SYS_OS_BASE +
+ sizeof(struct image_header)),
+ spl_image.size);
+
+ /*
+ * Copy DT blob (fdt) to SDRAM. Passing pointer to
+ * flash doesn't work (16 KiB should be enough for DT)
+ */
+ memcpy((void *)CONFIG_SYS_SPL_ARGS_ADDR,
+ (void *)(CONFIG_SYS_FDT_BASE),
+ (16 << 10));
+
+ return;
+ } else {
+ puts("The Expected Linux image was not found.\n"
+ "Please check your NOR configuration.\n"
+ "Trying to start u-boot now...\n");
+ }
}
+#endif
+
+ /*
+ * Load real U-Boot from its location in NOR flash to its
+ * defined location in SDRAM
+ */
+ spl_parse_image_header(
+ (const struct image_header *)CONFIG_SYS_UBOOT_BASE);
+
+ memcpy((void *)spl_image.load_addr,
+ (void *)(CONFIG_SYS_UBOOT_BASE + sizeof(struct image_header)),
+ spl_image.size);
}
diff --git a/common/usb.c b/common/usb.c
index 736cd9f..32e15cd 100644
--- a/common/usb.c
+++ b/common/usb.c
@@ -59,6 +59,7 @@ int usb_init(void)
void *ctrl;
struct usb_device *dev;
int i, start_index = 0;
+ int controllers_initialized = 0;
int ret;
dev_index = 0;
@@ -78,6 +79,7 @@ int usb_init(void)
ret = usb_lowlevel_init(i, USB_INIT_HOST, &ctrl);
if (ret == -ENODEV) { /* No such device. */
puts("Port not available.\n");
+ controllers_initialized++;
continue;
}
@@ -89,6 +91,7 @@ int usb_init(void)
* lowlevel init is OK, now scan the bus for devices
* i.e. search HUBs and configure them
*/
+ controllers_initialized++;
start_index = dev_index;
printf("scanning bus %d for devices... ", i);
dev = usb_alloc_new_device(ctrl);
@@ -110,12 +113,10 @@ int usb_init(void)
debug("scan end\n");
/* if we were not able to find at least one working bus, bail out */
- if (!usb_started) {
+ if (controllers_initialized == 0)
puts("USB error: all controllers failed lowlevel init\n");
- return -1;
- }
- return 0;
+ return usb_started ? 0 : -1;
}
/******************************************************************************
@@ -969,6 +970,8 @@ int usb_new_device(struct usb_device *dev)
printf("\n Couldn't reset port %i\n", dev->portnr);
return 1;
}
+ } else {
+ usb_reset_root_port();
}
#endif
diff --git a/common/usb_kbd.c b/common/usb_kbd.c
index bc7145e..ecc3085 100644
--- a/common/usb_kbd.c
+++ b/common/usb_kbd.c
@@ -332,7 +332,8 @@ static inline void usb_kbd_poll_for_event(struct usb_device *dev)
/* We've consumed all queued int packets, create new */
destroy_int_queue(dev, data->intq);
data->intq = create_int_queue(dev, data->intpipe, 1,
- USB_KBD_BOOT_REPORT_SIZE, data->new);
+ USB_KBD_BOOT_REPORT_SIZE, data->new,
+ data->intinterval);
}
#endif
}
@@ -453,7 +454,8 @@ static int usb_kbd_probe(struct usb_device *dev, unsigned int ifnum)
debug("USB KBD: enable interrupt pipe...\n");
#ifdef CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE
data->intq = create_int_queue(dev, data->intpipe, 1,
- USB_KBD_BOOT_REPORT_SIZE, data->new);
+ USB_KBD_BOOT_REPORT_SIZE, data->new,
+ data->intinterval);
if (!data->intq) {
#else
if (usb_submit_int_msg(dev, data->intpipe, data->new, data->intpktsize,
@@ -542,6 +544,10 @@ int usb_kbd_deregister(int force)
data = usb_kbd_dev->privptr;
if (stdio_deregister_dev(dev, force) != 0)
return 1;
+#ifdef CONFIG_CONSOLE_MUX
+ if (iomux_doenv(stdin, getenv("stdin")) != 0)
+ return 1;
+#endif
#ifdef CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE
destroy_int_queue(usb_kbd_dev, data->intq);
#endif