diff options
Diffstat (limited to 'arch/arm/boards/protonic-imx6/board.c')
-rw-r--r-- | arch/arm/boards/protonic-imx6/board.c | 459 |
1 files changed, 341 insertions, 118 deletions
diff --git a/arch/arm/boards/protonic-imx6/board.c b/arch/arm/boards/protonic-imx6/board.c index a718d54df4..9e62dc1544 100644 --- a/arch/arm/boards/protonic-imx6/board.c +++ b/arch/arm/boards/protonic-imx6/board.c @@ -4,22 +4,27 @@ // SPDX-FileCopyrightText: 2020 Oleksij Rempel, Pengutronix #include <bbu.h> +#include <boot.h> +#include <bootm.h> #include <common.h> +#include <deep-probe.h> #include <environment.h> #include <fcntl.h> +#include <globalvar.h> #include <gpio.h> #include <i2c/i2c.h> -#include <mach/bbu.h> -#include <mach/imx6.h> +#include <mach/imx/bbu.h> +#include <mach/imx/imx6.h> +#include <mach/imx/ocotp-fusemap.h> #include <mfd/imx6q-iomuxc-gpr.h> #include <mfd/syscon.h> #include <net.h> #include <of_device.h> -#include <regmap.h> +#include <linux/regmap.h> #include <sys/mount.h> #include <sys/stat.h> #include <unistd.h> -#include <usb/usb.h> +#include <linux/usb/usb.h> #define GPIO_HW_REV_ID {\ {IMX_GPIO_NR(2, 8), GPIOF_DIR_IN | GPIOF_ACTIVE_LOW, "rev_id0"}, \ @@ -50,6 +55,8 @@ enum { HW_TYPE_LANMCU = 23, HW_TYPE_PLYBAS = 24, HW_TYPE_VICTGO = 28, + HW_TYPE_JOZACP = 30, + HW_TYPE_JOZACPP = 31, }; enum prt_imx6_kvg_pw_mode { @@ -70,18 +77,20 @@ struct prt_machine_data { unsigned int hw_rev; unsigned int i2c_addr; unsigned int i2c_adapter; + unsigned int emmc_usdhc; + unsigned int sd_usdhc; unsigned int flags; int (*init)(struct prt_imx6_priv *priv); }; struct prt_imx6_priv { - struct device_d *dev; + struct device *dev; const struct prt_machine_data *dcfg; unsigned int hw_id; unsigned int hw_rev; const char *name; - struct poller_async poller; - unsigned int usb_delay; + unsigned int no_usb_check; + char *ocotp_serial; }; struct prti6q_rfid_contents { @@ -118,11 +127,27 @@ static const struct gpio prt_imx6_kvg_gpios[] = { }, }; +static int prt_of_fixup_hwrev(struct prt_imx6_priv *priv) +{ + const char *compat; + char *buf; + + compat = of_device_get_match_compatible(priv->dev); + + buf = xasprintf("%s-m%u-r%u", compat, priv->hw_id, + priv->hw_rev); + barebox_set_of_machine_compatible(buf); + + free(buf); + + return 0; +} + static int prt_imx6_read_rfid(struct prt_imx6_priv *priv, void *buf, size_t size) { const struct prt_machine_data *dcfg = priv->dcfg; - struct device_d *dev = priv->dev; + struct device *dev = priv->dev; struct i2c_client cl; int ret; @@ -136,7 +161,7 @@ static int prt_imx6_read_rfid(struct prt_imx6_priv *priv, void *buf, /* 0x6000 user storage in the RFID tag */ ret = i2c_read_reg(&cl, 0x6000 | I2C_ADDR_16_BIT, buf, size); if (ret < 0) { - dev_err(dev, "Failed to read the RFID: %i\n", ret); + dev_err(dev, "Failed to read the RFID: %pe\n", ERR_PTR(ret)); return ret; } @@ -162,7 +187,7 @@ static u8 prt_imx6_calc_rfid_cs(void *buf, size_t size) static int prt_imx6_set_mac(struct prt_imx6_priv *priv, struct prti6q_rfid_contents *rfid) { - struct device_d *dev = priv->dev; + struct device *dev = priv->dev; struct device_node *node; node = of_find_node_by_alias(of_get_root_node(), "ethernet0"); @@ -171,11 +196,11 @@ static int prt_imx6_set_mac(struct prt_imx6_priv *priv, return -ENODEV; } - if (!is_valid_ether_addr(&rfid->mac[0])) { - unsigned char ethaddr_str[sizeof("xx:xx:xx:xx:xx:xx")]; + if (!of_device_is_available(node)) + return 0; - ethaddr_to_string(&rfid->mac[0], ethaddr_str); - dev_err(dev, "bad MAC addr: %s\n", ethaddr_str); + if (!is_valid_ether_addr(&rfid->mac[0])) { + dev_err(dev, "bad MAC addr: %pM\n", &rfid->mac[0]); return -EILSEQ; } @@ -185,37 +210,18 @@ static int prt_imx6_set_mac(struct prt_imx6_priv *priv, return 0; } -static int prt_of_fixup_serial(struct device_node *dstroot, void *arg) -{ - struct device_node *srcroot = arg; - const char *ser; - int len; - - ser = of_get_property(srcroot, "serial-number", &len); - return of_set_property(dstroot, "serial-number", ser, len, 1); -} - -static void prt_oftree_fixup_serial(const char *serial) -{ - struct device_node *root = of_get_root_node(); - - of_set_property(root, "serial-number", serial, strlen(serial) + 1, 1); - of_register_fixup(prt_of_fixup_serial, root); -} - -static int prt_imx6_set_serial(struct prt_imx6_priv *priv, - struct prti6q_rfid_contents *rfid) +static int prt_imx6_set_serial(struct prt_imx6_priv *priv, char *serial) { - rfid->serial[9] = 0; /* Failsafe */ - dev_info(priv->dev, "Serial number: %s\n", rfid->serial); - prt_oftree_fixup_serial(rfid->serial); + serial[9] = 0; /* Failsafe */ + dev_info(priv->dev, "Serial number: %s\n", serial); + barebox_set_serial_number(serial); return 0; } static int prt_imx6_read_i2c_mac_serial(struct prt_imx6_priv *priv) { - struct device_d *dev = priv->dev; + struct device *dev = priv->dev; struct prti6q_rfid_contents rfid; int ret; @@ -232,16 +238,60 @@ static int prt_imx6_read_i2c_mac_serial(struct prt_imx6_priv *priv) if (ret) return ret; - ret = prt_imx6_set_serial(priv, &rfid); + ret = prt_imx6_set_serial(priv, rfid.serial); + if (ret) + return ret; + + return 0; +} + +#define PRT_IMX6_GP1_FMT_DEC BIT(31) + +static int prt_imx6_read_ocotp_serial(struct prt_imx6_priv *priv) +{ + int ret; + unsigned val; + + ret = imx_ocotp_read_field(OCOTP_GP1, &val); + if (ret) { + dev_err(priv->dev, "Failed to read ocotp serial (%i)\n", ret); + return ret; + } + + if (!(val & PRT_IMX6_GP1_FMT_DEC)) + return -EINVAL; + val &= PRT_IMX6_GP1_FMT_DEC - 1; + + priv->ocotp_serial = xasprintf("%u", val); + + return prt_imx6_set_serial(priv, priv->ocotp_serial); +} + +static int prt_imx6_set_ocotp_serial(struct param_d *param, void *driver_priv) +{ + struct prt_imx6_priv *priv = driver_priv; + int ret; + unsigned val; + + ret = kstrtouint(priv->ocotp_serial, 10, &val); + if (ret) + return ret; + + if (val & PRT_IMX6_GP1_FMT_DEC) + return -ERANGE; + val |= PRT_IMX6_GP1_FMT_DEC; + + ret = imx_ocotp_write_field(OCOTP_GP1, val); if (ret) return ret; + barebox_set_serial_number(priv->ocotp_serial); return 0; } -static int prt_imx6_usb_mount(struct prt_imx6_priv *priv, char **usbdisk) +static int prt_imx6_usb_mount(struct prt_imx6_priv *priv) { - struct device_d *dev = priv->dev; + struct device *dev = priv->dev; const char *path; struct stat s; int ret; @@ -258,8 +308,6 @@ static int prt_imx6_usb_mount(struct prt_imx6_priv *priv, char **usbdisk) ret = mount(path, NULL, "usb", NULL); if (ret) goto exit_usb_mount; - - *usbdisk = strdup("disk0.0"); return 0; } @@ -269,8 +317,6 @@ static int prt_imx6_usb_mount(struct prt_imx6_priv *priv, char **usbdisk) ret = mount(path, NULL, "usb", NULL); if (ret) goto exit_usb_mount; - - *usbdisk = strdup("disk0"); return 0; } @@ -281,25 +327,21 @@ exit_usb_mount: #define OTG_PORTSC1 (MX6_OTG_BASE_ADDR+0x184) -static void prt_imx6_check_usb_boot(void *data) +static int prt_imx6_usb_boot(struct bootentry *entry, int verbose, int dryrun) { - struct prt_imx6_priv *priv = data; - struct device_d *dev = priv->dev; - char *second_word, *bootsrc, *usbdisk; + struct prt_imx6_priv *priv = prt_priv; + struct device *dev = priv->dev; + char *second_word; char buf[sizeof("vicut1q recovery")] = {}; - unsigned int v; + struct bootm_data bootm_data = {}; ssize_t size; int fd, ret; - v = readl(OTG_PORTSC1); - if ((v & 0x0c00) == 0) /* LS == SE0 ==> nothing connected */ - return; - usb_rescan(); - ret = prt_imx6_usb_mount(priv, &usbdisk); + ret = prt_imx6_usb_mount(priv); if (ret) - return; + return ret; fd = open("/usb/boot_target", O_RDONLY); if (fd < 0) { @@ -338,60 +380,125 @@ static void prt_imx6_check_usb_boot(void *data) goto exit_usb_boot; } + bootm_data_init_defaults(&bootm_data); + second_word++; if (strncmp(second_word, "usb", 3) == 0) { - bootsrc = usbdisk; + dev_info(dev, "Booting from USB drive\n"); + bootm_data.os_file = "/usb/linuximage.fit"; } else if (strncmp(second_word, "recovery", 8) == 0) { - bootsrc = "recovery"; + dev_info(dev, "Booting internal recovery OS\n"); + bootm_data.os_file = "/dev/mmc2.5"; } else { dev_err(dev, "Unknown boot target!\n"); ret = -ENODEV; goto exit_usb_boot; } - dev_info(dev, "detected valid usb boot target file, overwriting boot to: %s\n", bootsrc); - ret = setenv("global.boot.default", bootsrc); + ret = globalvar_add_simple("linux.bootargs.root", + "root=/dev/ram rw rootwait ramdisk_size=196608"); + if (ret) + goto exit_usb_boot; + + if (verbose) + bootm_data.verbose = verbose; + if (dryrun) + bootm_data.dryrun = dryrun; + + ret = bootm_boot(&bootm_data); if (ret) goto exit_usb_boot; - free(usbdisk); - return; + return 0; exit_usb_boot: dev_err(dev, "Failed to run usb boot: %s\n", strerror(-ret)); - free(usbdisk); - return; + return ret; +} + +static void prt_imx6_bootentry_release(struct bootentry *entry) +{ + free(entry); +} + +static int prt_imx6_bootentry_create(struct bootentries *bootentries, const char *name) +{ + struct bootentry *entry; + + entry = xzalloc(sizeof(*entry)); + if (!entry) + return -ENOMEM; + + entry->me.type = MENU_ENTRY_NORMAL; + entry->release = prt_imx6_bootentry_release; + entry->boot = prt_imx6_usb_boot; + entry->title = xstrdup(name); + entry->description = xstrdup("Boot FIT image of a USB drive"); + bootentries_add_entry(bootentries, entry); + + return 0; +} + +static int prt_imx6_bootentry_provider(struct bootentries *bootentries, + const char *name) +{ + int found = 0; + unsigned int v; + + if (strncmp(name, "prt-usb", 7)) + return found; + + v = readl(OTG_PORTSC1); + if ((v & 0x0c00) == 0) /* No usb device detected */ + return found; + + if (!prt_imx6_bootentry_create(bootentries, name)) + found = 1; + + return found; } static int prt_imx6_env_init(struct prt_imx6_priv *priv) { const struct prt_machine_data *dcfg = priv->dcfg; - struct device_d *dev = priv->dev; - char *delay, *bootsrc; + struct device *dev = priv->dev; + char *delay, *bootsrc, *boot_targets; + unsigned int autoboot_timeout; int ret; ret = setenv("global.linux.bootargs.base", "consoleblank=0 vt.color=0x00"); if (ret) goto exit_env_init; - if (dcfg->flags & PRT_IMX6_USB_LONG_DELAY) - priv->usb_delay = 4; - else - priv->usb_delay = 1; - - /* the usb_delay value is used for poller_call_async() */ - delay = basprintf("%d", priv->usb_delay); - ret = setenv("global.autoboot_timeout", delay); - if (ret) - goto exit_env_init; + if (priv->no_usb_check) { + set_autoboot_state(AUTOBOOT_BOOT); + } else { + if (dcfg->flags & PRT_IMX6_USB_LONG_DELAY) + autoboot_timeout = 4; + else + autoboot_timeout = 1; + + /* the usb_delay value is used for poller_call_async() */ + delay = basprintf("%d", autoboot_timeout); + ret = setenv("global.autoboot_timeout", delay); + free(delay); + if (ret) + goto exit_env_init; + } if (dcfg->flags & PRT_IMX6_BOOTCHOOSER) bootsrc = "bootchooser"; else bootsrc = "mmc2"; - ret = setenv("global.boot.default", bootsrc); + if (!priv->no_usb_check) + boot_targets = xasprintf("prt-usb %s", bootsrc); + else + boot_targets = xstrdup(bootsrc); + + ret = setenv("global.boot.default", boot_targets); + free(boot_targets); if (ret) goto exit_env_init; @@ -399,7 +506,7 @@ static int prt_imx6_env_init(struct prt_imx6_priv *priv) return 0; exit_env_init: - dev_err(dev, "Failed to set env: %i\n", ret); + dev_err(dev, "Failed to set env: %pe\n", ERR_PTR(ret)); return ret; } @@ -408,6 +515,7 @@ static int prt_imx6_bbu(struct prt_imx6_priv *priv) { const struct prt_machine_data *dcfg = priv->dcfg; u32 emmc_flags = 0; + char *devicefile; int ret; if (dcfg->flags & PRT_IMX6_BOOTSRC_SPI_NOR) { @@ -419,25 +527,37 @@ static int prt_imx6_bbu(struct prt_imx6_priv *priv) emmc_flags = BBU_HANDLER_FLAG_DEFAULT; } - ret = imx6_bbu_internal_mmcboot_register_handler("eMMC", "/dev/mmc2", + devicefile = basprintf("/dev/mmc%d", dcfg->emmc_usdhc); + if (!devicefile) { + ret = -ENOMEM; + goto exit_bbu; + } + ret = imx6_bbu_internal_mmcboot_register_handler("eMMC", devicefile, emmc_flags); if (ret) goto exit_bbu; - ret = imx6_bbu_internal_mmc_register_handler("SD", "/dev/mmc0", 0); + devicefile = basprintf("/dev/mmc%d", dcfg->sd_usdhc); + if (!devicefile) { + ret = -ENOMEM; + goto exit_bbu; + } + + ret = imx6_bbu_internal_mmc_register_handler("SD", devicefile, 0); if (ret) goto exit_bbu; return 0; exit_bbu: - dev_err(priv->dev, "Failed to register bbu: %i\n", ret); + dev_err(priv->dev, "Failed to register bbu: %pe\n", ERR_PTR(ret)); return ret; } static int prt_imx6_devices_init(void) { struct prt_imx6_priv *priv = prt_priv; - int ret; + struct device *ocotp_dev; + struct param_d *p; if (!priv) return 0; @@ -447,19 +567,28 @@ static int prt_imx6_devices_init(void) prt_imx6_bbu(priv); - prt_imx6_read_i2c_mac_serial(priv); + /* + * Read serial number from fuses. On success we'll assume the imx_ocotp + * driver takes care of providing the mac address if needed. On + * failure we'll fallback to reading and setting serial and mac from an + * attached RFID eeprom. + */ + if (prt_imx6_read_ocotp_serial(priv) != 0) + prt_imx6_read_i2c_mac_serial(priv); + + bootentry_register_provider(prt_imx6_bootentry_provider); prt_imx6_env_init(priv); - ret = poller_async_register(&priv->poller, "usb-boot"); - if (ret) { - dev_err(priv->dev, "can't setup poller\n"); - return ret; + ocotp_dev = get_device_by_name("ocotp0"); + if (ocotp_dev) { + p = dev_add_param_string(ocotp_dev, "serial_number", + prt_imx6_set_ocotp_serial, NULL, + &priv->ocotp_serial, priv); + if (IS_ERR(p)) + return PTR_ERR(p); } - poller_call_async(&priv->poller, priv->usb_delay * SECOND, - &prt_imx6_check_usb_boot, priv); - return 0; } late_initcall(prt_imx6_devices_init); @@ -483,7 +612,7 @@ static int prt_imx6_yaco_set_kvg_power_mode(struct prt_imx6_priv *priv, const char *serial) { static const char command[] = "{\"command\":\"mode\",\"value\":\"kvg\",\"on2\":true}"; - struct device_d *dev = priv->dev; + struct device *dev = priv->dev; struct console_device *yccon; int ret; @@ -503,7 +632,7 @@ static int prt_imx6_yaco_set_kvg_power_mode(struct prt_imx6_priv *priv, return 0; exit_yaco_set_kvg_power_mode: - dev_err(dev, "Failed to set YaCO pw mode: %i", ret); + dev_err(dev, "Failed to set YaCO pw mode: %pe", ERR_PTR(ret)); return ret; } @@ -611,6 +740,34 @@ static int prt_imx6_init_kvg_yaco(struct prt_imx6_priv *priv) return prt_imx6_init_kvg_power(priv, PW_MODE_KVG_WITH_YACO); } +#define GPIO_KEY_F6 (0xe0 + 5) +#define GPIO_KEY_CYCLE (0xe0 + 2) + +static int prt_imx6_init_prtvt7(struct prt_imx6_priv *priv) +{ + /* This function relies heavely on the gpio-pca9539 driver */ + + gpio_direction_input(GPIO_KEY_F6); + gpio_direction_input(GPIO_KEY_CYCLE); + + if (gpio_get_value(GPIO_KEY_CYCLE) && gpio_get_value(GPIO_KEY_F6)) + priv->no_usb_check = 1; + + return 0; +} + +static int prt_imx6_init_prtwd3(struct prt_imx6_priv *priv) +{ + void __iomem *iomux = (void *)MX6_IOMUXC_BASE_ADDR; + uint32_t val; + + val = readl(iomux + IOMUXC_GPR1); + val |= IMX6Q_GPR1_ENET_CLK_SEL_ANATOP; + writel(val, iomux + IOMUXC_GPR1); + + return 0; +} + static int prt_imx6_rfid_fixup(struct prt_imx6_priv *priv, struct device_node *root) { @@ -628,24 +785,22 @@ static int prt_imx6_rfid_fixup(struct prt_imx6_priv *priv, } i2c_node = of_find_node_by_alias(root, alias); + kfree(alias); if (!i2c_node) { dev_err(priv->dev, "Unsupported i2c adapter\n"); - ret = -ENODEV; - goto free_alias; + return -ENODEV; } eeprom_node_name = basprintf("/eeprom@%x", dcfg->i2c_addr); if (!eeprom_node_name) { - ret = -ENOMEM; - goto free_alias; + return -ENOMEM; } node = of_create_node(i2c_node, eeprom_node_name); if (!node) { dev_err(priv->dev, "Failed to create node %s\n", eeprom_node_name); - ret = -ENOMEM; - goto free_eeprom; + return -ENOMEM; } ret = of_property_write_string(node, "compatible", "atmel,24c256"); @@ -669,10 +824,8 @@ static int prt_imx6_rfid_fixup(struct prt_imx6_priv *priv, return 0; free_eeprom: kfree(eeprom_node_name); -free_alias: - kfree(alias); exit_error: - dev_err(priv->dev, "Failed to apply fixup: %i\n", ret); + dev_err(priv->dev, "Failed to apply fixup: %pe\n", ERR_PTR(ret)); return ret; } @@ -693,7 +846,7 @@ static int prt_imx6_of_fixup(struct device_node *root, void *data) return 0; exit_of_fixups: - dev_err(priv->dev, "Failed to apply OF fixups: %i\n", ret); + dev_err(priv->dev, "Failed to apply OF fixups: %pe\n", ERR_PTR(ret)); return ret; } @@ -701,8 +854,17 @@ static int prt_imx6_get_id(struct prt_imx6_priv *priv) { struct gpio gpios_type[] = GPIO_HW_TYPE_ID; struct gpio gpios_rev[] = GPIO_HW_REV_ID; + struct device_node *gpio_np = NULL; int ret; + gpio_np = of_find_node_by_name_address(NULL, "gpio@20a0000"); + if (!gpio_np) + return -ENODEV; + + ret = of_device_ensure_probed(gpio_np); + if (ret) + return ret; + ret = gpio_array_to_id(gpios_type, ARRAY_SIZE(gpios_type), &priv->hw_id); if (ret) goto exit_get_id; @@ -713,7 +875,7 @@ static int prt_imx6_get_id(struct prt_imx6_priv *priv) return 0; exit_get_id: - dev_err(priv->dev, "Failed to read gpio ID: %i\n", ret); + dev_err(priv->dev, "Failed to read gpio ID: %pe\n", ERR_PTR(ret)); return ret; } @@ -749,10 +911,9 @@ exit_get_dcfg: return ret; } -static int prt_imx6_probe(struct device_d *dev) +static int prt_imx6_probe(struct device *dev) { struct prt_imx6_priv *priv; - const char *name, *ptr; struct param_d *p; int ret; @@ -761,9 +922,7 @@ static int prt_imx6_probe(struct device_d *dev) return -ENOMEM; priv->dev = dev; - name = of_device_get_match_compatible(priv->dev); - ptr = strchr(name, ','); - priv->name = ptr ? ptr + 1 : name; + priv->name = of_get_machine_compatible(); pr_info("Detected machine type: %s\n", priv->name); @@ -773,6 +932,7 @@ static int prt_imx6_probe(struct device_d *dev) pr_info(" HW type: %d\n", priv->hw_id); pr_info(" HW revision: %d\n", priv->hw_rev); + prt_of_fixup_hwrev(priv); ret = prt_imx6_get_dcfg(priv); if (ret) @@ -794,12 +954,6 @@ static int prt_imx6_probe(struct device_d *dev) if (ret) goto free_priv; - ret = of_register_fixup(prt_imx6_of_fixup, priv); - if (ret) { - dev_err(dev, "Failed to register fixup\n"); - goto free_priv; - } - prt_priv = priv; return 0; @@ -814,6 +968,8 @@ static const struct prt_machine_data prt_imx6_cfg_alti6p[] = { .hw_rev = 0, .i2c_addr = 0x51, .i2c_adapter = 0, + .emmc_usdhc = 2, + .sd_usdhc = 0, .flags = PRT_IMX6_BOOTSRC_EMMC, }, { .hw_id = UINT_MAX @@ -826,6 +982,8 @@ static const struct prt_machine_data prt_imx6_cfg_victgo[] = { .hw_rev = 0, .i2c_addr = 0x51, .i2c_adapter = 0, + .emmc_usdhc = 2, + .sd_usdhc = 0, .init = prt_imx6_init_victgo, .flags = PRT_IMX6_BOOTSRC_SPI_NOR, }, { @@ -839,12 +997,16 @@ static const struct prt_machine_data prt_imx6_cfg_vicut1[] = { .hw_rev = 0, .i2c_addr = 0x50, .i2c_adapter = 1, + .emmc_usdhc = 2, + .sd_usdhc = 0, .flags = PRT_IMX6_BOOTSRC_SPI_NOR, }, { .hw_id = HW_TYPE_VICUT1, .hw_rev = 1, .i2c_addr = 0x51, .i2c_adapter = 0, + .emmc_usdhc = 2, + .sd_usdhc = 0, .init = prt_imx6_init_kvg_yaco, .flags = PRT_IMX6_BOOTSRC_SPI_NOR, }, { @@ -852,6 +1014,8 @@ static const struct prt_machine_data prt_imx6_cfg_vicut1[] = { .hw_rev = 1, .i2c_addr = 0x51, .i2c_adapter = 0, + .emmc_usdhc = 2, + .sd_usdhc = 0, .init = prt_imx6_init_kvg_new, .flags = PRT_IMX6_BOOTSRC_SPI_NOR, }, { @@ -865,12 +1029,16 @@ static const struct prt_machine_data prt_imx6_cfg_vicut1q[] = { .hw_rev = 0, .i2c_addr = 0x50, .i2c_adapter = 1, + .emmc_usdhc = 2, + .sd_usdhc = 0, .flags = PRT_IMX6_BOOTSRC_SPI_NOR, }, { .hw_id = HW_TYPE_VICUT1, .hw_rev = 1, .i2c_addr = 0x51, .i2c_adapter = 0, + .emmc_usdhc = 2, + .sd_usdhc = 0, .init = prt_imx6_init_kvg_yaco, .flags = PRT_IMX6_BOOTSRC_SPI_NOR, }, { @@ -878,6 +1046,8 @@ static const struct prt_machine_data prt_imx6_cfg_vicut1q[] = { .hw_rev = 0, .i2c_addr = 0x51, .i2c_adapter = 0, + .emmc_usdhc = 2, + .sd_usdhc = 0, .init = prt_imx6_init_kvg_yaco, .flags = PRT_IMX6_BOOTSRC_SPI_NOR, }, { @@ -885,6 +1055,8 @@ static const struct prt_machine_data prt_imx6_cfg_vicut1q[] = { .hw_rev = 1, .i2c_addr = 0x51, .i2c_adapter = 0, + .emmc_usdhc = 2, + .sd_usdhc = 0, .init = prt_imx6_init_kvg_new, .flags = PRT_IMX6_BOOTSRC_SPI_NOR, }, { @@ -898,6 +1070,8 @@ static const struct prt_machine_data prt_imx6_cfg_vicutp[] = { .hw_rev = 1, .i2c_addr = 0x51, .i2c_adapter = 0, + .emmc_usdhc = 2, + .sd_usdhc = 0, .init = prt_imx6_init_kvg_new, .flags = PRT_IMX6_BOOTSRC_SPI_NOR, }, { @@ -911,6 +1085,8 @@ static const struct prt_machine_data prt_imx6_cfg_lanmcu[] = { .hw_rev = 0, .i2c_addr = 0x51, .i2c_adapter = 0, + .emmc_usdhc = 2, + .sd_usdhc = 0, .flags = PRT_IMX6_BOOTSRC_EMMC | PRT_IMX6_BOOTCHOOSER, }, { .hw_id = UINT_MAX @@ -923,6 +1099,8 @@ static const struct prt_machine_data prt_imx6_cfg_plybas[] = { .hw_rev = 0, .i2c_addr = 0x51, .i2c_adapter = 0, + .emmc_usdhc = 2, + .sd_usdhc = 0, .flags = PRT_IMX6_BOOTSRC_SPI_NOR | PRT_IMX6_USB_LONG_DELAY, }, { .hw_id = UINT_MAX @@ -935,6 +1113,8 @@ static const struct prt_machine_data prt_imx6_cfg_plym2m[] = { .hw_rev = 0, .i2c_addr = 0x51, .i2c_adapter = 0, + .emmc_usdhc = 2, + .sd_usdhc = 0, .flags = PRT_IMX6_BOOTSRC_SPI_NOR | PRT_IMX6_USB_LONG_DELAY, }, { .hw_id = UINT_MAX @@ -947,8 +1127,10 @@ static const struct prt_machine_data prt_imx6_cfg_prti6g[] = { .hw_rev = 0, .i2c_addr = 0x51, .i2c_adapter = 0, + .emmc_usdhc = 1, + .sd_usdhc = 0, .init = prt_imx6_init_prti6g, - .flags = PRT_IMX6_BOOTSRC_EMMC, + .flags = PRT_IMX6_BOOTSRC_EMMC | PRT_IMX6_BOOTCHOOSER, }, { .hw_id = UINT_MAX }, @@ -960,12 +1142,16 @@ static const struct prt_machine_data prt_imx6_cfg_prti6q[] = { .hw_rev = 0, .i2c_addr = 0x51, .i2c_adapter = 2, + .emmc_usdhc = 2, + .sd_usdhc = 0, .flags = PRT_IMX6_BOOTSRC_SPI_NOR, }, { .hw_id = HW_TYPE_PRTI6Q, .hw_rev = 1, .i2c_addr = 0x51, .i2c_adapter = 0, + .emmc_usdhc = 2, + .sd_usdhc = 0, .flags = PRT_IMX6_BOOTSRC_SPI_NOR, }, { .hw_id = UINT_MAX @@ -978,6 +1164,8 @@ static const struct prt_machine_data prt_imx6_cfg_prtmvt[] = { .hw_rev = 0, .i2c_addr = 0x51, .i2c_adapter = 0, + .emmc_usdhc = 2, + .sd_usdhc = 0, .flags = PRT_IMX6_BOOTSRC_SPI_NOR, }, { .hw_id = UINT_MAX @@ -990,6 +1178,8 @@ static const struct prt_machine_data prt_imx6_cfg_prtrvt[] = { .hw_rev = 0, .i2c_addr = 0x51, .i2c_adapter = 0, + .emmc_usdhc = 2, + .sd_usdhc = 0, .flags = PRT_IMX6_BOOTSRC_SPI_NOR, }, { .hw_id = UINT_MAX @@ -1002,7 +1192,11 @@ static const struct prt_machine_data prt_imx6_cfg_prtvt7[] = { .hw_rev = 0, .i2c_addr = 0x51, .i2c_adapter = 0, - .flags = PRT_IMX6_BOOTSRC_EMMC | PRT_IMX6_BOOTCHOOSER, + .emmc_usdhc = 2, + .sd_usdhc = 0, + .init = prt_imx6_init_prtvt7, + .flags = PRT_IMX6_BOOTSRC_EMMC | PRT_IMX6_BOOTCHOOSER | + PRT_IMX6_USB_LONG_DELAY, }, { .hw_id = UINT_MAX }, @@ -1014,6 +1208,8 @@ static const struct prt_machine_data prt_imx6_cfg_prtwd2[] = { .hw_rev = 0, .i2c_addr = 0x51, .i2c_adapter = 0, + .emmc_usdhc = 2, + .sd_usdhc = 0, .flags = PRT_IMX6_BOOTSRC_EMMC, }, { .hw_id = UINT_MAX @@ -1026,19 +1222,44 @@ static const struct prt_machine_data prt_imx6_cfg_prtwd3[] = { .hw_rev = 2, .i2c_addr = 0x51, .i2c_adapter = 0, + .emmc_usdhc = 2, + .sd_usdhc = 0, + .init = prt_imx6_init_prtwd3, .flags = PRT_IMX6_BOOTSRC_EMMC, }, { .hw_id = UINT_MAX }, }; +static const struct prt_machine_data prt_imx6_cfg_jozacp[] = { + { + .hw_id = HW_TYPE_JOZACP, + .hw_rev = 1, + .i2c_addr = 0x51, + .i2c_adapter = 0, + .emmc_usdhc = 0, + .sd_usdhc = 2, + .flags = PRT_IMX6_BOOTSRC_EMMC | PRT_IMX6_BOOTCHOOSER, + }, { + .hw_id = HW_TYPE_JOZACPP, + .hw_rev = 1, + .i2c_addr = 0x51, + .i2c_adapter = 0, + .emmc_usdhc = 0, + .sd_usdhc = 2, + .flags = PRT_IMX6_BOOTSRC_EMMC | PRT_IMX6_BOOTCHOOSER, + }, { + .hw_id = UINT_MAX + }, +}; + static const struct of_device_id prt_imx6_of_match[] = { { .compatible = "alt,alti6p", .data = &prt_imx6_cfg_alti6p }, { .compatible = "kvg,victgo", .data = &prt_imx6_cfg_victgo }, { .compatible = "kvg,vicut1", .data = &prt_imx6_cfg_vicut1 }, { .compatible = "kvg,vicut1q", .data = &prt_imx6_cfg_vicut1q }, { .compatible = "kvg,vicutp", .data = &prt_imx6_cfg_vicutp }, - { .compatible = "lan,lanmcu", .data = &prt_imx6_cfg_lanmcu }, + { .compatible = "vdl,lanmcu", .data = &prt_imx6_cfg_lanmcu }, { .compatible = "ply,plybas", .data = &prt_imx6_cfg_plybas }, { .compatible = "ply,plym2m", .data = &prt_imx6_cfg_plym2m }, { .compatible = "prt,prti6g", .data = &prt_imx6_cfg_prti6g }, @@ -1048,10 +1269,12 @@ static const struct of_device_id prt_imx6_of_match[] = { { .compatible = "prt,prtvt7", .data = &prt_imx6_cfg_prtvt7 }, { .compatible = "prt,prtwd2", .data = &prt_imx6_cfg_prtwd2 }, { .compatible = "prt,prtwd3", .data = &prt_imx6_cfg_prtwd3 }, + { .compatible = "joz,jozacp", .data = &prt_imx6_cfg_jozacp }, { /* sentinel */ }, }; +BAREBOX_DEEP_PROBE_ENABLE(prt_imx6_of_match); -static struct driver_d prt_imx6_board_driver = { +static struct driver prt_imx6_board_driver = { .name = "board-protonic-imx6", .probe = prt_imx6_probe, .of_compatible = DRV_OF_COMPAT(prt_imx6_of_match), |