From 497671d31bb54590d68f233c5419cc74b3782aba Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Mon, 13 Feb 2017 11:05:56 +0100 Subject: ARM: i.MX: iim: Only register actually equipped fuses The IIM unit in defferent i.MX SoCs is always the same, but the number of actually equipped fuses differs between the SoCs. Reading nonexistent fuses oopses, so only register the fuses we can actually read. Signed-off-by: Sascha Hauer --- arch/arm/mach-imx/iim.c | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/arch/arm/mach-imx/iim.c b/arch/arm/mach-imx/iim.c index 6addfed696..d4794cbac8 100644 --- a/arch/arm/mach-imx/iim.c +++ b/arch/arm/mach-imx/iim.c @@ -62,6 +62,7 @@ struct iim_priv { struct imx_iim_drvdata { void (*supply)(int enable); + char nregs[8]; }; static struct iim_priv *imx_iim; @@ -314,7 +315,7 @@ static struct regmap_bus imx_iim_regmap_bus = { .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 @@ static int imx_iim_add_bank(struct iim_priv *iim, int num) 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 @@ static int imx_iim_probe(struct device_d *dev) 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 @@ static int imx_iim_probe(struct device_d *dev) 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 void imx53_iim_supply(int enable) } 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[] = { @@ -546,9 +563,18 @@ static __maybe_unused struct of_device_id imx_iim_dt_ids[] = { }, { .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 */ } -- cgit v1.2.3 From 8175ff1df44b7041cb0fb0e747d9c57c92d5176c Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Tue, 14 Feb 2017 12:03:12 +0100 Subject: arm: imx: don't let MACH_SABRELITE select HAVE_PBL_MULTI_IMAGES MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit MACH_SABRELITE is only selectable if IMX_MULTI_BOARDS is enabled. The latter already selects HAVE_PBL_MULTI_IMAGES. Signed-off-by: Uwe Kleine-König Signed-off-by: Sascha Hauer --- arch/arm/mach-imx/Kconfig | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig index f83aedc0b9..36d110758f 100644 --- a/arch/arm/mach-imx/Kconfig +++ b/arch/arm/mach-imx/Kconfig @@ -309,7 +309,6 @@ config MACH_TX6X 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" -- cgit v1.2.3 From f0a2d7f036a7a7e9603814504e483f91393fdeed Mon Sep 17 00:00:00 2001 From: Alexander Kurz Date: Sun, 19 Feb 2017 19:57:58 +0100 Subject: scripts: imx-usb-loader: implement DCD v2 check command The DCD v2 check command supported by i.MX53 and later SoC polls a given memory location as long as a given condition is true. Enable imx-usb-loader to perform this check. When the timeout is hit, imx-usb-loader returns an error. For practical reasons the timeout computation will differ from the native implementation, since performing check commands via USB will be much slower compared to native processing. Signed-off-by: Alexander Kurz Signed-off-by: Sascha Hauer --- scripts/imx/imx-usb-loader.c | 95 +++++++++++++++++++++++++++++++++++++++++++- scripts/imx/imx.h | 16 ++++++++ 2 files changed, 109 insertions(+), 2 deletions(-) diff --git a/scripts/imx/imx-usb-loader.c b/scripts/imx/imx-usb-loader.c index 9de7bb3a8a..4105adeda9 100644 --- a/scripts/imx/imx-usb-loader.c +++ b/scripts/imx/imx-usb-loader.c @@ -798,6 +798,98 @@ static int do_dcd_v2_cmd_write(const unsigned char *dcd) 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 +942,7 @@ static int process_dcd_table_ivt(const struct imx_flash_header_v2 *hdr, 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"); diff --git a/scripts/imx/imx.h b/scripts/imx/imx.h index 57c7525369..f32ae52abf 100644 --- a/scripts/imx/imx.h +++ b/scripts/imx/imx.h @@ -95,4 +95,20 @@ struct imx_dcd_v2_write { 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); -- cgit v1.2.3 From 6d76aaf1bc38d4fa07315843c00607393cbe1796 Mon Sep 17 00:00:00 2001 From: Daniel Schultz Date: Wed, 1 Mar 2017 08:50:54 +0100 Subject: arm: boards: phytec-som-am335x: Remove 1GB RAM type This machine was a prototype and was never shipped to customers. Since it has no dependencies to any image, it can be removed. Signed-off-by: Daniel Schultz Signed-off-by: Sascha Hauer --- arch/arm/boards/phytec-som-am335x/lowlevel.c | 1 - arch/arm/boards/phytec-som-am335x/ram-timings.h | 21 --------------------- images/Makefile.am33xx | 6 ------ 3 files changed, 28 deletions(-) diff --git a/arch/arm/boards/phytec-som-am335x/lowlevel.c b/arch/arm/boards/phytec-som-am335x/lowlevel.c index 33e83c5a8e..03c7e98f5a 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_128mb, am335x_phytec_phycore_s 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 4ea654db12..d1947b588e 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 @@ enum { 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 @@ struct am335x_sdram_timings physom_timings[] = { }, }, - /* 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/images/Makefile.am33xx b/images/Makefile.am33xx index 8168fe4c93..d1c432e2c2 100644 --- a/images/Makefile.am33xx +++ b/images/Makefile.am33xx @@ -77,12 +77,6 @@ FILE_barebox-am33xx-phytec-phycore-mlo-2x512mb.spi.img = start_am33xx_phytec_phy 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 -- cgit v1.2.3 From 65c50e5859c5886283b92ef178d0bcabeeeb0cf0 Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Thu, 2 Mar 2017 15:43:12 +0100 Subject: scripts: imx imx-usb-loader: add usb path support In some cases we need to work with more than one device attached to one host. For this situation we need path filter to make sure we talk with proper device. Signed-off-by: Oleksij Rempel Signed-off-by: Sascha Hauer --- scripts/imx/imx-usb-loader.c | 99 ++++++++++++++++++++++++++++++++++++++------ 1 file changed, 86 insertions(+), 13 deletions(-) diff --git a/scripts/imx/imx-usb-loader.c b/scripts/imx/imx-usb-loader.c index 4105adeda9..2c8a118923 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; @@ -197,9 +203,64 @@ static const struct mach_id *imx_device(unsigned short vid, unsigned short pid) 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; + +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 +278,24 @@ static libusb_device *find_imx_dev(libusb_device **devs, const struct mach_id ** } 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; @@ -1378,6 +1453,7 @@ static void usage(const char *prgname) 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); @@ -1398,10 +1474,11 @@ int main(int argc, char *argv[]) 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; @@ -1414,6 +1491,9 @@ int main(int argc, char *argv[]) case 'i': initfile = optarg; break; + case 'p': + devpath = optarg; + break; case 's': w.do_dcd_once = 0; break; @@ -1441,19 +1521,12 @@ int main(int argc, char *argv[]) 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); -- cgit v1.2.3 From e7b1f56263adea753563a4e8856c4232d1ba249f Mon Sep 17 00:00:00 2001 From: Robin van der Gracht Date: Fri, 3 Mar 2017 10:47:49 +0100 Subject: clk: imx: clk-imx6ul: Use anatop_base pointer for consistency The anatop_base pointer was unused, but instead of removing it, assign and use it for readability like clk-imx6 and clk-imx6sx do. Signed-off-by: Robin van der Gracht Signed-off-by: Sascha Hauer --- drivers/clk/imx/clk-imx6ul.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/clk/imx/clk-imx6ul.c b/drivers/clk/imx/clk-imx6ul.c index 72b5fa2b75..5e10cfdd89 100644 --- a/drivers/clk/imx/clk-imx6ul.c +++ b/drivers/clk/imx/clk-imx6ul.c @@ -91,6 +91,7 @@ static int imx6_ccm_probe(struct device_d *dev) 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 @@ static int imx6_ccm_probe(struct device_d *dev) 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)); -- cgit v1.2.3 From ef55d12d59771b64e764a777aa3d7963e2ebb8dd Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Fri, 3 Mar 2017 11:38:41 +0100 Subject: scripts: imx imx-usb-loader: warn if device was excluded by path option notify user about the reason why device was ignored by imx-usb-loader. Signed-off-by: Oleksij Rempel Signed-off-by: Sascha Hauer --- scripts/imx/imx-usb-loader.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scripts/imx/imx-usb-loader.c b/scripts/imx/imx-usb-loader.c index 2c8a118923..ac7bc3ee94 100644 --- a/scripts/imx/imx-usb-loader.c +++ b/scripts/imx/imx-usb-loader.c @@ -250,6 +250,8 @@ static int device_location_equal(libusb_device *device, const char *location) /* 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); -- cgit v1.2.3 From 701f728c2a79628fbbb4f1a57e576ce5c5c8afd6 Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Tue, 7 Mar 2017 08:54:49 +0100 Subject: scripts: imx imx-usb-loader: add support for imx23 and imx28 This code was rewrtitten from mxs-usb-loader. Signed-off-by: Oleksij Rempel Signed-off-by: Sascha Hauer --- scripts/imx/imx-usb-loader.c | 85 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 84 insertions(+), 1 deletion(-) diff --git a/scripts/imx/imx-usb-loader.c b/scripts/imx/imx-usb-loader.c index ac7bc3ee94..90ee3e09d5 100644 --- a/scripts/imx/imx-usb-loader.c +++ b/scripts/imx/imx-usb-loader.c @@ -69,6 +69,9 @@ struct mach_id { #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 { @@ -87,7 +90,9 @@ static const struct mach_id imx_ids[] = { .vid = 0x066f, .pid = 0x3780, .name = "i.MX23", - .mode = MODE_BULK, + .mode = MODE_HID, + .max_transfer = 1024, + .dev_type = DEV_MXS, }, { .vid = 0x15a2, .pid = 0x0030, @@ -120,6 +125,8 @@ static const struct mach_id imx_ids[] = { .vid = 0x15a2, .pid = 0x004f, .name = "i.MX28", + .max_transfer = 1024, + .dev_type = DEV_MXS, }, { .vid = 0x15a2, .pid = 0x0052, @@ -187,6 +194,17 @@ struct sdp_command { 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; @@ -1441,6 +1459,66 @@ static int write_mem(const struct config_data *data, uint32_t addr, 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 = { @@ -1550,6 +1628,11 @@ int main(int argc, char *argv[]) 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"); -- cgit v1.2.3 From 3ca576cc4a4236a2556ab172b524c1e50e9ee4ad Mon Sep 17 00:00:00 2001 From: Oleksij Rempel Date: Tue, 7 Mar 2017 12:22:49 +0100 Subject: scripts: imx/mxs remove mxs-usb-loader ... and use imx-usb-loader instead Signed-off-by: Oleksij Rempel Signed-off-by: Sascha Hauer --- arch/arm/Kconfig | 1 + arch/arm/mach-imx/Kconfig | 7 -- arch/arm/mach-mxs/Kconfig | 7 -- scripts/Makefile | 5 +- scripts/imx/Kconfig | 7 ++ scripts/mxs-usb-loader.c | 236 ---------------------------------------------- 6 files changed, 9 insertions(+), 254 deletions(-) create mode 100644 scripts/imx/Kconfig delete mode 100644 scripts/mxs-usb-loader.c diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index e4663ea268..69c1d7c511 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -268,6 +268,7 @@ source arch/arm/mach-ep93xx/Kconfig 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/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig index 36d110758f..831755ce0d 100644 --- a/arch/arm/mach-imx/Kconfig +++ b/arch/arm/mach-imx/Kconfig @@ -656,13 +656,6 @@ endmenu 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-mxs/Kconfig b/arch/arm/mach-mxs/Kconfig index facab9c251..fed7b524de 100644 --- a/arch/arm/mach-mxs/Kconfig +++ b/arch/arm/mach-mxs/Kconfig @@ -143,11 +143,4 @@ endif 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/scripts/Makefile b/scripts/Makefile index 7f2527d1c2..8eda41e13b 100644 --- a/scripts/Makefile +++ b/scripts/Makefile @@ -22,9 +22,6 @@ hostprogs-$(CONFIG_ARCH_SOCFPGA) += socfpga_mkimage 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 @@ HOSTLOADLIBES_omap4_usbboot = -lpthread `pkg-config --libs libusb-1.0` 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 0000000000..fda9c639c1 --- /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/mxs-usb-loader.c b/scripts/mxs-usb-loader.c deleted file mode 100644 index 8529274d6e..0000000000 --- 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; -} -- cgit v1.2.3 From 0482159e9ab9fcd23ab8db2e9d6f585c3929d447 Mon Sep 17 00:00:00 2001 From: David Jander Date: Fri, 3 Mar 2017 08:33:53 +0100 Subject: drivers: clk: clk-imx6.c: Don't gate LDB and IPUs Depending on CONFIG_DRIVER_VIDEO_IMX_IPUV3 to decide whether to gate IPU clocks or not is rather fragile. Any inadvertent dependency on the IPU (like setting the NoC AQoS registers for i.MX6QP) will result in a freeze if CONFIG_DRIVER_VIDEO_IMX_IPUV3 is disabled. Signed-off-by: David Jander Signed-off-by: Sascha Hauer --- drivers/clk/imx/clk-imx6.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/clk/imx/clk-imx6.c b/drivers/clk/imx/clk-imx6.c index 8ac43bebb0..d0571bce5e 100644 --- a/drivers/clk/imx/clk-imx6.c +++ b/drivers/clk/imx/clk-imx6.c @@ -494,10 +494,7 @@ static int imx6_ccm_probe(struct device_d *dev) 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 -- cgit v1.2.3