X-Git-Url: https://git.kernelconcepts.de/?p=karo-tx-uboot.git;a=blobdiff_plain;f=board%2Fait%2Fcam_enc_4xx%2Fcam_enc_4xx.c;h=290dc1984ab3a9508e2dc3a2b6c0e393838691c3;hp=1351358298718c6bf187bc4edb689e3a0eda0246;hb=e99f30e105a253ee64bef1ef83b86a47e0d3b6f1;hpb=4dd834906dcc8207f82a686e060ffaa7b7ac878f diff --git a/board/ait/cam_enc_4xx/cam_enc_4xx.c b/board/ait/cam_enc_4xx/cam_enc_4xx.c index 1351358298..290dc1984a 100644 --- a/board/ait/cam_enc_4xx/cam_enc_4xx.c +++ b/board/ait/cam_enc_4xx/cam_enc_4xx.c @@ -4,29 +4,19 @@ * Copyright (C) 2011 * Heiko Schocher, DENX Software Engineering, hs@denx.de. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * SPDX-License-Identifier: GPL-2.0+ */ #include +#include +#include #include #include #include #include #include #include -#include +#include #include #ifdef CONFIG_DAVINCI_MMC #include @@ -36,21 +26,6 @@ DECLARE_GLOBAL_DATA_PTR; #ifndef CONFIG_SPL_BUILD -int dram_init(void) -{ - /* dram_init must store complete ramsize in gd->ram_size */ - gd->ram_size = get_ram_size( - (void *)CONFIG_SYS_SDRAM_BASE, - CONFIG_MAX_RAM_BANK_SIZE); - return 0; -} - -void dram_init_banksize(void) -{ - gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE; - gd->bd->bi_dram[0].size = gd->ram_size; -} - static struct davinci_timer *timer = (struct davinci_timer *)DAVINCI_TIMER3_BASE; @@ -61,6 +36,12 @@ static unsigned long get_timer_val(void) return now; } +static int timer_running(void) +{ + return readl(&timer->tcr) & + (DV_TIMER_TCR_ENAMODE_MASK << DV_TIMER_TCR_ENAMODE34_SHIFT); +} + static void stop_timer(void) { writel(0x0, &timer->tcr); @@ -81,8 +62,43 @@ int board_init(void) } #ifdef CONFIG_DRIVER_TI_EMAC +static int cam_enc_4xx_check_network(void) +{ + char *s; + + s = getenv("ethaddr"); + if (!s) + return -EINVAL; + + if (!is_valid_ether_addr((const u8 *)s)) + return -EINVAL; + + s = getenv("ipaddr"); + if (!s) + return -EINVAL; + + s = getenv("netmask"); + if (!s) + return -EINVAL; + + s = getenv("serverip"); + if (!s) + return -EINVAL; + + s = getenv("gatewayip"); + if (!s) + return -EINVAL; + + return 0; +} int board_eth_init(bd_t *bis) { + int ret; + + ret = cam_enc_4xx_check_network(); + if (ret) + return ret; + davinci_emac_initialize(); return 0; @@ -92,7 +108,7 @@ int board_eth_init(bd_t *bis) #ifdef CONFIG_NAND_DAVINCI static int davinci_std_read_page_syndrome(struct mtd_info *mtd, struct nand_chip *chip, - uint8_t *buf, int page) + uint8_t *buf, int oob_required, int page) { struct nand_chip *this = mtd->priv; int i, eccsize = chip->ecc.size; @@ -139,8 +155,9 @@ davinci_std_read_page_syndrome(struct mtd_info *mtd, struct nand_chip *chip, return 0; } -static void davinci_std_write_page_syndrome(struct mtd_info *mtd, - struct nand_chip *chip, const uint8_t *buf) +static int davinci_std_write_page_syndrome(struct mtd_info *mtd, + struct nand_chip *chip, const uint8_t *buf, + int oob_required) { unsigned char davinci_ecc_buf[NAND_MAX_OOBSIZE]; struct nand_chip *this = mtd->priv; @@ -190,6 +207,7 @@ static void davinci_std_write_page_syndrome(struct mtd_info *mtd, i = mtd->oobsize - (oob - chip->oob_poi); if (i) chip->write_buf(mtd, oob, i); + return 0; } static int davinci_std_write_oob_syndrome(struct mtd_info *mtd, @@ -211,7 +229,7 @@ static int davinci_std_write_oob_syndrome(struct mtd_info *mtd, } static int davinci_std_read_oob_syndrome(struct mtd_info *mtd, - struct nand_chip *chip, int page, int sndcmd) + struct nand_chip *chip, int page) { struct nand_chip *this = mtd->priv; uint8_t *buf = chip->oob_poi; @@ -221,7 +239,7 @@ static int davinci_std_read_oob_syndrome(struct mtd_info *mtd, chip->read_buf(mtd, bufpoi, mtd->oobsize); - return 1; + return 0; } static void nand_dm365evm_select_chip(struct mtd_info *mtd, int chip) @@ -269,8 +287,11 @@ static int nand_switch_hw_func(int mode) nand = mtd->priv; if (mode == 0) { - printf("switching to uboot hw functions.\n"); - memcpy(&nand->ecc, &org_ecc, sizeof(struct nand_ecc_ctrl)); + if (notsaved == 0) { + printf("switching to uboot hw functions.\n"); + memcpy(&nand->ecc, &org_ecc, + sizeof(struct nand_ecc_ctrl)); + } } else { /* RBL */ printf("switching to RBL hw functions.\n"); @@ -344,7 +365,8 @@ int board_late_init(void) struct davinci_gpio *gpio = davinci_gpio_bank45; /* 24MHz InputClock / 15 prediv -> 1.6 MHz timer running */ - while (get_timer_val() < 0x186a00) + while ((get_timer_val() < CONFIG_AIT_TIMER_TIMEOUT) && + timer_running()) ; /* 1 sec reached -> stop timer, clear all LED */ @@ -444,3 +466,641 @@ void arch_memory_failure_handle(void) ; } #endif +#if defined(CONFIG_MENU) +#include "menu.h" + +#define MENU_EXIT -1 +#define MENU_EXIT_BOOTCMD -2 +#define MENU_STAY 0 +#define MENU_MAIN 1 +#define MENU_UPDATE 2 +#define MENU_NETWORK 3 +#define MENU_LOAD 4 + +static int menu_start; + +#define FIT_SUBTYPE_UNKNOWN 0 +#define FIT_SUBTYPE_UBL_HEADER 1 +#define FIT_SUBTYPE_SPL_IMAGE 2 +#define FIT_SUBTYPE_UBOOT_IMAGE 3 +#define FIT_SUBTYPE_DF_ENV_IMAGE 4 +#define FIT_SUBTYPE_RAMDISK_IMAGE 5 + +struct fit_images_info { + u_int8_t type; + int subtype; + char desc[200]; + const void *data; + size_t size; +}; + +static struct fit_images_info imgs[10]; + +struct menu_display { + char title[50]; + int timeout; /* in sec */ + int id; /* MENU_* */ + char **menulist; + int (*menu_evaluate)(char *choice); +}; + +char *menu_main[] = { + "(1) Boot", + "(2) Update Software", + "(3) Reset to default setting and boot", + "(4) Enter U-Boot console", + NULL +}; + +char *menu_update[] = { + "(1) Network settings", + "(2) load image", + "(3) back to main", + NULL +}; + +char *menu_load[] = { + "(1) install image", + "(2) cancel", + NULL +}; + +char *menu_network[] = { + "(1) ipaddr ", + "(2) netmask ", + "(3) serverip ", + "(4) gatewayip", + "(5) tftp image name", + "(6) back to update software", + NULL +}; + +static void ait_menu_print(void *data) +{ + printf("%s\n", (char *)data); + return; +} + +static char *menu_handle(struct menu_display *display) +{ + struct menu *m; + int i; + void *choice = NULL; + char key[2]; + int ret; + char *s; + char temp[6][200]; + + m = menu_create(display->title, display->timeout, 1, ait_menu_print, + NULL, NULL); + + for (i = 0; display->menulist[i]; i++) { + sprintf(key, "%d", i + 1); + if (display->id == MENU_NETWORK) { + switch (i) { + case 0: + s = getenv("ipaddr"); + break; + case 1: + s = getenv("netmask"); + break; + case 2: + s = getenv("serverip"); + break; + case 3: + s = getenv("gatewayip"); + break; + case 4: + s = getenv("img_file"); + break; + default: + s = NULL; + break; + } + if (s) { + sprintf(temp[i], "%s: %s", + display->menulist[i], s); + ret = menu_item_add(m, key, temp[i]); + } else { + ret = menu_item_add(m, key, + display->menulist[i]); + } + } else { + ret = menu_item_add(m, key, display->menulist[i]); + } + + if (ret != 1) { + printf("failed to add item!"); + menu_destroy(m); + return NULL; + } + } + sprintf(key, "%d", 1); + menu_default_set(m, key); + + if (menu_get_choice(m, &choice) != 1) + debug("Problem picking a choice!\n"); + + menu_destroy(m); + + return choice; +} + +static int ait_menu_show(struct menu_display *display, int bootdelay) +{ + int end = MENU_STAY; + char *choice; + + if ((menu_start == 0) && (display->id == MENU_MAIN)) + display->timeout = bootdelay; + else + display->timeout = 0; + + while (end == MENU_STAY) { + choice = menu_handle(display); + if (choice) + end = display->menu_evaluate(choice); + + if (end == display->id) + end = MENU_STAY; + if (display->id == MENU_MAIN) { + if (menu_start == 0) + end = MENU_EXIT_BOOTCMD; + else + display->timeout = 0; + } + } + return end; +} + +static int ait_writeublheader(void) +{ + char s[20]; + unsigned long i; + int ret; + + for (i = CONFIG_SYS_NAND_BLOCK_SIZE; + i < CONFIG_SYS_NAND_U_BOOT_OFFS; + i += CONFIG_SYS_NAND_BLOCK_SIZE) { + sprintf(s, "%lx", i); + ret = setenv("header_addr", s); + if (ret == 0) + ret = run_command("run img_writeheader", 0); + if (ret != 0) + break; + } + return ret; +} + +static int ait_menu_install_images(void) +{ + int ret = 0; + int count = 0; + char s[100]; + char *t; + + /* + * possible image types: + * FIT_SUBTYPE_UNKNOWN + * FIT_SUBTYPE_UBL_HEADER + * FIT_SUBTYPE_SPL_IMAGE + * FIT_SUBTYPE_UBOOT_IMAGE + * FIT_SUBTYPE_DF_ENV_IMAGE + * FIT_SUBTYPE_RAMDISK_IMAGE + * + * use Envvariables: + * img_addr_r: image start addr + * header_addr: addr where to write to UBL header + * img_writeheader: write ubl header to nand + * img_writespl: write spl to nand + * img_writeuboot: write uboot to nand + * img_writedfenv: write default environment to ubi volume + * img_volume: which ubi volume should be updated with img_writeramdisk + * filesize: size of data for updating ubi volume + * img_writeramdisk: write ramdisk to ubi volume + */ + + while (imgs[count].type != IH_TYPE_INVALID) { + printf("Installing %s\n", + genimg_get_type_name(imgs[count].type)); + sprintf(s, "%p", imgs[count].data); + setenv("img_addr_r", s); + sprintf(s, "%lx", (unsigned long)imgs[count].size); + setenv("filesize", s); + switch (imgs[count].subtype) { + case FIT_SUBTYPE_DF_ENV_IMAGE: + ret = run_command("run img_writedfenv", 0); + break; + case FIT_SUBTYPE_RAMDISK_IMAGE: + t = getenv("img_volume"); + if (!t) { + ret = setenv("img_volume", "rootfs1"); + } else { + /* switch to other volume */ + if (strncmp(t, "rootfs1", 7) == 0) + ret = setenv("img_volume", "rootfs2"); + else + ret = setenv("img_volume", "rootfs1"); + } + if (ret != 0) + break; + + ret = run_command("run img_writeramdisk", 0); + break; + case FIT_SUBTYPE_SPL_IMAGE: + ret = run_command("run img_writespl", 0); + break; + case FIT_SUBTYPE_UBL_HEADER: + ret = ait_writeublheader(); + break; + case FIT_SUBTYPE_UBOOT_IMAGE: + ret = run_command("run img_writeuboot", 0); + break; + default: + /* not supported type */ + break; + } + count++; + } + /* now save dvn_* and img_volume env vars to new values */ + if (ret == 0) { + t = getenv("x_dvn_boot_vers"); + if (t) + setenv("dvn_boot_vers", t); + + t = getenv("x_dvn_app_vers"); + if (t) + setenv("dvn_boot_vers", t); + + setenv("x_dvn_boot_vers", NULL); + setenv("x_dvn_app_vers", NULL); + ret = run_command("run savenewvers", 0); + } + + return ret; +} + +static int ait_menu_evaluate_load(char *choice) +{ + if (!choice) + return -1; + + switch (choice[1]) { + case '1': + /* install image */ + ait_menu_install_images(); + break; + case '2': + /* cancel, back to main */ + setenv("x_dvn_boot_vers", NULL); + setenv("x_dvn_app_vers", NULL); + break; + } + + return MENU_MAIN; +} + +struct menu_display ait_load = { + .title = "AIT load image", + .timeout = 0, + .id = MENU_LOAD, + .menulist = menu_load, + .menu_evaluate = ait_menu_evaluate_load, +}; + +static void ait_menu_read_env(char *name) +{ + char output[CONFIG_SYS_CBSIZE]; + char cbuf[CONFIG_SYS_CBSIZE]; + int readret; + int ret; + + sprintf(output, "%s old: %s value: ", name, getenv(name)); + memset(cbuf, 0, CONFIG_SYS_CBSIZE); + readret = cli_readline_into_buffer(output, cbuf, 0); + + if (readret >= 0) { + ret = setenv(name, cbuf); + if (ret) { + printf("Error setting %s\n", name); + return; + } + } + return; +} + +static int ait_menu_evaluate_network(char *choice) +{ + if (!choice) + return MENU_MAIN; + + switch (choice[1]) { + case '1': + ait_menu_read_env("ipaddr"); + break; + case '2': + ait_menu_read_env("netmask"); + break; + case '3': + ait_menu_read_env("serverip"); + break; + case '4': + ait_menu_read_env("gatewayip"); + break; + case '5': + ait_menu_read_env("img_file"); + break; + case '6': + return MENU_UPDATE; + break; + } + + return MENU_STAY; +} + +struct menu_display ait_network = { + .title = "AIT network settings", + .timeout = 0, + .id = MENU_NETWORK, + .menulist = menu_network, + .menu_evaluate = ait_menu_evaluate_network, +}; + +static int fit_get_subtype(const void *fit, int noffset, char **subtype) +{ + int len; + + *subtype = (char *)fdt_getprop(fit, noffset, "subtype", &len); + if (*subtype == NULL) + return -1; + + return 0; +} + +static int ait_subtype_nr(char *subtype) +{ + int ret = FIT_SUBTYPE_UNKNOWN; + + if (!strncmp("ublheader", subtype, strlen("ublheader"))) + return FIT_SUBTYPE_UBL_HEADER; + if (!strncmp("splimage", subtype, strlen("splimage"))) + return FIT_SUBTYPE_SPL_IMAGE; + if (!strncmp("ubootimage", subtype, strlen("ubootimage"))) + return FIT_SUBTYPE_UBOOT_IMAGE; + if (!strncmp("dfenvimage", subtype, strlen("dfenvimage"))) + return FIT_SUBTYPE_DF_ENV_IMAGE; + + return ret; +} + +static int ait_menu_check_image(void) +{ + char *s; + unsigned long fit_addr; + void *addr; + int format; + char *desc; + char *subtype; + int images_noffset; + int noffset; + int ndepth; + int count = 0; + int ret; + int i; + int found_uboot = -1; + int found_ramdisk = -1; + + memset(imgs, 0, sizeof(imgs)); + s = getenv("fit_addr_r"); + fit_addr = s ? (unsigned long)simple_strtol(s, NULL, 16) : \ + CONFIG_BOARD_IMG_ADDR_R; + + addr = (void *)fit_addr; + /* check if it is a FIT image */ + format = genimg_get_format(addr); + if (format != IMAGE_FORMAT_FIT) + return -EINVAL; + + if (!fit_check_format(addr)) + return -EINVAL; + + /* print the FIT description */ + ret = fit_get_desc(addr, 0, &desc); + printf("FIT description: "); + if (ret) + printf("unavailable\n"); + else + printf("%s\n", desc); + + /* find images */ + images_noffset = fdt_path_offset(addr, FIT_IMAGES_PATH); + if (images_noffset < 0) { + printf("Can't find images parent node '%s' (%s)\n", + FIT_IMAGES_PATH, fdt_strerror(images_noffset)); + return -EINVAL; + } + + /* Process its subnodes, print out component images details */ + for (ndepth = 0, count = 0, + noffset = fdt_next_node(addr, images_noffset, &ndepth); + (noffset >= 0) && (ndepth > 0); + noffset = fdt_next_node(addr, noffset, &ndepth)) { + if (ndepth == 1) { + /* + * Direct child node of the images parent node, + * i.e. component image node. + */ + printf("Image %u (%s)\n", count, + fit_get_name(addr, noffset, NULL)); + + fit_image_print(addr, noffset, ""); + + fit_image_get_type(addr, noffset, + &imgs[count].type); + /* Mandatory properties */ + ret = fit_get_desc(addr, noffset, &desc); + printf("Description: "); + if (ret) + printf("unavailable\n"); + else + printf("%s\n", desc); + + ret = fit_get_subtype(addr, noffset, &subtype); + printf("Subtype: "); + if (ret) { + printf("unavailable\n"); + } else { + imgs[count].subtype = ait_subtype_nr(subtype); + printf("%s %d\n", subtype, + imgs[count].subtype); + } + + sprintf(imgs[count].desc, "%s", desc); + + ret = fit_image_get_data(addr, noffset, + &imgs[count].data, + &imgs[count].size); + + printf("Data Size: "); + if (ret) + printf("unavailable\n"); + else + genimg_print_size(imgs[count].size); + printf("Data @ %p\n", imgs[count].data); + count++; + } + } + + for (i = 0; i < count; i++) { + if (imgs[i].subtype == FIT_SUBTYPE_UBOOT_IMAGE) + found_uboot = i; + if (imgs[i].type == IH_TYPE_RAMDISK) { + found_ramdisk = i; + imgs[i].subtype = FIT_SUBTYPE_RAMDISK_IMAGE; + } + } + + /* dvn_* env var update, if the FIT descriptors are different */ + if (found_uboot >= 0) { + s = getenv("dvn_boot_vers"); + if (s) { + ret = strcmp(s, imgs[found_uboot].desc); + if (ret != 0) { + setenv("x_dvn_boot_vers", + imgs[found_uboot].desc); + } else { + found_uboot = -1; + printf("no new uboot version\n"); + } + } else { + setenv("dvn_boot_vers", imgs[found_uboot].desc); + } + } + if (found_ramdisk >= 0) { + s = getenv("dvn_app_vers"); + if (s) { + ret = strcmp(s, imgs[found_ramdisk].desc); + if (ret != 0) { + setenv("x_dvn_app_vers", + imgs[found_ramdisk].desc); + } else { + found_ramdisk = -1; + printf("no new ramdisk version\n"); + } + } else { + setenv("dvn_app_vers", imgs[found_ramdisk].desc); + } + } + if ((found_uboot == -1) && (found_ramdisk == -1)) + return -EINVAL; + + return 0; +} + +static int ait_menu_evaluate_update(char *choice) +{ + int ret; + + if (!choice) + return MENU_MAIN; + + switch (choice[1]) { + case '1': + return ait_menu_show(&ait_network, 0); + break; + case '2': + /* load image */ + ret = run_command("run load_img", 0); + printf("ret: %d\n", ret); + if (ret) + return MENU_UPDATE; + + ret = ait_menu_check_image(); + if (ret) + return MENU_UPDATE; + + return ait_menu_show(&ait_load, 0); + break; + case '3': + return MENU_MAIN; + break; + + } + + return MENU_MAIN; +} + +struct menu_display ait_update = { + .title = "AIT Update Software", + .timeout = 0, + .id = MENU_UPDATE, + .menulist = menu_update, + .menu_evaluate = ait_menu_evaluate_update, +}; + +static int ait_menu_evaluate_main(char *choice) +{ + if (!choice) + return MENU_STAY; + + menu_start = 1; + switch (choice[1]) { + case '1': + /* run bootcmd */ + return MENU_EXIT_BOOTCMD; + break; + case '2': + return ait_menu_show(&ait_update, 0); + break; + case '3': + /* reset to default settings */ + setenv("app_reset", "yes"); + return MENU_EXIT_BOOTCMD; + break; + case '4': + /* u-boot shell */ + return MENU_EXIT; + break; + } + + return MENU_EXIT; +} + +struct menu_display ait_main = { + .title = "AIT Main", + .timeout = CONFIG_BOOTDELAY, + .id = MENU_MAIN, + .menulist = menu_main, + .menu_evaluate = ait_menu_evaluate_main, +}; + +int menu_show(int bootdelay) +{ + int ret; + + run_command("run saveparms", 0); + ret = ait_menu_show(&ait_main, bootdelay); + run_command("run restoreparms", 0); + + if (ret == MENU_EXIT_BOOTCMD) + return 0; + + return MENU_EXIT; +} + +void menu_display_statusline(struct menu *m) +{ + char *s1, *s2; + + s1 = getenv("x_dvn_boot_vers"); + if (!s1) + s1 = getenv("dvn_boot_vers"); + + s2 = getenv("x_dvn_app_vers"); + if (!s2) + s2 = getenv("dvn_app_vers"); + + printf("State: dvn_boot_vers: %s dvn_app_vers: %s\n", s1, s2); + return; +} +#endif