From 5b613d386aad31c3a80d64261a54d565a0f7c955 Mon Sep 17 00:00:00 2001 From: Konstantin Porotchkin Date: Thu, 8 Dec 2016 12:22:27 +0200 Subject: [PATCH 1/9] arm64: mvebu: Modify the A8K SPI and I2C config in DTS Align the Armada-8040-db and Armada-7040-db SPI and I2C DTS settings with latest DB settings: - 8040-db: disable i2c0 and spi0 on AP (MPPs are reserved for SDIO) - 8040-db: disable cps_i2c0 on CP1 - 8040-db: enable spi1 on CP1 (the new location of the boot flash) The spi1 on CP1 is aliased as spi0 since this is the way the driver enumerates it. Signed-off-by: Konstantin Porotchkin Reviewed-by: Stefan Roese Cc: Stefan Roese Cc: Nadav Haklai Cc: Neta Zur Hershkovits Cc: Omri Itach Cc: Igal Liberman Cc: Haim Boot Cc: Hanna Hawa Signed-off-by: Stefan Roese --- arch/arm/dts/armada-7040-db.dts | 32 ---------------------- arch/arm/dts/armada-8040-db.dts | 60 +++++++++++++++++------------------------ 2 files changed, 25 insertions(+), 67 deletions(-) diff --git a/arch/arm/dts/armada-7040-db.dts b/arch/arm/dts/armada-7040-db.dts index b8fe5a9..1e4d676 100644 --- a/arch/arm/dts/armada-7040-db.dts +++ b/arch/arm/dts/armada-7040-db.dts @@ -66,38 +66,6 @@ }; }; -&i2c0 { - status = "okay"; - clock-frequency = <100000>; -}; - -&spi0 { - status = "okay"; - - spi-flash@0 { - #address-cells = <1>; - #size-cells = <1>; - compatible = "jedec,spi-nor"; - reg = <0>; - spi-max-frequency = <10000000>; - - partitions { - compatible = "fixed-partitions"; - #address-cells = <1>; - #size-cells = <1>; - - partition@0 { - label = "U-Boot"; - reg = <0 0x200000>; - }; - partition@400000 { - label = "Filesystem"; - reg = <0x200000 0xce0000>; - }; - }; - }; -}; - &uart0 { status = "okay"; }; diff --git a/arch/arm/dts/armada-8040-db.dts b/arch/arm/dts/armada-8040-db.dts index 7fb674b..86666a1 100644 --- a/arch/arm/dts/armada-8040-db.dts +++ b/arch/arm/dts/armada-8040-db.dts @@ -57,7 +57,7 @@ aliases { i2c0 = &cpm_i2c0; - spi0 = &spi0; + spi0 = &cps_spi1; }; memory@00000000 { @@ -66,38 +66,6 @@ }; }; -&i2c0 { - status = "okay"; - clock-frequency = <100000>; -}; - -&spi0 { - status = "okay"; - - spi-flash@0 { - #address-cells = <1>; - #size-cells = <1>; - compatible = "jedec,spi-nor"; - reg = <0>; - spi-max-frequency = <10000000>; - - partitions { - compatible = "fixed-partitions"; - #address-cells = <1>; - #size-cells = <1>; - - partition@0 { - label = "U-Boot"; - reg = <0 0x200000>; - }; - partition@400000 { - label = "Filesystem"; - reg = <0x200000 0xce0000>; - }; - }; - }; -}; - /* Accessible over the mini-USB CON9 connector on the main board */ &uart0 { status = "okay"; @@ -134,9 +102,31 @@ status = "okay"; }; -&cps_i2c0 { +&cps_spi1 { status = "okay"; - clock-frequency = <100000>; + + spi-flash@0 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <10000000>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + label = "U-Boot"; + reg = <0 0x200000>; + }; + partition@400000 { + label = "Filesystem"; + reg = <0x200000 0xce0000>; + }; + }; + }; }; /* CON4 on CP1 expansion */ From fa61ef6b4980dbc009e93baadbfcb1daa359d74b Mon Sep 17 00:00:00 2001 From: Konstantin Porotchkin Date: Thu, 8 Dec 2016 12:22:28 +0200 Subject: [PATCH 2/9] arm64: mvebu: Add bubt command for flash image burn Add support for mvebu bubt command for flash image load, check and burn on boot device. Signed-off-by: Konstantin Porotchkin Reviewed-by: Stefan Roese Cc: Stefan Roese Cc: Nadav Haklai Cc: Neta Zur Hershkovits Cc: Omri Itach Cc: Igal Liberman Cc: Haim Boot Cc: Hanna Hawa Signed-off-by: Stefan Roese --- cmd/Kconfig | 3 + cmd/Makefile | 2 + cmd/mvebu/Kconfig | 52 ++++ cmd/mvebu/Makefile | 8 + cmd/mvebu/bubt.c | 767 +++++++++++++++++++++++++++++++++++++++++++++++++ doc/mvebu/cmd/bubt.txt | 64 +++++ 6 files changed, 896 insertions(+) create mode 100644 cmd/mvebu/Kconfig create mode 100644 cmd/mvebu/Makefile create mode 100644 cmd/mvebu/bubt.c create mode 100644 doc/mvebu/cmd/bubt.txt diff --git a/cmd/Kconfig b/cmd/Kconfig index 586a645..bffa713 100644 --- a/cmd/Kconfig +++ b/cmd/Kconfig @@ -653,6 +653,9 @@ config CMD_QFW This provides access to the QEMU firmware interface. The main feature is to allow easy loading of files passed to qemu-system via -kernel / -initrd + +source "cmd/mvebu/Kconfig" + endmenu config CMD_BOOTSTAGE diff --git a/cmd/Makefile b/cmd/Makefile index 9c9a9d1..34bc544 100644 --- a/cmd/Makefile +++ b/cmd/Makefile @@ -163,3 +163,5 @@ obj-$(CONFIG_CMD_BLOB) += blob.o # core command obj-y += nvedit.o + +obj-$(CONFIG_ARCH_MVEBU) += mvebu/ diff --git a/cmd/mvebu/Kconfig b/cmd/mvebu/Kconfig new file mode 100644 index 0000000..ad10a57 --- /dev/null +++ b/cmd/mvebu/Kconfig @@ -0,0 +1,52 @@ +menu "MVEBU commands" +depends on ARCH_MVEBU + +config CMD_MVEBU_BUBT + bool "bubt" + default n + help + bubt - Burn a u-boot image to flash + For details about bubt command please see the documentation + in doc/mvebu/cmd/bubt.txt + +choice + prompt "Flash for image" + default MVEBU_SPI_BOOT + +config MVEBU_NAND_BOOT + bool "NAND flash boot" + depends on NAND_PXA3XX + help + Enable boot from NAND flash. + Allow usage of NAND flash as a target for "bubt" command + For details about bubt command please see the documentation + in doc/mvebu/cmd/bubt.txt + +config MVEBU_SPI_BOOT + bool "SPI flash boot" + depends on SPI_FLASH + help + Enable boot from SPI flash. + Allow usage of SPI flash as a target for "bubt" command + For details about bubt command please see the documentation + in doc/mvebu/cmd/bubt.txt + +config MVEBU_MMC_BOOT + bool "eMMC flash boot" + depends on MVEBU_MMC + help + Enable boot from eMMC boot partition + Allow usage of eMMC/SD device as a target for "bubt" command + For details about bubt command please see the documentation + in doc/mvebu/cmd/bubt.txt + +endchoice + +config MVEBU_UBOOT_DFLT_NAME + string "Default image name for bubt command" + default "flash-image.bin" + help + This option should contain a default file name to be used with + MVEBU "bubt" command if the source file name is omitted + +endmenu diff --git a/cmd/mvebu/Makefile b/cmd/mvebu/Makefile new file mode 100644 index 0000000..03de53e --- /dev/null +++ b/cmd/mvebu/Makefile @@ -0,0 +1,8 @@ +# +# Copyright (C) 2016 Marvell International Ltd. +# +# SPDX-License-Identifier: GPL-2.0 +# https://spdx.org/licenses + + +obj-$(CONFIG_CMD_MVEBU_BUBT) += bubt.o diff --git a/cmd/mvebu/bubt.c b/cmd/mvebu/bubt.c new file mode 100644 index 0000000..1cbfcf0 --- /dev/null +++ b/cmd/mvebu/bubt.c @@ -0,0 +1,767 @@ +/* + * Copyright (C) 2016 Marvell International Ltd. + * + * SPDX-License-Identifier: GPL-2.0 + * https://spdx.org/licenses + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef CONFIG_SYS_MMC_ENV_DEV +#define CONFIG_SYS_MMC_ENV_DEV 0 +#endif + +#if defined(CONFIG_ARMADA_8K) +#define MAIN_HDR_MAGIC 0xB105B002 + +struct mvebu_image_header { + u32 magic; /* 0-3 */ + u32 prolog_size; /* 4-7 */ + u32 prolog_checksum; /* 8-11 */ + u32 boot_image_size; /* 12-15 */ + u32 boot_image_checksum; /* 16-19 */ + u32 rsrvd0; /* 20-23 */ + u32 load_addr; /* 24-27 */ + u32 exec_addr; /* 28-31 */ + u8 uart_cfg; /* 32 */ + u8 baudrate; /* 33 */ + u8 ext_count; /* 34 */ + u8 aux_flags; /* 35 */ + u32 io_arg_0; /* 36-39 */ + u32 io_arg_1; /* 40-43 */ + u32 io_arg_2; /* 43-47 */ + u32 io_arg_3; /* 48-51 */ + u32 rsrvd1; /* 52-55 */ + u32 rsrvd2; /* 56-59 */ + u32 rsrvd3; /* 60-63 */ +}; +#elif defined(CONFIG_ARMADA_3700) /* A3700 */ +#define HASH_SUM_LEN 16 +#define IMAGE_VERSION_3_6_0 0x030600 +#define IMAGE_VERSION_3_5_0 0x030500 + +struct common_tim_data { + u32 version; + u32 identifier; + u32 trusted; + u32 issue_date; + u32 oem_unique_id; + u32 reserved[5]; /* Reserve 20 bytes */ + u32 boot_flash_sign; + u32 num_images; + u32 num_keys; + u32 size_of_reserved; +}; + +struct mvebu_image_info { + u32 image_id; + u32 next_image_id; + u32 flash_entry_addr; + u32 load_addr; + u32 image_size; + u32 image_size_to_hash; + u32 hash_algorithm_id; + u32 hash[HASH_SUM_LEN]; /* Reserve 512 bits for the hash */ + u32 partition_number; + u32 enc_algorithm_id; + u32 encrypt_start_offset; + u32 encrypt_size; +}; +#endif /* CONFIG_ARMADA_XXX */ + +struct bubt_dev { + char name[8]; + size_t (*read)(const char *file_name); + int (*write)(size_t image_size); + int (*active)(void); +}; + +static ulong get_load_addr(void) +{ + const char *addr_str; + unsigned long addr; + + addr_str = getenv("loadaddr"); + if (addr_str) + addr = simple_strtoul(addr_str, NULL, 16); + else + addr = CONFIG_SYS_LOAD_ADDR; + + return addr; +} + +/******************************************************************** + * eMMC services + ********************************************************************/ +#ifdef CONFIG_DM_MMC +static int mmc_burn_image(size_t image_size) +{ + struct mmc *mmc; + lbaint_t start_lba; + lbaint_t blk_count; + ulong blk_written; + int err; + const u8 mmc_dev_num = CONFIG_SYS_MMC_ENV_DEV; + + mmc = find_mmc_device(mmc_dev_num); + if (!mmc) { + printf("No SD/MMC/eMMC card found\n"); + return -ENOMEDIUM; + } + + err = mmc_init(mmc); + if (err) { + printf("%s(%d) init failed\n", IS_SD(mmc) ? "SD" : "MMC", + mmc_dev_num); + return err; + } + +#ifdef CONFIG_SYS_MMC_ENV_PART + if (mmc->part_num != CONFIG_SYS_MMC_ENV_PART) { + err = mmc_switch_part(mmc_dev_num, CONFIG_SYS_MMC_ENV_PART); + if (err) { + printf("MMC partition switch failed\n"); + return err; + } + } +#endif + + /* SD reserves LBA-0 for MBR and boots from LBA-1, + * MMC/eMMC boots from LBA-0 + */ + start_lba = IS_SD(mmc) ? 1 : 0; + blk_count = image_size / mmc->block_dev.blksz; + if (image_size % mmc->block_dev.blksz) + blk_count += 1; + + blk_written = mmc->block_dev.block_write(mmc_dev_num, + start_lba, blk_count, + (void *)get_load_addr()); + if (blk_written != blk_count) { + printf("Error - written %#lx blocks\n", blk_written); + return -ENOSPC; + } + printf("Done!\n"); + +#ifdef CONFIG_SYS_MMC_ENV_PART + if (mmc->part_num != CONFIG_SYS_MMC_ENV_PART) + mmc_switch_part(mmc_dev_num, mmc->part_num); +#endif + + return 0; +} + +static size_t mmc_read_file(const char *file_name) +{ + loff_t act_read = 0; + int rc; + struct mmc *mmc; + const u8 mmc_dev_num = CONFIG_SYS_MMC_ENV_DEV; + + mmc = find_mmc_device(mmc_dev_num); + if (!mmc) { + printf("No SD/MMC/eMMC card found\n"); + return 0; + } + + if (mmc_init(mmc)) { + printf("%s(%d) init failed\n", IS_SD(mmc) ? "SD" : "MMC", + mmc_dev_num); + return 0; + } + + /* Load from data partition (0) */ + if (fs_set_blk_dev("mmc", "0", FS_TYPE_ANY)) { + printf("Error: MMC 0 not found\n"); + return 0; + } + + /* Perfrom file read */ + rc = fs_read(file_name, get_load_addr(), 0, 0, &act_read); + if (rc) + return 0; + + return act_read; +} + +static int is_mmc_active(void) +{ + return 1; +} +#else /* CONFIG_DM_MMC */ +static int mmc_burn_image(size_t image_size) +{ + return -ENODEV; +} + +static size_t mmc_read_file(const char *file_name) +{ + return 0; +} + +static int is_mmc_active(void) +{ + return 0; +} +#endif /* CONFIG_DM_MMC */ + +/******************************************************************** + * SPI services + ********************************************************************/ +#ifdef CONFIG_SPI_FLASH +static int spi_burn_image(size_t image_size) +{ + int ret; + struct spi_flash *flash; + u32 erase_bytes; + + /* Probe the SPI bus to get the flash device */ + flash = spi_flash_probe(CONFIG_ENV_SPI_BUS, + CONFIG_ENV_SPI_CS, + CONFIG_SF_DEFAULT_SPEED, + CONFIG_SF_DEFAULT_MODE); + if (!flash) { + printf("Failed to probe SPI Flash\n"); + return -ENOMEDIUM; + } + +#ifdef CONFIG_SPI_FLASH_PROTECTION + spi_flash_protect(flash, 0); +#endif + erase_bytes = image_size + + (flash->erase_size - image_size % flash->erase_size); + printf("Erasing %d bytes (%d blocks) at offset 0 ...", + erase_bytes, erase_bytes / flash->erase_size); + ret = spi_flash_erase(flash, 0, erase_bytes); + if (ret) + printf("Error!\n"); + else + printf("Done!\n"); + + printf("Writing %d bytes from 0x%lx to offset 0 ...", + (int)image_size, get_load_addr()); + ret = spi_flash_write(flash, 0, image_size, (void *)get_load_addr()); + if (ret) + printf("Error!\n"); + else + printf("Done!\n"); + +#ifdef CONFIG_SPI_FLASH_PROTECTION + spi_flash_protect(flash, 1); +#endif + + return ret; +} + +static int is_spi_active(void) +{ + return 1; +} + +#else /* CONFIG_SPI_FLASH */ +static int spi_burn_image(size_t image_size) +{ + return -ENODEV; +} + +static int is_spi_active(void) +{ + return 0; +} +#endif /* CONFIG_SPI_FLASH */ + +/******************************************************************** + * NAND services + ********************************************************************/ +#ifdef CONFIG_CMD_NAND +static int nand_burn_image(size_t image_size) +{ + int ret, block_size; + nand_info_t *nand; + int dev = nand_curr_device; + + if ((dev < 0) || (dev >= CONFIG_SYS_MAX_NAND_DEVICE) || + (!nand_info[dev].name)) { + puts("\nno devices available\n"); + return -ENOMEDIUM; + } + nand = &nand_info[dev]; + block_size = nand->erasesize; + + /* Align U-Boot size to currently used blocksize */ + image_size = ((image_size + (block_size - 1)) & (~(block_size - 1))); + + /* Erase the U-BOOT image space */ + printf("Erasing 0x%x - 0x%x:...", 0, (int)image_size); + ret = nand_erase(nand, 0, image_size); + if (ret) { + printf("Error!\n"); + goto error; + } + printf("Done!\n"); + + /* Write the image to flash */ + printf("Writing image:..."); + printf("&image_size = 0x%p\n", (void *)&image_size); + ret = nand_write(nand, 0, &image_size, (void *)get_load_addr()); + if (ret) + printf("Error!\n"); + else + printf("Done!\n"); + +error: + return ret; +} + +static int is_nand_active(void) +{ + return 1; +} + +#else /* CONFIG_CMD_NAND */ +static int nand_burn_image(size_t image_size) +{ + return -ENODEV; +} + +static int is_nand_active(void) +{ + return 0; +} +#endif /* CONFIG_CMD_NAND */ + +/******************************************************************** + * USB services + ********************************************************************/ +#if defined(CONFIG_USB_STORAGE) && defined(CONFIG_BLK) +static size_t usb_read_file(const char *file_name) +{ + loff_t act_read = 0; + struct udevice *dev; + int rc; + + usb_stop(); + + if (usb_init() < 0) { + printf("Error: usb_init failed\n"); + return 0; + } + + /* Try to recognize storage devices immediately */ + blk_first_device(IF_TYPE_USB, &dev); + if (!dev) { + printf("Error: USB storage device not found\n"); + return 0; + } + + /* Always load from usb 0 */ + if (fs_set_blk_dev("usb", "0", FS_TYPE_ANY)) { + printf("Error: USB 0 not found\n"); + return 0; + } + + /* Perfrom file read */ + rc = fs_read(file_name, get_load_addr(), 0, 0, &act_read); + if (rc) + return 0; + + return act_read; +} + +static int is_usb_active(void) +{ + return 1; +} + +#else /* defined(CONFIG_USB_STORAGE) && defined (CONFIG_BLK) */ +static size_t usb_read_file(const char *file_name) +{ + return 0; +} + +static int is_usb_active(void) +{ + return 0; +} +#endif /* defined(CONFIG_USB_STORAGE) && defined (CONFIG_BLK) */ + +/******************************************************************** + * Network services + ********************************************************************/ +#ifdef CONFIG_CMD_NET +static size_t tftp_read_file(const char *file_name) +{ + /* update global variable load_addr before tftp file from network */ + load_addr = get_load_addr(); + return net_loop(TFTPGET); +} + +static int is_tftp_active(void) +{ + return 1; +} + +#else +static size_t tftp_read_file(const char *file_name) +{ + return 0; +} + +static int is_tftp_active(void) +{ + return 0; +} +#endif /* CONFIG_CMD_NET */ + +enum bubt_devices { + BUBT_DEV_NET = 0, + BUBT_DEV_USB, + BUBT_DEV_MMC, + BUBT_DEV_SPI, + BUBT_DEV_NAND, + + BUBT_MAX_DEV +}; + +struct bubt_dev bubt_devs[BUBT_MAX_DEV] = { + {"tftp", tftp_read_file, NULL, is_tftp_active}, + {"usb", usb_read_file, NULL, is_usb_active}, + {"mmc", mmc_read_file, mmc_burn_image, is_mmc_active}, + {"spi", NULL, spi_burn_image, is_spi_active}, + {"nand", NULL, nand_burn_image, is_nand_active}, +}; + +static int bubt_write_file(struct bubt_dev *dst, size_t image_size) +{ + if (!dst->write) { + printf("Error: Write not supported on device %s\n", dst->name); + return -ENOTSUPP; + } + + return dst->write(image_size); +} + +#if defined(CONFIG_ARMADA_8K) +u32 do_checksum32(u32 *start, int32_t len) +{ + u32 sum = 0; + u32 *startp = start; + + do { + sum += *startp; + startp++; + len -= 4; + } while (len > 0); + + return sum; +} + +static int check_image_header(void) +{ + struct mvebu_image_header *hdr = + (struct mvebu_image_header *)get_load_addr(); + u32 header_len = hdr->prolog_size; + u32 checksum; + u32 checksum_ref = hdr->prolog_checksum; + + /* + * For now compare checksum, and magic. Later we can + * verify more stuff on the header like interface type, etc + */ + if (hdr->magic != MAIN_HDR_MAGIC) { + printf("ERROR: Bad MAGIC 0x%08x != 0x%08x\n", + hdr->magic, MAIN_HDR_MAGIC); + return -ENOEXEC; + } + + /* The checksum value is discarded from checksum calculation */ + hdr->prolog_checksum = 0; + + checksum = do_checksum32((u32 *)hdr, header_len); + if (checksum != checksum_ref) { + printf("Error: Bad Image checksum. 0x%x != 0x%x\n", + checksum, checksum_ref); + return -ENOEXEC; + } + + /* Restore the checksum before writing */ + hdr->prolog_checksum = checksum_ref; + printf("Image checksum...OK!\n"); + + return 0; +} +#elif defined(CONFIG_ARMADA_3700) /* Armada 3700 */ +static int check_image_header(void) +{ + struct common_tim_data *hdr = (struct common_tim_data *)get_load_addr(); + int image_num; + u8 hash_160_output[SHA1_SUM_LEN]; + u8 hash_256_output[SHA256_SUM_LEN]; + sha1_context hash1_text; + sha256_context hash256_text; + u8 *hash_output; + u32 hash_algorithm_id; + u32 image_size_to_hash; + u32 flash_entry_addr; + u32 *hash_value; + u32 internal_hash[HASH_SUM_LEN]; + const u8 *buff; + u32 num_of_image = hdr->num_images; + u32 version = hdr->version; + u32 trusted = hdr->trusted; + + /* bubt checksum validation only supports nontrusted images */ + if (trusted == 1) { + printf("bypass image validation, "); + printf("only untrusted image is supported now\n"); + return 0; + } + /* only supports image version 3.5 and 3.6 */ + if (version != IMAGE_VERSION_3_5_0 && version != IMAGE_VERSION_3_6_0) { + printf("Error: Unsupported Image version = 0x%08x\n", version); + return -ENOEXEC; + } + /* validate images hash value */ + for (image_num = 0; image_num < num_of_image; image_num++) { + struct mvebu_image_info *info = + (struct mvebu_image_info *)(get_load_addr() + + sizeof(struct common_tim_data) + + image_num * sizeof(struct mvebu_image_info)); + hash_algorithm_id = info->hash_algorithm_id; + image_size_to_hash = info->image_size_to_hash; + flash_entry_addr = info->flash_entry_addr; + hash_value = info->hash; + buff = (const u8 *)(get_load_addr() + flash_entry_addr); + + if (image_num == 0) { + /* + * The first image includes hash values in its content. + * For hash calculation, we need to save the original + * hash values to a local variable that will be + * copied back for comparsion and set all zeros to + * the orignal hash values for calculating new value. + * First image original format : + * x...x (datum1) x...x(orig. hash values) x...x(datum2) + * Replaced first image format : + * x...x (datum1) 0...0(hash values) x...x(datum2) + */ + memcpy(internal_hash, hash_value, + sizeof(internal_hash)); + memset(hash_value, 0, sizeof(internal_hash)); + } + if (image_size_to_hash == 0) { + printf("Warning: Image_%d hash checksum is disabled, ", + image_num); + printf("skip the image validation.\n"); + continue; + } + switch (hash_algorithm_id) { + case SHA1_SUM_LEN: + sha1_starts(&hash1_text); + sha1_update(&hash1_text, buff, image_size_to_hash); + sha1_finish(&hash1_text, hash_160_output); + hash_output = hash_160_output; + break; + case SHA256_SUM_LEN: + sha256_starts(&hash256_text); + sha256_update(&hash256_text, buff, image_size_to_hash); + sha256_finish(&hash256_text, hash_256_output); + hash_output = hash_256_output; + break; + default: + printf("Error: Unsupported hash_algorithm_id = %d\n", + hash_algorithm_id); + return -ENOEXEC; + } + if (image_num == 0) + memcpy(hash_value, internal_hash, + sizeof(internal_hash)); + if (memcmp(hash_value, hash_output, hash_algorithm_id) != 0) { + printf("Error: Image_%d checksum is not correct\n", + image_num); + return -ENOEXEC; + } + } + printf("Image checksum...OK!\n"); + + return 0; +} + +#else /* Not ARMADA? */ +static int check_image_header(void) +{ + printf("bubt cmd does not support this SoC device or family!\n"); + return -ENOEXEC; +} +#endif + +static int bubt_verify(size_t image_size) +{ + int err; + + /* Check a correct image header exists */ + err = check_image_header(); + if (err) { + printf("Error: Image header verification failed\n"); + return err; + } + + return 0; +} + +static int bubt_read_file(struct bubt_dev *src) +{ + size_t image_size; + + if (!src->read) { + printf("Error: Read not supported on device \"%s\"\n", + src->name); + return 0; + } + + image_size = src->read(net_boot_file_name); + if (image_size <= 0) { + printf("Error: Failed to read file %s from %s\n", + net_boot_file_name, src->name); + return 0; + } + + return image_size; +} + +static int bubt_is_dev_active(struct bubt_dev *dev) +{ + if (!dev->active) { + printf("Device \"%s\" not supported by U-BOOT image\n", + dev->name); + return 0; + } + + if (!dev->active()) { + printf("Device \"%s\" is inactive\n", dev->name); + return 0; + } + + return 1; +} + +struct bubt_dev *find_bubt_dev(char *dev_name) +{ + int dev; + + for (dev = 0; dev < BUBT_MAX_DEV; dev++) { + if (strcmp(bubt_devs[dev].name, dev_name) == 0) + return &bubt_devs[dev]; + } + + return 0; +} + +#define DEFAULT_BUBT_SRC "tftp" + +#ifndef DEFAULT_BUBT_DST +#ifdef CONFIG_MVEBU_SPI_BOOT +#define DEFAULT_BUBT_DST "spi" +#elif defined(CONFIG_MVEBU_NAND_BOOT) +#define DEFAULT_BUBT_DST "nand" +#elif defined(CONFIG_MVEBU_MMC_BOOT) +#define DEFAULT_BUBT_DST "mmc" +else +#define DEFAULT_BUBT_DST "error" +#endif +#endif /* DEFAULT_BUBT_DST */ + +int do_bubt_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + struct bubt_dev *src, *dst; + size_t image_size; + char src_dev_name[8]; + char dst_dev_name[8]; + char *name; + int err; + + if (argc < 2) + copy_filename(net_boot_file_name, + CONFIG_MVEBU_UBOOT_DFLT_NAME, + sizeof(net_boot_file_name)); + else + copy_filename(net_boot_file_name, argv[1], + sizeof(net_boot_file_name)); + + if (argc >= 3) { + strncpy(dst_dev_name, argv[2], 8); + } else { + name = DEFAULT_BUBT_DST; + strncpy(dst_dev_name, name, 8); + } + + if (argc >= 4) + strncpy(src_dev_name, argv[3], 8); + else + strncpy(src_dev_name, DEFAULT_BUBT_SRC, 8); + + /* Figure out the destination device */ + dst = find_bubt_dev(dst_dev_name); + if (!dst) { + printf("Error: Unknown destination \"%s\"\n", dst_dev_name); + return -EINVAL; + } + + if (!bubt_is_dev_active(dst)) + return -ENODEV; + + /* Figure out the source device */ + src = find_bubt_dev(src_dev_name); + if (!src) { + printf("Error: Unknown source \"%s\"\n", src_dev_name); + return 1; + } + + if (!bubt_is_dev_active(src)) + return -ENODEV; + + printf("Burning U-BOOT image \"%s\" from \"%s\" to \"%s\"\n", + net_boot_file_name, src->name, dst->name); + + image_size = bubt_read_file(src); + if (!image_size) + return -EIO; + + err = bubt_verify(image_size); + if (err) + return err; + + err = bubt_write_file(dst, image_size); + if (err) + return err; + + return 0; +} + +U_BOOT_CMD( + bubt, 4, 0, do_bubt_cmd, + "Burn a u-boot image to flash", + "[file-name] [destination [source]]\n" + "\t-file-name The image file name to burn. Default = flash-image.bin\n" + "\t-destination Flash to burn to [spi, nand, mmc]. Default = active boot device\n" + "\t-source The source to load image from [tftp, usb, mmc]. Default = tftp\n" + "Examples:\n" + "\tbubt - Burn flash-image.bin from tftp to active boot device\n" + "\tbubt flash-image-new.bin nand - Burn flash-image-new.bin from tftp to NAND flash\n" + "\tbubt backup-flash-image.bin mmc usb - Burn backup-flash-image.bin from usb to MMC\n" + +); diff --git a/doc/mvebu/cmd/bubt.txt b/doc/mvebu/cmd/bubt.txt new file mode 100644 index 0000000..6f9f525 --- /dev/null +++ b/doc/mvebu/cmd/bubt.txt @@ -0,0 +1,64 @@ +BUBT (Burn ATF) command +-------------------------- +Bubt command is used to burn a new ATF image to flash device. + +The bubt command gets the following parameters: ATF file name, destination device and source device. +bubt [file-name] [destination [source]] + - file-name Image file name to burn. default = flash-image.bin + - destination Flash to burn to [spi, nand, mmc]. default = active flash + - source Source to load image from [tftp, usb]. default = tftp + +Examples: + bubt - Burn flash-image.bin from tftp to active flash + bubt latest-spi.bin nand - Burn latest-spi.bin from tftp to NAND flash + +Notes: +- For the TFTP interface set serverip and ipaddr. +- To burn image to SD/eMMC device, the target is defined + by parameters CONFIG_SYS_MMC_ENV_DEV and CONFIG_SYS_MMC_ENV_PART. + +Bubt command details (burn image step by-step) +---------------------------------------------- +This section describes bubt command flow: + +1. Fetch the requested ATF image from an available interface (USB/SD/SATA/XDB, etc.) + into the DRAM, and place it at + Example: when using the FAT file system on USB flash device: + # usb reset + # fatls usb 0 (see files in device) + # fatload usb 0 + +2. Erase the target device: + - NAND: # nand erase 0 100000 + - SPI: # sf probe 0 + # sf erase 0 100000 + - SD/eMMC: # mmc dev + +Notes: +- The eMMC has 2 boot partitions (BOOT0 and BOOT1) and a user data partition (DATA). + The boot partitions are numbered as partition 1 and 2 in MMC driver. + Number 0 is used for user data partition and should not be utilized for storing + boot images and U-Boot environment in RAW mode since it will break file system + structures usually located here. + The default boot partition is BOOT0. It is selected by the following parameter: + CONFIG_SYS_MMC_ENV_PART=1 + Valid values for this parameter are 1 for BOOT0 and 2 for BOOT1. + Please never use partition number 0 here! + The eMMC has 2 boot partitions (BOOT0 and BOOT1) and a user data partition (DATA). + The boot partitions are numbered as partition 1 and 2 in MMC driver. + Number 0 is used for user data partition and should not be utilized for storing + boot images and U-Boot environment in RAW mode since it will break file system + structures usually located here. + The default boot partition is BOOT0. It is selected by the following parameter: + CONFIG_SYS_MMC_ENV_PART=1 + Valid values for this parameter are 1 for BOOT0 and 2 for BOOT1. + Please never use partition number 0 here! +- The partition number is ignored if the target device is SD card. +- The boot image offset starts at block 0 for eMMC and block 1 for SD devices. + The block 0 on SD devices is left for MBR storage. + +3. Write the ATF image: + - NAND: # nand write 0 + - SPI: # sf write 0 + - SD/eMMC: # mmc write [0|1] / + From 656e6cc86b96be88f99f6f3ef1df3ef3122a8766 Mon Sep 17 00:00:00 2001 From: Konstantin Porotchkin Date: Thu, 8 Dec 2016 12:22:29 +0200 Subject: [PATCH 3/9] arm64: mvebu: pinctrl: Add pin control driver for A8K family Add a DM port of Marvell pin control driver. The A8K SoC family contains several silicone dies interconnected in a single package. Every die is normally equipped with its own pin controller unit. There are 2 pin controllers in A70x0 SoC and 3 in A80x0 SoC. Signed-off-by: Konstantin Porotchkin Reviewed-by: Simon Glass Cc: Simon Glass Cc: Stefan Roese Cc: Nadav Haklai Cc: Neta Zur Hershkovits Cc: Omri Itach Cc: Igal Liberman Cc: Haim Boot Cc: Hanna Hawa Signed-off-by: Stefan Roese --- arch/arm/include/asm/arch-armada8k/soc-info.h | 17 ++ .../pinctrl/marvell,armada-apn806-pinctrl.txt | 25 ++ .../pinctrl/marvell,armada-cp110-pinctrl.txt | 270 +++++++++++++++++++++ .../pinctrl/marvell,mvebu-pinctrl.txt | 113 +++++++++ drivers/pinctrl/Kconfig | 1 + drivers/pinctrl/Makefile | 1 + drivers/pinctrl/mvebu/Kconfig | 7 + drivers/pinctrl/mvebu/Makefile | 7 + drivers/pinctrl/mvebu/pinctrl-mvebu.c | 179 ++++++++++++++ drivers/pinctrl/mvebu/pinctrl-mvebu.h | 31 +++ 10 files changed, 651 insertions(+) create mode 100644 arch/arm/include/asm/arch-armada8k/soc-info.h create mode 100644 doc/device-tree-bindings/pinctrl/marvell,armada-apn806-pinctrl.txt create mode 100644 doc/device-tree-bindings/pinctrl/marvell,armada-cp110-pinctrl.txt create mode 100644 doc/device-tree-bindings/pinctrl/marvell,mvebu-pinctrl.txt create mode 100644 drivers/pinctrl/mvebu/Kconfig create mode 100644 drivers/pinctrl/mvebu/Makefile create mode 100644 drivers/pinctrl/mvebu/pinctrl-mvebu.c create mode 100644 drivers/pinctrl/mvebu/pinctrl-mvebu.h diff --git a/arch/arm/include/asm/arch-armada8k/soc-info.h b/arch/arm/include/asm/arch-armada8k/soc-info.h new file mode 100644 index 0000000..bae3995 --- /dev/null +++ b/arch/arm/include/asm/arch-armada8k/soc-info.h @@ -0,0 +1,17 @@ +/* + * Copyright (C) 2016 Marvell International Ltd. + * + * SPDX-License-Identifier: GPL-2.0 + * https://spdx.org/licenses + */ + +#ifndef _SOC_INFO_H_ +#define _SOC_INFO_H_ + +/* Pin Ctrl driver definitions */ +#define BITS_PER_PIN 4 +#define PIN_FUNC_MASK ((1 << BITS_PER_PIN) - 1) +#define PIN_REG_SHIFT 3 +#define PIN_FIELD_MASK ((1 << PIN_REG_SHIFT) - 1) + +#endif /* _SOC_INFO_H_ */ diff --git a/doc/device-tree-bindings/pinctrl/marvell,armada-apn806-pinctrl.txt b/doc/device-tree-bindings/pinctrl/marvell,armada-apn806-pinctrl.txt new file mode 100644 index 0000000..51f2f2c --- /dev/null +++ b/doc/device-tree-bindings/pinctrl/marvell,armada-apn806-pinctrl.txt @@ -0,0 +1,25 @@ + Functions of Armada APN806 pin controller + Function 0x0 for any MPP ID activates GPIO pin mode +---------------------------------------------------------------------- +MPP# 0x1 0x2 0x3 0x4 +---------------------------------------------------------------------- +0 SDIO_CLK - SPI0_CLK - +1 SDIO_CMD - SPI0_MISO - +2 SDIO_D[0] - SPI0_MOSI - +3 SDIO_D[1] - SPI0_CS0n - +4 SDIO_D[2] - I2C0_SDA SPI0_CS1n +5 SDIO_D[3] - I2C0_SCK - +6 SDIO_DS - - - +7 SDIO_D[4] - UART1_RXD - +8 SDIO_D[5] - UART1_TXD - +9 SDIO_D[6] - SPI0_CS1n - +10 SDIO_D[7] - - - +11 - - UART0_TXD - +12 SDIO_CARD_PW_OFF SDIO_HW_RST - - +13 - - - - +14 - - - - +15 - - - - +16 - - - - +17 - - - - +18 - - - - +19 - - UART0_RXD - diff --git a/doc/device-tree-bindings/pinctrl/marvell,armada-cp110-pinctrl.txt b/doc/device-tree-bindings/pinctrl/marvell,armada-cp110-pinctrl.txt new file mode 100644 index 0000000..3adcf3a --- /dev/null +++ b/doc/device-tree-bindings/pinctrl/marvell,armada-cp110-pinctrl.txt @@ -0,0 +1,270 @@ + Functions of Armada CP110 pin controller + Function 0x0 for any MPP ID activates GPIO pin mode + Function 0xc for any MPP ID activates DEBUG_BUS pin mode +------------------------------------------------------------------------------- +MPP# 0x1 0x2 0x3 0x4 +------------------------------------------------------------------------------- +0 DEV_ALE[1] AU_I2SMCLK GE0_RXD[3] TDM_PCLK +1 DEV_ALE[0] AU_I2SDO_SPDIFO GE0_RXD[2] TDM_DRX +2 DEV_AD[15] AU_I2SEXTCLK GE0_RXD[1] TDM_DTX +3 DEV_AD[14] AU_I2SLRCLK GE0_RXD[0] TDM_FSYNC +4 DEV_AD[13] AU_I2SBCLK GE0_RXCTL TDM_RSTn +5 DEV_AD[12] AU_I2SDI GE0_RXCLK TDM_INTn +6 DEV_AD[11] - GE0_TXD[3] SPI0_CSn[2] +7 DEV_AD[10] - GE0_TXD[2] SPI0_CSn[1] +8 DEV_AD[9] - GE0_TXD[1] SPI0_CSn[0] +9 DEV_AD[8] - GE0_TXD[0] SPI0_MOSI +10 DEV_READYn - GE0_TXCTL SPI0_MISO +11 DEV_WEn[1] - GE0_TXCLKOUT SPI0_CLK +12 DEV_CLK_OUT NF_RBn[1] SPI1_CSn[1] GE0_RXCLK +13 DEV_BURSTn NF_RBn[0] SPI1_MISO GE0_RXCTL +14 DEV_BOOTCSn DEV_CSn[0] SPI1_CSn[0] SPI0_CSn[3] +15 DEV_AD[7] - SPI1_MOSI - +16 DEV_AD[6] - SPI1_CLK - +17 DEV_AD[5] - - GE0_TXD[3] +18 DEV_AD[4] - - GE0_TXD[2] +19 DEV_AD[3] - - GE0_TXD[1] +20 DEV_AD[2] - - GE0_TXD[0] +21 DEV_AD[1] - - GE0_TXCTL +22 DEV_AD[0] - - GE0_TXCLKOUT +23 DEV_A[1] - - - +24 DEV_A[0] - - - +25 DEV_OEn - - - - +26 DEV_WEn[0] - - - +27 DEV_CSn[0] SPI1_MISO MSS_GPIO[4] GE0_RXD[3] +28 DEV_CSn[1] SPI1_CSn[0] MSS_GPIO[5] GE0_RXD[2] +29 DEV_CSn[2] SPI1_MOSI MSS_GPIO[6] GE0_RXD[1] +30 DEV_CSn[3] SPI1_CLK MSS_GPIO[7] GE0_RXD[0] +31 DEV_A[2] - MSS_GPIO[4] - +32 MII_COL MII_TXERR MSS_SPI_MISO TDM_DRX +33 MII_TXCLK SDIO_PWR1[0] MSS_SPI_CSn TDM_FSYNC +34 MII_RXERR SDIO_PWR1[1] MSS_SPI_MOSI TDM_DTX +35 SATA1_PRESENT_ACTIVEn TWSI1_SDA MSS_SPI_CLK TDM_PCLK +36 SYNCE2_CLK TWSI1_SCK PTP_CLK SYNCE1_CLK +37 UART2_RXD TWSI0_SCK PTP_PCLK_OUT TDM_INTn +38 UART2_TXD TWSI0_SDA PTP_PULSE TDM_RSTn +39 SDIO_WR_PROTECT - - AU_I2SBCLK PTP_CLK +40 SDIO_PWR1[1] SYNCE1_CLK MSS_TWSI_SDA AU_I2SDO_SPDIFO +41 SDIO_PWR1[0] SDIO_BUS_PWR MSS_TWSI_SCK AU_I2SLRCLK +42 SDIO_V18_EN SDIO_WR_PROTECT SYNCE2_CLK AU_I2SMCLK +43 SDIO_CARD_DETECT - SYNCE1_CLK AU_I2SEXTCLK +44 GE1_TXD[2] - - - +45 GE1_TXD[3] - - - +46 GE1_TXD[1] - - - +47 GE1_TXD[0] - - - +48 GE1_TXCTL_MII_TXEN - - - +49 GE1_TXCLKOUT MII_CRS - - +50 GE1_RXCLK MSS_TWSI_SDA - - +51 GE1_RXD[0] MSS_TWSI_SCK - - +52 GE1_RXD[1] SYNCE1_CLK - SYNCE2_CLK +53 GE1_RXD[2] - PTP_CLK - +54 GE1_RXD[3] SYNCE2_CLK PTP_PCLK_OUT SYNCE1_CLK +55 GE1_RXCTL_MII_RXDV - PTP_PULSE - +56 - - - TDM_DRX +57 - MSS_TWSI_SDA PTP_PCLK_OUT TDM_INTn +58 - MSS_TWSI_SCK PTP_CLK TDM_RSTn +59 MSS_GPIO[7] SYNCE2_CLK - TDM_FSYNC +60 MSS_GPIO[6] - PTP_PULSE TDM_DTX +61 MSS_GPIO[5] - PTP_CLK TDM_PCLK +62 MSS_GPIO[4] SYNCE1_CLK PTP_PCLK_OUT - + +------------------------------------------------------------------------------- +MPP# 0x5 0x6 0x7 +------------------------------------------------------------------------------- +0 - PTP_PULSE MSS_TWSI_SDA +1 - PTP_CLK MSS_TWSI_SCK +2 MSS_UART_RXD PTP_PCLK_OUT TWSI1_SCK +3 MSS_UART_TXD PCIe_RSTOUTn TWSI1_SDA +4 MSS_UART_RXD UART1_CTS PCIe0_CLKREQ +5 MSS_UART_TXD UART1_RTS PCIe1_CLKREQ +6 AU_I2SEXTCLK SATA1_PRESENT_ACTIVEn PCIe2_CLKREQ +7 SPI1_CSn[1] SATA0_PRESENT_ACTIVEn LED_DATA +8 SPI1_CSn[0] UART0_CTS LED_STB +9 SPI1_MOSI - PCIe_RSTOUTn +10 SPI1_MISO UART0_CTS SATA1_PRESENT_ACTIVEn +11 SPI1_CLK UART0_RTS LED_CLK +12 - - - +13 - - - +14 AU_I2SEXTCLK SPI0_MISO SATA0_PRESENT_ACTIVEn +15 - SPI0_MOSI - +16 - - - +17 - - - +18 - - - +19 - - - +20 - - - +21 - - - +22 - - - +23 AU_I2SMCLK - - +24 AU_I2SLRCLK - - +25 AU_I2SDO_SPDIFO - - +26 AU_I2SBCLK - - +27 SPI0_CSn[4] - - +28 SPI0_CSn[5] PCIe2_CLKREQ PTP_PULSE +29 SPI0_CSn[6] PCIe1_CLKREQ PTP_CLK +30 SPI0_CSn[7] PCIe0_CLKREQ PTP_PCLK_OUT +31 - PCIe_RSTOUTn - +32 AU_I2SEXTCLK AU_I2SDI GE_MDIO +33 AU_I2SMCLK SDIO_BUS_PWR - +34 AU_I2SLRCLK SDIO_WR_PROTECT GE_MDC +35 AU_I2SDO_SPDIFO SDIO_CARD_DETECT XG_MDIO +36 AU_I2SBCLK SATA0_PRESENT_ACTIVEn XG_MDC +37 MSS_TWSI_SCK SATA1_PRESENT_ACTIVEn GE_MDC +38 MSS_TWSI_SDA SATA0_PRESENT_ACTIVEn GE_MDIO +39 SPI0_CSn[1] - - +40 PTP_PCLK_OUT SPI0_CLK UART1_TXD +41 PTP_PULSE SPI0_MOSI UART1_RXD +42 MSS_UART_TXD SPI0_MISO UART1_CTS +43 MSS_UART_RXD SPI0_CSn[0] UART1_RTS +44 - - UART0_RTS +45 - - UART0_TXD +46 - - UART1_RTS +47 SPI1_CLK - UART1_TXD +48 SPI1_MOSI - - +49 SPI1_MISO - UART1_RXD +50 SPI1_CSn[0] UART2_TXD UART0_RXD +51 SPI1_CSn[1] UART2_RXD UART0_CTS +52 SPI1_CSn[2] - UART1_CTS +53 SPI1_CSn[3] - UART1_RXD +54 - - - +55 - - - +56 AU_I2SDO_SPDIFO SPI0_CLK UART1_RXD +57 AU_I2SBCLK SPI0_MOSI UART1_TXD +58 AU_I2SDI SPI0_MISO UART1_CTS +59 AU_I2SLRCLK SPI0_CSn[0] UART0_CTS +60 AU_I2SMCLK SPI0_CSn[1] UART0_RTS +61 AU_I2SEXTCLK SPI0_CSn[2] UART0_TXD +62 SATA1_PRESENT_ACTIVEn SPI0_CSn[3] UART0_RXD + +------------------------------------------------------------------------------- +MPP# 0x8 0x9 0xA +------------------------------------------------------------------------------- +0 UART0_RXD SATA0_PRESENT_ACTIVEn GE_MDIO +1 UART0_TXD SATA1_PRESENT_ACTIVEn GE_MDC +2 UART1_RXD SATA0_PRESENT_ACTIVEn XG_MDC +3 UART1_TXD SATA1_PRESENT_ACTIVEn XG_MDIO +4 UART3_RXD - GE_MDC +5 UART3_TXD - GE_MDIO +6 UART0_RXD PTP_PULSE - +7 UART0_TXD PTP_CLK - +8 UART2_RXD PTP_PCLK_OUT SYNCE1_CLK +9 - - SYNCE2_CLK +10 - - - +11 UART2_TXD SATA0_PRESENT_ACTIVEn - +12 - - - +13 MSS_SPI_MISO - - +14 MSS_SPI_CSn - - +15 MSS_SPI_MOSI - - +16 MSS_SPI_CLK - - +17 - - - +18 - - - +19 - - - +20 - - - +21 - - - +22 - - - +23 - - - +24 - - - +25 - - - +26 - - - +27 GE_MDIO SATA0_PRESENT_ACTIVEn UART0_RTS +28 GE_MDC SATA1_PRESENT_ACTIVEn UART0_CTS +29 MSS_TWSI_SDA SATA0_PRESENT_ACTIVEn UART0_RXD +30 MSS_TWSI_SCK SATA1_PRESENT_ACTIVEn UART0_TXD +31 GE_MDC - - +32 SDIO_V18_EN PCIe1_CLKREQ MSS_GPIO[0] +33 XG_MDIO PCIe2_CLKREQ MSS_GPIO[1] +34 - PCIe0_CLKREQ MSS_GPIO[2] +35 GE_MDIO PCIe_RSTOUTn MSS_GPIO[3] +36 GE_MDC PCIe2_CLKREQ MSS_GPIO[5] +37 XG_MDC PCIe1_CLKREQ MSS_GPIO[6] +38 XG_MDIO AU_I2SEXTCLK MSS_GPIO[7] +39 SATA1_PRESENT_ACTIVEn MSS_GPIO[0] +40 GE_MDIO SATA0_PRESENT_ACTIVEn MSS_GPIO[1] +41 GE_MDC SATA1_PRESENT_ACTIVEn MSS_GPIO[2] +42 XG_MDC SATA0_PRESENT_ACTIVEn MSS_GPIO[4] +43 XG_MDIO SATA1_PRESENT_ACTIVEn MSS_GPIO[5] +44 - - - +45 - PCIe_RSTOUTn - +46 - - - +47 GE_MDC CLKOUT - +48 XG_MDC - - +49 GE_MDIO PCIe0_CLKREQ SDIO_V18_EN +50 XG_MDIO - SDIO_PWR1[1] +51 - - SDIO_PWR1[0] +52 LED_CLK PCIe_RSTOUTn PCIe0_CLKREQ +53 LED_STB - - +54 LED_DATA - SDIO_HW_RST +55 - - SDIO_LED +56 - SATA1_PRESENT_ACTIVEn - +57 - SATA0_PRESENT_ACTIVEn - +58 LED_CLK - - +59 LED_STB UART1_TXD - +60 LED_DATA UART1_RXD - +61 UART2_TXD SATA1_PRESENT_ACTIVEn GE_MDIO +62 UART2_RXD SATA0_PRESENT_ACTIVEn GE_MDC + +------------------------------------------------------------------------------- +MPP# 0xB 0xD 0xE +------------------------------------------------------------------------------- +0 - - - +1 - - - +2 - - - +3 - - - +4 - - - +5 - - - +6 - - - +7 - - - +8 - - - +9 - - - +10 - - - +11 - CLKOUT_MPP_11 - +12 - - - +13 - - - +14 - - - +15 PTP_PULSE_CP2CP SAR_IN[5] - +16 - SAR_IN[3] - +17 - SAR_IN[6] - +18 PTP_CLK_CP2CP SAR_IN[11] - +19 WAKEUP_OUT_CP2CP SAR_IN[7] - +20 - SAR_IN[9] - +21 SEI_IN_CP2CP SAR_IN[8] - +22 WAKEUP_IN_CP2CP SAR_IN[10] - +23 LINK_RD_IN_CP2CP SAR_IN[4] - +24 - - - +25 - CLKOUT_MPP_25 - +26 - SAR_IN[0] - +27 REI_IN_CP2CP SAR_IN[1] - +28 LED_DATA SAR_IN[2] - +29 LED_STB AVS_FB_IN_CP2CP - +30 LED_CLK SAR_IN[13] - +31 - - - +32 - SAR_CP2CP_OUT[0] - +33 - SAR_CP2CP_OUT[1] - +34 - SAR_CP2CP_OUT[2] - +35 - SAR_CP2CP_OUT[3] - +36 - CLKIN - +37 LINK_RD_OUT_CP2CP SAR_CP2CP_OUT[4] - +38 PTP_PULSE_CP2CP SAR_CP2CP_OUT[5] - +39 - AVS_FB_OUT_CP2CP - +40 - - - +41 REI_OUT_CP2CP - - +42 - SAR_CP2CP_OUT[9] - +43 WAKEUP_OUT_CP2CP SAR_CP2CP_OUT[10] - +44 PTP_CLK_CP2CP SAR_CP2CP_OUT[11] - +45 - SAR_CP2CP_OUT[6] - +46 - SAR_CP2CP_OUT[13] - +47 - - - +48 WAKEUP_IN_CP2CP SAR_CP2CP_OUT[7] - +49 SEI_OUT_CP2CP SAR_CP2CP_OUT[8] - +50 - - - +51 - - - +52 - - - +53 SDIO_LED - - +54 SDIO_WR_PROTECT - - +55 SDIO_CARD_DETECT - - +56 - - SDIO0_CLK +57 - - SDIO0_CMD +58 - - SDIO0_D[0] +59 - - SDIO0_D[1] +60 - - SDIO0_D[2] +61 - - SDIO0_D[3] +62 - - - diff --git a/doc/device-tree-bindings/pinctrl/marvell,mvebu-pinctrl.txt b/doc/device-tree-bindings/pinctrl/marvell,mvebu-pinctrl.txt new file mode 100644 index 0000000..0973db8 --- /dev/null +++ b/doc/device-tree-bindings/pinctrl/marvell,mvebu-pinctrl.txt @@ -0,0 +1,113 @@ +The pinctrl driver enables Marvell Armada 8K SoCs to configure the multi-purpose +pins (mpp) to a specific function. +A Marvell SoC pin configuration node is a node of a group of pins which can +be used for a specific device or function. Each node requires one or more +mpp pins or group of pins and a mpp function common to all pins. + +Required properties for the pinctrl driver: +- compatible: "marvell,mvebu-pinctrl", + "marvell,armada-ap806-pinctrl", + "marvell,a70x0-pinctrl", + "marvell,a80x0-cp0-pinctrl", + "marvell,a80x0-cp1-pinctrl" +- bank-name: A string defining the pinc controller bank name +- reg: A pair of values defining the pin controller base address + and the address space +- pin-count: Numeric value defining the amount of multi purpose pins + included in this bank +- max-func: Numeric value defining the maximum function value for + pins in this bank +- pin-func: Array of pin function values for every pin in the bank. + When the function value for a specific pin equal 0xFF, + the pin configuration is skipped and a default function + value is used for this pin. + +The A8K is a hybrid SoC that contains several silicon dies interconnected in +a single package. Each such die may have a separate pin controller. + +Example: +/ { + ap806 { + config-space { + pinctl: pinctl@6F4000 { + compatible = "marvell,mvebu-pinctrl", + "marvell,armada-ap806-pinctrl"; + bank-name ="apn-806"; + reg = <0x6F4000 0x10>; + pin-count = <20>; + max-func = <3>; + /* MPP Bus: + SPI0 [0-3] + I2C0 [4-5] + UART0 [11,19] + */ + /* 0 1 2 3 4 5 6 7 8 9 */ + pin-func = < 3 3 3 3 3 3 0 0 0 0 + 0 3 0 0 0 0 0 0 0 3>; + }; + }; + }; + + cp110-master { + config-space { + cpm_pinctl: pinctl@44000 { + compatible = "marvell,mvebu-pinctrl", + "marvell,a70x0-pinctrl", + "marvell,a80x0-cp0-pinctrl"; + bank-name ="cp0-110"; + reg = <0x440000 0x20>; + pin-count = <63>; + max-func = <0xf>; + /* MPP Bus: + [0-31] = 0xff: Keep default CP0_shared_pins: + [11] CLKOUT_MPP_11 (out) + [23] LINK_RD_IN_CP2CP (in) + [25] CLKOUT_MPP_25 (out) + [29] AVS_FB_IN_CP2CP (in) + [32,34] SMI + [31] GPIO: push button/Wake + [35-36] GPIO + [37-38] I2C + [40-41] SATA[0/1]_PRESENT_ACTIVEn + [42-43] XSMI + [44-55] RGMII1 + [56-62] SD + */ + /* 0 1 2 3 4 5 6 7 8 9 */ + pin-func = < 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff + 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff + 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff + 0xff 0 7 0 7 0 0 2 2 0 + 0 0 8 8 1 1 1 1 1 1 + 1 1 1 1 1 1 0xE 0xE 0xE 0xE + 0xE 0xE 0xE>; + }; + }; + }; + + cp110-slave { + config-space { + cps_pinctl: pinctl@44000 { + compatible = "marvell,mvebu-pinctrl", + "marvell,a80x0-cp1-pinctrl"; + bank-name ="cp1-110"; + reg = <0x440000 0x20>; + pin-count = <63>; + max-func = <0xf>; + /* MPP Bus: + [0-11] RGMII0 + [27,31] GE_MDIO/MDC + [32-62] = 0xff: Keep default CP1_shared_pins: + */ + /* 0 1 2 3 4 5 6 7 8 9 */ + pin-func = < 0x3 0x3 0x3 0x3 0x3 0x3 0x3 0x3 0x3 0x3 + 0x3 0x3 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff + 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0x8 0xff 0xff + 0xff 0x8 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff + 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff + 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff + 0xff 0xff 0xff>; + }; + }; + }; +} diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index 12be3cf..efcb4c0 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -181,5 +181,6 @@ source "drivers/pinctrl/meson/Kconfig" source "drivers/pinctrl/nxp/Kconfig" source "drivers/pinctrl/uniphier/Kconfig" source "drivers/pinctrl/exynos/Kconfig" +source "drivers/pinctrl/mvebu/Kconfig" endmenu diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile index f28b5c1..512112a 100644 --- a/drivers/pinctrl/Makefile +++ b/drivers/pinctrl/Makefile @@ -15,3 +15,4 @@ obj-$(CONFIG_PINCTRL_UNIPHIER) += uniphier/ obj-$(CONFIG_PIC32_PINCTRL) += pinctrl_pic32.o obj-$(CONFIG_PINCTRL_EXYNOS) += exynos/ obj-$(CONFIG_PINCTRL_MESON) += meson/ +obj-$(CONFIG_PINCTRL_MVEBU) += mvebu/ diff --git a/drivers/pinctrl/mvebu/Kconfig b/drivers/pinctrl/mvebu/Kconfig new file mode 100644 index 0000000..cf9c299 --- /dev/null +++ b/drivers/pinctrl/mvebu/Kconfig @@ -0,0 +1,7 @@ +config PINCTRL_MVEBU + depends on ARCH_MVEBU + bool + default y + help + Support pin multiplexing and pin configuration control on + Marvell's Armada-8K SoC. diff --git a/drivers/pinctrl/mvebu/Makefile b/drivers/pinctrl/mvebu/Makefile new file mode 100644 index 0000000..f4f7864 --- /dev/null +++ b/drivers/pinctrl/mvebu/Makefile @@ -0,0 +1,7 @@ +# +# Copyright (C) 2016 Marvell International Ltd. +# +# SPDX-License-Identifier: GPL-2.0 +# https://spdx.org/licenses + +obj-$(CONFIG_PINCTRL_MVEBU) += pinctrl-mvebu.o diff --git a/drivers/pinctrl/mvebu/pinctrl-mvebu.c b/drivers/pinctrl/mvebu/pinctrl-mvebu.c new file mode 100644 index 0000000..b077639 --- /dev/null +++ b/drivers/pinctrl/mvebu/pinctrl-mvebu.c @@ -0,0 +1,179 @@ +/* + * Copyright (C) 2016 Marvell International Ltd. + * + * SPDX-License-Identifier: GPL-2.0 + * https://spdx.org/licenses + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "pinctrl-mvebu.h" + +DECLARE_GLOBAL_DATA_PTR; + +/* + * mvebu_pinctrl_set_state: configure pin functions. + * @dev: the pinctrl device to be configured. + * @config: the state to be configured. + * @return: 0 in success + */ +int mvebu_pinctrl_set_state(struct udevice *dev, struct udevice *config) +{ + const void *blob = gd->fdt_blob; + int node = config->of_offset; + struct mvebu_pinctrl_priv *priv; + u32 pin_arr[MVEBU_MAX_PINS_PER_BANK]; + u32 function; + int i, pin_count; + + priv = dev_get_priv(dev); + + pin_count = fdtdec_get_int_array_count(blob, node, + "marvell,pins", + pin_arr, + MVEBU_MAX_PINS_PER_BANK); + if (pin_count <= 0) { + debug("Failed reading pins array for pinconfig %s (%d)\n", + config->name, pin_count); + return -EINVAL; + } + + function = fdtdec_get_int(blob, node, "marvell,function", 0xff); + + for (i = 0; i < pin_count; i++) { + int reg_offset; + int field_offset; + int pin = pin_arr[i]; + + if (function > priv->max_func) { + debug("Illegal function %d for pinconfig %s\n", + function, config->name); + return -EINVAL; + } + + /* Calculate register address and bit in register */ + reg_offset = priv->reg_direction * 4 * + (pin >> (PIN_REG_SHIFT)); + field_offset = (BITS_PER_PIN) * (pin & PIN_FIELD_MASK); + + clrsetbits_le32(priv->base_reg + reg_offset, + PIN_FUNC_MASK << field_offset, + (function & PIN_FUNC_MASK) << field_offset); + } + + return 0; +} + +/* + * mvebu_pinctrl_set_state_all: configure the entire bank pin functions. + * @dev: the pinctrl device to be configured. + * @config: the state to be configured. + * @return: 0 in success + */ +static int mvebu_pinctrl_set_state_all(struct udevice *dev, + struct udevice *config) +{ + const void *blob = gd->fdt_blob; + int node = config->of_offset; + struct mvebu_pinctrl_priv *priv; + u32 func_arr[MVEBU_MAX_PINS_PER_BANK]; + int pin, err; + + priv = dev_get_priv(dev); + + err = fdtdec_get_int_array(blob, node, "pin-func", + func_arr, priv->pin_cnt); + if (err) { + debug("Failed reading pin functions for bank %s\n", + priv->bank_name); + return -EINVAL; + } + + for (pin = 0; pin < priv->pin_cnt; pin++) { + int reg_offset; + int field_offset; + u32 func = func_arr[pin]; + + /* Bypass pins with function 0xFF */ + if (func == 0xff) { + debug("Warning: pin %d value is not modified ", pin); + debug("(kept as default)\n"); + continue; + } else if (func > priv->max_func) { + debug("Illegal function %d for pin %d\n", func, pin); + return -EINVAL; + } + + /* Calculate register address and bit in register */ + reg_offset = priv->reg_direction * 4 * + (pin >> (PIN_REG_SHIFT)); + field_offset = (BITS_PER_PIN) * (pin & PIN_FIELD_MASK); + + clrsetbits_le32(priv->base_reg + reg_offset, + PIN_FUNC_MASK << field_offset, + (func & PIN_FUNC_MASK) << field_offset); + } + + return 0; +} + +int mvebu_pinctl_probe(struct udevice *dev) +{ + const void *blob = gd->fdt_blob; + int node = dev->of_offset; + struct mvebu_pinctrl_priv *priv; + + priv = dev_get_priv(dev); + if (!priv) { + debug("%s: Failed to get private\n", __func__); + return -EINVAL; + } + + priv->base_reg = dev_get_addr_ptr(dev); + if (priv->base_reg == (void *)FDT_ADDR_T_NONE) { + debug("%s: Failed to get base address\n", __func__); + return -EINVAL; + } + + priv->pin_cnt = fdtdec_get_int(blob, node, "pin-count", + MVEBU_MAX_PINS_PER_BANK); + priv->max_func = fdtdec_get_int(blob, node, "max-func", + MVEBU_MAX_FUNC); + priv->bank_name = fdt_getprop(blob, node, "bank-name", NULL); + + priv->reg_direction = 1; + if (fdtdec_get_bool(blob, node, "reverse-reg")) + priv->reg_direction = -1; + + return mvebu_pinctrl_set_state_all(dev, dev); +} + +static struct pinctrl_ops mvebu_pinctrl_ops = { + .set_state = mvebu_pinctrl_set_state +}; + +static const struct udevice_id mvebu_pinctrl_ids[] = { + { .compatible = "marvell,mvebu-pinctrl" }, + { .compatible = "marvell,armada-ap806-pinctrl" }, + { .compatible = "marvell,a70x0-pinctrl" }, + { .compatible = "marvell,a80x0-cp0-pinctrl" }, + { .compatible = "marvell,a80x0-cp1-pinctrl" }, + { } +}; + +U_BOOT_DRIVER(pinctrl_mvebu) = { + .name = "mvebu_pinctrl", + .id = UCLASS_PINCTRL, + .of_match = mvebu_pinctrl_ids, + .priv_auto_alloc_size = sizeof(struct mvebu_pinctrl_priv), + .ops = &mvebu_pinctrl_ops, + .probe = mvebu_pinctl_probe +}; diff --git a/drivers/pinctrl/mvebu/pinctrl-mvebu.h b/drivers/pinctrl/mvebu/pinctrl-mvebu.h new file mode 100644 index 0000000..1a1d3ef --- /dev/null +++ b/drivers/pinctrl/mvebu/pinctrl-mvebu.h @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2016 Marvell International Ltd. + * + * SPDX-License-Identifier: GPL-2.0 + * https://spdx.org/licenses + */ + + #ifndef __PINCTRL_MVEBU_H_ + #define __PINCTRL_MVEBU_H_ + + #define MVEBU_MAX_PINCTL_BANKS 4 + #define MVEBU_MAX_PINS_PER_BANK 100 + #define MVEBU_MAX_FUNC 0xF + +/* + * struct mvebu_pin_bank_data: mvebu-pinctrl bank data + * @base_reg: controller base address for this bank + * @pin_cnt: number of pins included in this bank + * @max_func: maximum configurable function value for pins in this bank + * @reg_direction: + * @bank_name: the pin's bank name + */ +struct mvebu_pinctrl_priv { + void *base_reg; + uint pin_cnt; + uint max_func; + int reg_direction; + const char *bank_name; +}; + +#endif /* __PINCTRL_MVEBU_H_ */ From f99386c5b17c6924c742ceb21b1378207deb5bec Mon Sep 17 00:00:00 2001 From: Konstantin Porotchkin Date: Thu, 8 Dec 2016 12:22:30 +0200 Subject: [PATCH 4/9] arm64: mvebu: Add pin control nodes to A8K family DTS files Add pin control nodes to APN806, CP-master, CP-slave and Armada-7040 and Armada-8040 boards DTS files Signed-off-by: Konstantin Porotchkin Cc: Stefan Roese Cc: Nadav Haklai Cc: Neta Zur Hershkovits Cc: Omri Itach Cc: Igal Liberman Cc: Haim Boot Cc: Hanna Hawa Signed-off-by: Stefan Roese --- arch/arm/dts/armada-7040-db.dts | 36 ++++++++++++++ arch/arm/dts/armada-8040-db.dts | 56 ++++++++++++++++++++++ arch/arm/dts/armada-ap806.dtsi | 18 +++++++ arch/arm/dts/armada-cp110-master.dtsi | 32 +++++++++++++ arch/arm/dts/armada-cp110-slave.dtsi | 19 ++++++++ .../pinctrl/marvell,mvebu-pinctrl.txt | 44 ++++++++--------- 6 files changed, 183 insertions(+), 22 deletions(-) diff --git a/arch/arm/dts/armada-7040-db.dts b/arch/arm/dts/armada-7040-db.dts index 1e4d676..466c6dc 100644 --- a/arch/arm/dts/armada-7040-db.dts +++ b/arch/arm/dts/armada-7040-db.dts @@ -66,6 +66,16 @@ }; }; +&ap_pinctl { + /* MPP Bus: + * SDIO [0-5] + * UART0 [11,19] + */ + /* 0 1 2 3 4 5 6 7 8 9 */ + pin-func = < 1 1 1 1 1 1 0 0 0 0 + 0 3 0 0 0 0 0 0 0 3 >; +}; + &uart0 { status = "okay"; }; @@ -76,11 +86,37 @@ }; &cpm_i2c0 { + pinctrl-names = "default"; + pinctrl-0 = <&cpm_i2c0_pins>; status = "okay"; clock-frequency = <100000>; }; +&cpm_pinctl { + /* MPP Bus: + * TDM [0-11] + * SPI [13-16] + * SATA1 [28] + * UART0 [29-30] + * SMI [32,34] + * XSMI [35-36] + * I2C [37-38] + * RGMII1[44-55] + * SD [56-62] + */ + /* 0 1 2 3 4 5 6 7 8 9 */ + pin-func = < 4 4 4 4 4 4 4 4 4 4 + 4 4 0 3 3 3 3 0 0 0 + 0 0 0 0 0 0 0 0 9 0xA + 0xA 0 7 0 7 7 7 2 2 0 + 0 0 0 0 1 1 1 1 1 1 + 1 1 1 1 1 1 0xE 0xE 0xE 0xE + 0xE 0xE 0xE >; +}; + &cpm_spi1 { + pinctrl-names = "default"; + pinctrl-0 = <&cpm_spi0_pins>; status = "okay"; spi-flash@0 { diff --git a/arch/arm/dts/armada-8040-db.dts b/arch/arm/dts/armada-8040-db.dts index 86666a1..40def9d 100644 --- a/arch/arm/dts/armada-8040-db.dts +++ b/arch/arm/dts/armada-8040-db.dts @@ -71,6 +71,41 @@ status = "okay"; }; +&ap_pinctl { + /* MPP Bus: + * SDIO [0-10] + * UART0 [11,19] + */ + /* 0 1 2 3 4 5 6 7 8 9 */ + pin-func = < 1 1 1 1 1 1 1 1 1 1 + 1 3 0 0 0 0 0 0 0 3 >; +}; + +&cpm_pinctl { + /* MPP Bus: + * [0-31] = 0xff: Keep default CP0_shared_pins: + * [11] CLKOUT_MPP_11 (out) + * [23] LINK_RD_IN_CP2CP (in) + * [25] CLKOUT_MPP_25 (out) + * [29] AVS_FB_IN_CP2CP (in) + * [32,34] SMI + * [31] GPIO: push button/Wake + * [35-36] GPIO + * [37-38] I2C + * [40-41] SATA[0/1]_PRESENT_ACTIVEn + * [42-43] XSMI + * [44-55] RGMII1 + * [56-62] SD + */ + /* 0 1 2 3 4 5 6 7 8 9 */ + pin-func = < 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff + 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff + 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff + 0xff 0 7 0 7 0 0 2 2 0 + 0 0 8 8 1 1 1 1 1 1 + 1 1 1 1 1 1 0xe 0xe 0xe 0xe + 0xe 0xe 0xe >; +}; /* CON5 on CP0 expansion */ &cpm_pcie2 { @@ -78,6 +113,8 @@ }; &cpm_i2c0 { + pinctrl-names = "default"; + pinctrl-0 = <&cpm_i2c0_pins>; status = "okay"; clock-frequency = <100000>; }; @@ -97,12 +134,31 @@ status = "okay"; }; +&cps_pinctl { + /* MPP Bus: + * [0-11] RGMII0 + * [13-16] SPI1 + * [27,31] GE_MDIO/MDC + * [32-62] = 0xff: Keep default CP1_shared_pins: + */ + /* 0 1 2 3 4 5 6 7 8 9 */ + pin-func = < 0x3 0x3 0x3 0x3 0x3 0x3 0x3 0x3 0x3 0x3 + 0x3 0x3 0xff 0x3 0x3 0x3 0x3 0xff 0xff 0xff + 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0x8 0xff 0xff + 0xff 0x8 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff + 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff + 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff + 0xff 0xff 0xff >; +}; + /* CON5 on CP1 expansion */ &cps_pcie2 { status = "okay"; }; &cps_spi1 { + pinctrl-names = "default"; + pinctrl-0 = <&cps_spi1_pins>; status = "okay"; spi-flash@0 { diff --git a/arch/arm/dts/armada-ap806.dtsi b/arch/arm/dts/armada-ap806.dtsi index d315b29..efb383b 100644 --- a/arch/arm/dts/armada-ap806.dtsi +++ b/arch/arm/dts/armada-ap806.dtsi @@ -140,6 +140,24 @@ marvell,spi-base = <128>, <136>, <144>, <152>; }; + ap_pinctl: ap-pinctl@6F4000 { + compatible = "marvell,armada-ap806-pinctrl"; + bank-name ="apn-806"; + reg = <0x6F4000 0x10>; + pin-count = <20>; + max-func = <3>; + + ap_i2c0_pins: i2c-pins-0 { + marvell,pins = < 4 5 >; + marvell,function = <3>; + }; + ap_emmc_pins: emmc-pins-0 { + marvell,pins = < 0 1 2 3 4 5 6 7 + 8 9 10 >; + marvell,function = <1>; + }; + }; + xor@400000 { compatible = "marvell,mv-xor-v2"; reg = <0x400000 0x1000>, diff --git a/arch/arm/dts/armada-cp110-master.dtsi b/arch/arm/dts/armada-cp110-master.dtsi index 422d754..d637867 100644 --- a/arch/arm/dts/armada-cp110-master.dtsi +++ b/arch/arm/dts/armada-cp110-master.dtsi @@ -81,6 +81,38 @@ "cpm-usb3dev", "cpm-eip150", "cpm-eip197"; }; + cpm_pinctl: cpm-pinctl@440000 { + compatible = "marvell,mvebu-pinctrl", + "marvell,a70x0-pinctrl", + "marvell,a80x0-cp0-pinctrl"; + bank-name ="cp0-110"; + reg = <0x440000 0x20>; + pin-count = <63>; + max-func = <0xf>; + + cpm_i2c0_pins: cpm-i2c-pins-0 { + marvell,pins = < 37 38 >; + marvell,function = <2>; + }; + cpm_ge2_rgmii_pins: cpm-ge-rgmii-pins-0 { + marvell,pins = < 44 45 46 47 48 49 50 51 + 52 53 54 55 >; + marvell,function = <1>; + }; + pca0_pins: cpm-pca0_pins { + marvell,pins = <62>; + marvell,function = <0>; + }; + cpm_sdhci_pins: cpm-sdhi-pins-0 { + marvell,pins = < 56 57 58 59 60 61 >; + marvell,function = <14>; + }; + cpm_spi0_pins: cpm-spi-pins-0 { + marvell,pins = < 13 14 15 16 >; + marvell,function = <3>; + }; + }; + cpm_sata0: sata@540000 { compatible = "marvell,armada-8k-ahci"; reg = <0x540000 0x30000>; diff --git a/arch/arm/dts/armada-cp110-slave.dtsi b/arch/arm/dts/armada-cp110-slave.dtsi index a7f77b9..92ef55c 100644 --- a/arch/arm/dts/armada-cp110-slave.dtsi +++ b/arch/arm/dts/armada-cp110-slave.dtsi @@ -81,6 +81,25 @@ "cps-usb3dev", "cps-eip150", "cps-eip197"; }; + cps_pinctl: cps-pinctl@440000 { + compatible = "marvell,mvebu-pinctrl", + "marvell,a80x0-cp1-pinctrl"; + bank-name ="cp1-110"; + reg = <0x440000 0x20>; + pin-count = <63>; + max-func = <0xf>; + + cps_ge1_rgmii_pins: cps-ge-rgmii-pins-0 { + marvell,pins = < 0 1 2 3 4 5 6 7 + 8 9 10 11 >; + marvell,function = <3>; + }; + cps_spi1_pins: cps-spi-pins-1 { + marvell,pins = < 13 14 15 16 >; + marvell,function = <3>; + }; + }; + cps_sata0: sata@540000 { compatible = "marvell,armada-8k-ahci"; reg = <0x540000 0x30000>; diff --git a/doc/device-tree-bindings/pinctrl/marvell,mvebu-pinctrl.txt b/doc/device-tree-bindings/pinctrl/marvell,mvebu-pinctrl.txt index 0973db8..5f86c0a 100644 --- a/doc/device-tree-bindings/pinctrl/marvell,mvebu-pinctrl.txt +++ b/doc/device-tree-bindings/pinctrl/marvell,mvebu-pinctrl.txt @@ -37,10 +37,10 @@ Example: pin-count = <20>; max-func = <3>; /* MPP Bus: - SPI0 [0-3] - I2C0 [4-5] - UART0 [11,19] - */ + * SPI0 [0-3] + * I2C0 [4-5] + * UART0 [11,19] + */ /* 0 1 2 3 4 5 6 7 8 9 */ pin-func = < 3 3 3 3 3 3 0 0 0 0 0 3 0 0 0 0 0 0 0 3>; @@ -59,20 +59,20 @@ Example: pin-count = <63>; max-func = <0xf>; /* MPP Bus: - [0-31] = 0xff: Keep default CP0_shared_pins: - [11] CLKOUT_MPP_11 (out) - [23] LINK_RD_IN_CP2CP (in) - [25] CLKOUT_MPP_25 (out) - [29] AVS_FB_IN_CP2CP (in) - [32,34] SMI - [31] GPIO: push button/Wake - [35-36] GPIO - [37-38] I2C - [40-41] SATA[0/1]_PRESENT_ACTIVEn - [42-43] XSMI - [44-55] RGMII1 - [56-62] SD - */ + * [0-31] = 0xff: Keep default CP0_shared_pins: + * [11] CLKOUT_MPP_11 (out) + * [23] LINK_RD_IN_CP2CP (in) + * [25] CLKOUT_MPP_25 (out) + * [29] AVS_FB_IN_CP2CP (in) + * [32,34] SMI + * [31] GPIO: push button/Wake + * [35-36] GPIO + * [37-38] I2C + * [40-41] SATA[0/1]_PRESENT_ACTIVEn + * [42-43] XSMI + * [44-55] RGMII1 + * [56-62] SD + */ /* 0 1 2 3 4 5 6 7 8 9 */ pin-func = < 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff @@ -95,10 +95,10 @@ Example: pin-count = <63>; max-func = <0xf>; /* MPP Bus: - [0-11] RGMII0 - [27,31] GE_MDIO/MDC - [32-62] = 0xff: Keep default CP1_shared_pins: - */ + * [0-11] RGMII0 + * [27,31] GE_MDIO/MDC + * [32-62] = 0xff: Keep default CP1_shared_pins: + */ /* 0 1 2 3 4 5 6 7 8 9 */ pin-func = < 0x3 0x3 0x3 0x3 0x3 0x3 0x3 0x3 0x3 0x3 0x3 0x3 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff From 27bd4b159a3144899b7ffd1efa78ec80b16f8041 Mon Sep 17 00:00:00 2001 From: Konstantin Porotchkin Date: Thu, 8 Dec 2016 12:22:31 +0200 Subject: [PATCH 5/9] arm64: mvebu: Enable BUBT command support in A8K default config Enable mvebu "bubt" command support in the default configuration file for Armada-7040 and Armada-8040 development boards Signed-off-by: Konstantin Porotchkin Cc: Stefan Roese Cc: Nadav Haklai Cc: Neta Zur Hershkovits Cc: Omri Itach Cc: Igal Liberman Cc: Haim Boot Cc: Hanna Hawa Signed-off-by: Stefan Roese --- configs/mvebu_db-88f7040_defconfig | 1 + configs/mvebu_db-88f8040_defconfig | 1 + 2 files changed, 2 insertions(+) diff --git a/configs/mvebu_db-88f7040_defconfig b/configs/mvebu_db-88f7040_defconfig index f153b9c..ed61f78 100644 --- a/configs/mvebu_db-88f7040_defconfig +++ b/configs/mvebu_db-88f7040_defconfig @@ -27,6 +27,7 @@ CONFIG_CMD_EXT4=y CONFIG_CMD_EXT4_WRITE=y CONFIG_CMD_FAT=y CONFIG_CMD_FS_GENERIC=y +CONFIG_CMD_MVEBU_BUBT=y CONFIG_BLOCK_CACHE=y CONFIG_DM_I2C=y CONFIG_SYS_I2C_MVTWSI=y diff --git a/configs/mvebu_db-88f8040_defconfig b/configs/mvebu_db-88f8040_defconfig index 61d58b5..fa2f597 100644 --- a/configs/mvebu_db-88f8040_defconfig +++ b/configs/mvebu_db-88f8040_defconfig @@ -27,6 +27,7 @@ CONFIG_CMD_EXT4=y CONFIG_CMD_EXT4_WRITE=y CONFIG_CMD_FAT=y CONFIG_CMD_FS_GENERIC=y +CONFIG_CMD_MVEBU_BUBT=y CONFIG_BLOCK_CACHE=y CONFIG_DM_I2C=y CONFIG_SYS_I2C_MVTWSI=y From 81647eaff31a4f2e5a270a5c71da0941b5ed952a Mon Sep 17 00:00:00 2001 From: Konstantin Porotchkin Date: Thu, 8 Dec 2016 12:22:32 +0200 Subject: [PATCH 6/9] arm64: mvebu: Enable pin control support in A8K default config Enable mvebu pin control support in the default configuration files for Armada-7040 and Armada-8040 development boards Signed-off-by: Konstantin Porotchkin Cc: Stefan Roese Cc: Nadav Haklai Cc: Neta Zur Hershkovits Cc: Omri Itach Cc: Igal Liberman Cc: Haim Boot Cc: Hanna Hawa Signed-off-by: Stefan Roese --- configs/mvebu_db-88f7040_defconfig | 1 + configs/mvebu_db-88f8040_defconfig | 1 + 2 files changed, 2 insertions(+) diff --git a/configs/mvebu_db-88f7040_defconfig b/configs/mvebu_db-88f7040_defconfig index ed61f78..e3bdda6 100644 --- a/configs/mvebu_db-88f7040_defconfig +++ b/configs/mvebu_db-88f7040_defconfig @@ -51,3 +51,4 @@ CONFIG_USB_XHCI_HCD=y CONFIG_USB_EHCI_HCD=y CONFIG_USB_STORAGE=y CONFIG_SMBIOS_MANUFACTURER="" +CONFIG_PINCTRL=y diff --git a/configs/mvebu_db-88f8040_defconfig b/configs/mvebu_db-88f8040_defconfig index fa2f597..5d5be64 100644 --- a/configs/mvebu_db-88f8040_defconfig +++ b/configs/mvebu_db-88f8040_defconfig @@ -54,3 +54,4 @@ CONFIG_USB_XHCI_HCD=y CONFIG_USB_EHCI_HCD=y CONFIG_USB_STORAGE=y CONFIG_SMBIOS_MANUFACTURER="" +CONFIG_PINCTRL=y From b58385df3a448ba90e4ed0b699d275597ff73ea9 Mon Sep 17 00:00:00 2001 From: Konstantin Porotchkin Date: Sun, 4 Dec 2016 18:34:13 +0200 Subject: [PATCH 7/9] arm64: mvebu: Add L3 cache flush functionality to A8K family Add missing L3 cache flush functionality which absence prevents Linux kernel from normal boot in case the L3 cache is enabled by ATF. The L3 cache is named the "last level" cache in order to keep the terminology similar to the ATF code. This cache should not be disabled by u-boot since the Linux kernel cannot activate it, so it is activates at ATF stage. However the cache flush is required for preventing data corruption after disabling the MMU and the data cache before passing control to the loaded Linux image. Signed-off-by: Konstantin Porotchkin Cc: Stefan Roese Cc: Nadav Haklai Cc: Neta Zur Hershkovits Cc: Omri Itach Cc: Igal Liberman Cc: Haim Boot Cc: Hanna Hawa Signed-off-by: Stefan Roese --- arch/arm/include/asm/arch-armada8k/cache_llc.h | 21 ++++++++++++++ arch/arm/mach-mvebu/armada8k/Makefile | 1 + arch/arm/mach-mvebu/armada8k/cache_llc.S | 39 ++++++++++++++++++++++++++ 3 files changed, 61 insertions(+) create mode 100644 arch/arm/include/asm/arch-armada8k/cache_llc.h create mode 100644 arch/arm/mach-mvebu/armada8k/cache_llc.S diff --git a/arch/arm/include/asm/arch-armada8k/cache_llc.h b/arch/arm/include/asm/arch-armada8k/cache_llc.h new file mode 100644 index 0000000..8f97e6d --- /dev/null +++ b/arch/arm/include/asm/arch-armada8k/cache_llc.h @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2016 Marvell International Ltd. + * + * SPDX-License-Identifier: GPL-2.0 + * https://spdx.org/licenses + */ + +#ifndef _CACHE_LLC_H_ +#define _CACHE_LLC_H_ + +/* Armada-7K/8K last level cache */ + +#define MVEBU_A8K_REGS_BASE_MSB 0xf000 +#define LLC_BASE_ADDR 0x8000 +#define LLC_CACHE_SYNC 0x700 +#define LLC_CACHE_SYNC_COMPLETE 0x730 +#define LLC_FLUSH_BY_WAY 0x7fc +#define LLC_WAY_MASK 0xffffffff +#define LLC_CACHE_SYNC_MASK 0x1 + +#endif /* _CACHE_LLC_H_ */ diff --git a/arch/arm/mach-mvebu/armada8k/Makefile b/arch/arm/mach-mvebu/armada8k/Makefile index 84c69d9..0facf14 100644 --- a/arch/arm/mach-mvebu/armada8k/Makefile +++ b/arch/arm/mach-mvebu/armada8k/Makefile @@ -5,3 +5,4 @@ # obj-y = cpu.o +obj-y += cache_llc.o diff --git a/arch/arm/mach-mvebu/armada8k/cache_llc.S b/arch/arm/mach-mvebu/armada8k/cache_llc.S new file mode 100644 index 0000000..71aecb2 --- /dev/null +++ b/arch/arm/mach-mvebu/armada8k/cache_llc.S @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2016 Marvell International Ltd. + * + * SPDX-License-Identifier: GPL-2.0 + * https://spdx.org/licenses + */ + +#include +#include + +/* + * int __asm_flush_l3_dcache + * + * flush Armada-8K last level cache. + * + */ +ENTRY(__asm_flush_l3_dcache) + /* flush cache */ + mov x0, #LLC_BASE_ADDR + add x0, x0, #LLC_FLUSH_BY_WAY + movk x0, #MVEBU_A8K_REGS_BASE_MSB, lsl #16 + mov w1, #LLC_WAY_MASK + str w1, [x0] + /* sync cache */ + mov x0, #LLC_BASE_ADDR + add x0, x0, #LLC_CACHE_SYNC + movk x0, #MVEBU_A8K_REGS_BASE_MSB, lsl #16 + str wzr, [x0] + /* check that cache sync completed */ + mov x0, #LLC_BASE_ADDR + add x0, x0, #LLC_CACHE_SYNC_COMPLETE + movk x0, #MVEBU_A8K_REGS_BASE_MSB, lsl #16 +1: ldr w1, [x0] + and w1, w1, #LLC_CACHE_SYNC_MASK + cbnz w1, 1b + /* return success */ + mov x0, #0 + ret +ENDPROC(__asm_flush_l3_dcache) From 1d136726f736c1d288aefc292a09287b92ebf0cf Mon Sep 17 00:00:00 2001 From: Konstantin Porotchkin Date: Sun, 4 Dec 2016 18:34:14 +0200 Subject: [PATCH 8/9] arm64: mvebu: Enable PCIe support in Armada-7040 configuration Enable PCIe bus support in Armada-7040 DB default configuration Signed-off-by: Konstantin Porotchkin Cc: Stefan Roese Cc: Nadav Haklai Cc: Neta Zur Hershkovits Cc: Omri Itach Cc: Igal Liberman Cc: Haim Boot Cc: Hanna Hawa Signed-off-by: Stefan Roese --- configs/mvebu_db-88f7040_defconfig | 3 +++ 1 file changed, 3 insertions(+) diff --git a/configs/mvebu_db-88f7040_defconfig b/configs/mvebu_db-88f7040_defconfig index e3bdda6..d9de252 100644 --- a/configs/mvebu_db-88f7040_defconfig +++ b/configs/mvebu_db-88f7040_defconfig @@ -37,6 +37,9 @@ CONFIG_SPI_FLASH_MACRONIX=y CONFIG_SPI_FLASH_SPANSION=y CONFIG_SPI_FLASH_STMICRO=y CONFIG_PHYLIB=y +CONFIG_PCI=y +CONFIG_DM_PCI=y +CONFIG_PCIE_DW_MVEBU=y CONFIG_MVEBU_COMPHY_SUPPORT=y # CONFIG_SPL_SERIAL_PRESENT is not set CONFIG_DEBUG_UART=y From a20b7a2a53d3ac668d1ed25b06cd6d15ca41f2a9 Mon Sep 17 00:00:00 2001 From: Konstantin Porotchkin Date: Sun, 4 Dec 2016 18:34:15 +0200 Subject: [PATCH 9/9] arm64: mvebu: Enable hush parser in A8K default configuration Enable hush parser in Armada-7040 and Armada-8040 DB default configurations. Signed-off-by: Konstantin Porotchkin Cc: Stefan Roese Cc: Nadav Haklai Cc: Neta Zur Hershkovits Cc: Omri Itach Cc: Igal Liberman Cc: Haim Boot Cc: Hanna Hawa Signed-off-by: Stefan Roese --- configs/mvebu_db-88f7040_defconfig | 1 + configs/mvebu_db-88f8040_defconfig | 1 + 2 files changed, 2 insertions(+) diff --git a/configs/mvebu_db-88f7040_defconfig b/configs/mvebu_db-88f7040_defconfig index d9de252..a2bb97a 100644 --- a/configs/mvebu_db-88f7040_defconfig +++ b/configs/mvebu_db-88f7040_defconfig @@ -55,3 +55,4 @@ CONFIG_USB_EHCI_HCD=y CONFIG_USB_STORAGE=y CONFIG_SMBIOS_MANUFACTURER="" CONFIG_PINCTRL=y +CONFIG_HUSH_PARSER=y diff --git a/configs/mvebu_db-88f8040_defconfig b/configs/mvebu_db-88f8040_defconfig index 5d5be64..1e92e9f 100644 --- a/configs/mvebu_db-88f8040_defconfig +++ b/configs/mvebu_db-88f8040_defconfig @@ -55,3 +55,4 @@ CONFIG_USB_EHCI_HCD=y CONFIG_USB_STORAGE=y CONFIG_SMBIOS_MANUFACTURER="" CONFIG_PINCTRL=y +CONFIG_HUSH_PARSER=y