diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index e4663ea..69c1d7c 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -268,6 +268,7 @@ source arch/arm/mach-highbank/Kconfig source arch/arm/mach-imx/Kconfig source arch/arm/mach-mxs/Kconfig +source scripts/imx/Kconfig source arch/arm/mach-mvebu/Kconfig source arch/arm/mach-netx/Kconfig source arch/arm/mach-nomadik/Kconfig diff --git a/arch/arm/boards/phytec-som-am335x/lowlevel.c b/arch/arm/boards/phytec-som-am335x/lowlevel.c index 33e83c5..03c7e98 100644 --- a/arch/arm/boards/phytec-som-am335x/lowlevel.c +++ b/arch/arm/boards/phytec-som-am335x/lowlevel.c @@ -122,7 +122,6 @@ PHYTEC_ENTRY_MLO(start_am33xx_phytec_phycore_sram_256mb, am335x_phytec_phycore_som_mlo, PHYCORE_MT41J128M16125IT_256MB); PHYTEC_ENTRY_MLO(start_am33xx_phytec_phycore_sram_512mb, am335x_phytec_phycore_som_mlo, PHYCORE_MT41J256M16HA15EIT_512MB); PHYTEC_ENTRY_MLO(start_am33xx_phytec_phycore_sram_2x512mb, am335x_phytec_phycore_som_mlo, PHYCORE_MT41J512M8125IT_2x512MB); -PHYTEC_ENTRY_MLO(start_am33xx_phytec_phycore_sram_1024mb, am335x_phytec_phycore_som_mlo, PHYCORE_IM8G16D3FBBG15EI_1024MB); PHYTEC_ENTRY_MLO(start_am33xx_phytec_phycore_r2_sram_512mb, am335x_phytec_phycore_som_mlo, PHYCORE_R2_MT41K256M16TW107IT_512MB); PHYTEC_ENTRY_MLO(start_am33xx_phytec_phycore_r2_sram_256mb, am335x_phytec_phycore_som_mlo, PHYCORE_R2_MT41K128M16JT_256MB); PHYTEC_ENTRY_MLO(start_am33xx_phytec_phycore_r2_sram_1024mb, am335x_phytec_phycore_som_mlo, PHYCORE_R2_MT41K512M16HA125IT_1024MB); diff --git a/arch/arm/boards/phytec-som-am335x/ram-timings.h b/arch/arm/boards/phytec-som-am335x/ram-timings.h index 4ea654d..d1947b5 100644 --- a/arch/arm/boards/phytec-som-am335x/ram-timings.h +++ b/arch/arm/boards/phytec-som-am335x/ram-timings.h @@ -29,7 +29,6 @@ PHYCORE_MT41J64M1615IT_128MB, PHYCORE_MT41J256M16HA15EIT_512MB, PHYCORE_MT41J512M8125IT_2x512MB, - PHYCORE_IM8G16D3FBBG15EI_1024MB, PHYCORE_R2_MT41K256M16TW107IT_512MB, PHYCORE_R2_MT41K128M16JT_256MB, PHYCORE_R2_MT41K512M16HA125IT_1024MB, @@ -162,26 +161,6 @@ }, }, - /* 1024MB */ - [PHYCORE_IM8G16D3FBBG15EI_1024MB] = { - .regs = { - .emif_read_latency = 0x7, - .emif_tim1 = 0x0AAAE4DB, - .emif_tim2 = 0x268F7FDA, - .emif_tim3 = 0x501F88BF, - .ocp_config = 0x003d3d3d, - .sdram_config = 0x61C053B2, - .zq_config = 0x50074BE4, - .sdram_ref_ctrl = 0x00000C30 - }, - .data = { - .rd_slave_ratio0 = 0x33, - .wr_dqs_slave_ratio0 = 0x4a, - .fifo_we_slave_ratio0 = 0xa4, - .wr_slave_ratio0 = 0x85, - }, - }, - /* 256MB */ [PHYCARD_NT5CB128M16BP_256MB] = { .regs = { diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig index f83aedc..831755c 100644 --- a/arch/arm/mach-imx/Kconfig +++ b/arch/arm/mach-imx/Kconfig @@ -309,7 +309,6 @@ config MACH_SABRELITE bool "Freescale i.MX6 Sabre Lite" select ARCH_IMX6 - select HAVE_PBL_MULTI_IMAGES config MACH_SABRESD bool "Freescale i.MX6 SabreSD" @@ -657,13 +656,6 @@ menu "i.MX specific settings" -config ARCH_IMX_USBLOADER - bool "compile imx-usb-loader" - help - imx-usb-loader is a tool to upload and start imximages to an i.MX SoC - in ROM boot mode. It requires libusb, so make sure you have the libusb - devel package installed on your machine. - config IMX_IIM tristate "IIM fusebox device" depends on !ARCH_IMX21 diff --git a/arch/arm/mach-imx/iim.c b/arch/arm/mach-imx/iim.c index 6addfed..d4794cb 100644 --- a/arch/arm/mach-imx/iim.c +++ b/arch/arm/mach-imx/iim.c @@ -62,6 +62,7 @@ struct imx_iim_drvdata { void (*supply)(int enable); + char nregs[8]; }; static struct iim_priv *imx_iim; @@ -314,7 +315,7 @@ .reg_read = imx_iim_reg_read, }; -static int imx_iim_add_bank(struct iim_priv *iim, int num) +static int imx_iim_add_bank(struct iim_priv *iim, int num, int nregs) { struct iim_bank *bank; char *name; @@ -331,7 +332,7 @@ bank->map_config.reg_bits = 8, bank->map_config.val_bits = 8, bank->map_config.reg_stride = 1, - bank->map_config.max_register = 31, + bank->map_config.max_register = (nregs - 1), bank->map_config.name = xasprintf("bank%d", num); bank->map = regmap_init(&iim->dev, &imx_iim_regmap_bus, bank, &bank->map_config); @@ -459,6 +460,7 @@ struct iim_priv *iim; int i, ret; struct imx_iim_drvdata *drvdata = NULL; + char *nregs = NULL; if (imx_iim) return -EBUSY; @@ -486,8 +488,16 @@ return PTR_ERR(iores); iim->base = IOMEM(iores->start); + if (drvdata && drvdata->nregs[0]) + nregs = drvdata->nregs; + for (i = 0; i < IIM_NUM_BANKS; i++) { - ret = imx_iim_add_bank(iim, i); + int n = nregs ? nregs[i] : 32; + + if (!n) + continue; + + ret = imx_iim_add_bank(iim, i, n); if (ret) return ret; } @@ -529,14 +539,21 @@ } static struct imx_iim_drvdata imx27_drvdata = { + .nregs = { 32, 32 }, +}; + +static struct imx_iim_drvdata imx25_imx31_imx35_drvdata = { + .nregs = { 32, 32, 32 }, }; static struct imx_iim_drvdata imx51_drvdata = { .supply = imx51_iim_supply, + .nregs = { 32, 32, 32, 32 }, }; static struct imx_iim_drvdata imx53_drvdata = { .supply = imx53_iim_supply, + .nregs = { 32, 32, 32, 32, 16 }, }; static __maybe_unused struct of_device_id imx_iim_dt_ids[] = { @@ -547,9 +564,18 @@ .compatible = "fsl,imx51-iim", .data = &imx51_drvdata, }, { + .compatible = "fsl,imx35-iim", + .data = &imx25_imx31_imx35_drvdata, + }, { + .compatible = "fsl,imx31-iim", + .data = &imx25_imx31_imx35_drvdata, + }, { .compatible = "fsl,imx27-iim", .data = &imx27_drvdata, }, { + .compatible = "fsl,imx25-iim", + .data = &imx25_imx31_imx35_drvdata, + }, { /* sentinel */ } }; diff --git a/arch/arm/mach-mxs/Kconfig b/arch/arm/mach-mxs/Kconfig index facab9c..fed7b52 100644 --- a/arch/arm/mach-mxs/Kconfig +++ b/arch/arm/mach-mxs/Kconfig @@ -143,11 +143,4 @@ endmenu -config ARCH_MXS_USBLOADER - bool "compile mxs-usb-loader" - help - mxs-usb-loader is a tool to upload and start mxs bootstream images to an - i.MX SoC in ROM boot mode. It requires libusb, so make sure you have the libusb - devel package installed on your machine. - endif diff --git a/drivers/clk/imx/clk-imx6.c b/drivers/clk/imx/clk-imx6.c index 8ac43be..d0571bc 100644 --- a/drivers/clk/imx/clk-imx6.c +++ b/drivers/clk/imx/clk-imx6.c @@ -494,10 +494,7 @@ writel(0xffffffff, ccm_base + CCGR0); writel(0xf0ffffff, ccm_base + CCGR1); /* gate GPU3D, GPU2D */ writel(0xffffffff, ccm_base + CCGR2); - if (IS_ENABLED(CONFIG_DRIVER_VIDEO_IMX_IPUV3)) - writel(0x3fffffff, ccm_base + CCGR3); /* gate OpenVG */ - else - writel(0x3fff0000, ccm_base + CCGR3); /* gate OpenVG, LDB, IPU1, IPU2 */ + writel(0x3fffffff, ccm_base + CCGR3); /* gate OpenVG */ if (IS_ENABLED(CONFIG_PCI_IMX6)) writel(0xffffffff, ccm_base + CCGR4); else diff --git a/drivers/clk/imx/clk-imx6ul.c b/drivers/clk/imx/clk-imx6ul.c index 0ca0652..f28660d 100644 --- a/drivers/clk/imx/clk-imx6ul.c +++ b/drivers/clk/imx/clk-imx6ul.c @@ -91,6 +91,7 @@ int i; struct device_node *ccm_node = dev->device_node; + anatop_base = IOMEM(MX6_ANATOP_BASE_ADDR); iores = dev_request_mem_resource(dev, 0); if (IS_ERR(iores)) return PTR_ERR(iores); @@ -100,8 +101,6 @@ clks[IMX6UL_CLK_DUMMY] = clk_fixed("dummy", 0); - base = IOMEM(MX6_ANATOP_BASE_ADDR); - clks[IMX6UL_PLL1_BYPASS_SRC] = imx_clk_mux("pll1_bypass_src", base + 0x00, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); clks[IMX6UL_PLL2_BYPASS_SRC] = imx_clk_mux("pll2_bypass_src", base + 0x30, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); clks[IMX6UL_PLL3_BYPASS_SRC] = imx_clk_mux("pll3_bypass_src", base + 0x10, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); diff --git a/images/Makefile.am33xx b/images/Makefile.am33xx index 8168fe4..d1c432e 100644 --- a/images/Makefile.am33xx +++ b/images/Makefile.am33xx @@ -77,12 +77,6 @@ am33xx-mlo-$(CONFIG_MACH_PHYTEC_SOM_AM335X) += barebox-am33xx-phytec-phycore-mlo-2x512mb.img am33xx-mlospi-$(CONFIG_MACH_PHYTEC_SOM_AM335X) += barebox-am33xx-phytec-phycore-mlo-2x512mb.spi.img -pblx-$(CONFIG_MACH_PHYTEC_SOM_AM335X) += start_am33xx_phytec_phycore_sram_1024mb -FILE_barebox-am33xx-phytec-phycore-mlo-1024mb.img = start_am33xx_phytec_phycore_sram_1024mb.pblx.mlo -FILE_barebox-am33xx-phytec-phycore-mlo-1024mb.spi.img = start_am33xx_phytec_phycore_sram_1024mb.pblx.mlospi -am33xx-mlo-$(CONFIG_MACH_PHYTEC_SOM_AM335X) += barebox-am33xx-phytec-phycore-mlo-1024mb.img -am33xx-mlospi-$(CONFIG_MACH_PHYTEC_SOM_AM335X) += barebox-am33xx-phytec-phycore-mlo-1024mb.spi.img - pblx-$(CONFIG_MACH_PHYTEC_SOM_AM335X) += start_am33xx_phytec_phycore_r2_sram_1024mb FILE_barebox-am33xx-phytec-phycore-r2-mlo-1024mb.img = start_am33xx_phytec_phycore_r2_sram_1024mb.pblx.mlo FILE_barebox-am33xx-phytec-phycore-r2-mlo-1024mb.spi.img = start_am33xx_phytec_phycore_r2_sram_1024mb.pblx.mlospi diff --git a/scripts/Makefile b/scripts/Makefile index 7f2527d..8eda41e 100644 --- a/scripts/Makefile +++ b/scripts/Makefile @@ -22,9 +22,6 @@ hostprogs-$(CONFIG_ARCH_MXS) += mxsimage mxsboot HOSTCFLAGS += -I$(srctree)/scripts/include/ HOSTLOADLIBES_mxsimage = `pkg-config --libs openssl` -HOSTCFLAGS_mxs-usb-loader.o = `pkg-config --cflags libusb-1.0` -HOSTLOADLIBES_mxs-usb-loader = `pkg-config --libs libusb-1.0` -hostprogs-$(CONFIG_ARCH_MXS_USBLOADER) += mxs-usb-loader HOSTCFLAGS_omap3-usb-loader.o = `pkg-config --cflags libusb-1.0` HOSTLOADLIBES_omap3-usb-loader = `pkg-config --libs libusb-1.0` hostprogs-$(CONFIG_OMAP3_USB_LOADER) += omap3-usb-loader @@ -33,7 +30,7 @@ hostprogs-$(CONFIG_OMAP4_USBBOOT) += omap4_usbboot subdir-y += mod -subdir-$(CONFIG_ARCH_IMX) += imx +subdir-y += imx subdir-$(CONFIG_X86) += setupmbr subdir-$(CONFIG_DTC) += dtc subdir-$(CONFIG_ARCH_TEGRA) += tegra diff --git a/scripts/imx/Kconfig b/scripts/imx/Kconfig new file mode 100644 index 0000000..fda9c63 --- /dev/null +++ b/scripts/imx/Kconfig @@ -0,0 +1,7 @@ +config ARCH_IMX_USBLOADER + depends on ARCH_MXS || ARCH_IMX + bool "compile imx-usb-loader" + help + imx-usb-loader is a tool to upload and start imximages to an i.MX SoC + in ROM boot mode. It requires libusb, so make sure you have the libusb + devel package installed on your machine. diff --git a/scripts/imx/imx-usb-loader.c b/scripts/imx/imx-usb-loader.c index 9de7bb3..90ee3e0 100644 --- a/scripts/imx/imx-usb-loader.c +++ b/scripts/imx/imx-usb-loader.c @@ -45,6 +45,12 @@ #define FT_DCD 0xee #define FT_LOAD_ONLY 0x00 +/* + * comment from libusb: + * As per the USB 3.0 specs, the current maximum limit for the depth is 7. + */ +#define MAX_USB_PORTS 7 + int verbose; static struct libusb_device_handle *usb_dev_handle; static struct usb_id *usb_id; @@ -63,6 +69,9 @@ #define HDR_MX53 2 unsigned char header_type; unsigned short max_transfer; +#define DEV_IMX 0 +#define DEV_MXS 1 + unsigned char dev_type; }; struct usb_work { @@ -81,7 +90,9 @@ .vid = 0x066f, .pid = 0x3780, .name = "i.MX23", - .mode = MODE_BULK, + .mode = MODE_HID, + .max_transfer = 1024, + .dev_type = DEV_MXS, }, { .vid = 0x15a2, .pid = 0x0030, @@ -114,6 +125,8 @@ .vid = 0x15a2, .pid = 0x004f, .name = "i.MX28", + .max_transfer = 1024, + .dev_type = DEV_MXS, }, { .vid = 0x15a2, .pid = 0x0052, @@ -181,6 +194,17 @@ uint8_t rsvd; } __attribute__((packed)); +#define MXS_CMD_FW_DOWNLOAD 0x02 +struct mxs_command { + uint32_t sign; /* Signature */ + uint32_t tag; /* Tag */ + uint32_t size; /* Payload size */ + uint8_t flags; /* Flags (host to device) */ + uint8_t rsvd[2]; /* Reserved */ + uint8_t cmd; /* Firmware download */ + uint32_t dw_size; /* Download size */ +} __attribute__((packed)); + static const struct mach_id *imx_device(unsigned short vid, unsigned short pid) { int i; @@ -197,9 +221,66 @@ return NULL; } -static libusb_device *find_imx_dev(libusb_device **devs, const struct mach_id **pp_id) +static int device_location_equal(libusb_device *device, const char *location) +{ + uint8_t port_path[MAX_USB_PORTS]; + uint8_t dev_bus; + int path_step, path_len; + int result = 0; + char *ptr, *loc; + + /* strtok need non const char */ + loc = strdup(location); + + path_len = libusb_get_port_numbers(device, port_path, MAX_USB_PORTS); + if (path_len == LIBUSB_ERROR_OVERFLOW) { + fprintf(stderr, "cannot determine path to usb device! (more than %i ports in path)\n", + MAX_USB_PORTS); + goto done; + } + + ptr = strtok(loc, "-"); + if (ptr == NULL) { + printf("no '-' in path\n"); + goto done; + } + + dev_bus = libusb_get_bus_number(device); + /* check bus mismatch */ + if (atoi(ptr) != dev_bus) + goto done; + + path_step = 0; + while (path_step < MAX_USB_PORTS) { + ptr = strtok(NULL, "."); + + /* no more tokens in path */ + if (ptr == NULL) + break; + + /* path mismatch at some step */ + if (path_step < path_len && atoi(ptr) != port_path[path_step]) + break; + + path_step++; + }; + + /* walked the full path, all elements match */ + if (path_step == path_len) + result = 1; + else + fprintf(stderr, " excluded by device path option\n"); + +done: + free(loc); + return result; +} + +static libusb_device *find_imx_dev(libusb_device **devs, const struct mach_id **pp_id, + const char *location) { int i = 0; + int err; const struct mach_id *p; for (;;) { @@ -217,10 +298,24 @@ } p = imx_device(desc.idVendor, desc.idProduct); - if (p) { - *pp_id = p; - return dev; + if (!p) + continue; + + err = libusb_open(dev, &usb_dev_handle); + if (err) { + fprintf(stderr, "Could not open device vid=0x%x pid=0x%x err=%d\n", + p->vid, p->pid, err); + continue; } + + if (location && !device_location_equal(dev, location)) { + libusb_close(usb_dev_handle); + usb_dev_handle = NULL; + continue; + } + + *pp_id = p; + return dev; } *pp_id = NULL; @@ -798,6 +893,98 @@ return 0; } +static int do_dcd_v2_cmd_check(const unsigned char *dcd) +{ + uint32_t mask; + uint32_t poll_count = 0; + int bytes; + enum imx_dcd_v2_check_cond cond; + struct imx_dcd_v2_check *check = (struct imx_dcd_v2_check *) dcd; + switch (ntohs(check->length)) { + case 12: + /* poll indefinitely */ + poll_count = 0xffffffff; + break; + case 16: + poll_count = ntohl(check->count); + if (poll_count == 0) + /* this command behaves as for NOP */ + return 0; + break; + default: + fprintf(stderr, "Error: invalid DCD check length\n"); + return -1; + } + + switch (check->param & 7) { + case 1: + case 2: + case 4: + bytes = check->param & 7; + break; + default: + fprintf(stderr, "Error: invalid DCD check size\n"); + return -1; + } + + switch ((check->param & 0xf8) >> 3) { + case check_all_bits_clear: + case check_all_bits_set: + case check_any_bit_clear: + case check_any_bit_set: + cond = (check->param & 0xf8) >> 3; + break; + default: + fprintf(stderr, "Error: invalid DCD check condition\n"); + return -1; + } + + mask = ntohl(check->mask); + + fprintf(stderr, "DCD check condition %i on address 0x%x\n", + cond, ntohl(check->addr)); + /* Reduce the poll count to some arbitrary practical limit. + Polling via SRP commands will be much slower compared to + polling when DCD is interpreted by the SOC microcode. + */ + if (poll_count > 1000) + poll_count = 1000; + + while (poll_count > 0) { + uint32_t data = 0; + int ret = read_memory(ntohl(check->addr), &data, bytes); + if (ret < 0) + return ret; + + data &= mask; + + switch (cond) { + case check_all_bits_clear: + if (data != 0) + return 0; + break; + case check_all_bits_set: + if (data != mask) + return 0; + break; + case check_any_bit_clear: + if (data == mask) + return 0; + break; + case check_any_bit_set: + if (data == 0) + return 0; + break; + } + poll_count--; + } + + fprintf(stderr, "Error: timeout waiting for DCD check condition %i " + "on address 0x%08x to match 0x%08x\n", cond, + ntohl(check->addr), ntohl(check->mask)); + return -1; +} + static int process_dcd_table_ivt(const struct imx_flash_header_v2 *hdr, const unsigned char *file_start, unsigned cnt) { @@ -850,8 +1037,7 @@ ret = do_dcd_v2_cmd_write(dcd); break; case TAG_CHECK: - fprintf(stderr, "DCD check not implemented yet\n"); - usleep(50000); + ret = do_dcd_v2_cmd_check(dcd); break; case TAG_UNLOCK: fprintf(stderr, "DCD unlock not implemented yet\n"); @@ -1273,6 +1459,66 @@ return modify_memory(addr, val, width, set_bits, clear_bits); } +/* MXS section */ +static int mxs_load_file(libusb_device_handle *dev, uint8_t *data, int size) +{ + static struct mxs_command dl_command; + int last_trans, err; + void *p; + int cnt; + + dl_command.sign = htonl(0x424c5443); /* Signature: BLTC */ + dl_command.tag = htonl(0x1); + dl_command.size = htonl(size); + dl_command.flags = 0; + dl_command.rsvd[0] = 0; + dl_command.rsvd[1] = 0; + dl_command.cmd = MXS_CMD_FW_DOWNLOAD; + dl_command.dw_size = htonl(size); + + err = transfer(1, (unsigned char *) &dl_command, 20, &last_trans); + if (err) { + printf("transfer error at init step: err=%i, last_trans=%i\n", + err, last_trans); + return err; + } + + p = data; + cnt = size; + + while (1) { + int now = get_min(cnt, usb_id->mach_id->max_transfer); + + if (!now) + break; + + err = transfer(2, p, now, &now); + if (err) { + printf("dl_command err=%i, last_trans=%i\n", err, now); + return err; + } + + p += now; + cnt -= now; + } + + return err; +} + +static int mxs_work(struct usb_work *curr) +{ + unsigned fsize = 0; + unsigned char *buf = NULL; + int ret; + + ret = read_file(curr->filename, &buf, &fsize); + if (ret < 0) + return ret; + + return mxs_load_file(usb_dev_handle, buf, fsize); +} +/* end of mxs section */ + static int parse_initfile(const char *filename) { struct config_data data = { @@ -1287,6 +1533,7 @@ fprintf(stderr, "usage: %s [OPTIONS] [FILENAME]\n\n" "-c check correctness of flashed image\n" "-i Specify custom SoC initialization file\n" + "-p Specify device path: -[.]...\n" "-s skip DCD included in image\n" "-v verbose (give multiple times to increase)\n" "-h this help\n", prgname); @@ -1307,10 +1554,11 @@ struct usb_work w = {}; int opt; char *initfile = NULL; + char *devpath = NULL; w.do_dcd_once = 1; - while ((opt = getopt(argc, argv, "cvhi:s")) != -1) { + while ((opt = getopt(argc, argv, "cvhi:p:s")) != -1) { switch (opt) { case 'c': verify = 1; @@ -1323,6 +1571,9 @@ case 'i': initfile = optarg; break; + case 'p': + devpath = optarg; + break; case 's': w.do_dcd_once = 0; break; @@ -1350,19 +1601,12 @@ goto out; } - dev = find_imx_dev(devs, &mach); + dev = find_imx_dev(devs, &mach, devpath); if (!dev) { fprintf(stderr, "no supported device found\n"); goto out; } - err = libusb_open(dev, &usb_dev_handle); - if (err) { - fprintf(stderr, "Could not open device vid=0x%x pid=0x%x err=%d\n", - mach->vid, mach->pid, err); - goto out; - } - libusb_free_device_list(devs, 1); libusb_get_configuration(usb_dev_handle, &config); @@ -1384,6 +1628,11 @@ usb_id->mach_id = mach; + if (mach->dev_type == DEV_MXS) { + ret = mxs_work(&w); + goto out; + } + err = do_status(); if (err) { printf("status failed\n"); diff --git a/scripts/imx/imx.h b/scripts/imx/imx.h index 57c7525..f32ae52 100644 --- a/scripts/imx/imx.h +++ b/scripts/imx/imx.h @@ -95,4 +95,20 @@ struct imx_dcd_v2_write_rec data[MAX_RECORDS_DCD_V2]; } __attribute__((packed)); +struct imx_dcd_v2_check { + uint8_t tag; + uint16_t length; + uint8_t param; + uint32_t addr; + uint32_t mask; + uint32_t count; +} __attribute__((packed)); + +enum imx_dcd_v2_check_cond { + check_all_bits_clear = 0, + check_all_bits_set = 1, + check_any_bit_clear = 2, + check_any_bit_set = 3, +} __attribute__((packed)); + int parse_config(struct config_data *data, const char *filename); diff --git a/scripts/mxs-usb-loader.c b/scripts/mxs-usb-loader.c deleted file mode 100644 index 8529274..0000000 --- a/scripts/mxs-usb-loader.c +++ /dev/null @@ -1,236 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id$ - * - * Copyright (C) 2010 Amaury Pouly - * - * 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 software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ -#include -#include -#include -#include -#include - -#ifndef MIN -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#endif - -void put32le(uint8_t * buf, uint32_t i) -{ - *buf++ = i & 0xff; - *buf++ = (i >> 8) & 0xff; - *buf++ = (i >> 16) & 0xff; - *buf++ = (i >> 24) & 0xff; -} - -void put32be(uint8_t * buf, uint32_t i) -{ - *buf++ = (i >> 24) & 0xff; - *buf++ = (i >> 16) & 0xff; - *buf++ = (i >> 8) & 0xff; - *buf++ = i & 0xff; -} - -enum dev_type_t { - HID_DEVICE, - RECOVERY_DEVICE, -}; - -struct dev_info_t { - uint16_t vendor_id; - uint16_t product_id; - unsigned xfer_size; - enum dev_type_t dev_type; -}; - -struct dev_info_t g_dev_info[] = { - {0x066f, 0x3780, 1024, HID_DEVICE}, /* i.MX233 / STMP3780 */ - {0x066f, 0x3770, 48, HID_DEVICE}, /* STMP3770 */ - {0x15A2, 0x004F, 1024, HID_DEVICE}, /* i.MX28 */ - {0x066f, 0x3600, 4096, RECOVERY_DEVICE}, /* STMP36xx */ -}; - -int send_hid(libusb_device_handle * dev, int xfer_size, uint8_t * data, - int size, int nr_xfers) -{ - int i; - - libusb_detach_kernel_driver(dev, 0); - libusb_detach_kernel_driver(dev, 4); - - libusb_claim_interface(dev, 0); - libusb_claim_interface(dev, 4); - - uint8_t *xfer_buf = malloc(1 + xfer_size); - uint8_t *p = xfer_buf; - - *p++ = 0x01; /* Report id */ - - /* Command block wrapper */ - *p++ = 'B'; /* Signature */ - *p++ = 'L'; - *p++ = 'T'; - *p++ = 'C'; - put32le(p, 0x1); /* Tag */ - p += 4; - put32le(p, size); /* Payload size */ - p += 4; - *p++ = 0; /* Flags (host to device) */ - p += 2; /* Reserved */ - - /* Command descriptor block */ - *p++ = 0x02; /* Firmware download */ - put32be(p, size); /* Download size */ - - int ret = libusb_control_transfer(dev, - LIBUSB_REQUEST_TYPE_CLASS | - LIBUSB_RECIPIENT_INTERFACE, 0x9, - 0x201, 0, - xfer_buf, xfer_size + 1, 1000); - if (ret < 0) { - printf("transfer error at init step\n"); - return 1; - } - - for (i = 0; i < nr_xfers; i++) { - xfer_buf[0] = 0x2; - memcpy(&xfer_buf[1], &data[i * xfer_size], xfer_size); - - ret = libusb_control_transfer(dev, - LIBUSB_REQUEST_TYPE_CLASS | - LIBUSB_RECIPIENT_INTERFACE, 0x9, - 0x202, 0, xfer_buf, xfer_size + 1, - 1000); - if (ret < 0) { - printf("transfer error at send step %d\n", i); - return 1; - } - } - - int recv_size; - ret = - libusb_interrupt_transfer(dev, 0x81, xfer_buf, xfer_size, - &recv_size, 1000); - if (ret < 0) { - printf("transfer error at final stage\n"); - return 1; - } - - return ret; -} - -int send_recovery(libusb_device_handle * dev, int xfer_size, uint8_t * data, - int size, int nr_xfers) -{ - (void)nr_xfers; - // there should be no kernel driver attached but in doubt... - libusb_detach_kernel_driver(dev, 0); - libusb_claim_interface(dev, 0); - - int sent = 0; - while (sent < size) { - int xfered; - int len = MIN(size - sent, xfer_size); - int ret = - libusb_bulk_transfer(dev, 1, data + sent, len, &xfered, - 1000); - if (ret < 0) { - printf("transfer error at send offset %d\n", sent); - return 1; - } - if (xfered == 0) { - printf("empty transfer at step offset %d\n", sent); - return 2; - } - sent += xfered; - } - return 0; -} - -int main(int argc, char **argv) -{ - if (argc != 3) { - printf("usage: %s \n", argv[0]); - printf - ("If is set to zero, the preferred one is used.\n"); - return 1; - } - - char *end; - int xfer_size = strtol(argv[1], &end, 0); - if (end != (argv[1] + strlen(argv[1]))) { - printf("Invalid transfer size !\n"); - return 1; - } - - libusb_device_handle *dev; - - libusb_init(NULL); - - libusb_set_debug(NULL, 3); - - unsigned i; - for (i = 0; i < sizeof(g_dev_info) / sizeof(g_dev_info[0]); i++) { - dev = libusb_open_device_with_vid_pid(NULL, - g_dev_info[i].vendor_id, - g_dev_info[i].product_id); - if (dev == NULL) - continue; - if (xfer_size == 0) - xfer_size = g_dev_info[i].xfer_size; - printf("Found a match for %04x:%04x\n", - g_dev_info[i].vendor_id, g_dev_info[i].product_id); - break; - } - if (dev == NULL) { - printf("Cannot open device\n"); - return 1; - } - - FILE *f = fopen(argv[2], "r"); - if (f == NULL) { - perror("cannot open file"); - return 1; - } - fseek(f, 0, SEEK_END); - size_t size = ftell(f); - fseek(f, 0, SEEK_SET); - - printf("Transfer size: %d\n", xfer_size); - int nr_xfers = (size + xfer_size - 1) / xfer_size; - uint8_t *file_buf = malloc(nr_xfers * xfer_size); - memset(file_buf, 0xff, nr_xfers * xfer_size); // pad with 0xff - if (fread(file_buf, size, 1, f) != 1) { - perror("read error"); - fclose(f); - return 1; - } - fclose(f); - - switch (g_dev_info[i].dev_type) { - case HID_DEVICE: - send_hid(dev, xfer_size, file_buf, size, nr_xfers); - break; - case RECOVERY_DEVICE: - send_recovery(dev, xfer_size, file_buf, size, nr_xfers); - break; - default: - printf("unknown device type\n"); - break; - } - - return 0; -}