From 8a67acfce24f825b4935c87b2dbd70915d6eeeaa Mon Sep 17 00:00:00 2001 From: Michael Trimarchi Date: Tue, 26 Jul 2022 18:33:11 +0200 Subject: [PATCH 001/374] mtd: nand: Rename the nand_manufacturers struct Upstream linux commit 8cfb9ab68f9070. Drop the 's' at the end of nand_manufacturers since the struct is actually describing a single manufacturer, not a manufacturer table. Signed-off-by: Michael Trimarchi Reviewed-by: Dario Binacchi Signed-off-by: Dario Binacchi --- drivers/mtd/nand/raw/nand_base.c | 4 ++-- drivers/mtd/nand/raw/nand_ids.c | 2 +- include/linux/mtd/rawnand.h | 8 ++++---- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c index 4b09a11288..9d8ccfda53 100644 --- a/drivers/mtd/nand/raw/nand_base.c +++ b/drivers/mtd/nand/raw/nand_base.c @@ -4261,7 +4261,7 @@ static bool find_full_id_nand(struct mtd_info *mtd, struct nand_chip *chip, * Returns a nand_manufacturer_desc object if the manufacturer is defined * in the NAND manufacturers database, NULL otherwise. */ -static const struct nand_manufacturers *nand_get_manufacturer_desc(u8 id) +static const struct nand_manufacturer *nand_get_manufacturer_desc(u8 id) { int i; @@ -4281,7 +4281,7 @@ struct nand_flash_dev *nand_get_flash_type(struct nand_chip *chip, int *maf_id, struct nand_flash_dev *type) { struct mtd_info *mtd = &chip->mtd; - const struct nand_manufacturers *manufacturer_desc; + const struct nand_manufacturer *manufacturer_desc; int busw, ret; u8 *id_data = chip->id.data; diff --git a/drivers/mtd/nand/raw/nand_ids.c b/drivers/mtd/nand/raw/nand_ids.c index 4dece1b206..d0cfacc69b 100644 --- a/drivers/mtd/nand/raw/nand_ids.c +++ b/drivers/mtd/nand/raw/nand_ids.c @@ -177,7 +177,7 @@ struct nand_flash_dev nand_flash_ids[] = { }; /* Manufacturer IDs */ -struct nand_manufacturers nand_manuf_ids[] = { +struct nand_manufacturer nand_manuf_ids[] = { {NAND_MFR_TOSHIBA, "Toshiba", &toshiba_nand_manuf_ops}, {NAND_MFR_SAMSUNG, "Samsung", &samsung_nand_manuf_ops}, {NAND_MFR_FUJITSU, "Fujitsu"}, diff --git a/include/linux/mtd/rawnand.h b/include/linux/mtd/rawnand.h index aa45558b3d..8dc2d81dba 100644 --- a/include/linux/mtd/rawnand.h +++ b/include/linux/mtd/rawnand.h @@ -976,7 +976,7 @@ struct nand_chip { void *priv; struct { - const struct nand_manufacturers *desc; + const struct nand_manufacturer *desc; void *priv; } manufacturer; }; @@ -1124,19 +1124,19 @@ struct nand_flash_dev { }; /** - * struct nand_manufacturers - NAND Flash Manufacturer ID Structure + * struct nand_manufacturer - NAND Flash Manufacturer ID Structure * @name: Manufacturer name * @id: manufacturer ID code of device. * @ops: manufacturer operations */ -struct nand_manufacturers { +struct nand_manufacturer { int id; char *name; const struct nand_manufacturer_ops *ops; }; extern struct nand_flash_dev nand_flash_ids[]; -extern struct nand_manufacturers nand_manuf_ids[]; +extern struct nand_manufacturer nand_manuf_ids[]; extern const struct nand_manufacturer_ops toshiba_nand_manuf_ops; extern const struct nand_manufacturer_ops samsung_nand_manuf_ops; From c76f9ddf91b14312e71594459ebb3dd72d885aa8 Mon Sep 17 00:00:00 2001 From: Michael Trimarchi Date: Mon, 25 Jul 2022 10:06:06 +0200 Subject: [PATCH 002/374] mtd: nand: change return type of nand_get_flash_type() to int Upstream linux commit 4722c0e958e636. The returned "type" is never used in nand_scan_ident() and spl code Make nand_get_flash_type() simply return an integer value in order to avoid unnecessary ERR_PTR/PTR_ERR dance. Signed-off-by: Michael Trimarchi Reviewed-by: Dario Binacchi Signed-off-by: Dario Binacchi --- drivers/mtd/nand/raw/mt7621_nand.c | 10 +++++----- drivers/mtd/nand/raw/mxs_nand_spl.c | 8 ++++---- drivers/mtd/nand/raw/nand_base.c | 28 +++++++++++++--------------- include/linux/mtd/rawnand.h | 5 ++--- 4 files changed, 24 insertions(+), 27 deletions(-) diff --git a/drivers/mtd/nand/raw/mt7621_nand.c b/drivers/mtd/nand/raw/mt7621_nand.c index 9763ae6dc5..a4a0bce35d 100644 --- a/drivers/mtd/nand/raw/mt7621_nand.c +++ b/drivers/mtd/nand/raw/mt7621_nand.c @@ -1184,13 +1184,13 @@ int mt7621_nfc_spl_post_init(struct mt7621_nfc *nfc) { struct nand_chip *nand = &nfc->nand; int nand_maf_id, nand_dev_id; - struct nand_flash_dev *type; + int ret; - type = nand_get_flash_type(nand, &nand_maf_id, - &nand_dev_id, NULL); + ret = nand_get_flash_type(nand, &nand_maf_id, + &nand_dev_id, NULL); - if (IS_ERR(type)) - return PTR_ERR(type); + if (ret) + return ret; nand->numchips = 1; nand->mtd.size = nand->chipsize; diff --git a/drivers/mtd/nand/raw/mxs_nand_spl.c b/drivers/mtd/nand/raw/mxs_nand_spl.c index 3daacbb330..773d375fc2 100644 --- a/drivers/mtd/nand/raw/mxs_nand_spl.c +++ b/drivers/mtd/nand/raw/mxs_nand_spl.c @@ -81,13 +81,13 @@ static int mxs_flash_full_ident(struct mtd_info *mtd) { int nand_maf_id, nand_dev_id; struct nand_chip *chip = mtd_to_nand(mtd); - struct nand_flash_dev *type; + int ret; - type = nand_get_flash_type(mtd, chip, &nand_maf_id, &nand_dev_id, NULL); + ret = nand_get_flash_type(mtd, chip, &nand_maf_id, &nand_dev_id, NULL); - if (IS_ERR(type)) { + if (ret) { chip->select_chip(mtd, -1); - return PTR_ERR(type); + return ret; } return 0; diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c index 9d8ccfda53..b4fa618dc4 100644 --- a/drivers/mtd/nand/raw/nand_base.c +++ b/drivers/mtd/nand/raw/nand_base.c @@ -4276,9 +4276,8 @@ static const struct nand_manufacturer *nand_get_manufacturer_desc(u8 id) /* * Get the flash and manufacturer id and lookup if the type is supported. */ -struct nand_flash_dev *nand_get_flash_type(struct nand_chip *chip, int *maf_id, - int *dev_id, - struct nand_flash_dev *type) +int nand_get_flash_type(struct nand_chip *chip, int *maf_id, + int *dev_id, struct nand_flash_dev *type) { struct mtd_info *mtd = &chip->mtd; const struct nand_manufacturer *manufacturer_desc; @@ -4291,7 +4290,7 @@ struct nand_flash_dev *nand_get_flash_type(struct nand_chip *chip, int *maf_id, */ ret = nand_reset(chip, 0); if (ret) - return ERR_PTR(ret); + return ret; /* Select the device */ chip->select_chip(mtd, 0); @@ -4299,7 +4298,7 @@ struct nand_flash_dev *nand_get_flash_type(struct nand_chip *chip, int *maf_id, /* Send the command for reading device ID */ ret = nand_readid_op(chip, 0, id_data, 2); if (ret) - return ERR_PTR(ret); + return ret; /* Read manufacturer and device IDs */ *maf_id = id_data[0]; @@ -4315,12 +4314,12 @@ struct nand_flash_dev *nand_get_flash_type(struct nand_chip *chip, int *maf_id, /* Read entire ID string */ ret = nand_readid_op(chip, 0, id_data, 8); if (ret) - return ERR_PTR(ret); + return ret; if (id_data[0] != *maf_id || id_data[1] != *dev_id) { pr_info("second ID read did not match %02x,%02x against %02x,%02x\n", *maf_id, *dev_id, id_data[0], id_data[1]); - return ERR_PTR(-ENODEV); + return -ENODEV; } chip->id.len = nand_id_len(id_data, ARRAY_SIZE(chip->id.data)); @@ -4368,7 +4367,7 @@ struct nand_flash_dev *nand_get_flash_type(struct nand_chip *chip, int *maf_id, } if (!type->name) - return ERR_PTR(-ENODEV); + return -ENODEV; if (!mtd->name) mtd->name = type->name; @@ -4401,7 +4400,7 @@ ident_done: pr_warn("bus width %d instead %d bit\n", (chip->options & NAND_BUSWIDTH_16) ? 16 : 8, busw ? 16 : 8); - return ERR_PTR(-EINVAL); + return -EINVAL; } nand_decode_bbm_options(mtd, chip); @@ -4432,7 +4431,7 @@ ident_done: ret = nand_manufacturer_init(chip); if (ret) - return ERR_PTR(ret); + return ret; pr_info("device found, Manufacturer ID: 0x%02x, Chip ID: 0x%02x\n", *maf_id, *dev_id); @@ -4460,7 +4459,7 @@ ident_done: pr_info("%d MiB, %s, erase size: %d KiB, page size: %d, OOB size: %d\n", (int)(chip->chipsize >> 20), nand_is_slc(chip) ? "SLC" : "MLC", mtd->erasesize >> 10, mtd->writesize, mtd->oobsize); - return type; + return 0; } EXPORT_SYMBOL(nand_get_flash_type); @@ -4547,7 +4546,6 @@ int nand_scan_ident(struct mtd_info *mtd, int maxchips, { int i, nand_maf_id, nand_dev_id; struct nand_chip *chip = mtd_to_nand(mtd); - struct nand_flash_dev *type; int ret; if (ofnode_valid(chip->flash_node)) { @@ -4560,14 +4558,14 @@ int nand_scan_ident(struct mtd_info *mtd, int maxchips, nand_set_defaults(chip, chip->options & NAND_BUSWIDTH_16); /* Read the flash type */ - type = nand_get_flash_type(chip, &nand_maf_id, + ret = nand_get_flash_type(chip, &nand_maf_id, &nand_dev_id, table); - if (IS_ERR(type)) { + if (ret) { if (!(chip->options & NAND_SCAN_SILENT_NODEV)) pr_warn("No NAND device found\n"); chip->select_chip(mtd, -1); - return PTR_ERR(type); + return ret; } /* Initialize the ->data_interface field. */ diff --git a/include/linux/mtd/rawnand.h b/include/linux/mtd/rawnand.h index 8dc2d81dba..8178f36b49 100644 --- a/include/linux/mtd/rawnand.h +++ b/include/linux/mtd/rawnand.h @@ -29,9 +29,8 @@ struct nand_flash_dev; struct device_node; /* Get the flash and manufacturer id and lookup if the type is supported. */ -struct nand_flash_dev *nand_get_flash_type(struct nand_chip *chip, - int *maf_id, int *dev_id, - struct nand_flash_dev *type); +int nand_get_flash_type(struct nand_chip *chip, int *maf_id, int *dev_id, + struct nand_flash_dev *type); /* Scan and identify a NAND device */ int nand_scan(struct mtd_info *mtd, int max_chips); From 6cda1dc210304d8d74fd3c4b98b80b47ba1982c1 Mon Sep 17 00:00:00 2001 From: Michael Trimarchi Date: Mon, 25 Jul 2022 10:18:51 +0200 Subject: [PATCH 003/374] mtd: nand: Rename nand_get_flash_type() into nand_detect() Upstream linux commit 7bb427990ee364. Rename the function to match this new behavior. NOTE: fix nand_detect/nand_get_flash_type parameters in mxs_nand_spl. This code seems never executed by any board as alternative for nand detect Signed-off-by: Michael Trimarchi Reviewed-by: Dario Binacchi Signed-off-by: Dario Binacchi --- drivers/mtd/nand/raw/mt7621_nand.c | 3 +-- drivers/mtd/nand/raw/mxs_nand_spl.c | 2 +- drivers/mtd/nand/raw/nand_base.c | 11 +++++------ include/linux/mtd/rawnand.h | 4 ++-- 4 files changed, 9 insertions(+), 11 deletions(-) diff --git a/drivers/mtd/nand/raw/mt7621_nand.c b/drivers/mtd/nand/raw/mt7621_nand.c index a4a0bce35d..f6eddb84a9 100644 --- a/drivers/mtd/nand/raw/mt7621_nand.c +++ b/drivers/mtd/nand/raw/mt7621_nand.c @@ -1186,8 +1186,7 @@ int mt7621_nfc_spl_post_init(struct mt7621_nfc *nfc) int nand_maf_id, nand_dev_id; int ret; - ret = nand_get_flash_type(nand, &nand_maf_id, - &nand_dev_id, NULL); + ret = nand_detect(nand, &nand_maf_id, &nand_dev_id, NULL); if (ret) return ret; diff --git a/drivers/mtd/nand/raw/mxs_nand_spl.c b/drivers/mtd/nand/raw/mxs_nand_spl.c index 773d375fc2..ef03b7789d 100644 --- a/drivers/mtd/nand/raw/mxs_nand_spl.c +++ b/drivers/mtd/nand/raw/mxs_nand_spl.c @@ -83,7 +83,7 @@ static int mxs_flash_full_ident(struct mtd_info *mtd) struct nand_chip *chip = mtd_to_nand(mtd); int ret; - ret = nand_get_flash_type(mtd, chip, &nand_maf_id, &nand_dev_id, NULL); + ret = nand_detect(chip, &nand_maf_id, &nand_dev_id, NULL); if (ret) { chip->select_chip(mtd, -1); diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c index b4fa618dc4..1a1a757932 100644 --- a/drivers/mtd/nand/raw/nand_base.c +++ b/drivers/mtd/nand/raw/nand_base.c @@ -4276,8 +4276,8 @@ static const struct nand_manufacturer *nand_get_manufacturer_desc(u8 id) /* * Get the flash and manufacturer id and lookup if the type is supported. */ -int nand_get_flash_type(struct nand_chip *chip, int *maf_id, - int *dev_id, struct nand_flash_dev *type) +int nand_detect(struct nand_chip *chip, int *maf_id, + int *dev_id, struct nand_flash_dev *type) { struct mtd_info *mtd = &chip->mtd; const struct nand_manufacturer *manufacturer_desc; @@ -4461,7 +4461,7 @@ ident_done: mtd->erasesize >> 10, mtd->writesize, mtd->oobsize); return 0; } -EXPORT_SYMBOL(nand_get_flash_type); +EXPORT_SYMBOL(nand_detect); #if CONFIG_IS_ENABLED(OF_CONTROL) @@ -4558,8 +4558,7 @@ int nand_scan_ident(struct mtd_info *mtd, int maxchips, nand_set_defaults(chip, chip->options & NAND_BUSWIDTH_16); /* Read the flash type */ - ret = nand_get_flash_type(chip, &nand_maf_id, - &nand_dev_id, table); + ret = nand_detect(chip, &nand_maf_id, &nand_dev_id, table); if (ret) { if (!(chip->options & NAND_SCAN_SILENT_NODEV)) @@ -4591,7 +4590,7 @@ int nand_scan_ident(struct mtd_info *mtd, int maxchips, for (i = 1; i < maxchips; i++) { u8 id[2]; - /* See comment in nand_get_flash_type for reset */ + /* See comment in nand_detect for reset */ nand_reset(chip, i); chip->select_chip(mtd, i); diff --git a/include/linux/mtd/rawnand.h b/include/linux/mtd/rawnand.h index 8178f36b49..fb002ae641 100644 --- a/include/linux/mtd/rawnand.h +++ b/include/linux/mtd/rawnand.h @@ -29,8 +29,8 @@ struct nand_flash_dev; struct device_node; /* Get the flash and manufacturer id and lookup if the type is supported. */ -int nand_get_flash_type(struct nand_chip *chip, int *maf_id, int *dev_id, - struct nand_flash_dev *type); +int nand_detect(struct nand_chip *chip, int *maf_id, int *dev_id, + struct nand_flash_dev *type); /* Scan and identify a NAND device */ int nand_scan(struct mtd_info *mtd, int max_chips); From 007f1d14738a1d4c94ebdb726f0d874f9e08f36d Mon Sep 17 00:00:00 2001 From: Michael Trimarchi Date: Mon, 25 Jul 2022 12:20:24 +0200 Subject: [PATCH 004/374] mtd: nand: samsung: Retrieve ECC requirements from extended Upstream linux commit 8fc82d456e40a0. On some nand controllers with hw-ecc the controller code wants to know the ecc strength and size and having these as 0, 0 is not accepted. Specifying these in devicetree is possible but undesirable as the nand may be different in different production runs of the same board, so it is better to get this info from the nand id where possible. This commit adds code to read the ecc strength and size from the nand for Samsung extended-id nands. This code is based on the info for the 5th id byte in the datasheets for the following Samsung nands: K9GAG08U0E, K9GAG08U0F, K9GAG08X0D, K9GBG08U0A, K9GBG08U0B. These all use these bits in the exact same way. Signed-off-by: Michael Trimarchi Reviewed-by: Dario Binacchi Signed-off-by: Dario Binacchi --- drivers/mtd/nand/raw/nand_samsung.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/drivers/mtd/nand/raw/nand_samsung.c b/drivers/mtd/nand/raw/nand_samsung.c index 0ab8062193..36ef48e5ec 100644 --- a/drivers/mtd/nand/raw/nand_samsung.c +++ b/drivers/mtd/nand/raw/nand_samsung.c @@ -64,6 +64,26 @@ static void samsung_nand_decode_id(struct nand_chip *chip) extid >>= 2; mtd->erasesize = (128 * 1024) << (((extid >> 1) & 0x04) | (extid & 0x03)); + + /* Extract ECC requirements from 5th id byte*/ + extid = (chip->id.data[4] >> 4) & 0x07; + if (extid < 5) { + chip->ecc_step_ds = 512; + chip->ecc_strength_ds = 1 << extid; + } else { + chip->ecc_step_ds = 1024; + switch (extid) { + case 5: + chip->ecc_strength_ds = 24; + break; + case 6: + chip->ecc_strength_ds = 40; + break; + case 7: + chip->ecc_strength_ds = 60; + break; + } + } } else { nand_decode_ext_id(chip); } From 1a29486e9fe352ca8806b79c37487855ff4b3d6a Mon Sep 17 00:00:00 2001 From: Michael Trimarchi Date: Thu, 28 Jul 2022 14:43:09 +0200 Subject: [PATCH 005/374] configs: imx8mn_bsh_smm_s2: Use nand_base ident for nand identification The board can mount different nand brand type. Try to use the full scan detection and not the onfi one Signed-off-by: Michael Trimarchi Reviewed-by: Dario Binacchi Signed-off-by: Dario Binacchi --- configs/imx8mn_bsh_smm_s2_defconfig | 2 ++ 1 file changed, 2 insertions(+) diff --git a/configs/imx8mn_bsh_smm_s2_defconfig b/configs/imx8mn_bsh_smm_s2_defconfig index 79995591f2..139cf0392b 100644 --- a/configs/imx8mn_bsh_smm_s2_defconfig +++ b/configs/imx8mn_bsh_smm_s2_defconfig @@ -44,6 +44,8 @@ CONFIG_SPL_DMA=y CONFIG_SPL_I2C=y CONFIG_SPL_MTD_SUPPORT=y CONFIG_SPL_NAND_SUPPORT=y +CONFIG_SPL_NAND_BASE=y +CONFIG_SPL_NAND_IDENT=y CONFIG_SPL_POWER=y CONFIG_SPL_WATCHDOG=y CONFIG_SYS_PROMPT="> " From 080b7d89aeb4339e09029b7fd7e365f9ee37b4b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Mon, 15 Aug 2022 10:01:40 +0200 Subject: [PATCH 006/374] mtd: rawnand: fsl_elbc: Remove NAND_NO_SUBPAGE_WRITE flag MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Subpage write support for freescale eLBC NAND controller driver is implemented in U-Boot and was fixes in the commit d3963721d93f ("nand: Sync with Linux v4.1"). So remove NAND_NO_SUBPAGE_WRITE flag from the fsl_elbc_nand.c driver. This partially revert commit cb04c7723429 ("nand/fsl: add NAND_NO_SUBPAGE_WRITE to eLBC and IFC drivers"), only eLBC driver part. With this change U-Boot with default settings can read from NAND UBIFS image created on Linux with Linux default settings. Prior this change U-Boot was unable to read from NAND UBIFS images created with Linux default settings due to differnet UBI geometry. Linux kernel fsl_elbc_nand.c driver also does not set NAND_NO_SUBPAGE_WRITE flag and has implemented subpage write support. Fixes: cb04c7723429 ("nand/fsl: add NAND_NO_SUBPAGE_WRITE to eLBC and IFC drivers") Fixes: d3963721d93f ("nand: Sync with Linux v4.1") Signed-off-by: Pali Rohár Reviewed-by: Michael Trimarchi Reviewed-by: Dario Binacchi Acked-By: Michael Trimarchi Signed-off-by: Dario Binacchi --- drivers/mtd/nand/raw/fsl_elbc_nand.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/mtd/nand/raw/fsl_elbc_nand.c b/drivers/mtd/nand/raw/fsl_elbc_nand.c index 48a3687f27..e28670a472 100644 --- a/drivers/mtd/nand/raw/fsl_elbc_nand.c +++ b/drivers/mtd/nand/raw/fsl_elbc_nand.c @@ -732,7 +732,6 @@ static int fsl_elbc_chip_init(int devnum, u8 *addr, struct udevice *dev) nand->bbt_md = &bbt_mirror_descr; /* set up nand options */ - nand->options = NAND_NO_SUBPAGE_WRITE; nand->bbt_options = NAND_BBT_USE_FLASH; nand->controller = &elbc_ctrl->controller; From ac30d240dbb520d0980f0687630feb702a14f51a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Fri, 19 Aug 2022 11:20:01 +0200 Subject: [PATCH 007/374] mtd: rawnand: fsl_elbc: Fix reading address pointer from DT MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit During compilation gcc throws warning: drivers/mtd/nand/raw/fsl_elbc_nand.c: In function ‘fsl_elbc_nand_probe’: drivers/mtd/nand/raw/fsl_elbc_nand.c:841:31: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] return fsl_elbc_chip_init(0, (void *)dev_read_addr(dev), dev); ^ Fix it by using dev_read_addr_ptr() function which returns pointer instead of dev_read_addr() which returns integer type. Signed-off-by: Pali Rohár Reviewed-by: Dario Binacchi Signed-off-by: Dario Binacchi --- drivers/mtd/nand/raw/fsl_elbc_nand.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mtd/nand/raw/fsl_elbc_nand.c b/drivers/mtd/nand/raw/fsl_elbc_nand.c index e28670a472..4f0acd7c89 100644 --- a/drivers/mtd/nand/raw/fsl_elbc_nand.c +++ b/drivers/mtd/nand/raw/fsl_elbc_nand.c @@ -838,7 +838,7 @@ void board_nand_init(void) static int fsl_elbc_nand_probe(struct udevice *dev) { - return fsl_elbc_chip_init(0, (void *)dev_read_addr(dev), dev); + return fsl_elbc_chip_init(0, dev_read_addr_ptr(dev), dev); } static const struct udevice_id fsl_elbc_nand_dt_ids[] = { From 11d8439e09bf664d5753ad2af9323855818c8ffc Mon Sep 17 00:00:00 2001 From: Jayesh Choudhary Date: Tue, 2 Aug 2022 18:38:14 +0530 Subject: [PATCH 008/374] configs: j721s2_evm_a72_defconfig: fix the bootcmd Remove the main_cpsw0_qsgmii_phyinit variable from the boot command as there is no ethernet firmware in j721s2. Fixes: 8886341aa670 ('configs: j721s2_evm_a72_defconfig: Add A72 specific defconfig') Signed-off-by: Jayesh Choudhary --- configs/j721s2_evm_a72_defconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configs/j721s2_evm_a72_defconfig b/configs/j721s2_evm_a72_defconfig index 671fce6268..a06312f4f5 100644 --- a/configs/j721s2_evm_a72_defconfig +++ b/configs/j721s2_evm_a72_defconfig @@ -32,7 +32,7 @@ CONFIG_SPL_LOAD_FIT=y CONFIG_SPL_LOAD_FIT_ADDRESS=0x81000000 # CONFIG_USE_SPL_FIT_GENERATOR is not set CONFIG_OF_BOARD_SETUP=y -CONFIG_BOOTCOMMAND="run findfdt; run envboot; run init_${boot}; run main_cpsw0_qsgmii_phyinit; run boot_rprocs; run get_kern_${boot}; run get_fdt_${boot}; run get_overlay_${boot}; run run_kern" +CONFIG_BOOTCOMMAND="run findfdt; run envboot; run init_${boot}; run boot_rprocs; run get_kern_${boot}; run get_fdt_${boot}; run get_overlay_${boot}; run run_kern" CONFIG_LOGLEVEL=7 CONFIG_SPL_MAX_SIZE=0xc0000 CONFIG_SPL_HAS_BSS_LINKER_SECTION=y From 42f051ceb6c2d0685991eadf430c3701cbbe2974 Mon Sep 17 00:00:00 2001 From: Davidson K Date: Tue, 9 Aug 2022 15:56:52 +0530 Subject: [PATCH 009/374] arm: total_compute: enable psci psci is used for system reset Signed-off-by: Davidson K --- arch/arm/dts/total_compute.dts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/arm/dts/total_compute.dts b/arch/arm/dts/total_compute.dts index 4399269a44..96edacda0b 100644 --- a/arch/arm/dts/total_compute.dts +++ b/arch/arm/dts/total_compute.dts @@ -45,4 +45,8 @@ clock-frequency = <24000000>; clock-output-names = "bp:clock24mhz"; }; + psci { + compatible = "arm,psci-1.0", "arm,psci-0.2"; + method = "smc"; + }; }; From 23ba5f34c8e13e65e8d3749bad610d56fc4814cc Mon Sep 17 00:00:00 2001 From: Sumit Garg Date: Thu, 4 Aug 2022 19:57:09 +0530 Subject: [PATCH 010/374] phy: Move qcom SoCs specific phy drivers to qcom folder Signed-off-by: Sumit Garg --- drivers/phy/Kconfig | 15 +-------------- drivers/phy/Makefile | 3 +-- drivers/phy/qcom/Kconfig | 13 +++++++++++++ drivers/phy/qcom/Makefile | 2 ++ drivers/phy/{ => qcom}/msm8916-usbh-phy.c | 0 drivers/phy/{ => qcom}/phy-qcom-ipq4019-usb.c | 0 6 files changed, 17 insertions(+), 16 deletions(-) create mode 100644 drivers/phy/qcom/Kconfig create mode 100644 drivers/phy/qcom/Makefile rename drivers/phy/{ => qcom}/msm8916-usbh-phy.c (100%) rename drivers/phy/{ => qcom}/phy-qcom-ipq4019-usb.c (100%) diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig index c25b42c68f..cf4d5908d7 100644 --- a/drivers/phy/Kconfig +++ b/drivers/phy/Kconfig @@ -143,12 +143,6 @@ config STI_USB_PHY used by USB2 and USB3 Host controllers available on STiH407 SoC families. -config PHY_QCOM_IPQ4019_USB - tristate "Qualcomm IPQ4019 USB PHY driver" - depends on PHY && ARCH_IPQ40XX - help - Support for the USB PHY-s on Qualcomm IPQ40xx SoC-s. - config PHY_RCAR_GEN2 tristate "Renesas R-Car Gen2 USB PHY" depends on PHY && RCAR_GEN2 @@ -220,14 +214,6 @@ config MESON_AXG_MIPI_PCIE_ANALOG_PHY This is the generic phy driver for the Amlogic Meson AXG MIPI PCIe Analog PHY. -config MSM8916_USB_PHY - bool "Qualcomm MSM8916 USB PHY support" - depends on PHY - help - Support the USB PHY in msm8916 - - This PHY is found on qualcomm dragonboard410c development board. - config OMAP_USB2_PHY bool "Support OMAP's USB2 PHY" depends on PHY @@ -298,5 +284,6 @@ config PHY_XILINX_ZYNQMP source "drivers/phy/rockchip/Kconfig" source "drivers/phy/cadence/Kconfig" source "drivers/phy/ti/Kconfig" +source "drivers/phy/qcom/Kconfig" endmenu diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile index d95439c425..a3b9f3c5b1 100644 --- a/drivers/phy/Makefile +++ b/drivers/phy/Makefile @@ -21,7 +21,6 @@ obj-$(CONFIG_PHY_SANDBOX) += sandbox-phy.o obj-$(CONFIG_$(SPL_)PIPE3_PHY) += ti-pipe3-phy.o obj-$(CONFIG_AM654_PHY) += phy-ti-am654.o obj-$(CONFIG_STI_USB_PHY) += sti_usb_phy.o -obj-$(CONFIG_PHY_QCOM_IPQ4019_USB) += phy-qcom-ipq4019-usb.o obj-$(CONFIG_PHY_RCAR_GEN2) += phy-rcar-gen2.o obj-$(CONFIG_PHY_RCAR_GEN3) += phy-rcar-gen3.o obj-$(CONFIG_PHY_STM32_USBPHYC) += phy-stm32-usbphyc.o @@ -30,7 +29,6 @@ obj-$(CONFIG_MESON_GXL_USB_PHY) += meson-gxl-usb2.o obj-$(CONFIG_MESON_G12A_USB_PHY) += meson-g12a-usb2.o meson-g12a-usb3-pcie.o obj-$(CONFIG_MESON_AXG_MIPI_DPHY) += meson-axg-mipi-dphy.o obj-$(CONFIG_MESON_AXG_MIPI_PCIE_ANALOG_PHY) += meson-axg-mipi-pcie-analog.o -obj-$(CONFIG_MSM8916_USB_PHY) += msm8916-usbh-phy.o obj-$(CONFIG_OMAP_USB2_PHY) += omap-usb2-phy.o obj-$(CONFIG_KEYSTONE_USB_PHY) += keystone-usb-phy.o obj-$(CONFIG_MT7620_USB_PHY) += mt7620-usb-phy.o @@ -42,3 +40,4 @@ obj-$(CONFIG_PHY_IMX8MQ_USB) += phy-imx8mq-usb.o obj-$(CONFIG_PHY_XILINX_ZYNQMP) += phy-zynqmp.o obj-y += cadence/ obj-y += ti/ +obj-y += qcom/ diff --git a/drivers/phy/qcom/Kconfig b/drivers/phy/qcom/Kconfig new file mode 100644 index 0000000000..f685a6455e --- /dev/null +++ b/drivers/phy/qcom/Kconfig @@ -0,0 +1,13 @@ +config MSM8916_USB_PHY + bool "Qualcomm MSM8916 USB PHY support" + depends on PHY + help + Support the USB PHY in msm8916 + + This PHY is found on qualcomm dragonboard410c development board. + +config PHY_QCOM_IPQ4019_USB + tristate "Qualcomm IPQ4019 USB PHY driver" + depends on PHY && ARCH_IPQ40XX + help + Support for the USB PHY-s on Qualcomm IPQ40xx SoC-s. diff --git a/drivers/phy/qcom/Makefile b/drivers/phy/qcom/Makefile new file mode 100644 index 0000000000..4a340e33c8 --- /dev/null +++ b/drivers/phy/qcom/Makefile @@ -0,0 +1,2 @@ +obj-$(CONFIG_PHY_QCOM_IPQ4019_USB) += phy-qcom-ipq4019-usb.o +obj-$(CONFIG_MSM8916_USB_PHY) += msm8916-usbh-phy.o diff --git a/drivers/phy/msm8916-usbh-phy.c b/drivers/phy/qcom/msm8916-usbh-phy.c similarity index 100% rename from drivers/phy/msm8916-usbh-phy.c rename to drivers/phy/qcom/msm8916-usbh-phy.c diff --git a/drivers/phy/phy-qcom-ipq4019-usb.c b/drivers/phy/qcom/phy-qcom-ipq4019-usb.c similarity index 100% rename from drivers/phy/phy-qcom-ipq4019-usb.c rename to drivers/phy/qcom/phy-qcom-ipq4019-usb.c From 0b746d287c6c467972522da02b836f567e3ed981 Mon Sep 17 00:00:00 2001 From: Sumit Garg Date: Thu, 4 Aug 2022 19:57:10 +0530 Subject: [PATCH 011/374] phy: Add support for drivers to enable USB on QCS404 SoC QCS404 SoC supports two types of PHY, one supports high speed mode or USB2 PHY and the other supports super speed mode or USB3 PHY. So add corresponding PHY drivers. Signed-off-by: Sumit Garg --- drivers/phy/qcom/Kconfig | 16 ++ drivers/phy/qcom/Makefile | 2 + drivers/phy/qcom/phy-qcom-usb-hs-28nm.c | 250 ++++++++++++++++++++++++ drivers/phy/qcom/phy-qcom-usb-ss.c | 154 +++++++++++++++ 4 files changed, 422 insertions(+) create mode 100644 drivers/phy/qcom/phy-qcom-usb-hs-28nm.c create mode 100644 drivers/phy/qcom/phy-qcom-usb-ss.c diff --git a/drivers/phy/qcom/Kconfig b/drivers/phy/qcom/Kconfig index f685a6455e..f4ca174805 100644 --- a/drivers/phy/qcom/Kconfig +++ b/drivers/phy/qcom/Kconfig @@ -11,3 +11,19 @@ config PHY_QCOM_IPQ4019_USB depends on PHY && ARCH_IPQ40XX help Support for the USB PHY-s on Qualcomm IPQ40xx SoC-s. + +config PHY_QCOM_USB_HS_28NM + tristate "Qualcomm 28nm High-Speed PHY" + depends on PHY && ARCH_SNAPDRAGON + help + Enable this to support the Qualcomm Synopsys DesignWare Core 28nm + High-Speed PHY driver. This driver supports the Hi-Speed PHY which + is usually paired with either the ChipIdea or Synopsys DWC3 USB + IPs on MSM SOCs. + +config PHY_QCOM_USB_SS + tristate "Qualcomm USB Super-Speed PHY driver" + depends on PHY && ARCH_SNAPDRAGON + help + Enable this to support the Super-Speed USB transceiver on various + Qualcomm chipsets. diff --git a/drivers/phy/qcom/Makefile b/drivers/phy/qcom/Makefile index 4a340e33c8..2113f178c0 100644 --- a/drivers/phy/qcom/Makefile +++ b/drivers/phy/qcom/Makefile @@ -1,2 +1,4 @@ obj-$(CONFIG_PHY_QCOM_IPQ4019_USB) += phy-qcom-ipq4019-usb.o obj-$(CONFIG_MSM8916_USB_PHY) += msm8916-usbh-phy.o +obj-$(CONFIG_PHY_QCOM_USB_HS_28NM) += phy-qcom-usb-hs-28nm.o +obj-$(CONFIG_PHY_QCOM_USB_SS) += phy-qcom-usb-ss.o diff --git a/drivers/phy/qcom/phy-qcom-usb-hs-28nm.c b/drivers/phy/qcom/phy-qcom-usb-hs-28nm.c new file mode 100644 index 0000000000..14c3d8394d --- /dev/null +++ b/drivers/phy/qcom/phy-qcom-usb-hs-28nm.c @@ -0,0 +1,250 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2022 Sumit Garg + * + * Based on Linux driver + */ + +#include +#include +#include +#include +#include +#include +#include + +/* PHY register and bit definitions */ +#define PHY_CTRL_COMMON0 0x078 +#define SIDDQ BIT(2) + +struct hsphy_init_seq { + int offset; + int val; + int delay; +}; + +struct hsphy_data { + const struct hsphy_init_seq *init_seq; + unsigned int init_seq_num; +}; + +struct hsphy_priv { + void __iomem *base; + struct clk_bulk clks; + struct reset_ctl phy_rst; + struct reset_ctl por_rst; + const struct hsphy_data *data; +}; + +static int hsphy_power_on(struct phy *phy) +{ + struct hsphy_priv *priv = dev_get_priv(phy->dev); + u32 val; + + val = readb(priv->base + PHY_CTRL_COMMON0); + val &= ~SIDDQ; + writeb(val, priv->base + PHY_CTRL_COMMON0); + + return 0; +} + +static int hsphy_power_off(struct phy *phy) +{ + struct hsphy_priv *priv = dev_get_priv(phy->dev); + u32 val; + + val = readb(priv->base + PHY_CTRL_COMMON0); + val |= SIDDQ; + writeb(val, priv->base + PHY_CTRL_COMMON0); + + return 0; +} + +static int hsphy_reset(struct hsphy_priv *priv) +{ + int ret; + + ret = reset_assert(&priv->phy_rst); + if (ret) + return ret; + + udelay(10); + + ret = reset_deassert(&priv->phy_rst); + if (ret) + return ret; + + udelay(80); + + return 0; +} + +static void hsphy_init_sequence(struct hsphy_priv *priv) +{ + const struct hsphy_data *data = priv->data; + const struct hsphy_init_seq *seq; + int i; + + /* Device match data is optional. */ + if (!data) + return; + + seq = data->init_seq; + + for (i = 0; i < data->init_seq_num; i++, seq++) { + writeb(seq->val, priv->base + seq->offset); + if (seq->delay) + udelay(seq->delay); + } +} + +static int hsphy_por_reset(struct hsphy_priv *priv) +{ + int ret; + u32 val; + + ret = reset_assert(&priv->por_rst); + if (ret) + return ret; + + /* + * The Femto PHY is POR reset in the following scenarios. + * + * 1. After overriding the parameter registers. + * 2. Low power mode exit from PHY retention. + * + * Ensure that SIDDQ is cleared before bringing the PHY + * out of reset. + */ + val = readb(priv->base + PHY_CTRL_COMMON0); + val &= ~SIDDQ; + writeb(val, priv->base + PHY_CTRL_COMMON0); + + /* + * As per databook, 10 usec delay is required between + * PHY POR assert and de-assert. + */ + udelay(10); + ret = reset_deassert(&priv->por_rst); + if (ret) + return ret; + + /* + * As per databook, it takes 75 usec for PHY to stabilize + * after the reset. + */ + udelay(80); + + return 0; +} + +static int hsphy_clk_init(struct udevice *dev, struct hsphy_priv *priv) +{ + int ret; + + ret = clk_get_bulk(dev, &priv->clks); + if (ret == -ENOSYS || ret == -ENOENT) + return 0; + if (ret) + return ret; + + ret = clk_enable_bulk(&priv->clks); + if (ret) { + clk_release_bulk(&priv->clks); + return ret; + } + + return 0; +} + +static int hsphy_init(struct phy *phy) +{ + struct hsphy_priv *priv = dev_get_priv(phy->dev); + int ret; + + ret = hsphy_clk_init(phy->dev, priv); + if (ret) + return ret; + + ret = hsphy_reset(priv); + if (ret) + return ret; + + hsphy_init_sequence(priv); + + hsphy_por_reset(priv); + if (ret) + return ret; + + return 0; +} + +static int hsphy_probe(struct udevice *dev) +{ + struct hsphy_priv *priv = dev_get_priv(dev); + int ret; + + priv->base = (void *)dev_read_addr(dev); + if ((ulong)priv->base == FDT_ADDR_T_NONE) + return -EINVAL; + + ret = reset_get_by_name(dev, "phy", &priv->phy_rst); + if (ret) + return ret; + + ret = reset_get_by_name(dev, "por", &priv->por_rst); + if (ret) + return ret; + + priv->data = (const struct hsphy_data *)dev_get_driver_data(dev); + + return 0; +} + +static struct phy_ops hsphy_ops = { + .power_on = hsphy_power_on, + .power_off = hsphy_power_off, + .init = hsphy_init, +}; + +/* + * The macro is used to define an initialization sequence. Each tuple + * is meant to program 'value' into phy register at 'offset' with 'delay' + * in us followed. + */ +#define HSPHY_INIT_CFG(o, v, d) { .offset = o, .val = v, .delay = d, } + +static const struct hsphy_init_seq init_seq_femtophy[] = { + HSPHY_INIT_CFG(0xc0, 0x01, 0), + HSPHY_INIT_CFG(0xe8, 0x0d, 0), + HSPHY_INIT_CFG(0x74, 0x12, 0), + HSPHY_INIT_CFG(0x98, 0x63, 0), + HSPHY_INIT_CFG(0x9c, 0x03, 0), + HSPHY_INIT_CFG(0xa0, 0x1d, 0), + HSPHY_INIT_CFG(0xa4, 0x03, 0), + HSPHY_INIT_CFG(0x8c, 0x23, 0), + HSPHY_INIT_CFG(0x78, 0x08, 0), + HSPHY_INIT_CFG(0x7c, 0xdc, 0), + HSPHY_INIT_CFG(0x90, 0xe0, 20), + HSPHY_INIT_CFG(0x74, 0x10, 0), + HSPHY_INIT_CFG(0x90, 0x60, 0), +}; + +static const struct hsphy_data data_femtophy = { + .init_seq = init_seq_femtophy, + .init_seq_num = ARRAY_SIZE(init_seq_femtophy), +}; + +static const struct udevice_id hsphy_ids[] = { + { .compatible = "qcom,usb-hs-28nm-femtophy", .data = (ulong)&data_femtophy }, + { } +}; + +U_BOOT_DRIVER(qcom_usb_hs_28nm) = { + .name = "qcom-usb-hs-28nm", + .id = UCLASS_PHY, + .of_match = hsphy_ids, + .ops = &hsphy_ops, + .probe = hsphy_probe, + .priv_auto = sizeof(struct hsphy_priv), +}; diff --git a/drivers/phy/qcom/phy-qcom-usb-ss.c b/drivers/phy/qcom/phy-qcom-usb-ss.c new file mode 100644 index 0000000000..4e816879c6 --- /dev/null +++ b/drivers/phy/qcom/phy-qcom-usb-ss.c @@ -0,0 +1,154 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2022 Sumit Garg + * + * Based on Linux driver + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define PHY_CTRL0 0x6C +#define PHY_CTRL1 0x70 +#define PHY_CTRL2 0x74 +#define PHY_CTRL4 0x7C + +/* PHY_CTRL bits */ +#define REF_PHY_EN BIT(0) +#define LANE0_PWR_ON BIT(2) +#define SWI_PCS_CLK_SEL BIT(4) +#define TST_PWR_DOWN BIT(4) +#define PHY_RESET BIT(7) + +struct ssphy_priv { + void __iomem *base; + struct clk_bulk clks; + struct reset_ctl com_rst; + struct reset_ctl phy_rst; +}; + +static inline void ssphy_updatel(void __iomem *addr, u32 mask, u32 val) +{ + writel((readl(addr) & ~mask) | val, addr); +} + +static int ssphy_do_reset(struct ssphy_priv *priv) +{ + int ret; + + ret = reset_assert(&priv->com_rst); + if (ret) + return ret; + + ret = reset_assert(&priv->phy_rst); + if (ret) + return ret; + + udelay(10); + + ret = reset_deassert(&priv->com_rst); + if (ret) + return ret; + + ret = reset_deassert(&priv->phy_rst); + if (ret) + return ret; + + return 0; +} + +static int ssphy_power_on(struct phy *phy) +{ + struct ssphy_priv *priv = dev_get_priv(phy->dev); + int ret; + + ret = ssphy_do_reset(priv); + if (ret) + return ret; + + writeb(SWI_PCS_CLK_SEL, priv->base + PHY_CTRL0); + ssphy_updatel(priv->base + PHY_CTRL4, LANE0_PWR_ON, LANE0_PWR_ON); + ssphy_updatel(priv->base + PHY_CTRL2, REF_PHY_EN, REF_PHY_EN); + ssphy_updatel(priv->base + PHY_CTRL4, TST_PWR_DOWN, 0); + + return 0; +} + +static int ssphy_power_off(struct phy *phy) +{ + struct ssphy_priv *priv = dev_get_priv(phy->dev); + + ssphy_updatel(priv->base + PHY_CTRL4, LANE0_PWR_ON, 0); + ssphy_updatel(priv->base + PHY_CTRL2, REF_PHY_EN, 0); + ssphy_updatel(priv->base + PHY_CTRL4, TST_PWR_DOWN, TST_PWR_DOWN); + + return 0; +} + +static int ssphy_clk_init(struct udevice *dev, struct ssphy_priv *priv) +{ + int ret; + + ret = clk_get_bulk(dev, &priv->clks); + if (ret == -ENOSYS || ret == -ENOENT) + return 0; + if (ret) + return ret; + + ret = clk_enable_bulk(&priv->clks); + if (ret) { + clk_release_bulk(&priv->clks); + return ret; + } + + return 0; +} + +static int ssphy_probe(struct udevice *dev) +{ + struct ssphy_priv *priv = dev_get_priv(dev); + int ret; + + priv->base = (void *)dev_read_addr(dev); + if ((ulong)priv->base == FDT_ADDR_T_NONE) + return -EINVAL; + + ret = ssphy_clk_init(dev, priv); + if (ret) + return ret; + + ret = reset_get_by_name(dev, "com", &priv->com_rst); + if (ret) + return ret; + + ret = reset_get_by_name(dev, "phy", &priv->phy_rst); + if (ret) + return ret; + + return 0; +} + +static struct phy_ops ssphy_ops = { + .power_on = ssphy_power_on, + .power_off = ssphy_power_off, +}; + +static const struct udevice_id ssphy_ids[] = { + { .compatible = "qcom,usb-ss-28nm-phy" }, + { } +}; + +U_BOOT_DRIVER(qcom_usb_ss) = { + .name = "qcom-usb-ss", + .id = UCLASS_PHY, + .of_match = ssphy_ids, + .ops = &ssphy_ops, + .probe = ssphy_probe, + .priv_auto = sizeof(struct ssphy_priv), +}; From 42588276b3375f20cf372ff59c7d3712f55cf48f Mon Sep 17 00:00:00 2001 From: Sumit Garg Date: Thu, 4 Aug 2022 19:57:11 +0530 Subject: [PATCH 012/374] reset: Convert ipq4019 driver to a generic Qcom driver Since the base functionality remains the same for a reset driver on Qcom SoCs, so leverage that to convert ipq4019 specific reset driver to a generic Qcom reset driver. With that one just need to provide SoC specific reset table. Signed-off-by: Sumit Garg --- drivers/reset/Kconfig | 9 ++-- drivers/reset/Makefile | 2 +- .../reset/{reset-ipq4019.c => reset-qcom.c} | 46 ++++++++++--------- 3 files changed, 30 insertions(+), 27 deletions(-) rename drivers/reset/{reset-ipq4019.c => reset-qcom.c} (79%) diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig index 69a7b4ccba..4cb0ba0850 100644 --- a/drivers/reset/Kconfig +++ b/drivers/reset/Kconfig @@ -156,13 +156,12 @@ config RESET_IMX7 help Support for reset controller on i.MX7/8 SoCs. -config RESET_IPQ419 - bool "Reset driver for Qualcomm IPQ40xx SoCs" - depends on DM_RESET && ARCH_IPQ40XX +config RESET_QCOM + bool "Reset driver for Qualcomm SoCs" + depends on DM_RESET && (ARCH_SNAPDRAGON || ARCH_IPQ40XX) default y help - Support for reset controller on Qualcomm - IPQ40xx SoCs. + Support for reset controller on Qualcomm SoCs. config RESET_SIFIVE bool "Reset Driver for SiFive SoC's" diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile index 97e3a782c0..0620b62809 100644 --- a/drivers/reset/Makefile +++ b/drivers/reset/Makefile @@ -24,7 +24,7 @@ obj-$(CONFIG_RESET_MTMIPS) += reset-mtmips.o obj-$(CONFIG_RESET_SUNXI) += reset-sunxi.o obj-$(CONFIG_RESET_HISILICON) += reset-hisilicon.o obj-$(CONFIG_RESET_IMX7) += reset-imx7.o -obj-$(CONFIG_RESET_IPQ419) += reset-ipq4019.o +obj-$(CONFIG_RESET_QCOM) += reset-qcom.o obj-$(CONFIG_RESET_SIFIVE) += reset-sifive.o obj-$(CONFIG_RESET_SYSCON) += reset-syscon.o obj-$(CONFIG_RESET_RASPBERRYPI) += reset-raspberrypi.o diff --git a/drivers/reset/reset-ipq4019.c b/drivers/reset/reset-qcom.c similarity index 79% rename from drivers/reset/reset-ipq4019.c rename to drivers/reset/reset-qcom.c index 7f0bd85ad6..40f436ede4 100644 --- a/drivers/reset/reset-ipq4019.c +++ b/drivers/reset/reset-qcom.c @@ -1,8 +1,10 @@ // SPDX-License-Identifier: GPL-2.0 /* * Copyright (c) 2020 Sartura Ltd. + * Copyright (c) 2022 Linaro Ltd. * * Author: Robert Marko + * Sumit Garg * * Based on Linux driver */ @@ -10,12 +12,11 @@ #include #include #include -#include #include #include #include -struct ipq4019_reset_priv { +struct qcom_reset_priv { phys_addr_t base; }; @@ -24,7 +25,9 @@ struct qcom_reset_map { u8 bit; }; -static const struct qcom_reset_map gcc_ipq4019_resets[] = { +#ifdef CONFIG_ARCH_IPQ40XX +#include +static const struct qcom_reset_map gcc_qcom_resets[] = { [WIFI0_CPU_INIT_RESET] = { 0x1f008, 5 }, [WIFI0_RADIO_SRIF_RESET] = { 0x1f008, 4 }, [WIFI0_RADIO_WARM_RESET] = { 0x1f008, 3 }, @@ -97,11 +100,12 @@ static const struct qcom_reset_map gcc_ipq4019_resets[] = { [GCC_MPM_BCR] = {0x24000, 0}, [GCC_SPDM_BCR] = {0x25000, 0}, }; +#endif -static int ipq4019_reset_assert(struct reset_ctl *rst) +static int qcom_reset_assert(struct reset_ctl *rst) { - struct ipq4019_reset_priv *priv = dev_get_priv(rst->dev); - const struct qcom_reset_map *reset_map = gcc_ipq4019_resets; + struct qcom_reset_priv *priv = dev_get_priv(rst->dev); + const struct qcom_reset_map *reset_map = gcc_qcom_resets; const struct qcom_reset_map *map; u32 value; @@ -114,10 +118,10 @@ static int ipq4019_reset_assert(struct reset_ctl *rst) return 0; } -static int ipq4019_reset_deassert(struct reset_ctl *rst) +static int qcom_reset_deassert(struct reset_ctl *rst) { - struct ipq4019_reset_priv *priv = dev_get_priv(rst->dev); - const struct qcom_reset_map *reset_map = gcc_ipq4019_resets; + struct qcom_reset_priv *priv = dev_get_priv(rst->dev); + const struct qcom_reset_map *reset_map = gcc_qcom_resets; const struct qcom_reset_map *map; u32 value; @@ -130,19 +134,19 @@ static int ipq4019_reset_deassert(struct reset_ctl *rst) return 0; } -static const struct reset_ops ipq4019_reset_ops = { - .rst_assert = ipq4019_reset_assert, - .rst_deassert = ipq4019_reset_deassert, +static const struct reset_ops qcom_reset_ops = { + .rst_assert = qcom_reset_assert, + .rst_deassert = qcom_reset_deassert, }; -static const struct udevice_id ipq4019_reset_ids[] = { +static const struct udevice_id qcom_reset_ids[] = { { .compatible = "qcom,gcc-reset-ipq4019" }, { } }; -static int ipq4019_reset_probe(struct udevice *dev) +static int qcom_reset_probe(struct udevice *dev) { - struct ipq4019_reset_priv *priv = dev_get_priv(dev); + struct qcom_reset_priv *priv = dev_get_priv(dev); priv->base = dev_read_addr(dev); if (priv->base == FDT_ADDR_T_NONE) @@ -151,11 +155,11 @@ static int ipq4019_reset_probe(struct udevice *dev) return 0; } -U_BOOT_DRIVER(ipq4019_reset) = { - .name = "ipq4019_reset", +U_BOOT_DRIVER(qcom_reset) = { + .name = "qcom_reset", .id = UCLASS_RESET, - .of_match = ipq4019_reset_ids, - .ops = &ipq4019_reset_ops, - .probe = ipq4019_reset_probe, - .priv_auto = sizeof(struct ipq4019_reset_priv), + .of_match = qcom_reset_ids, + .ops = &qcom_reset_ops, + .probe = qcom_reset_probe, + .priv_auto = sizeof(struct qcom_reset_priv), }; From 9b6f90ca9251e9a2c366fb676b7f49f42287b8c7 Mon Sep 17 00:00:00 2001 From: Sumit Garg Date: Thu, 4 Aug 2022 19:57:12 +0530 Subject: [PATCH 013/374] reset: qcom: Add support for QCS404 SoC reset table Signed-off-by: Sumit Garg --- drivers/reset/reset-qcom.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/drivers/reset/reset-qcom.c b/drivers/reset/reset-qcom.c index 40f436ede4..94315e76d5 100644 --- a/drivers/reset/reset-qcom.c +++ b/drivers/reset/reset-qcom.c @@ -102,6 +102,35 @@ static const struct qcom_reset_map gcc_qcom_resets[] = { }; #endif +#ifdef CONFIG_TARGET_QCS404EVB +#include +static const struct qcom_reset_map gcc_qcom_resets[] = { + [GCC_GENI_IR_BCR] = { 0x0F000 }, + [GCC_CDSP_RESTART] = { 0x18000 }, + [GCC_USB_HS_BCR] = { 0x41000 }, + [GCC_USB2_HS_PHY_ONLY_BCR] = { 0x41034 }, + [GCC_QUSB2_PHY_BCR] = { 0x4103c }, + [GCC_USB_HS_PHY_CFG_AHB_BCR] = { 0x0000c, 1 }, + [GCC_USB2A_PHY_BCR] = { 0x0000c, 0 }, + [GCC_USB3_PHY_BCR] = { 0x39004 }, + [GCC_USB_30_BCR] = { 0x39000 }, + [GCC_USB3PHY_PHY_BCR] = { 0x39008 }, + [GCC_PCIE_0_BCR] = { 0x3e000 }, + [GCC_PCIE_0_PHY_BCR] = { 0x3e004 }, + [GCC_PCIE_0_LINK_DOWN_BCR] = { 0x3e038 }, + [GCC_PCIEPHY_0_PHY_BCR] = { 0x3e03c }, + [GCC_PCIE_0_AXI_MASTER_STICKY_ARES] = { 0x3e040, 6}, + [GCC_PCIE_0_AHB_ARES] = { 0x3e040, 5 }, + [GCC_PCIE_0_AXI_SLAVE_ARES] = { 0x3e040, 4 }, + [GCC_PCIE_0_AXI_MASTER_ARES] = { 0x3e040, 3 }, + [GCC_PCIE_0_CORE_STICKY_ARES] = { 0x3e040, 2 }, + [GCC_PCIE_0_SLEEP_ARES] = { 0x3e040, 1 }, + [GCC_PCIE_0_PIPE_ARES] = { 0x3e040, 0 }, + [GCC_EMAC_BCR] = { 0x4e000 }, + [GCC_WDSP_RESTART] = {0x19000}, +}; +#endif + static int qcom_reset_assert(struct reset_ctl *rst) { struct qcom_reset_priv *priv = dev_get_priv(rst->dev); @@ -141,6 +170,7 @@ static const struct reset_ops qcom_reset_ops = { static const struct udevice_id qcom_reset_ids[] = { { .compatible = "qcom,gcc-reset-ipq4019" }, + { .compatible = "qcom,gcc-reset-qcs404" }, { } }; From 21ed4563cb942bdbe928a5366e02a130db74f13b Mon Sep 17 00:00:00 2001 From: Sumit Garg Date: Thu, 4 Aug 2022 19:57:13 +0530 Subject: [PATCH 014/374] dts: qcs404-evb: Add reset controller node Signed-off-by: Sumit Garg --- arch/arm/dts/qcs404-evb.dts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/arch/arm/dts/qcs404-evb.dts b/arch/arm/dts/qcs404-evb.dts index 4f0ae20bdb..3166b265ed 100644 --- a/arch/arm/dts/qcs404-evb.dts +++ b/arch/arm/dts/qcs404-evb.dts @@ -54,6 +54,12 @@ #size-cells = <0x0>; }; + reset: gcc-reset@1800000 { + compatible = "qcom,gcc-reset-qcs404"; + reg = <0x1800000 0x80000>; + #reset-cells = <1>; + }; + debug_uart: serial@78b1000 { compatible = "qcom,msm-uartdm-v1.4"; reg = <0x78b1000 0x200>; From c9e384e9b6f32070b2c4ac51b2315e5719765811 Mon Sep 17 00:00:00 2001 From: Sumit Garg Date: Thu, 4 Aug 2022 19:57:14 +0530 Subject: [PATCH 015/374] clocks: qcom: Add clock enable callback support Drivers like USB, ethernet etc. uses ".enable" hook to enable clocks. So add corresponding support for Qcom clock drivers. Signed-off-by: Sumit Garg --- arch/arm/mach-snapdragon/clock-apq8016.c | 5 +++++ arch/arm/mach-snapdragon/clock-apq8096.c | 5 +++++ arch/arm/mach-snapdragon/clock-qcs404.c | 5 +++++ arch/arm/mach-snapdragon/clock-sdm845.c | 5 +++++ arch/arm/mach-snapdragon/clock-snapdragon.c | 7 +++++++ 5 files changed, 27 insertions(+) diff --git a/arch/arm/mach-snapdragon/clock-apq8016.c b/arch/arm/mach-snapdragon/clock-apq8016.c index 6e4a0ccb90..23a37a1714 100644 --- a/arch/arm/mach-snapdragon/clock-apq8016.c +++ b/arch/arm/mach-snapdragon/clock-apq8016.c @@ -111,3 +111,8 @@ ulong msm_set_rate(struct clk *clk, ulong rate) return 0; } } + +int msm_enable(struct clk *clk) +{ + return 0; +} diff --git a/arch/arm/mach-snapdragon/clock-apq8096.c b/arch/arm/mach-snapdragon/clock-apq8096.c index e5011be8f2..66184596d5 100644 --- a/arch/arm/mach-snapdragon/clock-apq8096.c +++ b/arch/arm/mach-snapdragon/clock-apq8096.c @@ -93,3 +93,8 @@ ulong msm_set_rate(struct clk *clk, ulong rate) return 0; } } + +int msm_enable(struct clk *clk) +{ + return 0; +} diff --git a/arch/arm/mach-snapdragon/clock-qcs404.c b/arch/arm/mach-snapdragon/clock-qcs404.c index bb8a6fe067..230d7779a7 100644 --- a/arch/arm/mach-snapdragon/clock-qcs404.c +++ b/arch/arm/mach-snapdragon/clock-qcs404.c @@ -77,3 +77,8 @@ ulong msm_set_rate(struct clk *clk, ulong rate) return 0; } + +int msm_enable(struct clk *clk) +{ + return 0; +} diff --git a/arch/arm/mach-snapdragon/clock-sdm845.c b/arch/arm/mach-snapdragon/clock-sdm845.c index f69be80898..d6df0365af 100644 --- a/arch/arm/mach-snapdragon/clock-sdm845.c +++ b/arch/arm/mach-snapdragon/clock-sdm845.c @@ -91,3 +91,8 @@ ulong msm_set_rate(struct clk *clk, ulong rate) return 0; } } + +int msm_enable(struct clk *clk) +{ + return 0; +} diff --git a/arch/arm/mach-snapdragon/clock-snapdragon.c b/arch/arm/mach-snapdragon/clock-snapdragon.c index 5652d2fa36..fda7098274 100644 --- a/arch/arm/mach-snapdragon/clock-snapdragon.c +++ b/arch/arm/mach-snapdragon/clock-snapdragon.c @@ -20,6 +20,7 @@ #define CBCR_BRANCH_OFF_BIT BIT(31) extern ulong msm_set_rate(struct clk *clk, ulong rate); +extern int msm_enable(struct clk *clk); /* Enable clock controlled by CBC soft macro */ void clk_enable_cbc(phys_addr_t cbcr) @@ -126,8 +127,14 @@ static ulong msm_clk_set_rate(struct clk *clk, ulong rate) return msm_set_rate(clk, rate); } +static int msm_clk_enable(struct clk *clk) +{ + return msm_enable(clk); +} + static struct clk_ops msm_clk_ops = { .set_rate = msm_clk_set_rate, + .enable = msm_clk_enable, }; static const struct udevice_id msm_clk_ids[] = { From 968597b85c9ac6331a64d9b3584672d9f48c4a11 Mon Sep 17 00:00:00 2001 From: Sumit Garg Date: Thu, 4 Aug 2022 19:57:15 +0530 Subject: [PATCH 016/374] clocks: qcs404: Add support for USB clocks Add support for USB controller and PHY clocks for QCS404 SoC. Signed-off-by: Sumit Garg --- arch/arm/mach-snapdragon/clock-qcs404.c | 35 +++++++++++++++++++ .../include/mach/sysmap-qcs404.h | 17 +++++++++ 2 files changed, 52 insertions(+) diff --git a/arch/arm/mach-snapdragon/clock-qcs404.c b/arch/arm/mach-snapdragon/clock-qcs404.c index 230d7779a7..6fe92afe8d 100644 --- a/arch/arm/mach-snapdragon/clock-qcs404.c +++ b/arch/arm/mach-snapdragon/clock-qcs404.c @@ -47,6 +47,14 @@ static struct pll_vote_clk gpll0_vote_clk = { .vote_bit = BIT(0), }; +static const struct bcr_regs usb30_master_regs = { + .cfg_rcgr = USB30_MASTER_CFG_RCGR, + .cmd_rcgr = USB30_MASTER_CMD_RCGR, + .M = USB30_MASTER_M, + .N = USB30_MASTER_N, + .D = USB30_MASTER_D, +}; + ulong msm_set_rate(struct clk *clk, ulong rate) { struct msm_clk_priv *priv = dev_get_priv(clk->dev); @@ -80,5 +88,32 @@ ulong msm_set_rate(struct clk *clk, ulong rate) int msm_enable(struct clk *clk) { + struct msm_clk_priv *priv = dev_get_priv(clk->dev); + + switch (clk->id) { + case GCC_USB30_MASTER_CLK: + clk_enable_cbc(priv->base + USB30_MASTER_CBCR); + clk_rcg_set_rate_mnd(priv->base, &usb30_master_regs, 4, 0, 0, + CFG_CLK_SRC_GPLL0); + break; + case GCC_SYS_NOC_USB3_CLK: + clk_enable_cbc(priv->base + SYS_NOC_USB3_CBCR); + break; + case GCC_USB30_SLEEP_CLK: + clk_enable_cbc(priv->base + USB30_SLEEP_CBCR); + break; + case GCC_USB30_MOCK_UTMI_CLK: + clk_enable_cbc(priv->base + USB30_MOCK_UTMI_CBCR); + break; + case GCC_USB_HS_PHY_CFG_AHB_CLK: + clk_enable_cbc(priv->base + USB_HS_PHY_CFG_AHB_CBCR); + break; + case GCC_USB2A_PHY_SLEEP_CLK: + clk_enable_cbc(priv->base + USB_HS_PHY_CFG_AHB_CBCR); + break; + default: + return 0; + } + return 0; } diff --git a/arch/arm/mach-snapdragon/include/mach/sysmap-qcs404.h b/arch/arm/mach-snapdragon/include/mach/sysmap-qcs404.h index 4dc96b9fbc..e448faad2d 100644 --- a/arch/arm/mach-snapdragon/include/mach/sysmap-qcs404.h +++ b/arch/arm/mach-snapdragon/include/mach/sysmap-qcs404.h @@ -37,4 +37,21 @@ #define SDCC_APPS_CBCR(n) (((n) * 0x1000) + 0x41018) #define SDCC_AHB_CBCR(n) (((n) * 0x1000) + 0x4101C) +/* USB-3.0 controller clock control registers */ +#define SYS_NOC_USB3_CBCR (0x26014) +#define USB30_BCR (0x39000) +#define USB3PHY_BCR (0x39008) +#define USB30_MASTER_CBCR (0x3900C) +#define USB30_SLEEP_CBCR (0x39010) +#define USB30_MOCK_UTMI_CBCR (0x39014) +#define USB30_MOCK_UTMI_CMD_RCGR (0x3901C) +#define USB30_MOCK_UTMI_CFG_RCGR (0x39020) +#define USB30_MASTER_CMD_RCGR (0x39028) +#define USB30_MASTER_CFG_RCGR (0x3902C) +#define USB30_MASTER_M (0x39030) +#define USB30_MASTER_N (0x39034) +#define USB30_MASTER_D (0x39038) +#define USB2A_PHY_SLEEP_CBCR (0x4102C) +#define USB_HS_PHY_CFG_AHB_CBCR (0x41030) + #endif From 0c1eab6f759c6abe809bc68c44192924b1d2522a Mon Sep 17 00:00:00 2001 From: Sumit Garg Date: Thu, 4 Aug 2022 19:57:16 +0530 Subject: [PATCH 017/374] dts: qcs404-evb: Add USB controller and PHY nodes QCS404 SoC provides support for two USB controllers: one USB3 and the other one being USB2. The USB3 controller supports further 2 PHY: one high speed PHY and the other super speed PHY. The USB2 controller supports a single high speed PHY. So add corresponding DT nodes. Signed-off-by: Sumit Garg --- arch/arm/dts/qcs404-evb.dts | 87 +++++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) diff --git a/arch/arm/dts/qcs404-evb.dts b/arch/arm/dts/qcs404-evb.dts index 3166b265ed..719e6a25fb 100644 --- a/arch/arm/dts/qcs404-evb.dts +++ b/arch/arm/dts/qcs404-evb.dts @@ -52,6 +52,7 @@ reg = <0x1800000 0x80000>; #address-cells = <0x1>; #size-cells = <0x0>; + #clock-cells = <1>; }; reset: gcc-reset@1800000 { @@ -81,6 +82,92 @@ mmc-ddr-1_8v; mmc-hs400-1_8v; }; + + usb3_phy: phy@78000 { + compatible = "qcom,usb-ss-28nm-phy"; + #phy-cells = <0>; + reg = <0x78000 0x400>; + clocks = <&gcc GCC_USB_HS_PHY_CFG_AHB_CLK>, + <&gcc GCC_USB3_PHY_PIPE_CLK>; + clock-names = "ahb", "pipe"; + resets = <&reset GCC_USB3_PHY_BCR>, + <&reset GCC_USB3PHY_PHY_BCR>; + reset-names = "com", "phy"; + }; + + usb2_phy_prim: phy@7a000 { + compatible = "qcom,usb-hs-28nm-femtophy"; + #phy-cells = <0>; + reg = <0x7a000 0x200>; + clocks = <&gcc GCC_USB_HS_PHY_CFG_AHB_CLK>, + <&gcc GCC_USB2A_PHY_SLEEP_CLK>; + clock-names = "ahb", "sleep"; + resets = <&reset GCC_USB_HS_PHY_CFG_AHB_BCR>, + <&reset GCC_USB2A_PHY_BCR>; + reset-names = "phy", "por"; + }; + + usb2_phy_sec: phy@7c000 { + compatible = "qcom,usb-hs-28nm-femtophy"; + #phy-cells = <0>; + reg = <0x7c000 0x200>; + clocks = <&gcc GCC_USB_HS_PHY_CFG_AHB_CLK>, + <&gcc GCC_USB2A_PHY_SLEEP_CLK>; + clock-names = "ahb", "sleep"; + resets = <&reset GCC_QUSB2_PHY_BCR>, + <&reset GCC_USB2_HS_PHY_ONLY_BCR>; + reset-names = "phy", "por"; + }; + + usb3: usb@7678800 { + compatible = "qcom,dwc3"; + reg = <0x7678800 0x400>; + #address-cells = <1>; + #size-cells = <1>; + ranges; + clocks = <&gcc GCC_USB30_MASTER_CLK>, + <&gcc GCC_SYS_NOC_USB3_CLK>, + <&gcc GCC_USB30_SLEEP_CLK>, + <&gcc GCC_USB30_MOCK_UTMI_CLK>; + clock-names = "core", "iface", "sleep", "mock_utmi"; + + dwc3@7580000 { + compatible = "snps,dwc3"; + reg = <0x7580000 0xcd00>; + phys = <&usb2_phy_prim>, <&usb3_phy>; + phy-names = "usb2-phy", "usb3-phy"; + dr_mode = "host"; + snps,has-lpm-erratum; + snps,hird-threshold = /bits/ 8 <0x10>; + snps,usb3_lpm_capable; + maximum-speed = "super-speed"; + }; + }; + + usb2: usb@79b8800 { + compatible = "qcom,dwc3"; + reg = <0x79b8800 0x400>; + #address-cells = <1>; + #size-cells = <1>; + ranges; + clocks = <&gcc GCC_USB_HS_SYSTEM_CLK>, + <&gcc GCC_PCNOC_USB2_CLK>, + <&gcc GCC_USB_HS_INACTIVITY_TIMERS_CLK>, + <&gcc GCC_USB20_MOCK_UTMI_CLK>; + clock-names = "core", "iface", "sleep", "mock_utmi"; + + dwc3@78c0000 { + compatible = "snps,dwc3"; + reg = <0x78c0000 0xcc00>; + phys = <&usb2_phy_sec>; + phy-names = "usb2-phy"; + dr_mode = "peripheral"; + snps,has-lpm-erratum; + snps,hird-threshold = /bits/ 8 <0x10>; + snps,usb3_lpm_capable; + maximum-speed = "high-speed"; + }; + }; }; }; From e555d4caacd008b5091a8d755bdfff1ce8cceb2f Mon Sep 17 00:00:00 2001 From: Sumit Garg Date: Thu, 4 Aug 2022 19:57:17 +0530 Subject: [PATCH 018/374] pmic: Convert pm8916 driver to a generic Qcom PMIC driver Since both pm8916.c and pm8916_gpio.c are already supporting multiple Qcom SoCs, it makes sense to rename these drivers to pmic_qcom.c and qcom_pmic_gpio.c respectively. Also, these driver can be extended to support additional functionality if required for other Qcom SoCs. Along with this import latest DT binding: qcom,spmi-pmic.txt from Linux kernel and thereby remove pm8916.txt. Signed-off-by: Sumit Garg --- configs/dragonboard410c_defconfig | 4 +- configs/dragonboard820c_defconfig | 4 +- configs/dragonboard845c_defconfig | 4 +- configs/sandbox64_defconfig | 4 +- configs/sandbox_defconfig | 4 +- configs/sandbox_flattree_defconfig | 4 +- configs/sandbox_noinst_defconfig | 4 +- configs/sandbox_spl_defconfig | 4 +- configs/sandbox_vpl_defconfig | 4 +- configs/starqltechn_defconfig | 4 +- doc/device-tree-bindings/pmic/pm8916.txt | 18 --- .../pmic/qcom,spmi-pmic.txt | 94 +++++++++++++++ drivers/gpio/Kconfig | 10 +- drivers/gpio/Makefile | 2 +- .../gpio/{pm8916_gpio.c => qcom_pmic_gpio.c} | 108 +++++++++--------- drivers/power/pmic/Kconfig | 8 +- drivers/power/pmic/Makefile | 2 +- drivers/power/pmic/{pm8916.c => pmic_qcom.c} | 42 +++---- 18 files changed, 200 insertions(+), 124 deletions(-) delete mode 100644 doc/device-tree-bindings/pmic/pm8916.txt create mode 100644 doc/device-tree-bindings/pmic/qcom,spmi-pmic.txt rename drivers/gpio/{pm8916_gpio.c => qcom_pmic_gpio.c} (67%) rename drivers/power/pmic/{pm8916.c => pmic_qcom.c} (52%) diff --git a/configs/dragonboard410c_defconfig b/configs/dragonboard410c_defconfig index 4de32099ed..e5e70a2ada 100644 --- a/configs/dragonboard410c_defconfig +++ b/configs/dragonboard410c_defconfig @@ -43,7 +43,7 @@ CONFIG_FASTBOOT_BUF_ADDR=0x91000000 CONFIG_FASTBOOT_FLASH=y CONFIG_FASTBOOT_FLASH_MMC_DEV=0 CONFIG_MSM_GPIO=y -CONFIG_PM8916_GPIO=y +CONFIG_QCOM_PMIC_GPIO=y CONFIG_LED=y CONFIG_LED_GPIO=y CONFIG_MMC_SDHCI=y @@ -52,7 +52,7 @@ CONFIG_PHY=y CONFIG_PINCTRL=y CONFIG_PINCONF=y CONFIG_DM_PMIC=y -CONFIG_PMIC_PM8916=y +CONFIG_PMIC_QCOM=y CONFIG_MSM_SERIAL=y CONFIG_SPMI_MSM=y CONFIG_USB=y diff --git a/configs/dragonboard820c_defconfig b/configs/dragonboard820c_defconfig index 855f628213..e2e2e627ae 100644 --- a/configs/dragonboard820c_defconfig +++ b/configs/dragonboard820c_defconfig @@ -36,12 +36,12 @@ CONFIG_ENV_EXT4_INTERFACE="mmc" CONFIG_ENV_EXT4_DEVICE_AND_PART="0:1" CONFIG_SYS_RELOC_GD_ENV_ADDR=y CONFIG_CLK=y -CONFIG_PM8916_GPIO=y +CONFIG_QCOM_PMIC_GPIO=y CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI_MSM=y CONFIG_PINCTRL=y CONFIG_PINCONF=y CONFIG_DM_PMIC=y -CONFIG_PMIC_PM8916=y +CONFIG_PMIC_QCOM=y CONFIG_MSM_SERIAL=y CONFIG_SPMI_MSM=y diff --git a/configs/dragonboard845c_defconfig b/configs/dragonboard845c_defconfig index cf1a1d25cf..a69d82761a 100644 --- a/configs/dragonboard845c_defconfig +++ b/configs/dragonboard845c_defconfig @@ -20,10 +20,10 @@ CONFIG_CMD_GPIO=y # CONFIG_NET is not set CONFIG_CLK=y CONFIG_MSM_GPIO=y -CONFIG_PM8916_GPIO=y +CONFIG_QCOM_PMIC_GPIO=y CONFIG_PINCTRL=y CONFIG_DM_PMIC=y -CONFIG_PMIC_PM8916=y +CONFIG_PMIC_QCOM=y CONFIG_MSM_GENI_SERIAL=y CONFIG_SPMI_MSM=y CONFIG_LMB_MAX_REGIONS=64 diff --git a/configs/sandbox64_defconfig b/configs/sandbox64_defconfig index 290d1506c2..4599db73ed 100644 --- a/configs/sandbox64_defconfig +++ b/configs/sandbox64_defconfig @@ -127,7 +127,7 @@ CONFIG_FASTBOOT_FLASH=y CONFIG_FASTBOOT_FLASH_MMC_DEV=0 CONFIG_GPIO_HOG=y CONFIG_DM_GPIO_LOOKUP_LABEL=y -CONFIG_PM8916_GPIO=y +CONFIG_QCOM_PMIC_GPIO=y CONFIG_SANDBOX_GPIO=y CONFIG_I2C_CROS_EC_TUNNEL=y CONFIG_I2C_CROS_EC_LDO=y @@ -178,7 +178,7 @@ CONFIG_DM_PMIC=y CONFIG_PMIC_ACT8846=y CONFIG_DM_PMIC_PFUZE100=y CONFIG_DM_PMIC_MAX77686=y -CONFIG_PMIC_PM8916=y +CONFIG_PMIC_QCOM=y CONFIG_PMIC_RK8XX=y CONFIG_PMIC_S2MPS11=y CONFIG_DM_PMIC_SANDBOX=y diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig index ab5d3f19bf..4a0c51c7f5 100644 --- a/configs/sandbox_defconfig +++ b/configs/sandbox_defconfig @@ -171,7 +171,7 @@ CONFIG_FASTBOOT_FLASH=y CONFIG_FASTBOOT_FLASH_MMC_DEV=0 CONFIG_GPIO_HOG=y CONFIG_DM_GPIO_LOOKUP_LABEL=y -CONFIG_PM8916_GPIO=y +CONFIG_QCOM_PMIC_GPIO=y CONFIG_SANDBOX_GPIO=y CONFIG_DM_HWSPINLOCK=y CONFIG_HWSPINLOCK_SANDBOX=y @@ -231,7 +231,7 @@ CONFIG_PMIC_ACT8846=y CONFIG_DM_PMIC_PFUZE100=y CONFIG_DM_PMIC_MAX77686=y CONFIG_DM_PMIC_MC34708=y -CONFIG_PMIC_PM8916=y +CONFIG_PMIC_QCOM=y CONFIG_PMIC_RK8XX=y CONFIG_PMIC_S2MPS11=y CONFIG_DM_PMIC_SANDBOX=y diff --git a/configs/sandbox_flattree_defconfig b/configs/sandbox_flattree_defconfig index a8b439faa9..4b18c240ee 100644 --- a/configs/sandbox_flattree_defconfig +++ b/configs/sandbox_flattree_defconfig @@ -100,7 +100,7 @@ CONFIG_DM_DEMO_SHAPE=y CONFIG_DFU_SF=y CONFIG_GPIO_HOG=y CONFIG_DM_GPIO_LOOKUP_LABEL=y -CONFIG_PM8916_GPIO=y +CONFIG_QCOM_PMIC_GPIO=y CONFIG_SANDBOX_GPIO=y CONFIG_I2C_CROS_EC_TUNNEL=y CONFIG_I2C_CROS_EC_LDO=y @@ -153,7 +153,7 @@ CONFIG_PMIC_ACT8846=y CONFIG_DM_PMIC_PFUZE100=y CONFIG_DM_PMIC_MAX77686=y CONFIG_DM_PMIC_MC34708=y -CONFIG_PMIC_PM8916=y +CONFIG_PMIC_QCOM=y CONFIG_PMIC_S2MPS11=y CONFIG_DM_PMIC_SANDBOX=y CONFIG_PMIC_S5M8767=y diff --git a/configs/sandbox_noinst_defconfig b/configs/sandbox_noinst_defconfig index 3d34d81731..72c908f61a 100644 --- a/configs/sandbox_noinst_defconfig +++ b/configs/sandbox_noinst_defconfig @@ -126,7 +126,7 @@ CONFIG_DM_DEMO_SIMPLE=y CONFIG_DM_DEMO_SHAPE=y CONFIG_SPL_FIRMWARE=y CONFIG_GPIO_HOG=y -CONFIG_PM8916_GPIO=y +CONFIG_QCOM_PMIC_GPIO=y CONFIG_SANDBOX_GPIO=y CONFIG_I2C_CROS_EC_TUNNEL=y CONFIG_I2C_CROS_EC_LDO=y @@ -176,7 +176,7 @@ CONFIG_PMIC_ACT8846=y CONFIG_DM_PMIC_PFUZE100=y CONFIG_DM_PMIC_MAX77686=y CONFIG_DM_PMIC_MC34708=y -CONFIG_PMIC_PM8916=y +CONFIG_PMIC_QCOM=y CONFIG_PMIC_RK8XX=y CONFIG_PMIC_S2MPS11=y CONFIG_DM_PMIC_SANDBOX=y diff --git a/configs/sandbox_spl_defconfig b/configs/sandbox_spl_defconfig index 76e8acd126..11b9aa890b 100644 --- a/configs/sandbox_spl_defconfig +++ b/configs/sandbox_spl_defconfig @@ -127,7 +127,7 @@ CONFIG_DM_DEMO_SIMPLE=y CONFIG_DM_DEMO_SHAPE=y CONFIG_SPL_FIRMWARE=y CONFIG_GPIO_HOG=y -CONFIG_PM8916_GPIO=y +CONFIG_QCOM_PMIC_GPIO=y CONFIG_SANDBOX_GPIO=y CONFIG_I2C_CROS_EC_TUNNEL=y CONFIG_I2C_CROS_EC_LDO=y @@ -179,7 +179,7 @@ CONFIG_PMIC_ACT8846=y CONFIG_DM_PMIC_PFUZE100=y CONFIG_DM_PMIC_MAX77686=y CONFIG_DM_PMIC_MC34708=y -CONFIG_PMIC_PM8916=y +CONFIG_PMIC_QCOM=y CONFIG_PMIC_RK8XX=y CONFIG_PMIC_S2MPS11=y CONFIG_DM_PMIC_SANDBOX=y diff --git a/configs/sandbox_vpl_defconfig b/configs/sandbox_vpl_defconfig index 96c9622707..c3856a8374 100644 --- a/configs/sandbox_vpl_defconfig +++ b/configs/sandbox_vpl_defconfig @@ -136,7 +136,7 @@ CONFIG_DM_DEMO_SIMPLE=y CONFIG_DM_DEMO_SHAPE=y CONFIG_SPL_FIRMWARE=y CONFIG_GPIO_HOG=y -CONFIG_PM8916_GPIO=y +CONFIG_QCOM_PMIC_GPIO=y CONFIG_SANDBOX_GPIO=y CONFIG_I2C_CROS_EC_TUNNEL=y CONFIG_I2C_CROS_EC_LDO=y @@ -184,7 +184,7 @@ CONFIG_PMIC_ACT8846=y CONFIG_DM_PMIC_PFUZE100=y CONFIG_DM_PMIC_MAX77686=y CONFIG_DM_PMIC_MC34708=y -CONFIG_PMIC_PM8916=y +CONFIG_PMIC_QCOM=y CONFIG_PMIC_RK8XX=y CONFIG_PMIC_S2MPS11=y CONFIG_DM_PMIC_SANDBOX=y diff --git a/configs/starqltechn_defconfig b/configs/starqltechn_defconfig index 2d07767b61..4f84f5f974 100644 --- a/configs/starqltechn_defconfig +++ b/configs/starqltechn_defconfig @@ -23,10 +23,10 @@ CONFIG_CMD_BMP=y # CONFIG_DM_STDIO is not set CONFIG_CLK=y CONFIG_MSM_GPIO=y -CONFIG_PM8916_GPIO=y +CONFIG_QCOM_PMIC_GPIO=y CONFIG_PINCTRL=y CONFIG_DM_PMIC=y -CONFIG_PMIC_PM8916=y +CONFIG_PMIC_QCOM=y # CONFIG_REQUIRE_SERIAL_CONSOLE is not set CONFIG_SPMI_MSM=y CONFIG_DM_VIDEO=y diff --git a/doc/device-tree-bindings/pmic/pm8916.txt b/doc/device-tree-bindings/pmic/pm8916.txt deleted file mode 100644 index 15c598b8c4..0000000000 --- a/doc/device-tree-bindings/pmic/pm8916.txt +++ /dev/null @@ -1,18 +0,0 @@ -Qualcomm pm8916 PMIC - -This PMIC is connected using SPMI bus so should be child of SPMI bus controller. - -Required properties: -- compatible: "qcom,spmi-pmic"; -- reg: SPMI Slave ID, size (ignored) -- #address-cells: 0x1 (peripheral ID) -- #size-cells: 0x1 (size of peripheral register space) - -Example: - -pm8916@0 { - compatible = "qcom,spmi-pmic"; - reg = <0x0 0x1>; - #address-cells = <0x1>; - #size-cells = <0x1>; -}; diff --git a/doc/device-tree-bindings/pmic/qcom,spmi-pmic.txt b/doc/device-tree-bindings/pmic/qcom,spmi-pmic.txt new file mode 100644 index 0000000000..eb78e3ae77 --- /dev/null +++ b/doc/device-tree-bindings/pmic/qcom,spmi-pmic.txt @@ -0,0 +1,94 @@ + Qualcomm SPMI PMICs multi-function device bindings + +The Qualcomm SPMI series presently includes PM8941, PM8841 and PMA8084 +PMICs. These PMICs use a QPNP scheme through SPMI interface. +QPNP is effectively a partitioning scheme for dividing the SPMI extended +register space up into logical pieces, and set of fixed register +locations/definitions within these regions, with some of these regions +specifically used for interrupt handling. + +The QPNP PMICs are used with the Qualcomm Snapdragon series SoCs, and are +interfaced to the chip via the SPMI (System Power Management Interface) bus. +Support for multiple independent functions are implemented by splitting the +16-bit SPMI slave address space into 256 smaller fixed-size regions, 256 bytes +each. A function can consume one or more of these fixed-size register regions. + +Required properties: +- compatible: Should contain one of: + "qcom,pm660", + "qcom,pm660l", + "qcom,pm7325", + "qcom,pm8004", + "qcom,pm8005", + "qcom,pm8019", + "qcom,pm8028", + "qcom,pm8110", + "qcom,pm8150", + "qcom,pm8150b", + "qcom,pm8150c", + "qcom,pm8150l", + "qcom,pm8226", + "qcom,pm8350c", + "qcom,pm8841", + "qcom,pm8901", + "qcom,pm8909", + "qcom,pm8916", + "qcom,pm8941", + "qcom,pm8950", + "qcom,pm8953", + "qcom,pm8994", + "qcom,pm8998", + "qcom,pma8084", + "qcom,pmd9635", + "qcom,pmi8950", + "qcom,pmi8962", + "qcom,pmi8994", + "qcom,pmi8998", + "qcom,pmk8002", + "qcom,pmk8350", + "qcom,pmr735a", + "qcom,smb2351", + or generalized "qcom,spmi-pmic". +- reg: Specifies the SPMI USID slave address for this device. + For more information see: + Documentation/devicetree/bindings/spmi/spmi.yaml + +Required properties for peripheral child nodes: +- compatible: Should contain "qcom,xxx", where "xxx" is a peripheral name. + +Optional properties for peripheral child nodes: +- interrupts: Interrupts are specified as a 4-tuple. For more information + see: + Documentation/devicetree/bindings/spmi/qcom,spmi-pmic-arb.yaml +- interrupt-names: Corresponding interrupt name to the interrupts property + +Each child node of SPMI slave id represents a function of the PMIC. In the +example below the rtc device node represents a peripheral of pm8941 +SID = 0. The regulator device node represents a peripheral of pm8941 SID = 1. + +Example: + + spmi { + compatible = "qcom,spmi-pmic-arb"; + + pm8941@0 { + compatible = "qcom,pm8941", "qcom,spmi-pmic"; + reg = <0x0 SPMI_USID>; + + rtc { + compatible = "qcom,rtc"; + interrupts = <0x0 0x61 0x1 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "alarm"; + }; + }; + + pm8941@1 { + compatible = "qcom,pm8941", "qcom,spmi-pmic"; + reg = <0x1 SPMI_USID>; + + regulator { + compatible = "qcom,regulator"; + regulator-name = "8941_boost"; + }; + }; + }; diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 7e4c3577b3..c949f9d2f7 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -303,14 +303,14 @@ config CMD_PCA953X legacy GPIO interface. Several subcommands are provided which mirror the standard 'gpio' command. It should use that instead. -config PM8916_GPIO - bool "Qualcomm PM8916 PMIC GPIO/keypad driver" - depends on DM_GPIO && PMIC_PM8916 +config QCOM_PMIC_GPIO + bool "Qualcomm generic PMIC GPIO/keypad driver" + depends on DM_GPIO && PMIC_QCOM help Support for GPIO pins and power/reset buttons found on - Qualcomm PM8916 PMIC. + Qualcomm SoCs PMIC. Default name for GPIO bank is "pm8916". - Power and reset buttons are placed in "pm8916_key" bank and + Power and reset buttons are placed in "pwkey_qcom" bank and have gpio numbers 0 and 1 respectively. config PCF8575_GPIO diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index 39762fa06c..9d718a554e 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -63,7 +63,7 @@ obj-$(CONFIG_OCTEON_GPIO) += octeon_gpio.o obj-$(CONFIG_MVEBU_GPIO) += mvebu_gpio.o obj-$(CONFIG_MSM_GPIO) += msm_gpio.o obj-$(CONFIG_$(SPL_)PCF8575_GPIO) += pcf8575_gpio.o -obj-$(CONFIG_$(SPL_TPL_)PM8916_GPIO) += pm8916_gpio.o +obj-$(CONFIG_$(SPL_TPL_)QCOM_PMIC_GPIO) += qcom_pmic_gpio.o obj-$(CONFIG_MT7620_GPIO) += mt7620_gpio.o obj-$(CONFIG_MT7621_GPIO) += mt7621_gpio.o obj-$(CONFIG_MSCC_SGPIO) += mscc_sgpio.o diff --git a/drivers/gpio/pm8916_gpio.c b/drivers/gpio/qcom_pmic_gpio.c similarity index 67% rename from drivers/gpio/pm8916_gpio.c rename to drivers/gpio/qcom_pmic_gpio.c index 7ad95784a8..e9232a007f 100644 --- a/drivers/gpio/pm8916_gpio.c +++ b/drivers/gpio/qcom_pmic_gpio.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0+ /* - * Qualcomm pm8916 pmic gpio driver - part of Qualcomm PM8916 PMIC + * Qualcomm generic pmic gpio driver * * (C) Copyright 2015 Mateusz Kulikowski */ @@ -19,7 +19,7 @@ /* Register maps */ -/* Type and subtype are shared for all pm8916 peripherals */ +/* Type and subtype are shared for all PMIC peripherals */ #define REG_TYPE 0x4 #define REG_SUBTYPE 0x5 @@ -47,14 +47,14 @@ #define REG_EN_CTL 0x46 #define REG_EN_CTL_ENABLE (1 << 7) -struct pm8916_gpio_bank { +struct qcom_gpio_bank { uint32_t pid; /* Peripheral ID on SPMI bus */ }; -static int pm8916_gpio_set_direction(struct udevice *dev, unsigned offset, - bool input, int value) +static int qcom_gpio_set_direction(struct udevice *dev, unsigned offset, + bool input, int value) { - struct pm8916_gpio_bank *priv = dev_get_priv(dev); + struct qcom_gpio_bank *priv = dev_get_priv(dev); uint32_t gpio_base = priv->pid + REG_OFFSET(offset); int ret; @@ -101,20 +101,20 @@ static int pm8916_gpio_set_direction(struct udevice *dev, unsigned offset, REG_EN_CTL_ENABLE); } -static int pm8916_gpio_direction_input(struct udevice *dev, unsigned offset) +static int qcom_gpio_direction_input(struct udevice *dev, unsigned offset) { - return pm8916_gpio_set_direction(dev, offset, true, 0); + return qcom_gpio_set_direction(dev, offset, true, 0); } -static int pm8916_gpio_direction_output(struct udevice *dev, unsigned offset, - int value) +static int qcom_gpio_direction_output(struct udevice *dev, unsigned offset, + int value) { - return pm8916_gpio_set_direction(dev, offset, false, value); + return qcom_gpio_set_direction(dev, offset, false, value); } -static int pm8916_gpio_get_function(struct udevice *dev, unsigned offset) +static int qcom_gpio_get_function(struct udevice *dev, unsigned offset) { - struct pm8916_gpio_bank *priv = dev_get_priv(dev); + struct qcom_gpio_bank *priv = dev_get_priv(dev); uint32_t gpio_base = priv->pid + REG_OFFSET(offset); int reg; @@ -134,9 +134,9 @@ static int pm8916_gpio_get_function(struct udevice *dev, unsigned offset) } } -static int pm8916_gpio_get_value(struct udevice *dev, unsigned offset) +static int qcom_gpio_get_value(struct udevice *dev, unsigned offset) { - struct pm8916_gpio_bank *priv = dev_get_priv(dev); + struct qcom_gpio_bank *priv = dev_get_priv(dev); uint32_t gpio_base = priv->pid + REG_OFFSET(offset); int reg; @@ -147,10 +147,10 @@ static int pm8916_gpio_get_value(struct udevice *dev, unsigned offset) return !!(reg & REG_STATUS_VAL_MASK); } -static int pm8916_gpio_set_value(struct udevice *dev, unsigned offset, - int value) +static int qcom_gpio_set_value(struct udevice *dev, unsigned offset, + int value) { - struct pm8916_gpio_bank *priv = dev_get_priv(dev); + struct qcom_gpio_bank *priv = dev_get_priv(dev); uint32_t gpio_base = priv->pid + REG_OFFSET(offset); /* Set the output value of the gpio */ @@ -158,17 +158,17 @@ static int pm8916_gpio_set_value(struct udevice *dev, unsigned offset, REG_CTL_OUTPUT_MASK, !!value); } -static const struct dm_gpio_ops pm8916_gpio_ops = { - .direction_input = pm8916_gpio_direction_input, - .direction_output = pm8916_gpio_direction_output, - .get_value = pm8916_gpio_get_value, - .set_value = pm8916_gpio_set_value, - .get_function = pm8916_gpio_get_function, +static const struct dm_gpio_ops qcom_gpio_ops = { + .direction_input = qcom_gpio_direction_input, + .direction_output = qcom_gpio_direction_output, + .get_value = qcom_gpio_get_value, + .set_value = qcom_gpio_set_value, + .get_function = qcom_gpio_get_function, }; -static int pm8916_gpio_probe(struct udevice *dev) +static int qcom_gpio_probe(struct udevice *dev) { - struct pm8916_gpio_bank *priv = dev_get_priv(dev); + struct qcom_gpio_bank *priv = dev_get_priv(dev); int reg; priv->pid = dev_read_addr(dev); @@ -187,33 +187,33 @@ static int pm8916_gpio_probe(struct udevice *dev) return 0; } -static int pm8916_gpio_of_to_plat(struct udevice *dev) +static int qcom_gpio_of_to_plat(struct udevice *dev) { struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev); uc_priv->gpio_count = dev_read_u32_default(dev, "gpio-count", 0); uc_priv->bank_name = dev_read_string(dev, "gpio-bank-name"); if (uc_priv->bank_name == NULL) - uc_priv->bank_name = "pm8916"; + uc_priv->bank_name = "qcom_pmic"; return 0; } -static const struct udevice_id pm8916_gpio_ids[] = { +static const struct udevice_id qcom_gpio_ids[] = { { .compatible = "qcom,pm8916-gpio" }, { .compatible = "qcom,pm8994-gpio" }, /* 22 GPIO's */ { .compatible = "qcom,pm8998-gpio" }, { } }; -U_BOOT_DRIVER(gpio_pm8916) = { - .name = "gpio_pm8916", +U_BOOT_DRIVER(qcom_pmic_gpio) = { + .name = "qcom_pmic_gpio", .id = UCLASS_GPIO, - .of_match = pm8916_gpio_ids, - .of_to_plat = pm8916_gpio_of_to_plat, - .probe = pm8916_gpio_probe, - .ops = &pm8916_gpio_ops, - .priv_auto = sizeof(struct pm8916_gpio_bank), + .of_match = qcom_gpio_ids, + .of_to_plat = qcom_gpio_of_to_plat, + .probe = qcom_gpio_probe, + .ops = &qcom_gpio_ops, + .priv_auto = sizeof(struct qcom_gpio_bank), }; @@ -222,14 +222,14 @@ U_BOOT_DRIVER(gpio_pm8916) = { #define KPDPWR_ON_INT_BIT 0 #define RESIN_ON_INT_BIT 1 -static int pm8941_pwrkey_get_function(struct udevice *dev, unsigned offset) +static int qcom_pwrkey_get_function(struct udevice *dev, unsigned offset) { return GPIOF_INPUT; } -static int pm8941_pwrkey_get_value(struct udevice *dev, unsigned offset) +static int qcom_pwrkey_get_value(struct udevice *dev, unsigned offset) { - struct pm8916_gpio_bank *priv = dev_get_priv(dev); + struct qcom_gpio_bank *priv = dev_get_priv(dev); int reg = pmic_reg_read(dev->parent, priv->pid + PON_INT_RT_STS); @@ -247,14 +247,14 @@ static int pm8941_pwrkey_get_value(struct udevice *dev, unsigned offset) } } -static const struct dm_gpio_ops pm8941_pwrkey_ops = { - .get_value = pm8941_pwrkey_get_value, - .get_function = pm8941_pwrkey_get_function, +static const struct dm_gpio_ops qcom_pwrkey_ops = { + .get_value = qcom_pwrkey_get_value, + .get_function = qcom_pwrkey_get_function, }; -static int pm8941_pwrkey_probe(struct udevice *dev) +static int qcom_pwrkey_probe(struct udevice *dev) { - struct pm8916_gpio_bank *priv = dev_get_priv(dev); + struct qcom_gpio_bank *priv = dev_get_priv(dev); int reg; priv->pid = dev_read_addr(dev); @@ -273,31 +273,31 @@ static int pm8941_pwrkey_probe(struct udevice *dev) return 0; } -static int pm8941_pwrkey_of_to_plat(struct udevice *dev) +static int qcom_pwrkey_of_to_plat(struct udevice *dev) { struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev); uc_priv->gpio_count = 2; uc_priv->bank_name = dev_read_string(dev, "gpio-bank-name"); if (uc_priv->bank_name == NULL) - uc_priv->bank_name = "pm8916_key"; + uc_priv->bank_name = "pwkey_qcom"; return 0; } -static const struct udevice_id pm8941_pwrkey_ids[] = { +static const struct udevice_id qcom_pwrkey_ids[] = { { .compatible = "qcom,pm8916-pwrkey" }, { .compatible = "qcom,pm8994-pwrkey" }, { .compatible = "qcom,pm8998-pwrkey" }, { } }; -U_BOOT_DRIVER(pwrkey_pm89xx) = { - .name = "pwrkey_pm89xx", +U_BOOT_DRIVER(pwrkey_qcom) = { + .name = "pwrkey_qcom", .id = UCLASS_GPIO, - .of_match = pm8941_pwrkey_ids, - .of_to_plat = pm8941_pwrkey_of_to_plat, - .probe = pm8941_pwrkey_probe, - .ops = &pm8941_pwrkey_ops, - .priv_auto = sizeof(struct pm8916_gpio_bank), + .of_match = qcom_pwrkey_ids, + .of_to_plat = qcom_pwrkey_of_to_plat, + .probe = qcom_pwrkey_probe, + .ops = &qcom_pwrkey_ops, + .priv_auto = sizeof(struct qcom_gpio_bank), }; diff --git a/drivers/power/pmic/Kconfig b/drivers/power/pmic/Kconfig index 66b16b06e0..0478f2aa1d 100644 --- a/drivers/power/pmic/Kconfig +++ b/drivers/power/pmic/Kconfig @@ -216,10 +216,10 @@ config PMIC_MAX8997 - MUIC - Others -config PMIC_PM8916 - bool "Enable Driver Model for Qualcomm PM8916 PMIC" +config PMIC_QCOM + bool "Enable Driver Model for Qualcomm generic PMIC" ---help--- - The PM8916 is a PMIC connected to one (or several) processors + The Qcom PMIC is connected to one (or several) processors with SPMI bus. It has 2 slaves with several peripherals: - 18x LDO - 4x GPIO @@ -229,7 +229,7 @@ config PMIC_PM8916 - Vibrator drivers - Others - Driver binding info: doc/device-tree-bindings/pmic/pm8916.txt + Driver binding info: doc/device-tree-bindings/pmic/qcom,spmi-pmic.txt config PMIC_RK8XX bool "Enable support for Rockchip PMIC RK8XX" diff --git a/drivers/power/pmic/Makefile b/drivers/power/pmic/Makefile index f73b326255..e1d3545490 100644 --- a/drivers/power/pmic/Makefile +++ b/drivers/power/pmic/Makefile @@ -20,7 +20,7 @@ obj-$(CONFIG_PMIC_ACT8846) += act8846.o obj-$(CONFIG_PMIC_AS3722) += as3722.o as3722_gpio.o obj-$(CONFIG_$(SPL_)PMIC_AXP) += axp.o obj-$(CONFIG_PMIC_MAX8997) += max8997.o -obj-$(CONFIG_PMIC_PM8916) += pm8916.o +obj-$(CONFIG_PMIC_QCOM) += pmic_qcom.o obj-$(CONFIG_$(SPL_TPL_)PMIC_RK8XX) += rk8xx.o obj-$(CONFIG_PMIC_RN5T567) += rn5t567.o obj-$(CONFIG_PMIC_TPS65090) += tps65090.o diff --git a/drivers/power/pmic/pm8916.c b/drivers/power/pmic/pmic_qcom.c similarity index 52% rename from drivers/power/pmic/pm8916.c rename to drivers/power/pmic/pmic_qcom.c index 5f4386d4ad..ad8daf43f0 100644 --- a/drivers/power/pmic/pm8916.c +++ b/drivers/power/pmic/pmic_qcom.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0+ /* - * Qualcomm pm8916 pmic driver + * Qualcomm generic pmic driver * * (C) Copyright 2015 Mateusz Kulikowski */ @@ -13,19 +13,19 @@ #define PID_MASK (0xFF << PID_SHIFT) #define REG_MASK 0xFF -struct pm8916_priv { +struct pmic_qcom_priv { uint32_t usid; /* Slave ID on SPMI bus */ }; -static int pm8916_reg_count(struct udevice *dev) +static int pmic_qcom_reg_count(struct udevice *dev) { return 0xFFFF; } -static int pm8916_write(struct udevice *dev, uint reg, const uint8_t *buff, - int len) +static int pmic_qcom_write(struct udevice *dev, uint reg, const uint8_t *buff, + int len) { - struct pm8916_priv *priv = dev_get_priv(dev); + struct pmic_qcom_priv *priv = dev_get_priv(dev); if (len != 1) return -EINVAL; @@ -35,9 +35,9 @@ static int pm8916_write(struct udevice *dev, uint reg, const uint8_t *buff, *buff); } -static int pm8916_read(struct udevice *dev, uint reg, uint8_t *buff, int len) +static int pmic_qcom_read(struct udevice *dev, uint reg, uint8_t *buff, int len) { - struct pm8916_priv *priv = dev_get_priv(dev); + struct pmic_qcom_priv *priv = dev_get_priv(dev); int val; if (len != 1) @@ -52,20 +52,20 @@ static int pm8916_read(struct udevice *dev, uint reg, uint8_t *buff, int len) return 0; } -static struct dm_pmic_ops pm8916_ops = { - .reg_count = pm8916_reg_count, - .read = pm8916_read, - .write = pm8916_write, +static struct dm_pmic_ops pmic_qcom_ops = { + .reg_count = pmic_qcom_reg_count, + .read = pmic_qcom_read, + .write = pmic_qcom_write, }; -static const struct udevice_id pm8916_ids[] = { +static const struct udevice_id pmic_qcom_ids[] = { { .compatible = "qcom,spmi-pmic" }, { } }; -static int pm8916_probe(struct udevice *dev) +static int pmic_qcom_probe(struct udevice *dev) { - struct pm8916_priv *priv = dev_get_priv(dev); + struct pmic_qcom_priv *priv = dev_get_priv(dev); priv->usid = dev_read_addr(dev); @@ -75,12 +75,12 @@ static int pm8916_probe(struct udevice *dev) return 0; } -U_BOOT_DRIVER(pmic_pm8916) = { - .name = "pmic_pm8916", +U_BOOT_DRIVER(pmic_qcom) = { + .name = "pmic_qcom", .id = UCLASS_PMIC, - .of_match = pm8916_ids, + .of_match = pmic_qcom_ids, .bind = dm_scan_fdt_dev, - .probe = pm8916_probe, - .ops = &pm8916_ops, - .priv_auto = sizeof(struct pm8916_priv), + .probe = pmic_qcom_probe, + .ops = &pmic_qcom_ops, + .priv_auto = sizeof(struct pmic_qcom_priv), }; From cf515842b9367266c873a0e037dcc7ee856ea0ab Mon Sep 17 00:00:00 2001 From: Sumit Garg Date: Thu, 4 Aug 2022 19:57:18 +0530 Subject: [PATCH 019/374] gpio: qcom_pmic: Add support for GPIO LV/MV subtype GPIO LV (low voltage)/MV (medium voltage) subtypes have different features and register mappings than 4CH/8CH subtypes. Add support for LV and MV subtypes. With GPIO LV/MV subtype available, add "qcom,pms405-gpio" compatible which requires support for GPIO MV subtype. Signed-off-by: Sumit Garg --- drivers/gpio/qcom_pmic_gpio.c | 96 +++++++++++++++++++++++++++-------- 1 file changed, 76 insertions(+), 20 deletions(-) diff --git a/drivers/gpio/qcom_pmic_gpio.c b/drivers/gpio/qcom_pmic_gpio.c index e9232a007f..3be1be8692 100644 --- a/drivers/gpio/qcom_pmic_gpio.c +++ b/drivers/gpio/qcom_pmic_gpio.c @@ -23,6 +23,15 @@ #define REG_TYPE 0x4 #define REG_SUBTYPE 0x5 +/* GPIO peripheral type and subtype out_values */ +#define REG_TYPE_VAL 0x10 +#define REG_SUBTYPE_GPIO_4CH 0x1 +#define REG_SUBTYPE_GPIOC_4CH 0x5 +#define REG_SUBTYPE_GPIO_8CH 0x9 +#define REG_SUBTYPE_GPIOC_8CH 0xd +#define REG_SUBTYPE_GPIO_LV 0x10 +#define REG_SUBTYPE_GPIO_MV 0x11 + #define REG_STATUS 0x08 #define REG_STATUS_VAL_MASK 0x1 @@ -33,6 +42,10 @@ #define REG_CTL_MODE_INOUT 0x20 #define REG_CTL_MODE_OUTPUT 0x10 #define REG_CTL_OUTPUT_MASK 0x0F +#define REG_CTL_LV_MV_MODE_MASK 0x3 +#define REG_CTL_LV_MV_MODE_INPUT 0x0 +#define REG_CTL_LV_MV_MODE_INOUT 0x2 +#define REG_CTL_LV_MV_MODE_OUTPUT 0x1 #define REG_DIG_VIN_CTL 0x41 #define REG_DIG_VIN_VIN0 0 @@ -40,6 +53,10 @@ #define REG_DIG_PULL_CTL 0x42 #define REG_DIG_PULL_NO_PU 0x5 +#define REG_LV_MV_OUTPUT_CTL 0x44 +#define REG_LV_MV_OUTPUT_CTL_MASK 0x80 +#define REG_LV_MV_OUTPUT_CTL_SHIFT 7 + #define REG_DIG_OUT_CTL 0x45 #define REG_DIG_OUT_CTL_CMOS (0x0 << 4) #define REG_DIG_OUT_CTL_DRIVE_L 0x1 @@ -49,6 +66,7 @@ struct qcom_gpio_bank { uint32_t pid; /* Peripheral ID on SPMI bus */ + bool lv_mv_type; /* If subtype is GPIO_LV(0x10) or GPIO_MV(0x11) */ }; static int qcom_gpio_set_direction(struct udevice *dev, unsigned offset, @@ -56,6 +74,7 @@ static int qcom_gpio_set_direction(struct udevice *dev, unsigned offset, { struct qcom_gpio_bank *priv = dev_get_priv(dev); uint32_t gpio_base = priv->pid + REG_OFFSET(offset); + uint32_t reg_ctl_val; int ret; /* Disable the GPIO */ @@ -64,16 +83,31 @@ static int qcom_gpio_set_direction(struct udevice *dev, unsigned offset, if (ret < 0) return ret; - /* Select the mode */ - if (input) - ret = pmic_reg_write(dev->parent, gpio_base + REG_CTL, - REG_CTL_MODE_INPUT); - else - ret = pmic_reg_write(dev->parent, gpio_base + REG_CTL, - REG_CTL_MODE_INOUT | (value ? 1 : 0)); + /* Select the mode and output */ + if (priv->lv_mv_type) { + if (input) + reg_ctl_val = REG_CTL_LV_MV_MODE_INPUT; + else + reg_ctl_val = REG_CTL_LV_MV_MODE_INOUT; + } else { + if (input) + reg_ctl_val = REG_CTL_MODE_INPUT; + else + reg_ctl_val = REG_CTL_MODE_INOUT | !!value; + } + + ret = pmic_reg_write(dev->parent, gpio_base + REG_CTL, reg_ctl_val); if (ret < 0) return ret; + if (priv->lv_mv_type && !input) { + ret = pmic_reg_write(dev->parent, + gpio_base + REG_LV_MV_OUTPUT_CTL, + !!value << REG_LV_MV_OUTPUT_CTL_SHIFT); + if (ret < 0) + return ret; + } + /* Set the right pull (no pull) */ ret = pmic_reg_write(dev->parent, gpio_base + REG_DIG_PULL_CTL, REG_DIG_PULL_NO_PU); @@ -118,19 +152,30 @@ static int qcom_gpio_get_function(struct udevice *dev, unsigned offset) uint32_t gpio_base = priv->pid + REG_OFFSET(offset); int reg; - /* Set the output value of the gpio */ reg = pmic_reg_read(dev->parent, gpio_base + REG_CTL); if (reg < 0) return reg; - switch (reg & REG_CTL_MODE_MASK) { - case REG_CTL_MODE_INPUT: - return GPIOF_INPUT; - case REG_CTL_MODE_INOUT: /* Fallthrough */ - case REG_CTL_MODE_OUTPUT: - return GPIOF_OUTPUT; - default: - return GPIOF_UNKNOWN; + if (priv->lv_mv_type) { + switch (reg & REG_CTL_LV_MV_MODE_MASK) { + case REG_CTL_LV_MV_MODE_INPUT: + return GPIOF_INPUT; + case REG_CTL_LV_MV_MODE_INOUT: /* Fallthrough */ + case REG_CTL_LV_MV_MODE_OUTPUT: + return GPIOF_OUTPUT; + default: + return GPIOF_UNKNOWN; + } + } else { + switch (reg & REG_CTL_MODE_MASK) { + case REG_CTL_MODE_INPUT: + return GPIOF_INPUT; + case REG_CTL_MODE_INOUT: /* Fallthrough */ + case REG_CTL_MODE_OUTPUT: + return GPIOF_OUTPUT; + default: + return GPIOF_UNKNOWN; + } } } @@ -154,8 +199,14 @@ static int qcom_gpio_set_value(struct udevice *dev, unsigned offset, uint32_t gpio_base = priv->pid + REG_OFFSET(offset); /* Set the output value of the gpio */ - return pmic_clrsetbits(dev->parent, gpio_base + REG_CTL, - REG_CTL_OUTPUT_MASK, !!value); + if (priv->lv_mv_type) + return pmic_clrsetbits(dev->parent, + gpio_base + REG_LV_MV_OUTPUT_CTL, + REG_LV_MV_OUTPUT_CTL_MASK, + !!value << REG_LV_MV_OUTPUT_CTL_SHIFT); + else + return pmic_clrsetbits(dev->parent, gpio_base + REG_CTL, + REG_CTL_OUTPUT_MASK, !!value); } static const struct dm_gpio_ops qcom_gpio_ops = { @@ -177,13 +228,17 @@ static int qcom_gpio_probe(struct udevice *dev) /* Do a sanity check */ reg = pmic_reg_read(dev->parent, priv->pid + REG_TYPE); - if (reg != 0x10) + if (reg != REG_TYPE_VAL) return log_msg_ret("bad type", -ENXIO); reg = pmic_reg_read(dev->parent, priv->pid + REG_SUBTYPE); - if (reg != 0x5 && reg != 0x1) + if (reg != REG_SUBTYPE_GPIO_4CH && reg != REG_SUBTYPE_GPIOC_4CH && + reg != REG_SUBTYPE_GPIO_LV && reg != REG_SUBTYPE_GPIO_MV) return log_msg_ret("bad subtype", -ENXIO); + priv->lv_mv_type = reg == REG_SUBTYPE_GPIO_LV || + reg == REG_SUBTYPE_GPIO_MV; + return 0; } @@ -203,6 +258,7 @@ static const struct udevice_id qcom_gpio_ids[] = { { .compatible = "qcom,pm8916-gpio" }, { .compatible = "qcom,pm8994-gpio" }, /* 22 GPIO's */ { .compatible = "qcom,pm8998-gpio" }, + { .compatible = "qcom,pms405-gpio" }, { } }; From 9c96a0c62a0aa72af2bfcda016834845764b063c Mon Sep 17 00:00:00 2001 From: Sumit Garg Date: Thu, 4 Aug 2022 19:57:19 +0530 Subject: [PATCH 020/374] dts: qcs404-evb: Add PMIC GPIO controller node PMIC GPIOs are special GPIOs which are accessible through SPMI bus. So add corresponding DT nodes. Signed-off-by: Sumit Garg --- arch/arm/dts/qcs404-evb.dts | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/arch/arm/dts/qcs404-evb.dts b/arch/arm/dts/qcs404-evb.dts index 719e6a25fb..f127f5303a 100644 --- a/arch/arm/dts/qcs404-evb.dts +++ b/arch/arm/dts/qcs404-evb.dts @@ -168,6 +168,31 @@ maximum-speed = "high-speed"; }; }; + + spmi@200f000 { + compatible = "qcom,spmi-pmic-arb"; + reg = <0x200f000 0x1000 + 0x2400000 0x400000 + 0x2c00000 0x400000>; + #address-cells = <0x1>; + #size-cells = <0x1>; + + pms405_0: pms405@0 { + compatible = "qcom,spmi-pmic"; + reg = <0x0 0x1>; + #address-cells = <0x1>; + #size-cells = <0x1>; + + pms405_gpios: pms405_gpios@c000 { + compatible = "qcom,pms405-gpio"; + reg = <0xc000 0x400>; + gpio-controller; + gpio-count = <12>; + #gpio-cells = <2>; + gpio-bank-name="pmic"; + }; + }; + }; }; }; From 106822de5eec09cdf082f0d900d707190ffa30f8 Mon Sep 17 00:00:00 2001 From: Sumit Garg Date: Thu, 4 Aug 2022 19:57:20 +0530 Subject: [PATCH 021/374] board: qcs404-evb: Enable USB3 specific PMIC GPIO For USB3 host controller to detect devices on the bus it is required to enable a PMIC GPIO: usb_vbus_boost_pin. So enable that during board specific initialization. And since this PMIC GPIO parsing is quite u-boot specific, so add a DT override to qcs404-evb-uboot.dtsi to represent usb_vbus_boost_pin. Signed-off-by: Sumit Garg --- arch/arm/dts/qcs404-evb-uboot.dtsi | 6 ++++++ board/qualcomm/qcs404-evb/qcs404-evb.c | 29 ++++++++++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/arch/arm/dts/qcs404-evb-uboot.dtsi b/arch/arm/dts/qcs404-evb-uboot.dtsi index c18080a483..c73d71e8c7 100644 --- a/arch/arm/dts/qcs404-evb-uboot.dtsi +++ b/arch/arm/dts/qcs404-evb-uboot.dtsi @@ -22,3 +22,9 @@ }; }; }; + +&pms405_gpios { + usb_vbus_boost_pin { + gpios = <&pms405_gpios 2 0>; + }; +}; diff --git a/board/qualcomm/qcs404-evb/qcs404-evb.c b/board/qualcomm/qcs404-evb/qcs404-evb.c index f1e6e7f7eb..249dca7e72 100644 --- a/board/qualcomm/qcs404-evb/qcs404-evb.c +++ b/board/qualcomm/qcs404-evb/qcs404-evb.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -24,6 +25,34 @@ int dram_init(void) int board_init(void) { + struct udevice *pmic_gpio; + struct gpio_desc usb_vbus_boost_pin; + int ret, node; + + ret = uclass_get_device_by_name(UCLASS_GPIO, + "pms405_gpios@c000", + &pmic_gpio); + if (ret < 0) { + printf("Failed to find pms405_gpios@c000 node.\n"); + return ret; + } + + node = fdt_subnode_offset(gd->fdt_blob, dev_of_offset(pmic_gpio), + "usb_vbus_boost_pin"); + if (node < 0) { + printf("Failed to find usb_hub_reset_pm dt node.\n"); + return node; + } + ret = gpio_request_by_name_nodev(offset_to_ofnode(node), "gpios", 0, + &usb_vbus_boost_pin, 0); + if (ret < 0) { + printf("Failed to request usb_hub_reset_pm gpio.\n"); + return ret; + } + + dm_gpio_set_dir_flags(&usb_vbus_boost_pin, + GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE); + return 0; } From 54e77ad17d2e34b08ed4aba16a909ada00b9a233 Mon Sep 17 00:00:00 2001 From: Sumit Garg Date: Thu, 4 Aug 2022 19:57:21 +0530 Subject: [PATCH 022/374] qcs404evb_defconfig: Enable USB configs Enable USB config options along with its dependencies like PHY, RESET, PMIC GPIO etc. config options. Signed-off-by: Sumit Garg --- configs/qcs404evb_defconfig | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/configs/qcs404evb_defconfig b/configs/qcs404evb_defconfig index d45f6b2348..432d5d50c1 100644 --- a/configs/qcs404evb_defconfig +++ b/configs/qcs404evb_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_USB=y # CONFIG_NET is not set CONFIG_CLK=y CONFIG_MMC_HS400_SUPPORT=y @@ -35,4 +36,21 @@ CONFIG_MMC_SDHCI_ADMA=y CONFIG_MMC_SDHCI_MSM=y CONFIG_PINCTRL=y CONFIG_MSM_SERIAL=y +CONFIG_SPMI_MSM=y +CONFIG_DM_PMIC=y +CONFIG_PMIC_QCOM=y +CONFIG_QCOM_PMIC_GPIO=y +CONFIG_MISC=y +CONFIG_USB=y +CONFIG_DM_USB=y +CONFIG_USB_STORAGE=y +CONFIG_USB_DWC3=y +CONFIG_USB_DWC3_GENERIC=y +CONFIG_USB_XHCI_HCD=y +CONFIG_USB_XHCI_DWC3=y +CONFIG_DM_RESET=y +CONFIG_RESET_QCOM=y +CONFIG_PHY=y +CONFIG_PHY_QCOM_USB_HS_28NM=y +CONFIG_PHY_QCOM_USB_SS=y CONFIG_LMB_MAX_REGIONS=64 From a4b99582bbe12c2fe7586ceaf443d99b3a38e389 Mon Sep 17 00:00:00 2001 From: Sumit Garg Date: Wed, 27 Jul 2022 13:52:03 +0530 Subject: [PATCH 023/374] pinctrl: sdm845: Remove redundant CONFIG_SDM845 check DT compatible is sufficient to make platform specific differentiation, so remove redundant CONFIG_SDM845 check. Signed-off-by: Sumit Garg Reviewed-by: Ramon Fried --- arch/arm/mach-snapdragon/Makefile | 2 +- arch/arm/mach-snapdragon/pinctrl-snapdragon.c | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/arch/arm/mach-snapdragon/Makefile b/arch/arm/mach-snapdragon/Makefile index 0d31f10f68..cbaaf23f6b 100644 --- a/arch/arm/mach-snapdragon/Makefile +++ b/arch/arm/mach-snapdragon/Makefile @@ -16,6 +16,6 @@ obj-y += pinctrl-snapdragon.o obj-y += pinctrl-apq8016.o obj-y += pinctrl-apq8096.o obj-y += pinctrl-qcs404.o -obj-$(CONFIG_SDM845) += pinctrl-sdm845.o +obj-y += pinctrl-sdm845.o obj-$(CONFIG_TARGET_QCS404EVB) += clock-qcs404.o obj-$(CONFIG_TARGET_QCS404EVB) += sysmap-qcs404.o diff --git a/arch/arm/mach-snapdragon/pinctrl-snapdragon.c b/arch/arm/mach-snapdragon/pinctrl-snapdragon.c index c2148a5d0a..842e2da0c5 100644 --- a/arch/arm/mach-snapdragon/pinctrl-snapdragon.c +++ b/arch/arm/mach-snapdragon/pinctrl-snapdragon.c @@ -116,9 +116,7 @@ static struct pinctrl_ops msm_pinctrl_ops = { static const struct udevice_id msm_pinctrl_ids[] = { { .compatible = "qcom,tlmm-apq8016", .data = (ulong)&apq8016_data }, { .compatible = "qcom,tlmm-apq8096", .data = (ulong)&apq8096_data }, -#ifdef CONFIG_SDM845 { .compatible = "qcom,tlmm-sdm845", .data = (ulong)&sdm845_data }, -#endif { .compatible = "qcom,tlmm-qcs404", .data = (ulong)&qcs404_data }, { } }; From 0ddabb6830e5aee2c54f86f2430ea0f28f7538c3 Mon Sep 17 00:00:00 2001 From: Sumit Garg Date: Wed, 27 Jul 2022 13:52:04 +0530 Subject: [PATCH 024/374] arm: dts: qcom: Sync pinctrl DT nodes with Linux bindings Currently for all Qcom SoCs/boards there are separate compatibles for GPIO and pinctrl. But this is inconsistent with official (upstream) Linux bindings which requires only a single compatible "qcom,-pinctrl" and there is no such compatible property as "qcom,tlmm-". So fix this inconsistency for Qcom SoCs in order to comply with upstream DT bindings. This is done via removing compatibles from "msm_gpio" driver and via binding to "msm_gpio" driver from pinctrl driver in case "gpio-controller" property is specified for pinctrl node. Suggested-by: Stephan Gerhold Signed-off-by: Sumit Garg --- arch/arm/dts/dragonboard410c-uboot.dtsi | 2 +- arch/arm/dts/dragonboard410c.dts | 17 +++------ arch/arm/dts/dragonboard820c-uboot.dtsi | 2 +- arch/arm/dts/dragonboard820c.dts | 4 +- arch/arm/dts/qcom-ipq4019.dtsi | 18 +++------ arch/arm/dts/qcs404-evb.dts | 2 +- arch/arm/dts/sdm845.dtsi | 2 +- arch/arm/mach-ipq40xx/pinctrl-snapdragon.c | 31 +++++++++++++++- arch/arm/mach-snapdragon/pinctrl-snapdragon.c | 37 +++++++++++++++++-- drivers/gpio/msm_gpio.c | 10 +---- 10 files changed, 82 insertions(+), 43 deletions(-) diff --git a/arch/arm/dts/dragonboard410c-uboot.dtsi b/arch/arm/dts/dragonboard410c-uboot.dtsi index 9c1be2566f..e4fecaa19e 100644 --- a/arch/arm/dts/dragonboard410c-uboot.dtsi +++ b/arch/arm/dts/dragonboard410c-uboot.dtsi @@ -14,7 +14,7 @@ soc { u-boot,dm-pre-reloc; - qcom,tlmm@1000000 { + pinctrl@1000000 { u-boot,dm-pre-reloc; uart { diff --git a/arch/arm/dts/dragonboard410c.dts b/arch/arm/dts/dragonboard410c.dts index 50523712cb..59cf45eb17 100644 --- a/arch/arm/dts/dragonboard410c.dts +++ b/arch/arm/dts/dragonboard410c.dts @@ -60,9 +60,13 @@ reg = <0x60000 0x8000>; }; - pinctrl: qcom,tlmm@1000000 { - compatible = "qcom,tlmm-apq8016"; + soc_gpios: pinctrl@1000000 { + compatible = "qcom,msm8916-pinctrl"; reg = <0x1000000 0x400000>; + gpio-controller; + gpio-count = <122>; + gpio-bank-name="soc"; + #gpio-cells = <2>; blsp1_uart: uart { function = "blsp1_uart"; @@ -86,15 +90,6 @@ pinctrl-0 = <&blsp1_uart>; }; - soc_gpios: pinctrl@1000000 { - compatible = "qcom,apq8016-pinctrl"; - reg = <0x1000000 0x300000>; - gpio-controller; - gpio-count = <122>; - gpio-bank-name="soc"; - #gpio-cells = <2>; - }; - ehci@78d9000 { compatible = "qcom,ehci-host"; reg = <0x78d9000 0x400>; diff --git a/arch/arm/dts/dragonboard820c-uboot.dtsi b/arch/arm/dts/dragonboard820c-uboot.dtsi index 8610d7ec37..2270ac73bf 100644 --- a/arch/arm/dts/dragonboard820c-uboot.dtsi +++ b/arch/arm/dts/dragonboard820c-uboot.dtsi @@ -13,7 +13,7 @@ soc { u-boot,dm-pre-reloc; - qcom,tlmm@1010000 { + pinctrl@1010000 { u-boot,dm-pre-reloc; uart { diff --git a/arch/arm/dts/dragonboard820c.dts b/arch/arm/dts/dragonboard820c.dts index b72a2471cf..aaca681d2e 100644 --- a/arch/arm/dts/dragonboard820c.dts +++ b/arch/arm/dts/dragonboard820c.dts @@ -64,8 +64,8 @@ reg = <0x300000 0x90000>; }; - pinctrl: qcom,tlmm@1010000 { - compatible = "qcom,tlmm-apq8096"; + pinctrl: pinctrl@1010000 { + compatible = "qcom,msm8996-pinctrl"; reg = <0x1010000 0x400000>; blsp8_uart: uart { diff --git a/arch/arm/dts/qcom-ipq4019.dtsi b/arch/arm/dts/qcom-ipq4019.dtsi index 7a52ea2c4e..181732d262 100644 --- a/arch/arm/dts/qcom-ipq4019.dtsi +++ b/arch/arm/dts/qcom-ipq4019.dtsi @@ -75,9 +75,13 @@ u-boot,dm-pre-reloc; }; - pinctrl: qcom,tlmm@1000000 { - compatible = "qcom,tlmm-ipq4019"; + soc_gpios: pinctrl@1000000 { + compatible = "qcom,ipq4019-pinctrl"; reg = <0x1000000 0x300000>; + gpio-controller; + gpio-count = <100>; + gpio-bank-name="soc"; + #gpio-cells = <2>; u-boot,dm-pre-reloc; }; @@ -90,16 +94,6 @@ u-boot,dm-pre-reloc; }; - soc_gpios: pinctrl@1000000 { - compatible = "qcom,ipq4019-pinctrl"; - reg = <0x1000000 0x300000>; - gpio-controller; - gpio-count = <100>; - gpio-bank-name="soc"; - #gpio-cells = <2>; - u-boot,dm-pre-reloc; - }; - blsp1_spi1: spi@78b5000 { compatible = "qcom,spi-qup-v2.2.1"; reg = <0x78b5000 0x600>; diff --git a/arch/arm/dts/qcs404-evb.dts b/arch/arm/dts/qcs404-evb.dts index f127f5303a..0639af8fe3 100644 --- a/arch/arm/dts/qcs404-evb.dts +++ b/arch/arm/dts/qcs404-evb.dts @@ -38,7 +38,7 @@ compatible = "simple-bus"; pinctrl_north@1300000 { - compatible = "qcom,tlmm-qcs404"; + compatible = "qcom,qcs404-pinctrl"; reg = <0x1300000 0x200000>; blsp1_uart2: uart { diff --git a/arch/arm/dts/sdm845.dtsi b/arch/arm/dts/sdm845.dtsi index df5b6dfcfc..607af277f8 100644 --- a/arch/arm/dts/sdm845.dtsi +++ b/arch/arm/dts/sdm845.dtsi @@ -37,7 +37,7 @@ }; tlmm_north: pinctrl_north@3900000 { - compatible = "qcom,tlmm-sdm845"; + compatible = "qcom,sdm845-pinctrl"; reg = <0x3900000 0x400000>; gpio-count = <150>; gpio-controller; diff --git a/arch/arm/mach-ipq40xx/pinctrl-snapdragon.c b/arch/arm/mach-ipq40xx/pinctrl-snapdragon.c index c51a75ee94..036fec93d7 100644 --- a/arch/arm/mach-ipq40xx/pinctrl-snapdragon.c +++ b/arch/arm/mach-ipq40xx/pinctrl-snapdragon.c @@ -14,6 +14,8 @@ #include #include #include +#include +#include #include #include #include "pinctrl-snapdragon.h" @@ -110,6 +112,32 @@ static int msm_pinconf_set(struct udevice *dev, unsigned int pin_selector, return 0; } +static int msm_pinctrl_bind(struct udevice *dev) +{ + ofnode node = dev_ofnode(dev); + const char *name; + int ret; + + ofnode_get_property(node, "gpio-controller", &ret); + if (ret < 0) + return 0; + + /* Get the name of gpio node */ + name = ofnode_get_name(node); + if (!name) + return -EINVAL; + + /* Bind gpio node */ + ret = device_bind_driver_to_node(dev, "gpio_msm", + name, node, NULL); + if (ret) + return ret; + + dev_dbg(dev, "bind %s\n", name); + + return 0; +} + static struct pinctrl_ops msm_pinctrl_ops = { .get_pins_count = msm_get_pins_count, .get_pin_name = msm_get_pin_name, @@ -123,7 +151,7 @@ static struct pinctrl_ops msm_pinctrl_ops = { }; static const struct udevice_id msm_pinctrl_ids[] = { - { .compatible = "qcom,tlmm-ipq4019", .data = (ulong)&ipq4019_data }, + { .compatible = "qcom,ipq4019-pinctrl", .data = (ulong)&ipq4019_data }, { } }; @@ -134,4 +162,5 @@ U_BOOT_DRIVER(pinctrl_snapdraon) = { .priv_auto = sizeof(struct msm_pinctrl_priv), .ops = &msm_pinctrl_ops, .probe = msm_pinctrl_probe, + .bind = msm_pinctrl_bind, }; diff --git a/arch/arm/mach-snapdragon/pinctrl-snapdragon.c b/arch/arm/mach-snapdragon/pinctrl-snapdragon.c index 842e2da0c5..ab884ab6bf 100644 --- a/arch/arm/mach-snapdragon/pinctrl-snapdragon.c +++ b/arch/arm/mach-snapdragon/pinctrl-snapdragon.c @@ -10,6 +10,8 @@ #include #include #include +#include +#include #include #include #include "pinctrl-snapdragon.h" @@ -113,11 +115,37 @@ static struct pinctrl_ops msm_pinctrl_ops = { .get_function_name = msm_get_function_name, }; +static int msm_pinctrl_bind(struct udevice *dev) +{ + ofnode node = dev_ofnode(dev); + const char *name; + int ret; + + ofnode_get_property(node, "gpio-controller", &ret); + if (ret < 0) + return 0; + + /* Get the name of gpio node */ + name = ofnode_get_name(node); + if (!name) + return -EINVAL; + + /* Bind gpio node */ + ret = device_bind_driver_to_node(dev, "gpio_msm", + name, node, NULL); + if (ret) + return ret; + + dev_dbg(dev, "bind %s\n", name); + + return 0; +} + static const struct udevice_id msm_pinctrl_ids[] = { - { .compatible = "qcom,tlmm-apq8016", .data = (ulong)&apq8016_data }, - { .compatible = "qcom,tlmm-apq8096", .data = (ulong)&apq8096_data }, - { .compatible = "qcom,tlmm-sdm845", .data = (ulong)&sdm845_data }, - { .compatible = "qcom,tlmm-qcs404", .data = (ulong)&qcs404_data }, + { .compatible = "qcom,msm8916-pinctrl", .data = (ulong)&apq8016_data }, + { .compatible = "qcom,msm8996-pinctrl", .data = (ulong)&apq8096_data }, + { .compatible = "qcom,sdm845-pinctrl", .data = (ulong)&sdm845_data }, + { .compatible = "qcom,qcs404-pinctrl", .data = (ulong)&qcs404_data }, { } }; @@ -128,4 +156,5 @@ U_BOOT_DRIVER(pinctrl_snapdraon) = { .priv_auto = sizeof(struct msm_pinctrl_priv), .ops = &msm_pinctrl_ops, .probe = msm_pinctrl_probe, + .bind = msm_pinctrl_bind, }; diff --git a/drivers/gpio/msm_gpio.c b/drivers/gpio/msm_gpio.c index a3c3cd7824..51670f2637 100644 --- a/drivers/gpio/msm_gpio.c +++ b/drivers/gpio/msm_gpio.c @@ -116,20 +116,12 @@ static int msm_gpio_of_to_plat(struct udevice *dev) return 0; } -static const struct udevice_id msm_gpio_ids[] = { - { .compatible = "qcom,msm8916-pinctrl" }, - { .compatible = "qcom,apq8016-pinctrl" }, - { .compatible = "qcom,ipq4019-pinctrl" }, - { .compatible = "qcom,sdm845-pinctrl" }, - { } -}; - U_BOOT_DRIVER(gpio_msm) = { .name = "gpio_msm", .id = UCLASS_GPIO, - .of_match = msm_gpio_ids, .of_to_plat = msm_gpio_of_to_plat, .probe = msm_gpio_probe, .ops = &gpio_msm_ops, + .flags = DM_UC_FLAG_SEQ_ALIAS, .priv_auto = sizeof(struct msm_gpio_bank), }; From 59178501386a5355d4342be3fc595ae044c28c47 Mon Sep 17 00:00:00 2001 From: Andrew Davis Date: Mon, 25 Jul 2022 20:25:03 -0500 Subject: [PATCH 025/374] firmware: ti_sci: Reduce output on ti_sci_do_xfer error This ti_sci_do_xfer() function already prints out the reason for the failure, and the caller of each of these functions should also notify the user of the failed task. Remove this extra level of error message. Signed-off-by: Andrew Davis --- drivers/firmware/ti_sci.c | 132 ++++++++++---------------------------- 1 file changed, 34 insertions(+), 98 deletions(-) diff --git a/drivers/firmware/ti_sci.c b/drivers/firmware/ti_sci.c index 0b6ba35b59..85db3f05fd 100644 --- a/drivers/firmware/ti_sci.c +++ b/drivers/firmware/ti_sci.c @@ -287,10 +287,8 @@ static int ti_sci_cmd_get_revision(struct ti_sci_handle *handle) } ret = ti_sci_do_xfer(info, xfer); - if (ret) { - dev_err(info->dev, "Mbox communication fail %d\n", ret); + if (ret) return ret; - } rev_info = (struct ti_sci_msg_resp_version *)xfer->tx_message.buf; @@ -356,10 +354,8 @@ static int cmd_set_board_config_using_msg(const struct ti_sci_handle *handle, req.boardcfg_size = size; ret = ti_sci_do_xfer(info, xfer); - if (ret) { - dev_err(info->dev, "Mbox send fail %d\n", ret); + if (ret) return ret; - } resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf; @@ -516,10 +512,8 @@ static int ti_sci_set_device_state(const struct ti_sci_handle *handle, req.state = state; ret = ti_sci_do_xfer(info, xfer); - if (ret) { - dev_err(info->dev, "Mbox send fail %d\n", ret); + if (ret) return ret; - } resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf; @@ -572,7 +566,7 @@ static int ti_sci_set_device_state_no_wait(const struct ti_sci_handle *handle, ret = ti_sci_do_xfer(info, xfer); if (ret) - dev_err(info->dev, "Mbox send fail %d\n", ret); + return ret; return ret; } @@ -619,10 +613,8 @@ static int ti_sci_get_device_state(const struct ti_sci_handle *handle, req.id = id; ret = ti_sci_do_xfer(info, xfer); - if (ret) { - dev_err(info->dev, "Mbox send fail %d\n", ret); + if (ret) return ret; - } resp = (struct ti_sci_msg_resp_get_device_state *)xfer->tx_message.buf; if (!ti_sci_is_response_ack(resp)) @@ -908,10 +900,8 @@ static int ti_sci_cmd_set_device_resets(const struct ti_sci_handle *handle, req.resets = reset_state; ret = ti_sci_do_xfer(info, xfer); - if (ret) { - dev_err(info->dev, "Mbox send fail %d\n", ret); + if (ret) return ret; - } resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf; @@ -979,10 +969,8 @@ static int ti_sci_set_clock_state(const struct ti_sci_handle *handle, req.request_state = state; ret = ti_sci_do_xfer(info, xfer); - if (ret) { - dev_err(info->dev, "Mbox send fail %d\n", ret); + if (ret) return ret; - } resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf; @@ -1036,10 +1024,8 @@ static int ti_sci_cmd_get_clock_state(const struct ti_sci_handle *handle, req.clk_id = clk_id; ret = ti_sci_do_xfer(info, xfer); - if (ret) { - dev_err(info->dev, "Mbox send fail %d\n", ret); + if (ret) return ret; - } resp = (struct ti_sci_msg_resp_get_clock_state *)xfer->tx_message.buf; @@ -1253,10 +1239,8 @@ static int ti_sci_cmd_clk_set_parent(const struct ti_sci_handle *handle, req.parent_id = parent_id; ret = ti_sci_do_xfer(info, xfer); - if (ret) { - dev_err(info->dev, "Mbox send fail %d\n", ret); + if (ret) return ret; - } resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf; @@ -1305,10 +1289,8 @@ static int ti_sci_cmd_clk_get_parent(const struct ti_sci_handle *handle, req.clk_id = clk_id; ret = ti_sci_do_xfer(info, xfer); - if (ret) { - dev_err(info->dev, "Mbox send fail %d\n", ret); + if (ret) return ret; - } resp = (struct ti_sci_msg_resp_get_clock_parent *)xfer->tx_message.buf; @@ -1360,10 +1342,8 @@ static int ti_sci_cmd_clk_get_num_parents(const struct ti_sci_handle *handle, req.clk_id = clk_id; ret = ti_sci_do_xfer(info, xfer); - if (ret) { - dev_err(info->dev, "Mbox send fail %d\n", ret); + if (ret) return ret; - } resp = (struct ti_sci_msg_resp_get_clock_num_parents *) xfer->tx_message.buf; @@ -1428,10 +1408,8 @@ static int ti_sci_cmd_clk_get_match_freq(const struct ti_sci_handle *handle, req.max_freq_hz = max_freq; ret = ti_sci_do_xfer(info, xfer); - if (ret) { - dev_err(info->dev, "Mbox send fail %d\n", ret); + if (ret) return ret; - } resp = (struct ti_sci_msg_resp_query_clock_freq *)xfer->tx_message.buf; @@ -1493,10 +1471,8 @@ static int ti_sci_cmd_clk_set_freq(const struct ti_sci_handle *handle, req.max_freq_hz = max_freq; ret = ti_sci_do_xfer(info, xfer); - if (ret) { - dev_err(info->dev, "Mbox send fail %d\n", ret); + if (ret) return ret; - } resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf; @@ -1545,10 +1521,8 @@ static int ti_sci_cmd_clk_get_freq(const struct ti_sci_handle *handle, req.clk_id = clk_id; ret = ti_sci_do_xfer(info, xfer); - if (ret) { - dev_err(info->dev, "Mbox send fail %d\n", ret); + if (ret) return ret; - } resp = (struct ti_sci_msg_resp_get_clock_freq *)xfer->tx_message.buf; @@ -1592,10 +1566,8 @@ static int ti_sci_cmd_core_reboot(const struct ti_sci_handle *handle) req.domain = 0; ret = ti_sci_do_xfer(info, xfer); - if (ret) { - dev_err(info->dev, "Mbox send fail %d\n", ret); + if (ret) return ret; - } resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf; @@ -1650,10 +1622,8 @@ static int ti_sci_get_resource_range(const struct ti_sci_handle *handle, req.subtype = subtype & MSG_RM_RESOURCE_SUBTYPE_MASK; ret = ti_sci_do_xfer(info, xfer); - if (ret) { - dev_err(info->dev, "Mbox send fail %d\n", ret); + if (ret) goto fail; - } resp = (struct ti_sci_msg_resp_get_resource_range *)xfer->tx_message.buf; if (!ti_sci_is_response_ack(resp)) { @@ -1774,10 +1744,8 @@ static int ti_sci_cmd_query_msmc(const struct ti_sci_handle *handle, } ret = ti_sci_do_xfer(info, xfer); - if (ret) { - dev_err(info->dev, "Mbox send fail %d\n", ret); + if (ret) return ret; - } resp = (struct ti_sci_msg_resp_query_msmc *)xfer->tx_message.buf; @@ -1826,10 +1794,8 @@ static int ti_sci_cmd_proc_request(const struct ti_sci_handle *handle, req.processor_id = proc_id; ret = ti_sci_do_xfer(info, xfer); - if (ret) { - dev_err(info->dev, "Mbox send fail %d\n", ret); + if (ret) return ret; - } resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf; @@ -1873,10 +1839,8 @@ static int ti_sci_cmd_proc_release(const struct ti_sci_handle *handle, req.processor_id = proc_id; ret = ti_sci_do_xfer(info, xfer); - if (ret) { - dev_err(info->dev, "Mbox send fail %d\n", ret); + if (ret) return ret; - } resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf; @@ -1924,10 +1888,8 @@ static int ti_sci_cmd_proc_handover(const struct ti_sci_handle *handle, req.host_id = host_id; ret = ti_sci_do_xfer(info, xfer); - if (ret) { - dev_err(info->dev, "Mbox send fail %d\n", ret); + if (ret) return ret; - } resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf; @@ -1981,10 +1943,8 @@ static int ti_sci_cmd_set_proc_boot_cfg(const struct ti_sci_handle *handle, req.config_flags_clear = config_flags_clear; ret = ti_sci_do_xfer(info, xfer); - if (ret) { - dev_err(info->dev, "Mbox send fail %d\n", ret); + if (ret) return ret; - } resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf; @@ -2034,10 +1994,8 @@ static int ti_sci_cmd_set_proc_boot_ctrl(const struct ti_sci_handle *handle, req.control_flags_clear = control_flags_clear; ret = ti_sci_do_xfer(info, xfer); - if (ret) { - dev_err(info->dev, "Mbox send fail %d\n", ret); + if (ret) return ret; - } resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf; @@ -2088,10 +2046,8 @@ static int ti_sci_cmd_proc_auth_boot_image(const struct ti_sci_handle *handle, TISCI_ADDR_HIGH_SHIFT; ret = ti_sci_do_xfer(info, xfer); - if (ret) { - dev_err(info->dev, "Mbox send fail %d\n", ret); + if (ret) return ret; - } resp = (struct ti_sci_msg_resp_proc_auth_boot_image *)xfer->tx_message.buf; @@ -2141,10 +2097,8 @@ static int ti_sci_cmd_get_proc_boot_status(const struct ti_sci_handle *handle, req.processor_id = proc_id; ret = ti_sci_do_xfer(info, xfer); - if (ret) { - dev_err(info->dev, "Mbox send fail %d\n", ret); + if (ret) return ret; - } resp = (struct ti_sci_msg_resp_get_proc_boot_status *) xfer->tx_message.buf; @@ -2240,7 +2194,7 @@ ti_sci_proc_wait_boot_status_no_wait(const struct ti_sci_handle *handle, ret = ti_sci_do_xfer(info, xfer); if (ret) - dev_err(info->dev, "Mbox send fail %d\n", ret); + return ret; return ret; } @@ -2354,10 +2308,8 @@ static int ti_sci_cmd_ring_config(const struct ti_sci_handle *handle, req.order_id = order_id; ret = ti_sci_do_xfer(info, xfer); - if (ret) { - dev_err(info->dev, "RM_RA:Mbox config send fail %d\n", ret); + if (ret) goto fail; - } resp = (struct ti_sci_msg_rm_ring_cfg_resp *)xfer->tx_message.buf; @@ -2397,10 +2349,8 @@ static int ti_sci_cmd_rm_psil_pair(const struct ti_sci_handle *handle, req.dst_thread = dst_thread; ret = ti_sci_do_xfer(info, xfer); - if (ret) { - dev_err(info->dev, "RM_PSIL:Mbox send fail %d\n", ret); + if (ret) goto fail; - } resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf; ret = ti_sci_is_response_ack(resp) ? 0 : -ENODEV; @@ -2440,10 +2390,8 @@ static int ti_sci_cmd_rm_psil_unpair(const struct ti_sci_handle *handle, req.dst_thread = dst_thread; ret = ti_sci_do_xfer(info, xfer); - if (ret) { - dev_err(info->dev, "RM_PSIL:Mbox send fail %d\n", ret); + if (ret) goto fail; - } resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf; ret = ti_sci_is_response_ack(resp) ? 0 : -ENODEV; @@ -2501,10 +2449,8 @@ static int ti_sci_cmd_rm_udmap_tx_ch_cfg( req.extended_ch_type = params->extended_ch_type; ret = ti_sci_do_xfer(info, xfer); - if (ret) { - dev_err(info->dev, "Mbox send TX_CH_CFG fail %d\n", ret); + if (ret) goto fail; - } resp = (struct ti_sci_msg_rm_udmap_tx_ch_cfg_resp *)xfer->tx_message.buf; @@ -2559,10 +2505,8 @@ static int ti_sci_cmd_rm_udmap_rx_ch_cfg( req.rx_ignore_long = params->rx_ignore_long; ret = ti_sci_do_xfer(info, xfer); - if (ret) { - dev_err(info->dev, "Mbox send RX_CH_CFG fail %d\n", ret); + if (ret) goto fail; - } resp = (struct ti_sci_msg_rm_udmap_rx_ch_cfg_resp *)xfer->tx_message.buf; @@ -2624,10 +2568,8 @@ static int ti_sci_cmd_rm_udmap_rx_flow_cfg( req.rx_ps_location = params->rx_ps_location; ret = ti_sci_do_xfer(info, xfer); - if (ret) { - dev_err(info->dev, "RX_FL_CFG: Mbox send fail %d\n", ret); + if (ret) goto fail; - } resp = (struct ti_sci_msg_rm_udmap_flow_cfg_resp *)xfer->tx_message.buf; @@ -2681,10 +2623,8 @@ static int ti_sci_cmd_set_fwl_region(const struct ti_sci_handle *handle, req.end_address = region->end_address; ret = ti_sci_do_xfer(info, xfer); - if (ret) { - dev_err(info->dev, "Mbox send fail %d\n", ret); + if (ret) return ret; - } resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf; @@ -2731,10 +2671,8 @@ static int ti_sci_cmd_get_fwl_region(const struct ti_sci_handle *handle, req.n_permission_regs = region->n_permission_regs; ret = ti_sci_do_xfer(info, xfer); - if (ret) { - dev_err(info->dev, "Mbox send fail %d\n", ret); + if (ret) return ret; - } resp = (struct ti_sci_msg_fwl_get_firewall_region_resp *)xfer->tx_message.buf; @@ -2791,10 +2729,8 @@ static int ti_sci_cmd_change_fwl_owner(const struct ti_sci_handle *handle, req.owner_index = owner->owner_index; ret = ti_sci_do_xfer(info, xfer); - if (ret) { - dev_err(info->dev, "Mbox send fail %d\n", ret); + if (ret) return ret; - } resp = (struct ti_sci_msg_fwl_change_owner_info_resp *)xfer->tx_message.buf; From 0d74f2684bc6e0baa8e9fc8af6de1e8f446f3a52 Mon Sep 17 00:00:00 2001 From: Andrew Davis Date: Mon, 25 Jul 2022 20:25:04 -0500 Subject: [PATCH 026/374] firmware: ti_sci: Factor out message alloc failed message We don't need to print the same message in every location, just print it in the function that fails and remove all the extra message printouts. Signed-off-by: Andrew Davis --- drivers/firmware/ti_sci.c | 40 ++++----------------------------------- 1 file changed, 4 insertions(+), 36 deletions(-) diff --git a/drivers/firmware/ti_sci.c b/drivers/firmware/ti_sci.c index 85db3f05fd..687acbf2b4 100644 --- a/drivers/firmware/ti_sci.c +++ b/drivers/firmware/ti_sci.c @@ -134,8 +134,11 @@ static struct ti_sci_xfer *ti_sci_setup_one_xfer(struct ti_sci_info *info, if (rx_message_size > info->desc->max_msg_size || tx_message_size > info->desc->max_msg_size || (rx_message_size > 0 && rx_message_size < sizeof(*hdr)) || - tx_message_size < sizeof(*hdr)) + tx_message_size < sizeof(*hdr)) { + dev_err(info->dev, "TI-SCI message transfer size not sane\n"); return ERR_PTR(-ERANGE); + } + info->seq = ~info->seq; xfer->tx_message.buf = buf; @@ -282,7 +285,6 @@ static int ti_sci_cmd_get_revision(struct ti_sci_handle *handle) sizeof(*rev_info)); if (IS_ERR(xfer)) { ret = PTR_ERR(xfer); - dev_err(info->dev, "Message alloc failed(%d)\n", ret); return ret; } @@ -346,7 +348,6 @@ static int cmd_set_board_config_using_msg(const struct ti_sci_handle *handle, (u32 *)&req, sizeof(req), sizeof(*resp)); if (IS_ERR(xfer)) { ret = PTR_ERR(xfer); - dev_err(info->dev, "Message alloc failed(%d)\n", ret); return ret; } req.boardcfgp_high = (addr >> 32) & 0xffffffff; @@ -505,7 +506,6 @@ static int ti_sci_set_device_state(const struct ti_sci_handle *handle, (u32 *)&req, sizeof(req), sizeof(*resp)); if (IS_ERR(xfer)) { ret = PTR_ERR(xfer); - dev_err(info->dev, "Message alloc failed(%d)\n", ret); return ret; } req.id = id; @@ -558,7 +558,6 @@ static int ti_sci_set_device_state_no_wait(const struct ti_sci_handle *handle, (u32 *)&req, sizeof(req), 0); if (IS_ERR(xfer)) { ret = PTR_ERR(xfer); - dev_err(info->dev, "Message alloc failed(%d)\n", ret); return ret; } req.id = id; @@ -607,7 +606,6 @@ static int ti_sci_get_device_state(const struct ti_sci_handle *handle, (u32 *)&req, sizeof(req), sizeof(*resp)); if (IS_ERR(xfer)) { ret = PTR_ERR(xfer); - dev_err(info->dev, "Message alloc failed(%d)\n", ret); return ret; } req.id = id; @@ -893,7 +891,6 @@ static int ti_sci_cmd_set_device_resets(const struct ti_sci_handle *handle, (u32 *)&req, sizeof(req), sizeof(*resp)); if (IS_ERR(xfer)) { ret = PTR_ERR(xfer); - dev_err(info->dev, "Message alloc failed(%d)\n", ret); return ret; } req.id = id; @@ -961,7 +958,6 @@ static int ti_sci_set_clock_state(const struct ti_sci_handle *handle, (u32 *)&req, sizeof(req), sizeof(*resp)); if (IS_ERR(xfer)) { ret = PTR_ERR(xfer); - dev_err(info->dev, "Message alloc failed(%d)\n", ret); return ret; } req.dev_id = dev_id; @@ -1017,7 +1013,6 @@ static int ti_sci_cmd_get_clock_state(const struct ti_sci_handle *handle, (u32 *)&req, sizeof(req), sizeof(*resp)); if (IS_ERR(xfer)) { ret = PTR_ERR(xfer); - dev_err(info->dev, "Message alloc failed(%d)\n", ret); return ret; } req.dev_id = dev_id; @@ -1231,7 +1226,6 @@ static int ti_sci_cmd_clk_set_parent(const struct ti_sci_handle *handle, (u32 *)&req, sizeof(req), sizeof(*resp)); if (IS_ERR(xfer)) { ret = PTR_ERR(xfer); - dev_err(info->dev, "Message alloc failed(%d)\n", ret); return ret; } req.dev_id = dev_id; @@ -1282,7 +1276,6 @@ static int ti_sci_cmd_clk_get_parent(const struct ti_sci_handle *handle, (u32 *)&req, sizeof(req), sizeof(*resp)); if (IS_ERR(xfer)) { ret = PTR_ERR(xfer); - dev_err(info->dev, "Message alloc failed(%d)\n", ret); return ret; } req.dev_id = dev_id; @@ -1335,7 +1328,6 @@ static int ti_sci_cmd_clk_get_num_parents(const struct ti_sci_handle *handle, (u32 *)&req, sizeof(req), sizeof(*resp)); if (IS_ERR(xfer)) { ret = PTR_ERR(xfer); - dev_err(info->dev, "Message alloc failed(%d)\n", ret); return ret; } req.dev_id = dev_id; @@ -1398,7 +1390,6 @@ static int ti_sci_cmd_clk_get_match_freq(const struct ti_sci_handle *handle, (u32 *)&req, sizeof(req), sizeof(*resp)); if (IS_ERR(xfer)) { ret = PTR_ERR(xfer); - dev_err(info->dev, "Message alloc failed(%d)\n", ret); return ret; } req.dev_id = dev_id; @@ -1461,7 +1452,6 @@ static int ti_sci_cmd_clk_set_freq(const struct ti_sci_handle *handle, (u32 *)&req, sizeof(req), sizeof(*resp)); if (IS_ERR(xfer)) { ret = PTR_ERR(xfer); - dev_err(info->dev, "Message alloc failed(%d)\n", ret); return ret; } req.dev_id = dev_id; @@ -1514,7 +1504,6 @@ static int ti_sci_cmd_clk_get_freq(const struct ti_sci_handle *handle, (u32 *)&req, sizeof(req), sizeof(*resp)); if (IS_ERR(xfer)) { ret = PTR_ERR(xfer); - dev_err(info->dev, "Message alloc failed(%d)\n", ret); return ret; } req.dev_id = dev_id; @@ -1560,7 +1549,6 @@ static int ti_sci_cmd_core_reboot(const struct ti_sci_handle *handle) (u32 *)&req, sizeof(req), sizeof(*resp)); if (IS_ERR(xfer)) { ret = PTR_ERR(xfer); - dev_err(info->dev, "Message alloc failed(%d)\n", ret); return ret; } req.domain = 0; @@ -1613,7 +1601,6 @@ static int ti_sci_get_resource_range(const struct ti_sci_handle *handle, (u32 *)&req, sizeof(req), sizeof(*resp)); if (IS_ERR(xfer)) { ret = PTR_ERR(xfer); - dev_err(info->dev, "Message alloc failed(%d)\n", ret); return ret; } @@ -1739,7 +1726,6 @@ static int ti_sci_cmd_query_msmc(const struct ti_sci_handle *handle, (u32 *)&req, sizeof(req), sizeof(*resp)); if (IS_ERR(xfer)) { ret = PTR_ERR(xfer); - dev_err(info->dev, "Message alloc failed(%d)\n", ret); return ret; } @@ -1788,7 +1774,6 @@ static int ti_sci_cmd_proc_request(const struct ti_sci_handle *handle, (u32 *)&req, sizeof(req), sizeof(*resp)); if (IS_ERR(xfer)) { ret = PTR_ERR(xfer); - dev_err(info->dev, "Message alloc failed(%d)\n", ret); return ret; } req.processor_id = proc_id; @@ -1833,7 +1818,6 @@ static int ti_sci_cmd_proc_release(const struct ti_sci_handle *handle, (u32 *)&req, sizeof(req), sizeof(*resp)); if (IS_ERR(xfer)) { ret = PTR_ERR(xfer); - dev_err(info->dev, "Message alloc failed(%d)\n", ret); return ret; } req.processor_id = proc_id; @@ -1881,7 +1865,6 @@ static int ti_sci_cmd_proc_handover(const struct ti_sci_handle *handle, (u32 *)&req, sizeof(req), sizeof(*resp)); if (IS_ERR(xfer)) { ret = PTR_ERR(xfer); - dev_err(info->dev, "Message alloc failed(%d)\n", ret); return ret; } req.processor_id = proc_id; @@ -1932,7 +1915,6 @@ static int ti_sci_cmd_set_proc_boot_cfg(const struct ti_sci_handle *handle, (u32 *)&req, sizeof(req), sizeof(*resp)); if (IS_ERR(xfer)) { ret = PTR_ERR(xfer); - dev_err(info->dev, "Message alloc failed(%d)\n", ret); return ret; } req.processor_id = proc_id; @@ -1986,7 +1968,6 @@ static int ti_sci_cmd_set_proc_boot_ctrl(const struct ti_sci_handle *handle, (u32 *)&req, sizeof(req), sizeof(*resp)); if (IS_ERR(xfer)) { ret = PTR_ERR(xfer); - dev_err(info->dev, "Message alloc failed(%d)\n", ret); return ret; } req.processor_id = proc_id; @@ -2038,7 +2019,6 @@ static int ti_sci_cmd_proc_auth_boot_image(const struct ti_sci_handle *handle, (u32 *)&req, sizeof(req), sizeof(*resp)); if (IS_ERR(xfer)) { ret = PTR_ERR(xfer); - dev_err(info->dev, "Message alloc failed(%d)\n", ret); return ret; } req.cert_addr_low = *image_addr & TISCI_ADDR_LOW_MASK; @@ -2091,7 +2071,6 @@ static int ti_sci_cmd_get_proc_boot_status(const struct ti_sci_handle *handle, (u32 *)&req, sizeof(req), sizeof(*resp)); if (IS_ERR(xfer)) { ret = PTR_ERR(xfer); - dev_err(info->dev, "Message alloc failed(%d)\n", ret); return ret; } req.processor_id = proc_id; @@ -2179,7 +2158,6 @@ ti_sci_proc_wait_boot_status_no_wait(const struct ti_sci_handle *handle, (u32 *)&req, sizeof(req), 0); if (IS_ERR(xfer)) { ret = PTR_ERR(xfer); - dev_err(info->dev, "Message alloc failed(%d)\n", ret); return ret; } req.processor_id = proc_id; @@ -2294,7 +2272,6 @@ static int ti_sci_cmd_ring_config(const struct ti_sci_handle *handle, (u32 *)&req, sizeof(req), sizeof(*resp)); if (IS_ERR(xfer)) { ret = PTR_ERR(xfer); - dev_err(info->dev, "RM_RA:Message config failed(%d)\n", ret); return ret; } req.valid_params = valid_params; @@ -2341,7 +2318,6 @@ static int ti_sci_cmd_rm_psil_pair(const struct ti_sci_handle *handle, (u32 *)&req, sizeof(req), sizeof(*resp)); if (IS_ERR(xfer)) { ret = PTR_ERR(xfer); - dev_err(info->dev, "RM_PSIL:Message alloc failed(%d)\n", ret); return ret; } req.nav_id = nav_id; @@ -2382,7 +2358,6 @@ static int ti_sci_cmd_rm_psil_unpair(const struct ti_sci_handle *handle, (u32 *)&req, sizeof(req), sizeof(*resp)); if (IS_ERR(xfer)) { ret = PTR_ERR(xfer); - dev_err(info->dev, "RM_PSIL:Message alloc failed(%d)\n", ret); return ret; } req.nav_id = nav_id; @@ -2424,7 +2399,6 @@ static int ti_sci_cmd_rm_udmap_tx_ch_cfg( (u32 *)&req, sizeof(req), sizeof(*resp)); if (IS_ERR(xfer)) { ret = PTR_ERR(xfer); - dev_err(info->dev, "Message TX_CH_CFG alloc failed(%d)\n", ret); return ret; } req.valid_params = params->valid_params; @@ -2483,7 +2457,6 @@ static int ti_sci_cmd_rm_udmap_rx_ch_cfg( (u32 *)&req, sizeof(req), sizeof(*resp)); if (IS_ERR(xfer)) { ret = PTR_ERR(xfer); - dev_err(info->dev, "Message RX_CH_CFG alloc failed(%d)\n", ret); return ret; } @@ -2539,8 +2512,6 @@ static int ti_sci_cmd_rm_udmap_rx_flow_cfg( (u32 *)&req, sizeof(req), sizeof(*resp)); if (IS_ERR(xfer)) { ret = PTR_ERR(xfer); - dev_err(info->dev, "RX_FL_CFG: Message alloc failed(%d)\n", - ret); return ret; } @@ -2608,7 +2579,6 @@ static int ti_sci_cmd_set_fwl_region(const struct ti_sci_handle *handle, (u32 *)&req, sizeof(req), sizeof(*resp)); if (IS_ERR(xfer)) { ret = PTR_ERR(xfer); - dev_err(info->dev, "Message alloc failed(%d)\n", ret); return ret; } @@ -2662,7 +2632,6 @@ static int ti_sci_cmd_get_fwl_region(const struct ti_sci_handle *handle, (u32 *)&req, sizeof(req), sizeof(*resp)); if (IS_ERR(xfer)) { ret = PTR_ERR(xfer); - dev_err(info->dev, "Message alloc failed(%d)\n", ret); return ret; } @@ -2720,7 +2689,6 @@ static int ti_sci_cmd_change_fwl_owner(const struct ti_sci_handle *handle, (u32 *)&req, sizeof(req), sizeof(*resp)); if (IS_ERR(xfer)) { ret = PTR_ERR(xfer); - dev_err(info->dev, "Message alloc failed(%d)\n", ret); return ret; } From f127a58e054b5607803da62e2b80cb4cd4194938 Mon Sep 17 00:00:00 2001 From: Andrew Davis Date: Mon, 25 Jul 2022 20:25:05 -0500 Subject: [PATCH 027/374] firmware: ti_sci: Remove inline keyword from functions The inline hint is not needed here, the compiler will do the right thing based on if we are compiling for speed or for code size. In this case the inline causes this function to be placed inside each callsite which is not the right thing to do for either speed nor size. There is no performance benefit to this due to the larger function size reducing cache locality, but there is a huge size penalty. Remove inline keyword. Signed-off-by: Andrew Davis --- drivers/firmware/ti_sci.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/firmware/ti_sci.c b/drivers/firmware/ti_sci.c index 687acbf2b4..facc0709ae 100644 --- a/drivers/firmware/ti_sci.c +++ b/drivers/firmware/ti_sci.c @@ -164,7 +164,7 @@ static struct ti_sci_xfer *ti_sci_setup_one_xfer(struct ti_sci_info *info, * return corresponding error, else if all goes well, * return 0. */ -static inline int ti_sci_get_response(struct ti_sci_info *info, +static int ti_sci_get_response(struct ti_sci_info *info, struct ti_sci_xfer *xfer, struct mbox_chan *chan) { @@ -218,7 +218,7 @@ static inline int ti_sci_get_response(struct ti_sci_info *info, * * Return: 0 if all went fine, else return appropriate error. */ -static inline int ti_sci_do_xfer(struct ti_sci_info *info, +static int ti_sci_do_xfer(struct ti_sci_info *info, struct ti_sci_xfer *xfer) { struct k3_sec_proxy_msg *msg = &xfer->tx_message; @@ -310,7 +310,7 @@ static int ti_sci_cmd_get_revision(struct ti_sci_handle *handle) * * Return: true if the response was an ACK, else returns false. */ -static inline bool ti_sci_is_response_ack(void *r) +static bool ti_sci_is_response_ack(void *r) { struct ti_sci_msg_hdr *hdr = r; From 96e036a4e592dc2c353b90aa70a6c4690867a301 Mon Sep 17 00:00:00 2001 From: Andrew Davis Date: Mon, 25 Jul 2022 20:25:06 -0500 Subject: [PATCH 028/374] firmware: ti_sci: Move ACK checking to ti_sci_do_xfer() function We can check if the message was acknowledged in the common ti_sci_do_xfer() which lets us remove it from after each call to this function. This simplifies the code and reduces binary size. Signed-off-by: Andrew Davis --- drivers/firmware/ti_sci.c | 165 ++++++-------------------------------- 1 file changed, 24 insertions(+), 141 deletions(-) diff --git a/drivers/firmware/ti_sci.c b/drivers/firmware/ti_sci.c index facc0709ae..727e090e8a 100644 --- a/drivers/firmware/ti_sci.c +++ b/drivers/firmware/ti_sci.c @@ -211,6 +211,19 @@ static int ti_sci_get_response(struct ti_sci_info *info, return ret; } +/** + * ti_sci_is_response_ack() - Generic ACK/NACK message checkup + * @r: pointer to response buffer + * + * Return: true if the response was an ACK, else returns false. + */ +static bool ti_sci_is_response_ack(void *r) +{ + struct ti_sci_msg_hdr *hdr = r; + + return hdr->flags & TI_SCI_FLAG_RESP_GENERIC_ACK ? true : false; +} + /** * ti_sci_do_xfer() - Do one transfer * @info: Pointer to SCI entity information @@ -249,8 +262,13 @@ static int ti_sci_do_xfer(struct ti_sci_info *info, } /* Get response if requested */ - if (xfer->rx_len) + if (xfer->rx_len) { ret = ti_sci_get_response(info, xfer, &info->chan_rx); + if (!ti_sci_is_response_ack(xfer->tx_message.buf)) { + dev_err(info->dev, "Message not acknowledged"); + ret = -ENODEV; + } + } return ret; } @@ -304,19 +322,6 @@ static int ti_sci_cmd_get_revision(struct ti_sci_handle *handle) return 0; } -/** - * ti_sci_is_response_ack() - Generic ACK/NACK message checkup - * @r: pointer to response buffer - * - * Return: true if the response was an ACK, else returns false. - */ -static bool ti_sci_is_response_ack(void *r) -{ - struct ti_sci_msg_hdr *hdr = r; - - return hdr->flags & TI_SCI_FLAG_RESP_GENERIC_ACK ? true : false; -} - /** * cmd_set_board_config_using_msg() - Common command to send board configuration * message @@ -358,11 +363,6 @@ static int cmd_set_board_config_using_msg(const struct ti_sci_handle *handle, if (ret) return ret; - resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf; - - if (!ti_sci_is_response_ack(resp)) - return -ENODEV; - return ret; } @@ -515,11 +515,6 @@ static int ti_sci_set_device_state(const struct ti_sci_handle *handle, if (ret) return ret; - resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf; - - if (!ti_sci_is_response_ack(resp)) - return -ENODEV; - if (state == MSG_DEVICE_SW_STATE_AUTO_OFF) ti_sci_delete_exclusive_dev(info, id); else if (flags & MSG_FLAG_DEVICE_EXCLUSIVE) @@ -615,8 +610,6 @@ static int ti_sci_get_device_state(const struct ti_sci_handle *handle, return ret; resp = (struct ti_sci_msg_resp_get_device_state *)xfer->tx_message.buf; - if (!ti_sci_is_response_ack(resp)) - return -ENODEV; if (clcnt) *clcnt = resp->context_loss_count; @@ -900,11 +893,6 @@ static int ti_sci_cmd_set_device_resets(const struct ti_sci_handle *handle, if (ret) return ret; - resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf; - - if (!ti_sci_is_response_ack(resp)) - return -ENODEV; - return ret; } @@ -968,11 +956,6 @@ static int ti_sci_set_clock_state(const struct ti_sci_handle *handle, if (ret) return ret; - resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf; - - if (!ti_sci_is_response_ack(resp)) - return -ENODEV; - return ret; } @@ -1024,9 +1007,6 @@ static int ti_sci_cmd_get_clock_state(const struct ti_sci_handle *handle, resp = (struct ti_sci_msg_resp_get_clock_state *)xfer->tx_message.buf; - if (!ti_sci_is_response_ack(resp)) - return -ENODEV; - if (programmed_state) *programmed_state = resp->programmed_state; if (current_state) @@ -1236,11 +1216,6 @@ static int ti_sci_cmd_clk_set_parent(const struct ti_sci_handle *handle, if (ret) return ret; - resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf; - - if (!ti_sci_is_response_ack(resp)) - return -ENODEV; - return ret; } @@ -1285,12 +1260,7 @@ static int ti_sci_cmd_clk_get_parent(const struct ti_sci_handle *handle, if (ret) return ret; - resp = (struct ti_sci_msg_resp_get_clock_parent *)xfer->tx_message.buf; - - if (!ti_sci_is_response_ack(resp)) - ret = -ENODEV; - else - *parent_id = resp->parent_id; + *parent_id = resp->parent_id; return ret; } @@ -1340,10 +1310,7 @@ static int ti_sci_cmd_clk_get_num_parents(const struct ti_sci_handle *handle, resp = (struct ti_sci_msg_resp_get_clock_num_parents *) xfer->tx_message.buf; - if (!ti_sci_is_response_ack(resp)) - ret = -ENODEV; - else - *num_parents = resp->num_parents; + *num_parents = resp->num_parents; return ret; } @@ -1404,10 +1371,7 @@ static int ti_sci_cmd_clk_get_match_freq(const struct ti_sci_handle *handle, resp = (struct ti_sci_msg_resp_query_clock_freq *)xfer->tx_message.buf; - if (!ti_sci_is_response_ack(resp)) - ret = -ENODEV; - else - *match_freq = resp->freq_hz; + *match_freq = resp->freq_hz; return ret; } @@ -1464,11 +1428,6 @@ static int ti_sci_cmd_clk_set_freq(const struct ti_sci_handle *handle, if (ret) return ret; - resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf; - - if (!ti_sci_is_response_ack(resp)) - return -ENODEV; - return ret; } @@ -1515,10 +1474,7 @@ static int ti_sci_cmd_clk_get_freq(const struct ti_sci_handle *handle, resp = (struct ti_sci_msg_resp_get_clock_freq *)xfer->tx_message.buf; - if (!ti_sci_is_response_ack(resp)) - ret = -ENODEV; - else - *freq = resp->freq_hz; + *freq = resp->freq_hz; return ret; } @@ -1557,11 +1513,6 @@ static int ti_sci_cmd_core_reboot(const struct ti_sci_handle *handle) if (ret) return ret; - resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf; - - if (!ti_sci_is_response_ack(resp)) - return -ENODEV; - return ret; } @@ -1613,9 +1564,7 @@ static int ti_sci_get_resource_range(const struct ti_sci_handle *handle, goto fail; resp = (struct ti_sci_msg_resp_get_resource_range *)xfer->tx_message.buf; - if (!ti_sci_is_response_ack(resp)) { - ret = -ENODEV; - } else if (!resp->range_start && !resp->range_num) { + if (!resp->range_start && !resp->range_num) { ret = -ENODEV; } else { *range_start = resp->range_start; @@ -1735,9 +1684,6 @@ static int ti_sci_cmd_query_msmc(const struct ti_sci_handle *handle, resp = (struct ti_sci_msg_resp_query_msmc *)xfer->tx_message.buf; - if (!ti_sci_is_response_ack(resp)) - return -ENODEV; - *msmc_start = ((u64)resp->msmc_start_high << TISCI_ADDR_HIGH_SHIFT) | resp->msmc_start_low; *msmc_end = ((u64)resp->msmc_end_high << TISCI_ADDR_HIGH_SHIFT) | @@ -1782,11 +1728,6 @@ static int ti_sci_cmd_proc_request(const struct ti_sci_handle *handle, if (ret) return ret; - resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf; - - if (!ti_sci_is_response_ack(resp)) - ret = -ENODEV; - return ret; } @@ -1826,11 +1767,6 @@ static int ti_sci_cmd_proc_release(const struct ti_sci_handle *handle, if (ret) return ret; - resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf; - - if (!ti_sci_is_response_ack(resp)) - ret = -ENODEV; - return ret; } @@ -1874,11 +1810,6 @@ static int ti_sci_cmd_proc_handover(const struct ti_sci_handle *handle, if (ret) return ret; - resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf; - - if (!ti_sci_is_response_ack(resp)) - ret = -ENODEV; - return ret; } @@ -1928,11 +1859,6 @@ static int ti_sci_cmd_set_proc_boot_cfg(const struct ti_sci_handle *handle, if (ret) return ret; - resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf; - - if (!ti_sci_is_response_ack(resp)) - ret = -ENODEV; - return ret; } @@ -1978,11 +1904,6 @@ static int ti_sci_cmd_set_proc_boot_ctrl(const struct ti_sci_handle *handle, if (ret) return ret; - resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf; - - if (!ti_sci_is_response_ack(resp)) - ret = -ENODEV; - return ret; } @@ -2031,9 +1952,6 @@ static int ti_sci_cmd_proc_auth_boot_image(const struct ti_sci_handle *handle, resp = (struct ti_sci_msg_resp_proc_auth_boot_image *)xfer->tx_message.buf; - if (!ti_sci_is_response_ack(resp)) - return -ENODEV; - *image_addr = (resp->image_addr_low & TISCI_ADDR_LOW_MASK) | (((u64)resp->image_addr_high << TISCI_ADDR_HIGH_SHIFT) & TISCI_ADDR_HIGH_MASK); @@ -2082,8 +2000,6 @@ static int ti_sci_cmd_get_proc_boot_status(const struct ti_sci_handle *handle, resp = (struct ti_sci_msg_resp_get_proc_boot_status *) xfer->tx_message.buf; - if (!ti_sci_is_response_ack(resp)) - return -ENODEV; *bv = (resp->bootvector_low & TISCI_ADDR_LOW_MASK) | (((u64)resp->bootvector_high << TISCI_ADDR_HIGH_SHIFT) & TISCI_ADDR_HIGH_MASK); @@ -2288,10 +2204,6 @@ static int ti_sci_cmd_ring_config(const struct ti_sci_handle *handle, if (ret) goto fail; - resp = (struct ti_sci_msg_rm_ring_cfg_resp *)xfer->tx_message.buf; - - ret = ti_sci_is_response_ack(resp) ? 0 : -ENODEV; - fail: dev_dbg(info->dev, "RM_RA:config ring %u ret:%d\n", index, ret); return ret; @@ -2328,9 +2240,6 @@ static int ti_sci_cmd_rm_psil_pair(const struct ti_sci_handle *handle, if (ret) goto fail; - resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf; - ret = ti_sci_is_response_ack(resp) ? 0 : -ENODEV; - fail: dev_dbg(info->dev, "RM_PSIL: nav: %u link pair %u->%u ret:%u\n", nav_id, src_thread, dst_thread, ret); @@ -2368,9 +2277,6 @@ static int ti_sci_cmd_rm_psil_unpair(const struct ti_sci_handle *handle, if (ret) goto fail; - resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf; - ret = ti_sci_is_response_ack(resp) ? 0 : -ENODEV; - fail: dev_dbg(info->dev, "RM_PSIL: link unpair %u->%u ret:%u\n", src_thread, dst_thread, ret); @@ -2426,10 +2332,6 @@ static int ti_sci_cmd_rm_udmap_tx_ch_cfg( if (ret) goto fail; - resp = - (struct ti_sci_msg_rm_udmap_tx_ch_cfg_resp *)xfer->tx_message.buf; - ret = ti_sci_is_response_ack(resp) ? 0 : -EINVAL; - fail: dev_dbg(info->dev, "TX_CH_CFG: chn %u ret:%u\n", params->index, ret); return ret; @@ -2481,10 +2383,6 @@ static int ti_sci_cmd_rm_udmap_rx_ch_cfg( if (ret) goto fail; - resp = - (struct ti_sci_msg_rm_udmap_rx_ch_cfg_resp *)xfer->tx_message.buf; - ret = ti_sci_is_response_ack(resp) ? 0 : -EINVAL; - fail: dev_dbg(info->dev, "RX_CH_CFG: chn %u ret:%d\n", params->index, ret); return ret; @@ -2542,10 +2440,6 @@ static int ti_sci_cmd_rm_udmap_rx_flow_cfg( if (ret) goto fail; - resp = - (struct ti_sci_msg_rm_udmap_flow_cfg_resp *)xfer->tx_message.buf; - ret = ti_sci_is_response_ack(resp) ? 0 : -EINVAL; - fail: dev_dbg(info->dev, "RX_FL_CFG: %u ret:%d\n", params->flow_index, ret); return ret; @@ -2596,11 +2490,6 @@ static int ti_sci_cmd_set_fwl_region(const struct ti_sci_handle *handle, if (ret) return ret; - resp = (struct ti_sci_msg_hdr *)xfer->tx_message.buf; - - if (!ti_sci_is_response_ack(resp)) - return -ENODEV; - return 0; } @@ -2645,9 +2534,6 @@ static int ti_sci_cmd_get_fwl_region(const struct ti_sci_handle *handle, resp = (struct ti_sci_msg_fwl_get_firewall_region_resp *)xfer->tx_message.buf; - if (!ti_sci_is_response_ack(resp)) - return -ENODEV; - region->fwl_id = resp->fwl_id; region->region = resp->region; region->n_permission_regs = resp->n_permission_regs; @@ -2702,9 +2588,6 @@ static int ti_sci_cmd_change_fwl_owner(const struct ti_sci_handle *handle, resp = (struct ti_sci_msg_fwl_change_owner_info_resp *)xfer->tx_message.buf; - if (!ti_sci_is_response_ack(resp)) - return -ENODEV; - owner->fwl_id = resp->fwl_id; owner->region = resp->region; owner->owner_index = resp->owner_index; From adf13bcc403dbd0cb645fe1080d8812d9de5f01f Mon Sep 17 00:00:00 2001 From: Tom Rini Date: Wed, 10 Aug 2022 10:29:27 -0400 Subject: [PATCH 029/374] Convert CONFIG_SYS_I2C_EEPROM_CCID et al to Kconfig This converts the following to Kconfig: CONFIG_SYS_I2C_EEPROM_CCID CONFIG_SYS_I2C_EEPROM_NXID CONFIG_SYS_EEPROM_BUS_NUM Signed-off-by: Tom Rini --- common/Kconfig | 21 +++++++++++++++++++ configs/MPC8548CDS_36BIT_defconfig | 1 + configs/MPC8548CDS_defconfig | 1 + configs/MPC8548CDS_legacy_defconfig | 1 + configs/ls1021atwr_nor_SECURE_BOOT_defconfig | 1 + configs/ls1021atwr_nor_defconfig | 1 + configs/ls1021atwr_nor_lpuart_defconfig | 1 + configs/ls1021atwr_qspi_defconfig | 1 + ...s1021atwr_sdcard_ifc_SECURE_BOOT_defconfig | 1 + configs/ls1021atwr_sdcard_ifc_defconfig | 1 + configs/ls1021atwr_sdcard_qspi_defconfig | 1 + include/configs/MPC8548CDS.h | 3 --- include/configs/P1010RDB.h | 4 ---- include/configs/P2041RDB.h | 4 ---- include/configs/T102xRDB.h | 4 ---- include/configs/T208xQDS.h | 4 ---- include/configs/T208xRDB.h | 4 ---- include/configs/corenet_ds.h | 4 ---- include/configs/ls1012aqds.h | 4 ---- include/configs/ls1021aiot.h | 4 ---- include/configs/ls1021aqds.h | 4 ---- include/configs/ls1021atsn.h | 4 ---- include/configs/ls1021atwr.h | 4 ---- include/configs/ls1028a_common.h | 4 ---- include/configs/ls1043aqds.h | 4 ---- include/configs/ls1043ardb.h | 6 ------ include/configs/ls1046afrwy.h | 2 -- include/configs/ls1046aqds.h | 4 ---- include/configs/ls1046ardb.h | 2 -- include/configs/ls1088aqds.h | 4 ---- include/configs/ls1088ardb.h | 4 ---- include/configs/ls2080aqds.h | 4 ---- include/configs/ls2080ardb.h | 4 ---- include/configs/lx2160a_common.h | 4 ---- include/configs/lx2160aqds.h | 4 ---- include/configs/lx2160ardb.h | 4 ---- include/configs/lx2162aqds.h | 4 ---- include/configs/sifive-unmatched.h | 2 -- 38 files changed, 31 insertions(+), 103 deletions(-) diff --git a/common/Kconfig b/common/Kconfig index e7914ca750..2c3f7f4274 100644 --- a/common/Kconfig +++ b/common/Kconfig @@ -671,6 +671,27 @@ config ID_EEPROM A number of different systems and vendors enable a vendor-specified EEPROM that contains various identifying features. +config SYS_EEPROM_BUS_NUM + int "I2C bus number of the system identifier EEPROM" + depends on ID_EEPROM + default 0 + +choice + prompt "EEPROM starts with 'CCID' or 'NXID'" + depends on ID_EEPROM && (PPC || ARCH_LS1021A || FSL_LAYERSCAPE) + default SYS_I2C_EEPROM_NXID + help + Specify if the Freescale / NXP ID EEPROM starts with 'CCID' or 'NXID' + ASCII literal string. + +config SYS_I2C_EEPROM_CCID + bool "EEPROM starts with 'CCID'" + +config SYS_I2C_EEPROM_NXID + bool "EEPROM starts with 'NXID'" + +endchoice + config PCI_INIT_R bool "Enumerate PCI buses during init" depends on PCI diff --git a/configs/MPC8548CDS_36BIT_defconfig b/configs/MPC8548CDS_36BIT_defconfig index def5d6fdf4..feb0be5a49 100644 --- a/configs/MPC8548CDS_36BIT_defconfig +++ b/configs/MPC8548CDS_36BIT_defconfig @@ -21,6 +21,7 @@ CONFIG_USE_BOOTCOMMAND=y CONFIG_BOOTCOMMAND="setenv bootargs root=/dev/nfs rw nfsroot=$serverip:$rootpath ip=$ipaddr:$serverip:$gatewayip:$netmask:$hostname:$netdev:off console=$consoledev,$baudrate $othbootargs;tftp $loadaddr $bootfile;tftp $fdtaddr $fdtfile;bootm $loadaddr - $fdtaddr" # CONFIG_MISC_INIT_R is not set CONFIG_ID_EEPROM=y +CONFIG_SYS_I2C_EEPROM_CCID=y CONFIG_HUSH_PARSER=y CONFIG_SYS_PBSIZE=276 CONFIG_CMD_IMLS=y diff --git a/configs/MPC8548CDS_defconfig b/configs/MPC8548CDS_defconfig index 881fca912b..945347941b 100644 --- a/configs/MPC8548CDS_defconfig +++ b/configs/MPC8548CDS_defconfig @@ -20,6 +20,7 @@ CONFIG_USE_BOOTCOMMAND=y CONFIG_BOOTCOMMAND="setenv bootargs root=/dev/nfs rw nfsroot=$serverip:$rootpath ip=$ipaddr:$serverip:$gatewayip:$netmask:$hostname:$netdev:off console=$consoledev,$baudrate $othbootargs;tftp $loadaddr $bootfile;tftp $fdtaddr $fdtfile;bootm $loadaddr - $fdtaddr" # CONFIG_MISC_INIT_R is not set CONFIG_ID_EEPROM=y +CONFIG_SYS_I2C_EEPROM_CCID=y CONFIG_HUSH_PARSER=y CONFIG_SYS_PBSIZE=276 CONFIG_CMD_IMLS=y diff --git a/configs/MPC8548CDS_legacy_defconfig b/configs/MPC8548CDS_legacy_defconfig index 99a63300af..f069451697 100644 --- a/configs/MPC8548CDS_legacy_defconfig +++ b/configs/MPC8548CDS_legacy_defconfig @@ -21,6 +21,7 @@ CONFIG_USE_BOOTCOMMAND=y CONFIG_BOOTCOMMAND="setenv bootargs root=/dev/nfs rw nfsroot=$serverip:$rootpath ip=$ipaddr:$serverip:$gatewayip:$netmask:$hostname:$netdev:off console=$consoledev,$baudrate $othbootargs;tftp $loadaddr $bootfile;tftp $fdtaddr $fdtfile;bootm $loadaddr - $fdtaddr" # CONFIG_MISC_INIT_R is not set CONFIG_ID_EEPROM=y +CONFIG_SYS_I2C_EEPROM_CCID=y CONFIG_HUSH_PARSER=y CONFIG_SYS_PBSIZE=276 CONFIG_CMD_IMLS=y diff --git a/configs/ls1021atwr_nor_SECURE_BOOT_defconfig b/configs/ls1021atwr_nor_SECURE_BOOT_defconfig index e385ea47aa..f66aacc991 100644 --- a/configs/ls1021atwr_nor_SECURE_BOOT_defconfig +++ b/configs/ls1021atwr_nor_SECURE_BOOT_defconfig @@ -33,6 +33,7 @@ CONFIG_SILENT_CONSOLE=y CONFIG_SYS_CONSOLE_IS_IN_ENV=y CONFIG_MISC_INIT_R=y CONFIG_ID_EEPROM=y +CONFIG_SYS_EEPROM_BUS_NUM=1 CONFIG_SYS_CBSIZE=256 CONFIG_SYS_PBSIZE=276 CONFIG_SYS_BOOTM_LEN=0x4000000 diff --git a/configs/ls1021atwr_nor_defconfig b/configs/ls1021atwr_nor_defconfig index 1d4e57c6ed..110cf5d3d2 100644 --- a/configs/ls1021atwr_nor_defconfig +++ b/configs/ls1021atwr_nor_defconfig @@ -34,6 +34,7 @@ CONFIG_SYS_CONSOLE_IS_IN_ENV=y CONFIG_ARCH_MISC_INIT=y CONFIG_MISC_INIT_R=y CONFIG_ID_EEPROM=y +CONFIG_SYS_EEPROM_BUS_NUM=1 CONFIG_SYS_CBSIZE=256 CONFIG_SYS_PBSIZE=276 CONFIG_SYS_BOOTM_LEN=0x4000000 diff --git a/configs/ls1021atwr_nor_lpuart_defconfig b/configs/ls1021atwr_nor_lpuart_defconfig index 391f46459f..9d8dbbf043 100644 --- a/configs/ls1021atwr_nor_lpuart_defconfig +++ b/configs/ls1021atwr_nor_lpuart_defconfig @@ -34,6 +34,7 @@ CONFIG_SYS_CONSOLE_IS_IN_ENV=y CONFIG_ARCH_MISC_INIT=y CONFIG_MISC_INIT_R=y CONFIG_ID_EEPROM=y +CONFIG_SYS_EEPROM_BUS_NUM=1 CONFIG_SYS_CBSIZE=256 CONFIG_SYS_PBSIZE=276 CONFIG_SYS_BOOTM_LEN=0x4000000 diff --git a/configs/ls1021atwr_qspi_defconfig b/configs/ls1021atwr_qspi_defconfig index 3b37641c6a..039c9842e9 100644 --- a/configs/ls1021atwr_qspi_defconfig +++ b/configs/ls1021atwr_qspi_defconfig @@ -35,6 +35,7 @@ CONFIG_SYS_CONSOLE_IS_IN_ENV=y CONFIG_ARCH_MISC_INIT=y CONFIG_MISC_INIT_R=y CONFIG_ID_EEPROM=y +CONFIG_SYS_EEPROM_BUS_NUM=1 CONFIG_SYS_CBSIZE=256 CONFIG_SYS_PBSIZE=276 CONFIG_SYS_BOOTM_LEN=0x4000000 diff --git a/configs/ls1021atwr_sdcard_ifc_SECURE_BOOT_defconfig b/configs/ls1021atwr_sdcard_ifc_SECURE_BOOT_defconfig index 38c074d158..a916959d57 100644 --- a/configs/ls1021atwr_sdcard_ifc_SECURE_BOOT_defconfig +++ b/configs/ls1021atwr_sdcard_ifc_SECURE_BOOT_defconfig @@ -43,6 +43,7 @@ CONFIG_SILENT_CONSOLE=y CONFIG_SYS_CONSOLE_IS_IN_ENV=y CONFIG_MISC_INIT_R=y CONFIG_ID_EEPROM=y +CONFIG_SYS_EEPROM_BUS_NUM=1 CONFIG_SPL_MAX_SIZE=0x1a000 CONFIG_SPL_PAD_TO=0x1c000 CONFIG_SPL_HAS_BSS_LINKER_SECTION=y diff --git a/configs/ls1021atwr_sdcard_ifc_defconfig b/configs/ls1021atwr_sdcard_ifc_defconfig index 3dd0871213..65f033aed9 100644 --- a/configs/ls1021atwr_sdcard_ifc_defconfig +++ b/configs/ls1021atwr_sdcard_ifc_defconfig @@ -44,6 +44,7 @@ CONFIG_SYS_CONSOLE_IS_IN_ENV=y CONFIG_ARCH_MISC_INIT=y CONFIG_MISC_INIT_R=y CONFIG_ID_EEPROM=y +CONFIG_SYS_EEPROM_BUS_NUM=1 CONFIG_SPL_MAX_SIZE=0x1a000 CONFIG_SPL_PAD_TO=0x1c000 CONFIG_SPL_HAS_BSS_LINKER_SECTION=y diff --git a/configs/ls1021atwr_sdcard_qspi_defconfig b/configs/ls1021atwr_sdcard_qspi_defconfig index 84722b01e8..45c9179727 100644 --- a/configs/ls1021atwr_sdcard_qspi_defconfig +++ b/configs/ls1021atwr_sdcard_qspi_defconfig @@ -45,6 +45,7 @@ CONFIG_SYS_CONSOLE_IS_IN_ENV=y CONFIG_ARCH_MISC_INIT=y CONFIG_MISC_INIT_R=y CONFIG_ID_EEPROM=y +CONFIG_SYS_EEPROM_BUS_NUM=1 CONFIG_SPL_MAX_SIZE=0x1a000 CONFIG_SPL_PAD_TO=0x1c000 CONFIG_SPL_HAS_BSS_LINKER_SECTION=y diff --git a/include/configs/MPC8548CDS.h b/include/configs/MPC8548CDS.h index 0c710ef886..eb7a835179 100644 --- a/include/configs/MPC8548CDS.h +++ b/include/configs/MPC8548CDS.h @@ -255,9 +255,6 @@ #define CONFIG_SYS_I2C_NOPROBES { {0, 0x69} } #endif -/* EEPROM */ -#define CONFIG_SYS_I2C_EEPROM_CCID - /* * General PCI * Memory space is mapped 1-1, but I/O space must start from 0. diff --git a/include/configs/P1010RDB.h b/include/configs/P1010RDB.h index 7f5eaf88aa..8492a64d43 100644 --- a/include/configs/P1010RDB.h +++ b/include/configs/P1010RDB.h @@ -351,10 +351,6 @@ extern unsigned long get_sdram_size(void); /* I2C EEPROM */ #if defined(CONFIG_TARGET_P1010RDB_PB) -#ifdef CONFIG_ID_EEPROM -#define CONFIG_SYS_I2C_EEPROM_NXID -#endif -#define CONFIG_SYS_EEPROM_BUS_NUM 0 #define MAX_NUM_PORTS 9 /* for 128Bytes EEPROM */ #endif /* enable read and write access to EEPROM */ diff --git a/include/configs/P2041RDB.h b/include/configs/P2041RDB.h index 11a3db5902..925720d234 100644 --- a/include/configs/P2041RDB.h +++ b/include/configs/P2041RDB.h @@ -67,10 +67,6 @@ #define CONFIG_SYS_DCSRBAR_PHYS 0xf00000000ull #endif -/* EEPROM */ -#define CONFIG_SYS_I2C_EEPROM_NXID -#define CONFIG_SYS_EEPROM_BUS_NUM 0 - /* * DDR Setup */ diff --git a/include/configs/T102xRDB.h b/include/configs/T102xRDB.h index a5461d7fc6..e0aa2b9598 100644 --- a/include/configs/T102xRDB.h +++ b/include/configs/T102xRDB.h @@ -112,10 +112,6 @@ #define CONFIG_SYS_DCSRBAR_PHYS 0xf00000000ull #endif -/* EEPROM */ -#define CONFIG_SYS_I2C_EEPROM_NXID -#define CONFIG_SYS_EEPROM_BUS_NUM 0 - /* * DDR Setup */ diff --git a/include/configs/T208xQDS.h b/include/configs/T208xQDS.h index fc068c94a9..e852fc4cdc 100644 --- a/include/configs/T208xQDS.h +++ b/include/configs/T208xQDS.h @@ -82,10 +82,6 @@ #define CONFIG_SYS_DCSRBAR 0xf0000000 #define CONFIG_SYS_DCSRBAR_PHYS 0xf00000000ull -/* EEPROM */ -#define CONFIG_SYS_I2C_EEPROM_NXID -#define CONFIG_SYS_EEPROM_BUS_NUM 0 - /* * DDR Setup */ diff --git a/include/configs/T208xRDB.h b/include/configs/T208xRDB.h index 056e2d1925..68cf13581a 100644 --- a/include/configs/T208xRDB.h +++ b/include/configs/T208xRDB.h @@ -77,10 +77,6 @@ #define CONFIG_SYS_DCSRBAR 0xf0000000 #define CONFIG_SYS_DCSRBAR_PHYS 0xf00000000ull -/* EEPROM */ -#define CONFIG_SYS_I2C_EEPROM_NXID -#define CONFIG_SYS_EEPROM_BUS_NUM 0 - /* * DDR Setup */ diff --git a/include/configs/corenet_ds.h b/include/configs/corenet_ds.h index 7e65b2b6aa..6ee5ec0962 100644 --- a/include/configs/corenet_ds.h +++ b/include/configs/corenet_ds.h @@ -62,10 +62,6 @@ #define CONFIG_SYS_DCSRBAR_PHYS 0xf00000000ull #endif -/* EEPROM */ -#define CONFIG_SYS_I2C_EEPROM_NXID -#define CONFIG_SYS_EEPROM_BUS_NUM 0 - /* * DDR Setup */ diff --git a/include/configs/ls1012aqds.h b/include/configs/ls1012aqds.h index 48fe8288aa..9ad3a12011 100644 --- a/include/configs/ls1012aqds.h +++ b/include/configs/ls1012aqds.h @@ -49,10 +49,6 @@ #define RTC #define CONFIG_SYS_I2C_RTC_ADDR 0x51 /* Channel 3*/ -/* EEPROM */ -#define CONFIG_SYS_I2C_EEPROM_NXID -#define CONFIG_SYS_EEPROM_BUS_NUM 0 - /* Voltage monitor on channel 2*/ #define I2C_VOL_MONITOR_ADDR 0x40 diff --git a/include/configs/ls1021aiot.h b/include/configs/ls1021aiot.h index ec688741a0..f418c8ccf7 100644 --- a/include/configs/ls1021aiot.h +++ b/include/configs/ls1021aiot.h @@ -59,10 +59,6 @@ * I2C */ -/* EEPROM */ -#define CONFIG_SYS_I2C_EEPROM_NXID -#define CONFIG_SYS_EEPROM_BUS_NUM 0 - /* * MMC */ diff --git a/include/configs/ls1021aqds.h b/include/configs/ls1021aqds.h index aaf28a346d..d383b6c655 100644 --- a/include/configs/ls1021aqds.h +++ b/include/configs/ls1021aqds.h @@ -246,10 +246,6 @@ /* GPIO */ -/* EEPROM */ -#define CONFIG_SYS_I2C_EEPROM_NXID -#define CONFIG_SYS_EEPROM_BUS_NUM 0 - /* * I2C bus multiplexer */ diff --git a/include/configs/ls1021atsn.h b/include/configs/ls1021atsn.h index f318eb5860..157f218a8e 100644 --- a/include/configs/ls1021atsn.h +++ b/include/configs/ls1021atsn.h @@ -71,10 +71,6 @@ /* I2C */ -/* EEPROM */ -#define CONFIG_SYS_I2C_EEPROM_NXID -#define CONFIG_SYS_EEPROM_BUS_NUM 0 - /* PCIe */ #define FSL_PCIE_COMPAT "fsl,ls1021a-pcie" diff --git a/include/configs/ls1021atwr.h b/include/configs/ls1021atwr.h index 5f3e8d5b71..83c74b66d3 100644 --- a/include/configs/ls1021atwr.h +++ b/include/configs/ls1021atwr.h @@ -161,10 +161,6 @@ /* GPIO */ -/* EEPROM */ -#define CONFIG_SYS_I2C_EEPROM_NXID -#define CONFIG_SYS_EEPROM_BUS_NUM 1 - #define CONFIG_PEN_ADDR_BIG_ENDIAN #define CONFIG_SMP_PEN_ADDR 0x01ee0200 diff --git a/include/configs/ls1028a_common.h b/include/configs/ls1028a_common.h index 8413e68f3a..24422665e8 100644 --- a/include/configs/ls1028a_common.h +++ b/include/configs/ls1028a_common.h @@ -63,10 +63,6 @@ #define I2C_MUX_PCA_ADDR_PRI 0x77 /* Primary Mux*/ #define I2C_MUX_CH_DEFAULT 0x8 -/* EEPROM */ -#define CONFIG_SYS_I2C_EEPROM_NXID -#define CONFIG_SYS_EEPROM_BUS_NUM 0 - /* DisplayPort */ #define DP_PWD_EN_DEFAULT_MASK 0x8 diff --git a/include/configs/ls1043aqds.h b/include/configs/ls1043aqds.h index 49f6cd6be1..4158d15cc0 100644 --- a/include/configs/ls1043aqds.h +++ b/include/configs/ls1043aqds.h @@ -37,10 +37,6 @@ /* SATA */ -/* EEPROM */ -#define CONFIG_SYS_I2C_EEPROM_NXID -#define CONFIG_SYS_EEPROM_BUS_NUM 0 - #define CONFIG_SYS_SATA AHCI_BASE_ADDR /* diff --git a/include/configs/ls1043ardb.h b/include/configs/ls1043ardb.h index ff5da5d275..4bfe4e3ecd 100644 --- a/include/configs/ls1043ardb.h +++ b/include/configs/ls1043ardb.h @@ -184,12 +184,6 @@ #define CONFIG_SYS_CS2_FTIM2 CONFIG_SYS_CPLD_FTIM2 #define CONFIG_SYS_CS2_FTIM3 CONFIG_SYS_CPLD_FTIM3 -/* EEPROM */ -#ifndef SPL_NO_EEPROM -#define CONFIG_SYS_I2C_EEPROM_NXID -#define CONFIG_SYS_EEPROM_BUS_NUM 0 -#endif - /* * Environment */ diff --git a/include/configs/ls1046afrwy.h b/include/configs/ls1046afrwy.h index 43717cdd4e..2df5f3f6c0 100644 --- a/include/configs/ls1046afrwy.h +++ b/include/configs/ls1046afrwy.h @@ -59,8 +59,6 @@ #define CONFIG_SYS_CS0_FTIM3 CONFIG_SYS_NAND_FTIM3 /* EEPROM */ -#define CONFIG_SYS_I2C_EEPROM_NXID -#define CONFIG_SYS_EEPROM_BUS_NUM 0 #define I2C_RETIMER_ADDR 0x18 /* I2C bus multiplexer */ diff --git a/include/configs/ls1046aqds.h b/include/configs/ls1046aqds.h index 869bbd7634..1f54e51645 100644 --- a/include/configs/ls1046aqds.h +++ b/include/configs/ls1046aqds.h @@ -54,10 +54,6 @@ #define CFG_LPUART_EN 0x2 #endif -/* EEPROM */ -#define CONFIG_SYS_I2C_EEPROM_NXID -#define CONFIG_SYS_EEPROM_BUS_NUM 0 - /* * IFC Definitions */ diff --git a/include/configs/ls1046ardb.h b/include/configs/ls1046ardb.h index 382d5c7646..5d329577a6 100644 --- a/include/configs/ls1046ardb.h +++ b/include/configs/ls1046ardb.h @@ -98,8 +98,6 @@ #define CONFIG_SYS_CS2_FTIM3 CONFIG_SYS_CPLD_FTIM3 /* EEPROM */ -#define CONFIG_SYS_I2C_EEPROM_NXID -#define CONFIG_SYS_EEPROM_BUS_NUM 0 #define I2C_RETIMER_ADDR 0x18 /* PMIC */ diff --git a/include/configs/ls1088aqds.h b/include/configs/ls1088aqds.h index 747ee9d442..2d3351e6b4 100644 --- a/include/configs/ls1088aqds.h +++ b/include/configs/ls1088aqds.h @@ -287,10 +287,6 @@ #define RTC #define CONFIG_SYS_I2C_RTC_ADDR 0x51 /* Channel 3*/ -/* EEPROM */ -#define CONFIG_SYS_I2C_EEPROM_NXID -#define CONFIG_SYS_EEPROM_BUS_NUM 0 - #ifdef CONFIG_FSL_DSPI #if !defined(CONFIG_TFABOOT) && \ !defined(CONFIG_QSPI_BOOT) && !defined(CONFIG_SD_BOOT_QSPI) diff --git a/include/configs/ls1088ardb.h b/include/configs/ls1088ardb.h index 3e829ea865..d98ed39812 100644 --- a/include/configs/ls1088ardb.h +++ b/include/configs/ls1088ardb.h @@ -198,10 +198,6 @@ #define CONFIG_SYS_I2C_RTC_ADDR 0x51 /* Channel 3*/ #endif -/* EEPROM */ -#define CONFIG_SYS_I2C_EEPROM_NXID -#define CONFIG_SYS_EEPROM_BUS_NUM 0 - #ifndef SPL_NO_ENV /* Initial environment variables */ #ifdef CONFIG_TFABOOT diff --git a/include/configs/ls2080aqds.h b/include/configs/ls2080aqds.h index 6487397f65..d02d7fc588 100644 --- a/include/configs/ls2080aqds.h +++ b/include/configs/ls2080aqds.h @@ -235,10 +235,6 @@ #define CONFIG_RTC_DS3231 1 #define CONFIG_SYS_I2C_RTC_ADDR 0x68 -/* EEPROM */ -#define CONFIG_SYS_I2C_EEPROM_NXID -#define CONFIG_SYS_EEPROM_BUS_NUM 0 - /* Initial environment variables */ #undef CONFIG_EXTRA_ENV_SETTINGS #ifdef CONFIG_NXP_ESBC diff --git a/include/configs/ls2080ardb.h b/include/configs/ls2080ardb.h index 87d07b765c..09484dc609 100644 --- a/include/configs/ls2080ardb.h +++ b/include/configs/ls2080ardb.h @@ -222,10 +222,6 @@ #define CONFIG_SYS_I2C_RTC_ADDR 0x68 #endif -/* EEPROM */ -#define CONFIG_SYS_I2C_EEPROM_NXID -#define CONFIG_SYS_EEPROM_BUS_NUM 0 - #define BOOT_TARGET_DEVICES(func) \ func(USB, usb, 0) \ func(MMC, mmc, 0) \ diff --git a/include/configs/lx2160a_common.h b/include/configs/lx2160a_common.h index d39c0032c4..ed69b85758 100644 --- a/include/configs/lx2160a_common.h +++ b/include/configs/lx2160a_common.h @@ -78,10 +78,6 @@ #define RTC #define CONFIG_SYS_I2C_RTC_ADDR 0x51 /* Channel 3*/ -/* EEPROM */ -#define CONFIG_SYS_I2C_EEPROM_NXID -#define CONFIG_SYS_EEPROM_BUS_NUM 0 - /* Qixis */ #define CONFIG_SYS_I2C_FPGA_ADDR 0x66 diff --git a/include/configs/lx2160aqds.h b/include/configs/lx2160aqds.h index 585aab26bf..4e8a904859 100644 --- a/include/configs/lx2160aqds.h +++ b/include/configs/lx2160aqds.h @@ -13,10 +13,6 @@ /* MAC/PHY configuration */ -/* EEPROM */ -#define CONFIG_SYS_I2C_EEPROM_NXID -#define CONFIG_SYS_EEPROM_BUS_NUM 0 - /* Initial environment variables */ #define CONFIG_EXTRA_ENV_SETTINGS \ EXTRA_ENV_SETTINGS \ diff --git a/include/configs/lx2160ardb.h b/include/configs/lx2160ardb.h index 5c4ea27787..bb9239cc59 100644 --- a/include/configs/lx2160ardb.h +++ b/include/configs/lx2160ardb.h @@ -17,10 +17,6 @@ #define I2C_EMC2305_CMD 0x40 #define I2C_EMC2305_PWM 0x80 -/* EEPROM */ -#define CONFIG_SYS_I2C_EEPROM_NXID -#define CONFIG_SYS_EEPROM_BUS_NUM 0 - /* Initial environment variables */ #define CONFIG_EXTRA_ENV_SETTINGS \ EXTRA_ENV_SETTINGS \ diff --git a/include/configs/lx2162aqds.h b/include/configs/lx2162aqds.h index d1ae403473..b70abb013f 100644 --- a/include/configs/lx2162aqds.h +++ b/include/configs/lx2162aqds.h @@ -13,10 +13,6 @@ /* RTC */ #define CONFIG_SYS_RTC_BUS_NUM 0 -/* EEPROM */ -#define CONFIG_SYS_I2C_EEPROM_NXID -#define CONFIG_SYS_EEPROM_BUS_NUM 0 - /* Initial environment variables */ #define CONFIG_EXTRA_ENV_SETTINGS \ EXTRA_ENV_SETTINGS \ diff --git a/include/configs/sifive-unmatched.h b/include/configs/sifive-unmatched.h index 9923f3d9c3..85fab92719 100644 --- a/include/configs/sifive-unmatched.h +++ b/include/configs/sifive-unmatched.h @@ -51,6 +51,4 @@ "fdtfile=" CONFIG_DEFAULT_FDT_FILE "\0" \ BOOTENV -#define CONFIG_SYS_EEPROM_BUS_NUM 0 - #endif /* __SIFIVE_UNMATCHED_H */ From 12bbcd6a85c1e4821bda9d5055b19ec8a7c723e0 Mon Sep 17 00:00:00 2001 From: Tom Rini Date: Wed, 10 Aug 2022 10:29:28 -0400 Subject: [PATCH 030/374] Remove CONFIG_SYS_I2C_EEPROM_PAGE_WRITE_BITS et al This removes the following symbols: CONFIG_SYS_I2C_EEPROM_PAGE_WRITE_BITS CONFIG_SYS_I2C_EEPROM_PAGE_WRITE_DELAY_MS CONFIG_SYS_I2C_LDI_ADDR CONFIG_SYS_I2C_DVI_ADDR CONFIG_SYS_I2C_DVI_BUS_NUM They are unused by any code in tree at this time. Signed-off-by: Tom Rini --- include/configs/T104xRDB.h | 5 ----- include/configs/tqma6.h | 4 ---- 2 files changed, 9 deletions(-) diff --git a/include/configs/T104xRDB.h b/include/configs/T104xRDB.h index 560083c5b3..918aabcbb5 100644 --- a/include/configs/T104xRDB.h +++ b/include/configs/T104xRDB.h @@ -292,11 +292,6 @@ #if defined(CONFIG_TARGET_T1042RDB_PI) || \ defined(CONFIG_TARGET_T1040D4RDB) || \ defined(CONFIG_TARGET_T1042D4RDB) -/* LDI/DVI Encoder for display */ -#define CONFIG_SYS_I2C_LDI_ADDR 0x38 -#define CONFIG_SYS_I2C_DVI_ADDR 0x75 -#define CONFIG_SYS_I2C_DVI_BUS_NUM 0 - /* * RTC configuration */ diff --git a/include/configs/tqma6.h b/include/configs/tqma6.h index a782e3d02b..9498dbeadf 100644 --- a/include/configs/tqma6.h +++ b/include/configs/tqma6.h @@ -37,10 +37,6 @@ /* I2C Configs */ #define CONFIG_I2C_MULTI_BUS -/* I2C EEPROM (M24C64) */ -#define CONFIG_SYS_I2C_EEPROM_PAGE_WRITE_BITS 5 /* 32 Bytes */ -#define CONFIG_SYS_I2C_EEPROM_PAGE_WRITE_DELAY_MS 20 - #if !defined(CONFIG_DM_PMIC) #define CONFIG_POWER_PFUZE100 #define CONFIG_POWER_PFUZE100_I2C_ADDR 0x08 From 111688839ab4bc35fbc2a92c5696a0d246838da6 Mon Sep 17 00:00:00 2001 From: Philip Oberfichtner Date: Wed, 17 Aug 2022 15:07:12 +0200 Subject: [PATCH 031/374] Convert CONFIG_SYS_L2_PL310 to Kconfig This converts CONFIG_SYS_L2_PL310 to Kconfig. For omap2 and mvebu the 'select SYS_L2_PL310' locations were determined using ./tools/moveconfig -i CONFIG_SYS_L2_PL310. For mx6 I manually chose ARCH_MX6 as 'select' location. The correctness has been verified using $ ./tools/moveconfig.py -f ARCH_MX6 ~SYS_L2_PL310 ~SYS_L2CACHE_OFF 0 matches That means whenever an ARCH_MX6 board had SYS_L2_PL310 disabled, this was correctly reflected in SYS_L2CACHE_OFF. Thus it's safe to insert the 'select' statement under ARCH_MX6. Signed-off-by: Philip Oberfichtner --- README | 2 -- arch/arm/Kconfig | 5 +++++ arch/arm/mach-mvebu/Kconfig | 1 + arch/arm/mach-mvebu/include/mach/config.h | 2 -- arch/arm/mach-omap2/Kconfig | 1 + configs/omap4_panda_defconfig | 1 + configs/omap4_sdp4430_defconfig | 1 + configs/poleg_evb_defconfig | 1 + configs/socfpga_arria10_defconfig | 1 + configs/socfpga_arria5_defconfig | 1 + configs/socfpga_chameleonv3_defconfig | 1 + configs/socfpga_cyclone5_defconfig | 1 + configs/socfpga_dbm_soc1_defconfig | 1 + configs/socfpga_de0_nano_soc_defconfig | 1 + configs/socfpga_de10_nano_defconfig | 1 + configs/socfpga_de10_standard_defconfig | 1 + configs/socfpga_de1_soc_defconfig | 1 + configs/socfpga_is1_defconfig | 1 + configs/socfpga_mcvevk_defconfig | 1 + configs/socfpga_secu1_defconfig | 1 + configs/socfpga_sockit_defconfig | 1 + configs/socfpga_socrates_defconfig | 1 + configs/socfpga_sr1500_defconfig | 1 + configs/socfpga_vining_fpga_defconfig | 1 + configs/stemmy_defconfig | 1 + include/configs/am43xx_evm.h | 1 - include/configs/brppt2.h | 1 - include/configs/cm_t43.h | 1 - include/configs/mx6_common.h | 1 - include/configs/odroid.h | 1 - include/configs/poleg.h | 1 - include/configs/socfpga_common.h | 1 - include/configs/stemmy.h | 1 - include/configs/ti_omap4_common.h | 1 - include/configs/trats.h | 1 - include/configs/trats2.h | 1 - include/configs/zynq-common.h | 1 - scripts/config_whitelist.txt | 1 - 38 files changed, 27 insertions(+), 17 deletions(-) diff --git a/README b/README index 98185af624..186f1f9a5f 100644 --- a/README +++ b/README @@ -415,8 +415,6 @@ The following options need to be configured: the defaults discussed just above. - Cache Configuration for ARM: - CONFIG_SYS_L2_PL310 - Enable support for ARM PL310 L2 cache - controller CONFIG_SYS_PL310_BASE - Physical base address of PL310 controller register space diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 0b72e4f650..456a7faee4 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -488,6 +488,10 @@ config TPL_SYS_THUMB_BUILD density. For ARM architectures that support Thumb2 this flag will result in Thumb2 code generated by GCC. +config SYS_L2_PL310 + bool "ARM PL310 L2 cache controller" + help + Enable support for ARM PL310 L2 cache controller in U-Boot config SYS_L2CACHE_OFF bool "L2cache off" @@ -989,6 +993,7 @@ config ARCH_MX6 select SYS_FSL_HAS_SEC select SYS_FSL_SEC_COMPAT_4 select SYS_FSL_SEC_LE + select SYS_L2_PL310 if !SYS_L2CACHE_OFF imply MXC_GPIO imply SYS_THUMB_BUILD imply SPL_SEPARATE_BSS diff --git a/arch/arm/mach-mvebu/Kconfig b/arch/arm/mach-mvebu/Kconfig index a81b8e2b0d..2ebe341ed1 100644 --- a/arch/arm/mach-mvebu/Kconfig +++ b/arch/arm/mach-mvebu/Kconfig @@ -14,6 +14,7 @@ config ARMADA_32BIT select SPL_SKIP_LOWLEVEL_INIT if SPL select SPL_SIMPLE_BUS if SPL select SUPPORT_SPL + select SYS_L2_PL310 if !SYS_L2CACHE_OFF select TRANSLATION_OFFSET select SPL_SYS_NO_VECTOR_TABLE if SPL select ARCH_VERY_EARLY_INIT diff --git a/arch/arm/mach-mvebu/include/mach/config.h b/arch/arm/mach-mvebu/include/mach/config.h index 4add0d9e10..0bba0a4cf9 100644 --- a/arch/arm/mach-mvebu/include/mach/config.h +++ b/arch/arm/mach-mvebu/include/mach/config.h @@ -25,8 +25,6 @@ #define MV88F78X60 /* for the DDR training bin_hdr code */ #endif -#define CONFIG_SYS_L2_PL310 - #define MV_UART_CONSOLE_BASE MVEBU_UART0_BASE /* Needed for SPI NOR booting in SPL */ diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig index 914d43b049..78317e474d 100644 --- a/arch/arm/mach-omap2/Kconfig +++ b/arch/arm/mach-omap2/Kconfig @@ -96,6 +96,7 @@ config TI816X config AM43XX bool "AM43XX SoC" select SPECIFY_CONSOLE_INDEX + select SYS_L2_PL310 if !SYS_L2CACHE_OFF imply NAND_OMAP_ELM imply NAND_OMAP_GPMC imply SPL_DM diff --git a/configs/omap4_panda_defconfig b/configs/omap4_panda_defconfig index 3a28adf2ae..814953fae6 100644 --- a/configs/omap4_panda_defconfig +++ b/configs/omap4_panda_defconfig @@ -1,4 +1,5 @@ CONFIG_ARM=y +CONFIG_SYS_L2_PL310=y CONFIG_ARCH_OMAP2PLUS=y CONFIG_SYS_MALLOC_F_LEN=0x4000 CONFIG_DEFAULT_DEVICE_TREE="omap4-panda" diff --git a/configs/omap4_sdp4430_defconfig b/configs/omap4_sdp4430_defconfig index 6d5de532f3..a2645b9819 100644 --- a/configs/omap4_sdp4430_defconfig +++ b/configs/omap4_sdp4430_defconfig @@ -1,4 +1,5 @@ CONFIG_ARM=y +CONFIG_SYS_L2_PL310=y # CONFIG_SPL_USE_ARCH_MEMCPY is not set # CONFIG_SPL_USE_ARCH_MEMSET is not set CONFIG_ARCH_OMAP2PLUS=y diff --git a/configs/poleg_evb_defconfig b/configs/poleg_evb_defconfig index ba017e327a..597a72eed9 100644 --- a/configs/poleg_evb_defconfig +++ b/configs/poleg_evb_defconfig @@ -1,5 +1,6 @@ CONFIG_ARM=y CONFIG_ARCH_CPU_INIT=y +CONFIG_SYS_L2_PL310=y CONFIG_ARCH_NPCM=y CONFIG_SYS_TEXT_BASE=0x8200 CONFIG_SYS_MALLOC_LEN=0x240000 diff --git a/configs/socfpga_arria10_defconfig b/configs/socfpga_arria10_defconfig index 3eac3dfa5d..6fe8d55002 100644 --- a/configs/socfpga_arria10_defconfig +++ b/configs/socfpga_arria10_defconfig @@ -1,4 +1,5 @@ CONFIG_ARM=y +CONFIG_SYS_L2_PL310=y CONFIG_ARCH_SOCFPGA=y CONFIG_SYS_MALLOC_LEN=0x4000000 CONFIG_ENV_SIZE=0x2000 diff --git a/configs/socfpga_arria5_defconfig b/configs/socfpga_arria5_defconfig index dbadb3d49a..2632c0af4e 100644 --- a/configs/socfpga_arria5_defconfig +++ b/configs/socfpga_arria5_defconfig @@ -1,4 +1,5 @@ CONFIG_ARM=y +CONFIG_SYS_L2_PL310=y CONFIG_ARCH_SOCFPGA=y CONFIG_SYS_MALLOC_LEN=0x4000000 CONFIG_ENV_SIZE=0x2000 diff --git a/configs/socfpga_chameleonv3_defconfig b/configs/socfpga_chameleonv3_defconfig index 2a5a277319..478efc59ea 100644 --- a/configs/socfpga_chameleonv3_defconfig +++ b/configs/socfpga_chameleonv3_defconfig @@ -1,4 +1,5 @@ CONFIG_ARM=y +CONFIG_SYS_L2_PL310=y CONFIG_ARCH_SOCFPGA=y CONFIG_ENV_SIZE=0x10000 CONFIG_ENV_OFFSET=0x4400 diff --git a/configs/socfpga_cyclone5_defconfig b/configs/socfpga_cyclone5_defconfig index 4fd14d2e2c..451de03e1d 100644 --- a/configs/socfpga_cyclone5_defconfig +++ b/configs/socfpga_cyclone5_defconfig @@ -1,4 +1,5 @@ CONFIG_ARM=y +CONFIG_SYS_L2_PL310=y CONFIG_ARCH_SOCFPGA=y CONFIG_SYS_MALLOC_LEN=0x4000000 CONFIG_ENV_SIZE=0x2000 diff --git a/configs/socfpga_dbm_soc1_defconfig b/configs/socfpga_dbm_soc1_defconfig index 5c17ccb651..7786843427 100644 --- a/configs/socfpga_dbm_soc1_defconfig +++ b/configs/socfpga_dbm_soc1_defconfig @@ -1,4 +1,5 @@ CONFIG_ARM=y +CONFIG_SYS_L2_PL310=y CONFIG_ARCH_SOCFPGA=y CONFIG_SYS_MALLOC_LEN=0x4000000 CONFIG_ENV_SIZE=0x2000 diff --git a/configs/socfpga_de0_nano_soc_defconfig b/configs/socfpga_de0_nano_soc_defconfig index 1ef0dd9398..cfc8b50e2b 100644 --- a/configs/socfpga_de0_nano_soc_defconfig +++ b/configs/socfpga_de0_nano_soc_defconfig @@ -1,4 +1,5 @@ CONFIG_ARM=y +CONFIG_SYS_L2_PL310=y CONFIG_ARCH_SOCFPGA=y CONFIG_SYS_MALLOC_LEN=0x4000000 CONFIG_ENV_SIZE=0x2000 diff --git a/configs/socfpga_de10_nano_defconfig b/configs/socfpga_de10_nano_defconfig index 296128c9fb..53c4ff5ffd 100644 --- a/configs/socfpga_de10_nano_defconfig +++ b/configs/socfpga_de10_nano_defconfig @@ -1,4 +1,5 @@ CONFIG_ARM=y +CONFIG_SYS_L2_PL310=y CONFIG_ARCH_SOCFPGA=y CONFIG_SYS_MALLOC_LEN=0x4000000 CONFIG_ENV_SIZE=0x2000 diff --git a/configs/socfpga_de10_standard_defconfig b/configs/socfpga_de10_standard_defconfig index 8e6fe0697d..15d4599526 100644 --- a/configs/socfpga_de10_standard_defconfig +++ b/configs/socfpga_de10_standard_defconfig @@ -1,4 +1,5 @@ CONFIG_ARM=y +CONFIG_SYS_L2_PL310=y CONFIG_ARCH_SOCFPGA=y CONFIG_SYS_MALLOC_LEN=0x4000000 CONFIG_ENV_SIZE=0x2000 diff --git a/configs/socfpga_de1_soc_defconfig b/configs/socfpga_de1_soc_defconfig index 15089fe6d9..2a15936806 100644 --- a/configs/socfpga_de1_soc_defconfig +++ b/configs/socfpga_de1_soc_defconfig @@ -1,4 +1,5 @@ CONFIG_ARM=y +CONFIG_SYS_L2_PL310=y CONFIG_ARCH_SOCFPGA=y CONFIG_SYS_MALLOC_LEN=0x4000000 CONFIG_ENV_SIZE=0x2000 diff --git a/configs/socfpga_is1_defconfig b/configs/socfpga_is1_defconfig index 832b26f6de..3a21bc77a2 100644 --- a/configs/socfpga_is1_defconfig +++ b/configs/socfpga_is1_defconfig @@ -1,4 +1,5 @@ CONFIG_ARM=y +CONFIG_SYS_L2_PL310=y CONFIG_ARCH_SOCFPGA=y CONFIG_SYS_MALLOC_LEN=0x4000000 CONFIG_ENV_SIZE=0x2000 diff --git a/configs/socfpga_mcvevk_defconfig b/configs/socfpga_mcvevk_defconfig index 75190c0eb5..35ea73a598 100644 --- a/configs/socfpga_mcvevk_defconfig +++ b/configs/socfpga_mcvevk_defconfig @@ -1,4 +1,5 @@ CONFIG_ARM=y +CONFIG_SYS_L2_PL310=y CONFIG_ARCH_SOCFPGA=y CONFIG_SYS_MALLOC_LEN=0x4000000 CONFIG_ENV_SIZE=0x2000 diff --git a/configs/socfpga_secu1_defconfig b/configs/socfpga_secu1_defconfig index 400c89b84f..a6106f2a43 100644 --- a/configs/socfpga_secu1_defconfig +++ b/configs/socfpga_secu1_defconfig @@ -1,4 +1,5 @@ CONFIG_ARM=y +CONFIG_SYS_L2_PL310=y CONFIG_ARCH_SOCFPGA=y CONFIG_SYS_MALLOC_LEN=0x4000000 CONFIG_SYS_MALLOC_F_LEN=0x800 diff --git a/configs/socfpga_sockit_defconfig b/configs/socfpga_sockit_defconfig index 1e9dc14af0..0539d2937e 100644 --- a/configs/socfpga_sockit_defconfig +++ b/configs/socfpga_sockit_defconfig @@ -1,4 +1,5 @@ CONFIG_ARM=y +CONFIG_SYS_L2_PL310=y CONFIG_ARCH_SOCFPGA=y CONFIG_SYS_MALLOC_LEN=0x4000000 CONFIG_ENV_SIZE=0x2000 diff --git a/configs/socfpga_socrates_defconfig b/configs/socfpga_socrates_defconfig index dab11f8920..a81f74d329 100644 --- a/configs/socfpga_socrates_defconfig +++ b/configs/socfpga_socrates_defconfig @@ -1,4 +1,5 @@ CONFIG_ARM=y +CONFIG_SYS_L2_PL310=y CONFIG_ARCH_SOCFPGA=y CONFIG_SYS_MALLOC_LEN=0x4000000 CONFIG_ENV_SIZE=0x2000 diff --git a/configs/socfpga_sr1500_defconfig b/configs/socfpga_sr1500_defconfig index 90ffa9a9c5..59d809ca0e 100644 --- a/configs/socfpga_sr1500_defconfig +++ b/configs/socfpga_sr1500_defconfig @@ -1,4 +1,5 @@ CONFIG_ARM=y +CONFIG_SYS_L2_PL310=y CONFIG_ARCH_SOCFPGA=y CONFIG_SYS_MALLOC_LEN=0x4000000 CONFIG_ENV_SIZE=0x4000 diff --git a/configs/socfpga_vining_fpga_defconfig b/configs/socfpga_vining_fpga_defconfig index 1b88ccd209..3a99667811 100644 --- a/configs/socfpga_vining_fpga_defconfig +++ b/configs/socfpga_vining_fpga_defconfig @@ -1,4 +1,5 @@ CONFIG_ARM=y +CONFIG_SYS_L2_PL310=y CONFIG_ARCH_SOCFPGA=y CONFIG_SYS_MALLOC_LEN=0x4000000 CONFIG_ENV_SIZE=0x4000 diff --git a/configs/stemmy_defconfig b/configs/stemmy_defconfig index 7fc0a39872..f1d3ef5b12 100644 --- a/configs/stemmy_defconfig +++ b/configs/stemmy_defconfig @@ -1,5 +1,6 @@ CONFIG_ARM=y CONFIG_SKIP_LOWLEVEL_INIT=y +CONFIG_SYS_L2_PL310=y CONFIG_ARCH_U8500=y CONFIG_SUPPORT_PASSING_ATAGS=y # CONFIG_SETUP_MEMORY_TAGS is not set diff --git a/include/configs/am43xx_evm.h b/include/configs/am43xx_evm.h index 87d3a27099..fc82a8c003 100644 --- a/include/configs/am43xx_evm.h +++ b/include/configs/am43xx_evm.h @@ -29,7 +29,6 @@ /* SPL defines. */ /* Enabling L2 Cache */ -#define CONFIG_SYS_L2_PL310 #define CONFIG_SYS_PL310_BASE 0x48242000 /* diff --git a/include/configs/brppt2.h b/include/configs/brppt2.h index adaba410ce..0c7fe5f3ab 100644 --- a/include/configs/brppt2.h +++ b/include/configs/brppt2.h @@ -13,7 +13,6 @@ /* -- i.mx6 specifica -- */ #ifndef CONFIG_SYS_L2CACHE_OFF -#define CONFIG_SYS_L2_PL310 #define CONFIG_SYS_PL310_BASE L2_PL310_BASE #endif /* !CONFIG_SYS_L2CACHE_OFF */ diff --git a/include/configs/cm_t43.h b/include/configs/cm_t43.h index 07c5cb8ded..50cb2a4718 100644 --- a/include/configs/cm_t43.h +++ b/include/configs/cm_t43.h @@ -36,7 +36,6 @@ #define CONFIG_POWER_TPS65218 /* Enabling L2 Cache */ -#define CONFIG_SYS_L2_PL310 #define CONFIG_SYS_PL310_BASE 0x48242000 /* diff --git a/include/configs/mx6_common.h b/include/configs/mx6_common.h index e416f81e43..4314556754 100644 --- a/include/configs/mx6_common.h +++ b/include/configs/mx6_common.h @@ -12,7 +12,6 @@ #define CONFIG_SC_TIMER_CLK 8000000 /* 8Mhz */ #else #ifndef CONFIG_SYS_L2CACHE_OFF -#define CONFIG_SYS_L2_PL310 #define CONFIG_SYS_PL310_BASE L2_PL310_BASE #endif diff --git a/include/configs/odroid.h b/include/configs/odroid.h index 7448cc9520..babd3ca963 100644 --- a/include/configs/odroid.h +++ b/include/configs/odroid.h @@ -14,7 +14,6 @@ #include #ifndef CONFIG_SYS_L2CACHE_OFF -#define CONFIG_SYS_L2_PL310 #define CONFIG_SYS_PL310_BASE 0x10502000 #endif diff --git a/include/configs/poleg.h b/include/configs/poleg.h index f1c259f476..05253d59ef 100644 --- a/include/configs/poleg.h +++ b/include/configs/poleg.h @@ -7,7 +7,6 @@ #define __CONFIG_POLEG_H #ifndef CONFIG_SYS_L2CACHE_OFF -#define CONFIG_SYS_L2_PL310 1 #define CONFIG_SYS_PL310_BASE 0xF03FC000 /* L2 - Cache Regs Base (4k Space)*/ #endif diff --git a/include/configs/socfpga_common.h b/include/configs/socfpga_common.h index 4a7da76e51..c3f30afe2b 100644 --- a/include/configs/socfpga_common.h +++ b/include/configs/socfpga_common.h @@ -48,7 +48,6 @@ /* * Cache */ -#define CONFIG_SYS_L2_PL310 #define CONFIG_SYS_PL310_BASE SOCFPGA_MPUL2_ADDRESS /* diff --git a/include/configs/stemmy.h b/include/configs/stemmy.h index 71b25c23b1..3c70856fc7 100644 --- a/include/configs/stemmy.h +++ b/include/configs/stemmy.h @@ -15,7 +15,6 @@ */ /* FIXME: This should be loaded from device tree... */ -#define CONFIG_SYS_L2_PL310 #define CONFIG_SYS_PL310_BASE 0xa0412000 /* Linux does not boot if FDT / initrd is loaded to end of RAM */ diff --git a/include/configs/ti_omap4_common.h b/include/configs/ti_omap4_common.h index 3d78972bfe..0568946fc8 100644 --- a/include/configs/ti_omap4_common.h +++ b/include/configs/ti_omap4_common.h @@ -12,7 +12,6 @@ #define __CONFIG_TI_OMAP4_COMMON_H #ifndef CONFIG_SYS_L2CACHE_OFF -#define CONFIG_SYS_L2_PL310 1 #define CONFIG_SYS_PL310_BASE 0x48242000 #endif diff --git a/include/configs/trats.h b/include/configs/trats.h index 53f5a6996b..530b413d5b 100644 --- a/include/configs/trats.h +++ b/include/configs/trats.h @@ -12,7 +12,6 @@ #include #ifndef CONFIG_SYS_L2CACHE_OFF -#define CONFIG_SYS_L2_PL310 #define CONFIG_SYS_PL310_BASE 0x10502000 #endif diff --git a/include/configs/trats2.h b/include/configs/trats2.h index b7449dab8b..06c1fcd23e 100644 --- a/include/configs/trats2.h +++ b/include/configs/trats2.h @@ -13,7 +13,6 @@ #include #ifndef CONFIG_SYS_L2CACHE_OFF -#define CONFIG_SYS_L2_PL310 #define CONFIG_SYS_PL310_BASE 0x10502000 #endif diff --git a/include/configs/zynq-common.h b/include/configs/zynq-common.h index 75ae68766f..dc0cba0010 100644 --- a/include/configs/zynq-common.h +++ b/include/configs/zynq-common.h @@ -11,7 +11,6 @@ /* Cache options */ #ifndef CONFIG_SYS_L2CACHE_OFF -# define CONFIG_SYS_L2_PL310 # define CONFIG_SYS_PL310_BASE 0xf8f02000 #endif diff --git a/scripts/config_whitelist.txt b/scripts/config_whitelist.txt index c5e8942a76..2a589eeb07 100644 --- a/scripts/config_whitelist.txt +++ b/scripts/config_whitelist.txt @@ -845,7 +845,6 @@ CONFIG_SYS_JFFS2_FIRST_SECTOR CONFIG_SYS_JFFS2_NUM_BANKS CONFIG_SYS_KMBEC_FPGA_BASE CONFIG_SYS_KMBEC_FPGA_SIZE -CONFIG_SYS_L2_PL310 CONFIG_SYS_L2_SIZE CONFIG_SYS_L3_SIZE CONFIG_SYS_LATCH_ADDR From b6664eace8a26f0850ffa0a3e349ca2ffa960f2a Mon Sep 17 00:00:00 2001 From: Philip Oberfichtner Date: Wed, 17 Aug 2022 15:07:13 +0200 Subject: [PATCH 032/374] ARM: cache: Allow SPL to build cache-pl310.c Introduce the new Kconfig symbol CONFIG_SPL_SYS_L2_PL310 to allow the SPL to build cache-pl310.c. Before this commit, the SPL could enable the PL310 L2 cache [1], but the cache maintenance functions from cache-pl310.c were only useable for non-SPL builds. After enabling the cache one must be able to flush it, too. Thus this commit allows cache-pl310.c to be included in the SPL build. [1] See for example arch/arm/mach-imx/cache.c: v7_outer_cache_enable() Signed-off-by: Philip Oberfichtner --- arch/arm/Kconfig | 5 +++++ arch/arm/lib/Makefile | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 456a7faee4..d6c5658ee8 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -493,6 +493,11 @@ config SYS_L2_PL310 help Enable support for ARM PL310 L2 cache controller in U-Boot +config SPL_SYS_L2_PL310 + bool "ARM PL310 L2 cache controller in SPL" + help + Enable support for ARM PL310 L2 cache controller in SPL + config SYS_L2CACHE_OFF bool "L2cache off" help diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile index c603fe61bc..d137b4bf0f 100644 --- a/arch/arm/lib/Makefile +++ b/arch/arm/lib/Makefile @@ -33,7 +33,6 @@ obj-$(CONFIG_OF_LIBFDT) += bootm-fdt.o obj-$(CONFIG_CMD_BOOTI) += bootm.o image.o obj-$(CONFIG_CMD_BOOTM) += bootm.o obj-$(CONFIG_CMD_BOOTZ) += bootm.o zimage.o -obj-$(CONFIG_SYS_L2_PL310) += cache-pl310.o else obj-$(CONFIG_$(SPL_TPL_)FRAMEWORK) += spl.o obj-$(CONFIG_SPL_FRAMEWORK) += zimage.o @@ -46,6 +45,7 @@ else obj-$(CONFIG_$(SPL_TPL_)USE_ARCH_MEMSET) += memset.o obj-$(CONFIG_$(SPL_TPL_)USE_ARCH_MEMCPY) += memcpy.o endif +obj-$(CONFIG_$(SPL_TPL_)SYS_L2_PL310) += cache-pl310.o obj-$(CONFIG_$(SPL_TPL_)SEMIHOSTING) += semihosting.o ifneq ($(filter y,$(CONFIG_SAVE_PREV_BL_INITRAMFS_START_ADDR) $(CONFIG_SAVE_PREV_BL_FDT_ADDR)),) From ab2a6e82d4dbbdd236065805b4872cb18c8d2fd4 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Wed, 17 Aug 2022 15:07:14 +0200 Subject: [PATCH 033/374] ARM: imx6: dh-imx6: Enable d-cache early in SPL Enable d-cache early in SPL right after DRAM is started up. This reduces U-Boot proper load time by 650ms when loaded from SPI NOR. Signed-off-by: Marek Vasut Signed-off-by: Philip Oberfichtner --- board/dhelectronics/dh_imx6/dh_imx6_spl.c | 41 +++++++++++++++++++++++ configs/dh_imx6_defconfig | 1 + 2 files changed, 42 insertions(+) diff --git a/board/dhelectronics/dh_imx6/dh_imx6_spl.c b/board/dhelectronics/dh_imx6/dh_imx6_spl.c index e49e97724a..20a330cce6 100644 --- a/board/dhelectronics/dh_imx6/dh_imx6_spl.c +++ b/board/dhelectronics/dh_imx6/dh_imx6_spl.c @@ -6,6 +6,7 @@ */ #include +#include #include #include #include @@ -14,11 +15,13 @@ #include #include #include +#include #include #include #include #include #include +#include #include #include #include @@ -610,6 +613,20 @@ static void dhcom_spl_dram_init(void) } } +void dram_bank_mmu_setup(int bank) +{ + int i; + + set_section_dcache(ROMCP_ARB_BASE_ADDR >> MMU_SECTION_SHIFT, DCACHE_DEFAULT_OPTION); + set_section_dcache(IRAM_BASE_ADDR >> MMU_SECTION_SHIFT, DCACHE_DEFAULT_OPTION); + + for (i = MMDC0_ARB_BASE_ADDR >> MMU_SECTION_SHIFT; + i < ((MMDC0_ARB_BASE_ADDR >> MMU_SECTION_SHIFT) + + (SZ_1G >> MMU_SECTION_SHIFT)); + i++) + set_section_dcache(i, DCACHE_DEFAULT_OPTION); +} + void board_init_f(ulong dummy) { /* setup AIPS and disable watchdog */ @@ -636,9 +653,33 @@ void board_init_f(ulong dummy) /* DDR3 initialization */ dhcom_spl_dram_init(); + /* Set up early MMU tables at the beginning of DRAM and start d-cache */ + gd->arch.tlb_addr = MMDC0_ARB_BASE_ADDR + SZ_32M; + gd->arch.tlb_size = PGTABLE_SIZE; + enable_caches(); + /* Clear the BSS. */ memset(__bss_start, 0, __bss_end - __bss_start); /* load/boot image from boot device */ board_init_r(NULL, 0); } + +void spl_board_prepare_for_boot(void) +{ + /* + * Flush and disable dcache. Without it, the following bootstage might fail randomly because + * dirty cache lines may not have been written back to DRAM. + * + * If dcache_disable() would be omitted, the following scenario may occur: + * + * The SPL enables dcache and cachelines get populated with data. Then dcache gets disabled + * in U-Boot proper, but still contains dirty data, i.e. the corresponding DRAM locations + * have not yet been updated. When U-Boot reads these locations, it sees an (incorrect) old + * state of the content. + * + * Furthermore, the DRAM contents have likely been modified by U-Boot while dcache was + * disabled. Thus, U-Boot flushing dcache would corrupt DRAM with stale data. + */ + dcache_disable(); /* implies flush_dcache_all() */ +} diff --git a/configs/dh_imx6_defconfig b/configs/dh_imx6_defconfig index 4b6776ea9c..c7fb2c67a7 100644 --- a/configs/dh_imx6_defconfig +++ b/configs/dh_imx6_defconfig @@ -1,4 +1,5 @@ CONFIG_ARM=y +CONFIG_SPL_SYS_L2_PL310=y CONFIG_ARCH_MX6=y CONFIG_SYS_TEXT_BASE=0x17800000 CONFIG_SYS_MALLOC_F_LEN=0x1000 From d88260710b212815ae1f461aec24ad926c668d36 Mon Sep 17 00:00:00 2001 From: "Matwey V. Kornilov" Date: Tue, 9 Aug 2022 18:54:07 +0300 Subject: [PATCH 034/374] distro_bootcmd: Introduce support for extension command Try to load required DTB overlays if the board supports extensions and CONFIG_CMD_EXTENSION is enabled. Signed-off-by: Matwey V. Kornilov --- include/config_distro_bootcmd.h | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/include/config_distro_bootcmd.h b/include/config_distro_bootcmd.h index c6e9c49741..2157f3533e 100644 --- a/include/config_distro_bootcmd.h +++ b/include/config_distro_bootcmd.h @@ -160,11 +160,13 @@ "scan_dev_for_efi=" \ "setenv efi_fdtfile ${fdtfile}; " \ BOOTENV_EFI_SET_FDTFILE_FALLBACK \ + BOOTENV_RUN_EXTENSION_INIT \ "for prefix in ${efi_dtb_prefixes}; do " \ "if test -e ${devtype} " \ "${devnum}:${distro_bootpart} " \ "${prefix}${efi_fdtfile}; then " \ "run load_efi_dtb; " \ + BOOTENV_RUN_EXTENSION_APPLY \ "fi;" \ "done;" \ "run boot_efi_bootmgr;" \ @@ -416,6 +418,34 @@ BOOT_TARGET_DEVICES_references_PXE_without_CONFIG_CMD_DHCP_or_PXE #endif +#if defined(CONFIG_CMD_EXTENSION) +#define BOOTENV_RUN_EXTENSION_INIT "run extension_init; " +#define BOOTENV_RUN_EXTENSION_APPLY "run extension_apply; " +#define BOOTENV_SET_EXTENSION_NEED_INIT \ + "extension_need_init=; " \ + "setenv extension_overlay_addr ${fdtoverlay_addr_r}; " +#define BOOTENV_SHARED_EXTENSION \ + "extension_init=" \ + "echo Extension init...; " \ + "if ${extension_need_init}; then " \ + "extension_need_init=false; " \ + "extension scan; " \ + "fi\0" \ + \ + "extension_overlay_cmd=" \ + "load ${devtype} ${devnum}:${distro_bootpart} " \ + "${extension_overlay_addr} ${prefix}${extension_overlay_name}\0" \ + "extension_apply=" \ + "if fdt addr -q ${fdt_addr_r}; then " \ + "extension apply all; " \ + "fi\0" +#else +#define BOOTENV_RUN_EXTENSION_INIT +#define BOOTENV_RUN_EXTENSION_APPLY +#define BOOTENV_SET_EXTENSION_NEED_INIT +#define BOOTENV_SHARED_EXTENSION +#endif + #define BOOTENV_DEV_NAME(devtypeu, devtypel, instance, ...) \ BOOTENV_DEV_NAME_##devtypeu(devtypeu, devtypel, instance, ## __VA_ARGS__) #define BOOTENV_BOOT_TARGETS \ @@ -435,6 +465,7 @@ BOOTENV_SHARED_UBIFS \ BOOTENV_SHARED_EFI \ BOOTENV_SHARED_VIRTIO \ + BOOTENV_SHARED_EXTENSION \ "boot_prefixes=/ /boot/\0" \ "boot_scripts=boot.scr.uimg boot.scr\0" \ "boot_script_dhcp=boot.scr.uimg\0" \ @@ -499,6 +530,7 @@ BOOTENV_SET_NVME_NEED_INIT \ BOOTENV_SET_IDE_NEED_INIT \ BOOTENV_SET_VIRTIO_NEED_INIT \ + BOOTENV_SET_EXTENSION_NEED_INIT \ "for target in ${boot_targets}; do " \ "run bootcmd_${target}; " \ "done\0" From dc0d17c26a3a03634994c59adb0b657807827183 Mon Sep 17 00:00:00 2001 From: Samuel Dionne-Riel Date: Thu, 18 Aug 2022 15:44:04 -0400 Subject: [PATCH 035/374] cmd: Add pause command This command is being introduced with the goal of allowing user-friendly "generic use case" U-Boot builds to pause until user input under some situations. The main use case would be when a boot failure happens, to pause until the user has had time to acknowledge the current state. Tested using: make && ./u-boot -v -T -c 'ut lib lib_test_hush_pause' Signed-off-by: Samuel Dionne-Riel Cc: Simon Glass --- cmd/Kconfig | 6 +++++ cmd/Makefile | 1 + cmd/pause.c | 32 ++++++++++++++++++++++ configs/sandbox64_defconfig | 1 + configs/sandbox_defconfig | 1 + doc/usage/cmd/pause.rst | 53 +++++++++++++++++++++++++++++++++++++ doc/usage/index.rst | 1 + test/cmd/Makefile | 3 +++ test/cmd/test_pause.c | 45 +++++++++++++++++++++++++++++++ 9 files changed, 143 insertions(+) create mode 100644 cmd/pause.c create mode 100644 doc/usage/cmd/pause.rst create mode 100644 test/cmd/test_pause.c diff --git a/cmd/Kconfig b/cmd/Kconfig index 211ebe9c87..67c7d2512f 100644 --- a/cmd/Kconfig +++ b/cmd/Kconfig @@ -1971,6 +1971,12 @@ config CMD_GETTIME milliseconds. See also the 'bootstage' command which provides more flexibility for boot timing. +config CMD_PAUSE + bool "pause command" + help + Delay execution waiting for any user input. + Useful to allow the user to read a failure log. + config CMD_RNG bool "rng command" depends on DM_RNG diff --git a/cmd/Makefile b/cmd/Makefile index 6e87522b62..7abe1d3630 100644 --- a/cmd/Makefile +++ b/cmd/Makefile @@ -102,6 +102,7 @@ obj-$(CONFIG_CMD_MFSL) += mfsl.o obj-$(CONFIG_CMD_MII) += mii.o obj-$(CONFIG_CMD_MISC) += misc.o obj-$(CONFIG_CMD_MDIO) += mdio.o +obj-$(CONFIG_CMD_PAUSE) += pause.o obj-$(CONFIG_CMD_SLEEP) += sleep.o obj-$(CONFIG_CMD_MMC) += mmc.o obj-$(CONFIG_CMD_OPTEE_RPMB) += optee_rpmb.o diff --git a/cmd/pause.c b/cmd/pause.c new file mode 100644 index 0000000000..c97833c0d7 --- /dev/null +++ b/cmd/pause.c @@ -0,0 +1,32 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * (C) Copyright 2021 + * Samuel Dionne-Riel + */ + +#include +#include + +static int do_pause(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) +{ + char *message = "Press any key to continue..."; + + if (argc == 2) + message = argv[1]; + + /* No newline, so it sticks to the bottom of the screen */ + printf("%s", message); + + /* Wait on "any" key... */ + (void) getchar(); + + /* Since there was no newline, we need it now */ + printf("\n"); + + return CMD_RET_SUCCESS; +} + +U_BOOT_CMD(pause, 2, 1, do_pause, + "delay until user input", + "[prompt] - Wait until users presses any key. [prompt] can be used to customize the message.\n" +); diff --git a/configs/sandbox64_defconfig b/configs/sandbox64_defconfig index 4599db73ed..9a1b6e4bbf 100644 --- a/configs/sandbox64_defconfig +++ b/configs/sandbox64_defconfig @@ -67,6 +67,7 @@ CONFIG_CMD_BMP=y CONFIG_CMD_EFIDEBUG=y CONFIG_CMD_RTC=y CONFIG_CMD_TIME=y +CONFIG_CMD_PAUSE=y CONFIG_CMD_TIMER=y CONFIG_CMD_SOUND=y CONFIG_CMD_QFW=y diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig index 4a0c51c7f5..e6a1718571 100644 --- a/configs/sandbox_defconfig +++ b/configs/sandbox_defconfig @@ -96,6 +96,7 @@ CONFIG_CMD_BOOTCOUNT=y CONFIG_CMD_EFIDEBUG=y CONFIG_CMD_RTC=y CONFIG_CMD_TIME=y +CONFIG_CMD_PAUSE=y CONFIG_CMD_TIMER=y CONFIG_CMD_SOUND=y CONFIG_CMD_QFW=y diff --git a/doc/usage/cmd/pause.rst b/doc/usage/cmd/pause.rst new file mode 100644 index 0000000000..c79e399c02 --- /dev/null +++ b/doc/usage/cmd/pause.rst @@ -0,0 +1,53 @@ +.. SPDX-License-Identifier: GPL-2.0-or-later: + +pause command +============= + +Synopsis +-------- + +:: + + pause [prompt] + + +Description +----------- + +The pause command delays execution waiting for any user input. + +It can accept a single parameter to change the prompt message. + +Examples +-------- + +Using with the default prompt: + +:: + + => pause + Press any key to continue... + + +Using with a custom prompt: + +:: + + => pause 'Prompt for pause...' + Prompt for pause... + +Note that complex prompts require proper quoting: + +:: + + => pause Prompt for pause... + pause - delay until user input + + Usage: + pause [prompt] - Wait until users presses any key. [prompt] can be used to customize the message. + +Return value +------------ + +The return value $? is always set to 0 (true), unless invoked in an invalid +manner. diff --git a/doc/usage/index.rst b/doc/usage/index.rst index 28f9683a3e..5170fa8b4a 100644 --- a/doc/usage/index.rst +++ b/doc/usage/index.rst @@ -52,6 +52,7 @@ Shell commands cmd/mbr cmd/md cmd/mmc + cmd/pause cmd/pinmux cmd/printenv cmd/pstore diff --git a/test/cmd/Makefile b/test/cmd/Makefile index c331757425..1bb02d93a2 100644 --- a/test/cmd/Makefile +++ b/test/cmd/Makefile @@ -5,6 +5,9 @@ ifdef CONFIG_HUSH_PARSER obj-$(CONFIG_CONSOLE_RECORD) += test_echo.o endif +ifdef CONFIG_CONSOLE_RECORD +obj-$(CONFIG_CMD_PAUSE) += test_pause.o +endif obj-y += mem.o obj-$(CONFIG_CMD_ADDRMAP) += addrmap.o obj-$(CONFIG_CMD_FDT) += fdt.o diff --git a/test/cmd/test_pause.c b/test/cmd/test_pause.c new file mode 100644 index 0000000000..2b85cce327 --- /dev/null +++ b/test/cmd/test_pause.c @@ -0,0 +1,45 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Tests for pause command + * + * Copyright 2022, Samuel Dionne-Riel + */ + +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +static int lib_test_hush_pause(struct unit_test_state *uts) +{ + /* Test default message */ + console_record_reset_enable(); + /* Cook a newline when the command is expected to pause */ + console_in_puts("\n"); + ut_assertok(run_command("pause", 0)); + console_record_readline(uts->actual_str, sizeof(uts->actual_str)); + ut_asserteq_str("Press any key to continue...", uts->actual_str); + ut_assertok(ut_check_console_end(uts)); + + /* Test provided message */ + console_record_reset_enable(); + /* Cook a newline when the command is expected to pause */ + console_in_puts("\n"); + ut_assertok(run_command("pause 'Prompt for pause...'", 0)); + console_record_readline(uts->actual_str, sizeof(uts->actual_str)); + ut_asserteq_str("Prompt for pause...", uts->actual_str); + ut_assertok(ut_check_console_end(uts)); + + /* Test providing more than one params */ + console_record_reset_enable(); + /* No newline cooked here since the command is expected to fail */ + ut_asserteq(1, run_command("pause a b", 0)); + console_record_readline(uts->actual_str, sizeof(uts->actual_str)); + ut_asserteq_str("pause - delay until user input", uts->actual_str); + ut_asserteq(1, ut_check_console_end(uts)); + + return 0; +} +LIB_TEST(lib_test_hush_pause, 0); From 583f1b2f10be36f86a2da3686d406bfd90cfbc70 Mon Sep 17 00:00:00 2001 From: Sergei Antonov Date: Sun, 21 Aug 2022 16:34:20 +0300 Subject: [PATCH 036/374] arm: ARMv4 assembly compatibility There is currently a problem that U-Boot can not work on ARMv4 because assembly imlementations of memcpy() and some other functions use "bx lr" instruction that is not available on ARMv4 ("mov pc, lr" should be used instead). A working preprocessor-based solution to this problem is found in arch/arm/lib/relocate.S. Move it to the "ret" macro in arch/arm/include/asm/assembler.h and change all "bx lr" code to "ret lr" in functions that may run on ARMv4. Linux source code deals with this problem in the same manner. v1 -> v2: Comment update. Pointed out by Andre Przywara. Signed-off-by: Sergei Antonov CC: Samuel Holland CC: Ye Li CC: Simon Glass CC: Andre Przywara CC: Marek Vasut CC: Sean Anderson CC: Tom Rini --- arch/arm/include/asm/assembler.h | 10 ++++++++-- arch/arm/lib/lib1funcs.S | 8 ++++---- arch/arm/lib/memcpy.S | 6 +++--- arch/arm/lib/relocate.S | 10 ++-------- arch/arm/lib/setjmp.S | 4 ++-- 5 files changed, 19 insertions(+), 19 deletions(-) diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h index b146918586..8d42ef4823 100644 --- a/arch/arm/include/asm/assembler.h +++ b/arch/arm/include/asm/assembler.h @@ -58,16 +58,22 @@ #endif /* - * We only support cores that support at least Thumb-1 and thus we use - * 'bx lr' + * Use 'bx lr' everywhere except ARMv4 (without 'T') where only 'mov pc, lr' + * works */ .irp c,,eq,ne,cs,cc,mi,pl,vs,vc,hi,ls,ge,lt,gt,le,hs,lo .macro ret\c, reg + + /* ARMv4- don't know bx lr but the assembler fails to see that */ +#ifdef __ARM_ARCH_4__ + mov\c pc, \reg +#else .ifeqs "\reg", "lr" bx\c \reg .else mov\c pc, \reg .endif +#endif .endm .endr diff --git a/arch/arm/lib/lib1funcs.S b/arch/arm/lib/lib1funcs.S index 700eee5fbb..7ff4446dd6 100644 --- a/arch/arm/lib/lib1funcs.S +++ b/arch/arm/lib/lib1funcs.S @@ -377,7 +377,7 @@ ENTRY(__gnu_thumb1_case_sqi) lsls r1, r1, #1 add lr, lr, r1 pop {r1} - bx lr + ret lr ENDPROC(__gnu_thumb1_case_sqi) .popsection @@ -391,7 +391,7 @@ ENTRY(__gnu_thumb1_case_uqi) lsls r1, r1, #1 add lr, lr, r1 pop {r1} - bx lr + ret lr ENDPROC(__gnu_thumb1_case_uqi) .popsection @@ -406,7 +406,7 @@ ENTRY(__gnu_thumb1_case_shi) lsls r1, r1, #1 add lr, lr, r1 pop {r0, r1} - bx lr + ret lr ENDPROC(__gnu_thumb1_case_shi) .popsection @@ -421,7 +421,7 @@ ENTRY(__gnu_thumb1_case_uhi) lsls r1, r1, #1 add lr, lr, r1 pop {r0, r1} - bx lr + ret lr ENDPROC(__gnu_thumb1_case_uhi) .popsection #endif diff --git a/arch/arm/lib/memcpy.S b/arch/arm/lib/memcpy.S index eee7a219ce..a1c996f94e 100644 --- a/arch/arm/lib/memcpy.S +++ b/arch/arm/lib/memcpy.S @@ -59,7 +59,7 @@ #endif ENTRY(memcpy) cmp r0, r1 - bxeq lr + reteq lr enter r4, lr @@ -148,7 +148,7 @@ ENTRY(memcpy) str1b r0, ip, cs, abort=21f exit r4, lr - bx lr + ret lr 9: rsb ip, ip, #4 cmp ip, #2 @@ -258,7 +258,7 @@ ENTRY(memcpy) .macro copy_abort_end ldmfd sp!, {r4, lr} - bx lr + ret lr .endm ENDPROC(memcpy) diff --git a/arch/arm/lib/relocate.S b/arch/arm/lib/relocate.S index 5102bfabde..dd6f2e3bd5 100644 --- a/arch/arm/lib/relocate.S +++ b/arch/arm/lib/relocate.S @@ -61,7 +61,7 @@ ENTRY(relocate_vectors) stmia r1!, {r2-r8,r10} #endif #endif - bx lr + ret lr ENDPROC(relocate_vectors) @@ -127,13 +127,7 @@ relocate_done: mcr p15, 0, r0, c7, c10, 4 /* drain write buffer */ #endif - /* ARMv4- don't know bx lr but the assembler fails to see that */ - -#ifdef __ARM_ARCH_4__ - mov pc, lr -#else - bx lr -#endif + ret lr ENDPROC(relocate_code) diff --git a/arch/arm/lib/setjmp.S b/arch/arm/lib/setjmp.S index 176a1d5315..2f041aeef0 100644 --- a/arch/arm/lib/setjmp.S +++ b/arch/arm/lib/setjmp.S @@ -17,7 +17,7 @@ ENTRY(setjmp) mov ip, sp stm a1, {v1-v8, ip, lr} mov a1, #0 - bx lr + ret lr ENDPROC(setjmp) .popsection @@ -31,6 +31,6 @@ ENTRY(longjmp) bne 1f mov a1, #1 1: - bx lr + ret lr ENDPROC(longjmp) .popsection From a55014d09b29d7bc2cbaeb8e41a155c9a257a183 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 3 Aug 2022 12:13:08 -0600 Subject: [PATCH 037/374] Makefile: Allow LTO to be disabled for a build LTO (Link-Time Optimisation) is an very useful feature which can significantly reduce the size of U-Boot binaries. So far it has been made available for selected ARM boards and sandbox. However, incremental builds are much slower when LTO is used. For example, an incremental build of sandbox takes 2.1 seconds on my machine, but 6.7 seconds with LTO enabled. Add a NO_LTO parameter to the build, similar to NO_SDL, so it can be disabled during development if needed, for faster builds. Add some documentation about LTO while we are here. Signed-off-by: Simon Glass --- Makefile | 17 ++++++++++++----- arch/arm/config.mk | 4 ++-- arch/arm/include/asm/global_data.h | 2 +- doc/build/gcc.rst | 17 +++++++++++++++++ scripts/Makefile.spl | 2 +- 5 files changed, 33 insertions(+), 9 deletions(-) diff --git a/Makefile b/Makefile index 541e942ed5..27375f033f 100644 --- a/Makefile +++ b/Makefile @@ -643,6 +643,13 @@ export CFLAGS_EFI # Compiler flags to add when building EFI app export CFLAGS_NON_EFI # Compiler flags to remove when building EFI app export EFI_TARGET # binutils target if EFI is natively supported +export LTO_ENABLE + +# This is y if LTO is enabled for this build. See NO_LTO=1 to disable LTO +ifeq ($(NO_LTO),) +LTO_ENABLE=$(if $(CONFIG_LTO),y) +endif + # If board code explicitly specified LDSCRIPT or CONFIG_SYS_LDSCRIPT, use # that (or fail if absent). Otherwise, search for a linker script in a # standard location. @@ -708,16 +715,16 @@ endif LTO_CFLAGS := LTO_FINAL_LDFLAGS := export LTO_CFLAGS LTO_FINAL_LDFLAGS -ifdef CONFIG_LTO +ifeq ($(LTO_ENABLE),y) ifeq ($(cc-name),clang) - LTO_CFLAGS += -flto + LTO_CFLAGS += -DLTO_ENABLE -flto LTO_FINAL_LDFLAGS += -flto AR = $(shell $(CC) -print-prog-name=llvm-ar) NM = $(shell $(CC) -print-prog-name=llvm-nm) else NPROC := $(shell nproc 2>/dev/null || echo 1) - LTO_CFLAGS += -flto=$(NPROC) + LTO_CFLAGS += -DLTO_ENABLE -flto=$(NPROC) LTO_FINAL_LDFLAGS += -fuse-linker-plugin -flto=$(NPROC) # use plugin aware tools @@ -1765,7 +1772,7 @@ ARCH_POSTLINK := $(wildcard $(srctree)/arch/$(ARCH)/Makefile.postlink) # Generate linker list symbols references to force compiler to not optimize # them away when compiling with LTO -ifdef CONFIG_LTO +ifeq ($(LTO_ENABLE),y) u-boot-keep-syms-lto := keep-syms-lto.o u-boot-keep-syms-lto_c := $(patsubst %.o,%.c,$(u-boot-keep-syms-lto)) @@ -1787,7 +1794,7 @@ endif # Rule to link u-boot # May be overridden by arch/$(ARCH)/config.mk -ifdef CONFIG_LTO +ifeq ($(LTO_ENABLE),y) quiet_cmd_u-boot__ ?= LTO $@ cmd_u-boot__ ?= \ $(CC) -nostdlib -nostartfiles \ diff --git a/arch/arm/config.mk b/arch/arm/config.mk index b3548ce243..2065438d05 100644 --- a/arch/arm/config.mk +++ b/arch/arm/config.mk @@ -15,11 +15,11 @@ CFLAGS_NON_EFI := -fno-pic -ffixed-r9 -ffunction-sections -fdata-sections \ -fstack-protector-strong CFLAGS_EFI := -fpic -fshort-wchar -ifneq ($(CONFIG_LTO)$(CONFIG_USE_PRIVATE_LIBGCC),yy) +ifneq ($(LTO_ENABLE)$(CONFIG_USE_PRIVATE_LIBGCC),yy) LDFLAGS_FINAL += --gc-sections endif -ifndef CONFIG_LTO +ifneq ($(LTO_ENABLE),y) PLATFORM_RELFLAGS += -ffunction-sections -fdata-sections endif diff --git a/arch/arm/include/asm/global_data.h b/arch/arm/include/asm/global_data.h index 6ee2a76761..cd6112dfcd 100644 --- a/arch/arm/include/asm/global_data.h +++ b/arch/arm/include/asm/global_data.h @@ -101,7 +101,7 @@ struct arch_global_data { #include -#if defined(__clang__) || defined(CONFIG_LTO) +#if defined(__clang__) || defined(LTO_ENABLE) #define DECLARE_GLOBAL_DATA_PTR #define gd get_gd() diff --git a/doc/build/gcc.rst b/doc/build/gcc.rst index ee544ad87e..a71f860a48 100644 --- a/doc/build/gcc.rst +++ b/doc/build/gcc.rst @@ -152,6 +152,23 @@ of dtc is new enough. It also makes sure that pylibfdt is present, if needed Note that the :doc:`tools` are always built with the included version of libfdt so it is not possible to build U-Boot tools with a system libfdt, at present. +Link-time optimisation (LTO) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +U-Boot supports link-time optimisation which can reduce the size of the final +U-Boot binaries, particularly with SPL. + +At present this can be enabled by ARM boards by adding `CONFIG_LTO=y` into the +defconfig file. Other architectures are not supported. LTO is enabled by default +for sandbox. + +This does incur a link-time penalty of several seconds. For faster incremental +builds during development, you can disable it by setting `NO_LTO` to `1`. + +.. code-block:: bash + + NO_LTO=1 make + Other build targets ~~~~~~~~~~~~~~~~~~~ diff --git a/scripts/Makefile.spl b/scripts/Makefile.spl index 3bafeb4fe9..0b3a51da13 100644 --- a/scripts/Makefile.spl +++ b/scripts/Makefile.spl @@ -489,7 +489,7 @@ endif # Rule to link u-boot-spl # May be overridden by arch/$(ARCH)/config.mk -ifdef CONFIG_LTO +ifeq ($(LTO_ENABLE),y) quiet_cmd_u-boot-spl ?= LTO $@ cmd_u-boot-spl ?= \ ( \ From 1aa168ca8fa472620a0aa72ff10b6eb4d0414e03 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 3 Aug 2022 12:13:09 -0600 Subject: [PATCH 038/374] ci: Add a test for a non-LTO build Check that sandbox builds and runs tests OK with LTO disabled. Signed-off-by: Simon Glass --- .azure-pipelines.yml | 4 ++++ .gitlab-ci.yml | 7 +++++++ 2 files changed, 11 insertions(+) diff --git a/.azure-pipelines.yml b/.azure-pipelines.yml index 0fa92479b4..d78a170d0c 100644 --- a/.azure-pipelines.yml +++ b/.azure-pipelines.yml @@ -243,6 +243,9 @@ stages: sandbox_clang: TEST_PY_BD: "sandbox" OVERRIDE: "-O clang-13" + sandbox_nolto: + TEST_PY_BD: "sandbox" + BUILD_ENV: "NO_LTO=1" sandbox_spl: TEST_PY_BD: "sandbox_spl" TEST_PY_TEST_SPEC: "test_ofplatdata or test_handoff or test_spl" @@ -354,6 +357,7 @@ stages: export TEST_PY_ID="${TEST_PY_ID}" export TEST_PY_TEST_SPEC="${TEST_PY_TEST_SPEC}" export OVERRIDE="${OVERRIDE}" + export BUILD_ENV="${BUILD_ENV}" EOF cat << "EOF" >> test.sh # the below corresponds to .gitlab-ci.yml "before_script" diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 5592862f74..8e94bf8d4e 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -33,6 +33,7 @@ stages: script: # If we've been asked to use clang only do one configuration. - export UBOOT_TRAVIS_BUILD_DIR=/tmp/${TEST_PY_BD} + - echo BUILD_ENV ${BUILD_ENV} - tools/buildman/buildman -o ${UBOOT_TRAVIS_BUILD_DIR} -w -E -W -e --board ${TEST_PY_BD} ${OVERRIDE} - cp ~/grub_x86.efi $UBOOT_TRAVIS_BUILD_DIR/ @@ -254,6 +255,12 @@ sandbox with clang test.py: OVERRIDE: "-O clang-13" <<: *buildman_and_testpy_dfn +sandbox without LTO test.py: + variables: + TEST_PY_BD: "sandbox" + BUILD_ENV: "NO_LTO=1" + <<: *buildman_and_testpy_dfn + sandbox_spl test.py: variables: TEST_PY_BD: "sandbox_spl" From e033c180d0327e8fa791660ae26cdebd5e400153 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 1 Aug 2022 07:58:44 -0600 Subject: [PATCH 039/374] dm: rtc: Make use of ut_assertnonnull() Use this (newish) macro since it is designed for the purpose of making sure things are non-NULL. Signed-off-by: Simon Glass --- test/dm/rtc.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/test/dm/rtc.c b/test/dm/rtc.c index c7f9f8f0ce..a8349756c1 100644 --- a/test/dm/rtc.c +++ b/test/dm/rtc.c @@ -66,7 +66,7 @@ static int dm_test_rtc_set_get(struct unit_test_state *uts) ut_assertok(dm_rtc_get(dev, &now)); ut_assertok(i2c_emul_find(dev, &emul)); - ut_assert(emul != NULL); + ut_assertnonnull(emul); /* Tell the RTC to go into manual mode */ old_offset = sandbox_i2c_rtc_set_offset(emul, false, 0); @@ -161,7 +161,7 @@ static int dm_test_rtc_read_write(struct unit_test_state *uts) ut_asserteq(memcmp(buf, "at", 3), 0); ut_assertok(i2c_emul_find(dev, &emul)); - ut_assert(emul != NULL); + ut_assertnonnull(emul); old_offset = sandbox_i2c_rtc_set_offset(emul, false, 0); ut_assertok(dm_rtc_get(dev, &time)); @@ -245,7 +245,7 @@ static int dm_test_rtc_reset(struct unit_test_state *uts) ut_assertok(dm_rtc_get(dev, &now)); ut_assertok(i2c_emul_find(dev, &emul)); - ut_assert(emul != NULL); + ut_assertnonnull(emul); old_base_time = sandbox_i2c_rtc_get_set_base_time(emul, 0); @@ -274,9 +274,9 @@ static int dm_test_rtc_dual(struct unit_test_state *uts) ut_assertok(dm_rtc_get(dev2, &now2)); ut_assertok(i2c_emul_find(dev1, &emul1)); - ut_assert(emul1 != NULL); + ut_assertnonnull(emul1); ut_assertok(i2c_emul_find(dev2, &emul2)); - ut_assert(emul2 != NULL); + ut_assertnonnull(emul2); offset = sandbox_i2c_rtc_set_offset(emul1, false, -1); sandbox_i2c_rtc_set_offset(emul2, false, offset + 1); From ea94d053e19ee3341301cf999a8dd78e37b83cca Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 1 Aug 2022 07:58:45 -0600 Subject: [PATCH 040/374] test: Allow running tests multiple times Some tests can have race conditions which are hard to detect on a single one. Add a way to run tests more than once, to help with this. Each individual test is run the requested number of times before moving to the next test. If any runs failed, a message is shown. This is most useful when running a single test, since running all tests multiple times can take a while. Signed-off-by: Simon Glass --- arch/sandbox/cpu/spl.c | 2 +- doc/develop/tests_sandbox.rst | 24 ++++++++++++++++++++++++ include/test/test.h | 2 ++ include/test/ut.h | 3 ++- test/cmd_ut.c | 12 ++++++++++-- test/dm/test-dm.c | 13 ++++++++++--- test/test-main.c | 14 +++++++++++--- 7 files changed, 60 insertions(+), 10 deletions(-) diff --git a/arch/sandbox/cpu/spl.c b/arch/sandbox/cpu/spl.c index fe5d44d36e..1d49a9bd10 100644 --- a/arch/sandbox/cpu/spl.c +++ b/arch/sandbox/cpu/spl.c @@ -89,7 +89,7 @@ void spl_board_init(void) int ret; ret = ut_run_list("spl", NULL, tests, count, - state->select_unittests); + state->select_unittests, 1); /* continue execution into U-Boot */ } } diff --git a/doc/develop/tests_sandbox.rst b/doc/develop/tests_sandbox.rst index 40cf8ecdd7..8e42a32afb 100644 --- a/doc/develop/tests_sandbox.rst +++ b/doc/develop/tests_sandbox.rst @@ -119,6 +119,30 @@ You can easily use gdb on these tests, without needing --gdbserver:: You can then single-step and look at variables as needed. +Running tests multiple times +---------------------------- + +Some tests can have race conditions which are hard to detect on a single +one. It is possible to run each individual test multiple times, before moving +to the next test, with the '-r' flag. + +This is most useful when running a single test, since running all tests +multiple times can take a while. + +For example:: + + => ut dm -r1000 dm_test_rtc_set_get + ... + Test: dm_test_rtc_set_get: rtc.c (flat tree) + Test: dm_test_rtc_set_get: rtc.c + test/dm/rtc.c:257, dm_test_rtc_reset(): old_base_time == base_time: Expected 0x62e7453c (1659323708), got 0x62e7453d (1659323709) + Test: dm_test_rtc_set_get: rtc.c (flat tree) + Test: dm_test_rtc_set_get: rtc.c + Test: dm_test_rtc_set_get: rtc.c (flat tree) + ... + Test dm_test_rtc_reset failed 3 times + + Running sandbox_spl tests directly ---------------------------------- diff --git a/include/test/test.h b/include/test/test.h index c888d68b1e..2b68331b54 100644 --- a/include/test/test.h +++ b/include/test/test.h @@ -20,6 +20,7 @@ * @testdev: Test device * @force_fail_alloc: Force all memory allocs to fail * @skip_post_probe: Skip uclass post-probe processing + * @runs_per_test: Number of times to run each test (typically 1) * @expect_str: Temporary string used to hold expected string value * @actual_str: Temporary string used to hold actual string value */ @@ -32,6 +33,7 @@ struct unit_test_state { struct udevice *testdev; int force_fail_alloc; int skip_post_probe; + int runs_per_test; char expect_str[512]; char actual_str[512]; }; diff --git a/include/test/ut.h b/include/test/ut.h index 18740f5807..f7d1d18f7c 100644 --- a/include/test/ut.h +++ b/include/test/ut.h @@ -403,9 +403,10 @@ void test_set_state(struct unit_test_state *uts); * @count: Number of tests to run * @select_name: Name of a single test to run (from the list provided). If NULL * then all tests are run + * @runs_per_test: Number of times to run each test (typically 1) * Return: 0 if all tests passed, -1 if any failed */ int ut_run_list(const char *name, const char *prefix, struct unit_test *tests, - int count, const char *select_name); + int count, const char *select_name, int runs_per_test); #endif diff --git a/test/cmd_ut.c b/test/cmd_ut.c index 3789c6b784..11c219b48a 100644 --- a/test/cmd_ut.c +++ b/test/cmd_ut.c @@ -18,10 +18,17 @@ int cmd_ut_category(const char *name, const char *prefix, struct unit_test *tests, int n_ents, int argc, char *const argv[]) { + int runs_per_text = 1; int ret; + if (argc > 1 && !strncmp("-r", argv[1], 2)) { + runs_per_text = dectoul(argv[1] + 2, NULL); + argv++; + argc++; + } + ret = ut_run_list(name, prefix, tests, n_ents, - argc > 1 ? argv[1] : NULL); + argc > 1 ? argv[1] : NULL, runs_per_text); return ret ? CMD_RET_FAILURE : 0; } @@ -168,7 +175,8 @@ static char ut_help_text[] = #ifdef CONFIG_CMD_LOADM "ut loadm [test-name]- test of parameters and load memory blob\n" #endif - ; + "All commands accept an optional [-r] flag before [test-name], to\n" + "run each test multiple times ( is in decimal)"; #endif /* CONFIG_SYS_LONGHELP */ U_BOOT_CMD( diff --git a/test/dm/test-dm.c b/test/dm/test-dm.c index f5cda81bbf..eb3581333b 100644 --- a/test/dm/test-dm.c +++ b/test/dm/test-dm.c @@ -29,13 +29,14 @@ DECLARE_GLOBAL_DATA_PTR; * "fdt_pre_reloc"), or NULL to run all * Return: 0 if all tests passed, 1 if not */ -static int dm_test_run(const char *test_name) +static int dm_test_run(const char *test_name, int runs_per_text) { struct unit_test *tests = UNIT_TEST_SUITE_START(dm_test); const int n_ents = UNIT_TEST_SUITE_COUNT(dm_test); int ret; - ret = ut_run_list("driver model", "dm_test_", tests, n_ents, test_name); + ret = ut_run_list("driver model", "dm_test_", tests, n_ents, test_name, + runs_per_text); return ret ? CMD_RET_FAILURE : 0; } @@ -43,9 +44,15 @@ static int dm_test_run(const char *test_name) int do_ut_dm(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) { const char *test_name = NULL; + int runs_per_text = 1; + if (argc > 1 && !strncmp("-r", argv[1], 2)) { + runs_per_text = dectoul(argv[1] + 2, NULL); + argv++; + argc++; + } if (argc > 1) test_name = argv[1]; - return dm_test_run(test_name); + return dm_test_run(test_name, runs_per_text); } diff --git a/test/test-main.c b/test/test-main.c index 31837e57a8..4f1c54b0f9 100644 --- a/test/test-main.c +++ b/test/test-main.c @@ -390,11 +390,17 @@ static int ut_run_tests(struct unit_test_state *uts, const char *prefix, for (test = tests; test < tests + count; test++) { const char *test_name = test->name; - int ret; + int ret, i, old_fail_count; if (!test_matches(prefix, test_name, select_name)) continue; - ret = ut_run_test_live_flat(uts, test, select_name); + old_fail_count = uts->fail_count; + for (i = 0; i < uts->runs_per_test; i++) + ret = ut_run_test_live_flat(uts, test, select_name); + if (uts->fail_count != old_fail_count) { + printf("Test %s failed %d times\n", select_name, + uts->fail_count - old_fail_count); + } found++; if (ret == -EAGAIN) continue; @@ -408,7 +414,8 @@ static int ut_run_tests(struct unit_test_state *uts, const char *prefix, } int ut_run_list(const char *category, const char *prefix, - struct unit_test *tests, int count, const char *select_name) + struct unit_test *tests, int count, const char *select_name, + int runs_per_test) { struct unit_test_state uts = { .fail_count = 0 }; bool has_dm_tests = false; @@ -432,6 +439,7 @@ int ut_run_list(const char *category, const char *prefix, printf("Running %d %s tests\n", count, category); uts.of_root = gd_of_root(); + uts.runs_per_test = runs_per_test; ret = ut_run_tests(&uts, prefix, tests, count, select_name); if (ret == -ENOENT) From c4d7247a389ae2770ddcdada5143401068a696c0 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 1 Aug 2022 07:58:46 -0600 Subject: [PATCH 041/374] dm: rtc: Avoid a race in the rtc_reset test Since resetting the RTC on sandbox causes it to read the base time from the system, we cannot rely on this being unchanged since it was last read. Allow for a one-second delay. Reviewed-by: Heinrich Schuchardt Fixes: https://source.denx.de/u-boot/u-boot/-/issues/4 Reported-by: Bin Meng Reported-by: Tom Rini Suggested-by: Rasmus Villemoes Signed-off-by: Simon Glass --- test/dm/rtc.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/test/dm/rtc.c b/test/dm/rtc.c index a8349756c1..e23905b3e2 100644 --- a/test/dm/rtc.c +++ b/test/dm/rtc.c @@ -251,10 +251,15 @@ static int dm_test_rtc_reset(struct unit_test_state *uts) ut_asserteq(0, sandbox_i2c_rtc_get_set_base_time(emul, -1)); - /* Resetting the RTC should put he base time back to normal */ + /* + * Resetting the RTC should put the base time back to normal. Allow for + * a one-second adjustment in case the time flips over while this + * test process is pre-empted, since reset_time() in i2c_rtc_emul.c + * reads the time from the OS. + */ ut_assertok(dm_rtc_reset(dev)); base_time = sandbox_i2c_rtc_get_set_base_time(emul, -1); - ut_asserteq(old_base_time, base_time); + ut_assert(base_time - old_base_time <= 1); return 0; } From fc7ceae0d5b7a017c3fed88a8bfe2eb3d24058a9 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 1 Aug 2022 07:58:47 -0600 Subject: [PATCH 042/374] dm: rtc: Try to avoid a race in rtc_set_get test It seems that the time can change in between getting it and reading the offset. Check for this and try again if this happens. Signed-off-by: Simon Glass --- test/dm/rtc.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/test/dm/rtc.c b/test/dm/rtc.c index e23905b3e2..50086ffcf3 100644 --- a/test/dm/rtc.c +++ b/test/dm/rtc.c @@ -60,16 +60,27 @@ static int dm_test_rtc_set_get(struct unit_test_state *uts) { struct rtc_time now, time, cmp; struct udevice *dev, *emul; - long offset, old_offset, old_base_time; + long offset, check_offset, old_offset, old_base_time; + int i; ut_assertok(uclass_get_device(UCLASS_RTC, 0, &dev)); - ut_assertok(dm_rtc_get(dev, &now)); ut_assertok(i2c_emul_find(dev, &emul)); ut_assertnonnull(emul); - /* Tell the RTC to go into manual mode */ - old_offset = sandbox_i2c_rtc_set_offset(emul, false, 0); + /* Get the offset, putting the RTC into manual mode */ + i = 0; + do { + check_offset = sandbox_i2c_rtc_set_offset(emul, false, 0); + ut_assertok(dm_rtc_get(dev, &now)); + + /* Tell the RTC to go into manual mode */ + old_offset = sandbox_i2c_rtc_set_offset(emul, false, 0); + + /* If the times changed in that period, read it again */ + } while (++i < 2 && check_offset != old_offset); + ut_asserteq(check_offset, old_offset); + old_base_time = sandbox_i2c_rtc_get_set_base_time(emul, -1); memset(&time, '\0', sizeof(time)); @@ -127,7 +138,8 @@ static int dm_test_rtc_set_get(struct unit_test_state *uts) ut_asserteq(now.tm_sec + 1, cmp.tm_sec); } - old_offset = sandbox_i2c_rtc_set_offset(emul, true, 0); + /* return RTC to normal mode */ + sandbox_i2c_rtc_set_offset(emul, true, 0); return 0; } From 21ddac140e3040b2693c1a5558a84c19a879c04f Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 1 Aug 2022 07:58:48 -0600 Subject: [PATCH 043/374] dm: rtc: Try to handle the localtime() race At present the sandbox timer uses localtime() which can jump around twice a year when daylight-saving time changes. It would be tricky to make use of gmtime() since we still need to present the time in local time, as seems to be required by U-Boot's RTC interface. The problem can only happen once, so use a loop to detect it and try again. This should be sufficient to detect either a change in the 'second' value, or a daylight-saving change. We can assume that the latter also incorporates a 'second' change, so there is no need to loop more than twice. Signed-off-by: Simon Glass --- test/dm/rtc.c | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/test/dm/rtc.c b/test/dm/rtc.c index 50086ffcf3..bf97dbbd2f 100644 --- a/test/dm/rtc.c +++ b/test/dm/rtc.c @@ -252,6 +252,7 @@ static int dm_test_rtc_reset(struct unit_test_state *uts) struct rtc_time now; struct udevice *dev, *emul; long old_base_time, base_time; + int i; ut_assertok(uclass_get_device(UCLASS_RTC, 0, &dev)); ut_assertok(dm_rtc_get(dev, &now)); @@ -259,19 +260,24 @@ static int dm_test_rtc_reset(struct unit_test_state *uts) ut_assertok(i2c_emul_find(dev, &emul)); ut_assertnonnull(emul); - old_base_time = sandbox_i2c_rtc_get_set_base_time(emul, 0); + i = 0; + do { + old_base_time = sandbox_i2c_rtc_get_set_base_time(emul, 0); - ut_asserteq(0, sandbox_i2c_rtc_get_set_base_time(emul, -1)); + ut_asserteq(0, sandbox_i2c_rtc_get_set_base_time(emul, -1)); - /* - * Resetting the RTC should put the base time back to normal. Allow for - * a one-second adjustment in case the time flips over while this - * test process is pre-empted, since reset_time() in i2c_rtc_emul.c - * reads the time from the OS. - */ - ut_assertok(dm_rtc_reset(dev)); - base_time = sandbox_i2c_rtc_get_set_base_time(emul, -1); - ut_assert(base_time - old_base_time <= 1); + ut_assertok(dm_rtc_reset(dev)); + base_time = sandbox_i2c_rtc_get_set_base_time(emul, -1); + + /* + * Resetting the RTC should put the base time back to normal. + * Allow for a one-timeadjustment in case the time flips over + * while this test process is pre-empted (either by a second + * or a daylight-saving change), since reset_time() in + * i2c_rtc_emul.c reads the time from the OS. + */ + } while (++i < 2 && base_time != old_base_time); + ut_asserteq(old_base_time, base_time); return 0; } From b7e0750d8872af4f294ec46533fe5243514dcb59 Mon Sep 17 00:00:00 2001 From: Stefan Herbrechtsmeier Date: Fri, 5 Aug 2022 08:16:28 +0200 Subject: [PATCH 044/374] zynq: Convert arm twd timer to DM driver Move arm twd timer driver from zynq to generic location. DM timer drivers are designed differently to original driver. Timer is counting up and not down. Information about clock rates are find out in timer_pre_probe() that's why there is no need to get any additional information from DT in the driver itself (only register offset). Signed-off-by: Stefan Herbrechtsmeier Link: https://lore.kernel.org/r/20220805061629.1207-1-stefan.herbrechtsmeier-oss@weidmueller.com Signed-off-by: Michal Simek --- arch/arm/Kconfig | 3 + arch/arm/dts/zynq-7000.dtsi | 1 + arch/arm/mach-zynq/Makefile | 1 - arch/arm/mach-zynq/clk.c | 6 +- arch/arm/mach-zynq/timer.c | 113 ---------------------------------- drivers/timer/Kconfig | 6 ++ drivers/timer/Makefile | 1 + drivers/timer/arm_twd_timer.c | 108 ++++++++++++++++++++++++++++++++ 8 files changed, 123 insertions(+), 116 deletions(-) delete mode 100644 arch/arm/mach-zynq/timer.c create mode 100644 drivers/timer/arm_twd_timer.c diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index d6c5658ee8..3649222470 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1259,6 +1259,7 @@ config ARCH_VF610 config ARCH_ZYNQ bool "Xilinx Zynq based platform" + select ARM_TWD_TIMER select CLK select CLK_ZYNQ select CPU_V7A @@ -1278,7 +1279,9 @@ config ARCH_ZYNQ select SPL_DM_SPI_FLASH if SPL select SPL_OF_CONTROL if SPL select SPL_SEPARATE_BSS if SPL + select SPL_TIMER if SPL select SUPPORT_SPL + select TIMER imply ARCH_EARLY_INIT_R imply BOARD_LATE_INIT imply CMD_CLK diff --git a/arch/arm/dts/zynq-7000.dtsi b/arch/arm/dts/zynq-7000.dtsi index 37155df0fd..a7ca00fb76 100644 --- a/arch/arm/dts/zynq-7000.dtsi +++ b/arch/arm/dts/zynq-7000.dtsi @@ -416,6 +416,7 @@ }; scutimer: timer@f8f00600 { + u-boot,dm-pre-reloc; interrupt-parent = <&intc>; interrupts = <1 13 0x301>; compatible = "arm,cortex-a9-twd-timer"; diff --git a/arch/arm/mach-zynq/Makefile b/arch/arm/mach-zynq/Makefile index 8737f434d9..d9b2b999e1 100644 --- a/arch/arm/mach-zynq/Makefile +++ b/arch/arm/mach-zynq/Makefile @@ -6,7 +6,6 @@ # (C) Copyright 2008 # Guennadi Liakhovetki, DENX Software Engineering, -obj-y := timer.o obj-y += cpu.o obj-y += ddrc.o obj-y += slcr.o diff --git a/arch/arm/mach-zynq/clk.c b/arch/arm/mach-zynq/clk.c index 27f6bf2183..1945f60e08 100644 --- a/arch/arm/mach-zynq/clk.c +++ b/arch/arm/mach-zynq/clk.c @@ -52,10 +52,12 @@ int set_cpu_clk_info(void) return ret; rate = clk_get_rate(&clk) / 1000000; - if (i) + if (i) { gd->bd->bi_ddr_freq = rate; - else + } else { gd->bd->bi_arm_freq = rate; + gd->cpu_clk = clk_get_rate(&clk); + } clk_free(&clk); } diff --git a/arch/arm/mach-zynq/timer.c b/arch/arm/mach-zynq/timer.c deleted file mode 100644 index a51822a530..0000000000 --- a/arch/arm/mach-zynq/timer.c +++ /dev/null @@ -1,113 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Copyright (C) 2017 Weidmüller Interface GmbH & Co. KG - * Stefan Herbrechtsmeier - * - * Copyright (C) 2012 Michal Simek - * Copyright (C) 2011-2017 Xilinx, Inc. All rights reserved. - * - * (C) Copyright 2008 - * Guennadi Liakhovetki, DENX Software Engineering, - * - * (C) Copyright 2004 - * Philippe Robin, ARM Ltd. - * - * (C) Copyright 2002-2004 - * Gary Jennejohn, DENX Software Engineering, - * - * (C) Copyright 2003 - * Texas Instruments - * - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Marius Groeger - * - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Alex Zuepke - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -DECLARE_GLOBAL_DATA_PTR; - -struct scu_timer { - u32 load; /* Timer Load Register */ - u32 counter; /* Timer Counter Register */ - u32 control; /* Timer Control Register */ -}; - -static struct scu_timer *timer_base = - (struct scu_timer *)ZYNQ_SCUTIMER_BASEADDR; - -#define SCUTIMER_CONTROL_PRESCALER_MASK 0x0000FF00 /* Prescaler */ -#define SCUTIMER_CONTROL_PRESCALER_SHIFT 8 -#define SCUTIMER_CONTROL_AUTO_RELOAD_MASK 0x00000002 /* Auto-reload */ -#define SCUTIMER_CONTROL_ENABLE_MASK 0x00000001 /* Timer enable */ - -#define TIMER_LOAD_VAL 0xFFFFFFFF -#define TIMER_PRESCALE 255 - -int timer_init(void) -{ - const u32 emask = SCUTIMER_CONTROL_AUTO_RELOAD_MASK | - (TIMER_PRESCALE << SCUTIMER_CONTROL_PRESCALER_SHIFT) | - SCUTIMER_CONTROL_ENABLE_MASK; - - struct udevice *dev; - struct clk clk; - int ret; - - ret = uclass_get_device_by_driver(UCLASS_CLK, - DM_DRIVER_GET(zynq_clk), &dev); - if (ret) - return ret; - - clk.id = cpu_6or4x_clk; - ret = clk_request(dev, &clk); - if (ret < 0) - return ret; - - gd->cpu_clk = clk_get_rate(&clk); - - clk_free(&clk); - - gd->arch.timer_rate_hz = (gd->cpu_clk / 2) / (TIMER_PRESCALE + 1); - - /* Load the timer counter register */ - writel(0xFFFFFFFF, &timer_base->load); - - /* - * Start the A9Timer device - * Enable Auto reload mode, Clear prescaler control bits - * Set prescaler value, Enable the decrementer - */ - clrsetbits_le32(&timer_base->control, SCUTIMER_CONTROL_PRESCALER_MASK, - emask); - - /* Reset time */ - gd->arch.lastinc = readl(&timer_base->counter) / - (gd->arch.timer_rate_hz / CONFIG_SYS_HZ); - gd->arch.tbl = 0; - - return 0; -} - -/* - * This function is derived from PowerPC code (timebase clock frequency). - * On ARM it returns the number of timer ticks per second. - */ -ulong get_tbclk(void) -{ - return gd->arch.timer_rate_hz; -} diff --git a/drivers/timer/Kconfig b/drivers/timer/Kconfig index 4049290148..1b49236039 100644 --- a/drivers/timer/Kconfig +++ b/drivers/timer/Kconfig @@ -73,6 +73,12 @@ config ARC_TIMER usually at least one of them exists. Either of them is supported in U-Boot. +config ARM_TWD_TIMER + bool "ARM timer watchdog (TWD) timer support" + depends on TIMER && CLK + help + Select this to enable support for the ARM global timer watchdog timer. + config AST_TIMER bool "Aspeed ast2400/ast2500 timer support" depends on TIMER diff --git a/drivers/timer/Makefile b/drivers/timer/Makefile index 560e2d27e1..7bfb7749e9 100644 --- a/drivers/timer/Makefile +++ b/drivers/timer/Makefile @@ -6,6 +6,7 @@ obj-y += timer-uclass.o obj-$(CONFIG_ALTERA_TIMER) += altera_timer.o obj-$(CONFIG_ANDES_PLMT_TIMER) += andes_plmt_timer.o obj-$(CONFIG_ARC_TIMER) += arc_timer.o +obj-$(CONFIG_ARM_TWD_TIMER) += arm_twd_timer.o obj-$(CONFIG_AST_TIMER) += ast_timer.o obj-$(CONFIG_ATCPIT100_TIMER) += atcpit100_timer.o obj-$(CONFIG_$(SPL_)ATMEL_PIT_TIMER) += atmel_pit_timer.o diff --git a/drivers/timer/arm_twd_timer.c b/drivers/timer/arm_twd_timer.c new file mode 100644 index 0000000000..40ccd16587 --- /dev/null +++ b/drivers/timer/arm_twd_timer.c @@ -0,0 +1,108 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2017-2022 Weidmüller Interface GmbH & Co. KG + * Stefan Herbrechtsmeier + * + * Copyright (C) 2012 Michal Simek + * Copyright (C) 2011-2017 Xilinx, Inc. All rights reserved. + * + * (C) Copyright 2008 + * Guennadi Liakhovetki, DENX Software Engineering, + * + * (C) Copyright 2004 + * Philippe Robin, ARM Ltd. + * + * (C) Copyright 2002-2004 + * Gary Jennejohn, DENX Software Engineering, + * + * (C) Copyright 2003 + * Texas Instruments + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Marius Groeger + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Alex Zuepke + */ + +#include +#include +#include +#include +#include + +#include + +#define SCUTIMER_CONTROL_PRESCALER_MASK 0x0000FF00 /* Prescaler */ +#define SCUTIMER_CONTROL_AUTO_RELOAD_MASK 0x00000002 /* Auto-reload */ +#define SCUTIMER_CONTROL_ENABLE_MASK 0x00000001 /* Timer enable */ + +#define TIMER_LOAD_VAL 0xFFFFFFFF + +struct arm_twd_timer_regs { + u32 load; /* Timer Load Register */ + u32 counter; /* Timer Counter Register */ + u32 control; /* Timer Control Register */ +}; + +struct arm_twd_timer_priv { + struct arm_twd_timer_regs *base; +}; + +static u64 arm_twd_timer_get_count(struct udevice *dev) +{ + struct arm_twd_timer_priv *priv = dev_get_priv(dev); + struct arm_twd_timer_regs *regs = priv->base; + u32 count = TIMER_LOAD_VAL - readl(®s->counter); + + return timer_conv_64(count); +} + +static int arm_twd_timer_probe(struct udevice *dev) +{ + struct arm_twd_timer_priv *priv = dev_get_priv(dev); + struct arm_twd_timer_regs *regs; + fdt_addr_t addr; + + addr = dev_read_addr(dev); + if (addr == FDT_ADDR_T_NONE) + return -EINVAL; + + priv->base = (struct arm_twd_timer_regs *)addr; + + regs = priv->base; + + /* Load the timer counter register */ + writel(0xFFFFFFFF, ®s->load); + + /* + * Start the A9Timer device + * Enable Auto reload mode, Clear prescaler control bits + * Set prescaler value, Enable the decrementer + */ + clrsetbits_le32(®s->control, SCUTIMER_CONTROL_PRESCALER_MASK, + SCUTIMER_CONTROL_AUTO_RELOAD_MASK | + SCUTIMER_CONTROL_ENABLE_MASK); + + return 0; +} + +static const struct timer_ops arm_twd_timer_ops = { + .get_count = arm_twd_timer_get_count, +}; + +static const struct udevice_id arm_twd_timer_ids[] = { + { .compatible = "arm,cortex-a9-twd-timer" }, + {} +}; + +U_BOOT_DRIVER(arm_twd_timer) = { + .name = "arm_twd_timer", + .id = UCLASS_TIMER, + .of_match = arm_twd_timer_ids, + .priv_auto = sizeof(struct arm_twd_timer_priv), + .probe = arm_twd_timer_probe, + .ops = &arm_twd_timer_ops, +}; From 7a0bc18b6309be421b7968ee70efb54c9e3d59dd Mon Sep 17 00:00:00 2001 From: Stefan Herbrechtsmeier Date: Mon, 8 Aug 2022 16:53:31 +0200 Subject: [PATCH 045/374] fpga: zynq: Remove post config info message for SPL The drivers informs the user that a post config was not run after FPGA configuration. This message is unnecessary in SPL because the ps7_post_config function is called via spl_board_prepare_for_boot function before jump_to_image_no_args function from board_init_r function. Signed-off-by: Stefan Herbrechtsmeier Link: https://lore.kernel.org/r/20220808145331.24723-1-stefan.herbrechtsmeier-oss@weidmueller.com Signed-off-by: Michal Simek --- drivers/fpga/zynqpl.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/fpga/zynqpl.c b/drivers/fpga/zynqpl.c index d8ebd542ab..0c83df46da 100644 --- a/drivers/fpga/zynqpl.c +++ b/drivers/fpga/zynqpl.c @@ -413,7 +413,8 @@ static int zynq_load(xilinx_desc *desc, const void *buf, size_t bsize, if (bstype != BIT_PARTIAL) zynq_slcr_devcfg_enable(); - puts("INFO:post config was not run, please run manually if needed\n"); + if (!IS_ENABLED(CONFIG_SPL_BUILD)) + puts("INFO:post config was not run, please run manually if needed\n"); return FPGA_SUCCESS; } From cf5c48d102bd50eb24eb03ddd5cc1f0c33a3f57a Mon Sep 17 00:00:00 2001 From: Janne Ylalehto Date: Tue, 16 Aug 2022 15:45:25 +0300 Subject: [PATCH 046/374] xilinx: zynqmp: Fix AES with a user provided key The user provided key address was not flushed in struct aes because of the flushing location in the function. Signed-off-by: Janne Ylalehto Link: https://lore.kernel.org/r/20220816124525.19671-1-ylalehto@gmail.com Signed-off-by: Michal Simek --- board/xilinx/zynqmp/cmds.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/board/xilinx/zynqmp/cmds.c b/board/xilinx/zynqmp/cmds.c index 2ab9596248..e20030ecda 100644 --- a/board/xilinx/zynqmp/cmds.c +++ b/board/xilinx/zynqmp/cmds.c @@ -142,9 +142,6 @@ static int do_zynqmp_aes(struct cmd_tbl *cmdtp, int flag, int argc, aes->keysrc = hextoul(argv[6], NULL); aes->dstaddr = hextoul(argv[7], NULL); - flush_dcache_range((ulong)aes, (ulong)(aes) + - roundup(sizeof(struct aes), ARCH_DMA_MINALIGN)); - if (aes->srcaddr && aes->ivaddr && aes->dstaddr) { flush_dcache_range(aes->srcaddr, (aes->srcaddr + @@ -169,6 +166,9 @@ static int do_zynqmp_aes(struct cmd_tbl *cmdtp, int flag, int argc, ARCH_DMA_MINALIGN))); } + flush_dcache_range((ulong)aes, (ulong)(aes) + + roundup(sizeof(struct aes), ARCH_DMA_MINALIGN)); + ret = xilinx_pm_request(PM_SECURE_AES, upper_32_bits((ulong)aes), lower_32_bits((ulong)aes), 0, 0, ret_payload); if (ret || ret_payload[1]) From 86cba52a981ddab898ff4a7b079437fac497c1e6 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Fri, 5 Aug 2022 11:19:53 +0200 Subject: [PATCH 047/374] xilinx: versal: Enable i2c mux uclass with pca954x driver Xilinx is using pca954x i2c muxes on a lot of boards that's why enable this driver by default. Signed-off-by: Michal Simek Link: https://lore.kernel.org/r/c090aea3436c7a4ebe698da6cbc70e70a14baae3.1659691195.git.michal.simek@amd.com --- configs/xilinx_versal_virt_defconfig | 2 ++ 1 file changed, 2 insertions(+) diff --git a/configs/xilinx_versal_virt_defconfig b/configs/xilinx_versal_virt_defconfig index 6e61abd0c6..c4d7aac7b5 100644 --- a/configs/xilinx_versal_virt_defconfig +++ b/configs/xilinx_versal_virt_defconfig @@ -69,6 +69,8 @@ CONFIG_FPGA_XILINX=y CONFIG_FPGA_VERSALPL=y CONFIG_DM_I2C=y CONFIG_SYS_I2C_CADENCE=y +CONFIG_I2C_MUX=y +CONFIG_I2C_MUX_PCA954x=y CONFIG_DM_MAILBOX=y CONFIG_ZYNQMP_IPI=y CONFIG_MISC=y From 2fb4b5ae54704f8e334a1491c4c9f2f90958456b Mon Sep 17 00:00:00 2001 From: Ashok Reddy Soma Date: Fri, 5 Aug 2022 11:19:54 +0200 Subject: [PATCH 048/374] xilinx: zynqmp: Disable various configs for mini U-Boot With 2022.01-rc3 upgrade, the size of the mini U-Boot increased and is not able to fit in OCM. Hence disable unnecessary configs and make room. Signed-off-by: Ashok Reddy Soma Signed-off-by: Michal Simek Link: https://lore.kernel.org/r/306b57818601fa3571bc75c4182f25aaa3f2a793.1659691195.git.michal.simek@amd.com --- configs/xilinx_zynqmp_mini_qspi_defconfig | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/configs/xilinx_zynqmp_mini_qspi_defconfig b/configs/xilinx_zynqmp_mini_qspi_defconfig index e6d4308347..d0cc0360d2 100644 --- a/configs/xilinx_zynqmp_mini_qspi_defconfig +++ b/configs/xilinx_zynqmp_mini_qspi_defconfig @@ -3,7 +3,7 @@ CONFIG_SYS_CONFIG_NAME="xilinx_zynqmp_mini_qspi" CONFIG_SYS_ICACHE_OFF=y CONFIG_ARCH_ZYNQMP=y CONFIG_SYS_TEXT_BASE=0xFFFC0000 -CONFIG_SYS_MALLOC_LEN=0x1a00 +CONFIG_SYS_MALLOC_LEN=0x1b00 CONFIG_NR_DRAM_BANKS=1 CONFIG_ENV_SIZE=0x80 CONFIG_DEFAULT_DEVICE_TREE="zynqmp-mini-qspi" @@ -19,7 +19,9 @@ CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0xfffe0000 # CONFIG_EXPERT is not set CONFIG_REMAKE_ELF=y # CONFIG_LEGACY_IMAGE_FORMAT is not set +# CONFIG_ARCH_FIXUP_FDT_MEMORY is not set # CONFIG_AUTOBOOT is not set +CONFIG_LOGLEVEL=0 # CONFIG_DISPLAY_CPUINFO is not set # CONFIG_BOARD_LATE_INIT is not set CONFIG_CLOCKS=y @@ -62,6 +64,7 @@ CONFIG_SYS_PBSIZE=1049 # CONFIG_CMD_SOURCE is not set # CONFIG_CMD_SETEXPR is not set # CONFIG_CMD_SLEEP is not set +# CONFIG_CMD_MP is not set CONFIG_SPL_OF_CONTROL=y CONFIG_OF_EMBED=y CONFIG_SYS_RELOC_GD_ENV_ADDR=y @@ -69,17 +72,24 @@ CONFIG_SYS_RELOC_GD_ENV_ADDR=y # CONFIG_DM_WARN is not set # CONFIG_DM_DEVICE_REMOVE is not set CONFIG_SPL_DM_SEQ_ALIAS=y +# CONFIG_FIRMWARE is not set +# CONFIG_GPIO is not set +# CONFIG_I2C is not set +# CONFIG_INPUT is not set # CONFIG_MMC is not set -CONFIG_SPI_FLASH_BAR=y +# CONFIG_SPI_FLASH_SMART_HWCAPS is not set +# CONFIG_SPI_FLASH_UNLOCK_ALL is not set CONFIG_SPI_FLASH_ISSI=y CONFIG_SPI_FLASH_MACRONIX=y CONFIG_SPI_FLASH_SPANSION=y CONFIG_SPI_FLASH_STMICRO=y CONFIG_SPI_FLASH_WINBOND=y # CONFIG_SPI_FLASH_USE_4K_SECTORS is not set +# CONFIG_POWER is not set CONFIG_ARM_DCC=y CONFIG_SPI=y CONFIG_ZYNQMP_GQSPI=y +# CONFIG_FAT_WRITE is not set CONFIG_PANIC_HANG=y # CONFIG_GZIP is not set # CONFIG_LMB is not set From 85007da94bad2d27e40e0258fa5437a35034ee1d Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Wed, 7 Sep 2022 09:52:09 +0200 Subject: [PATCH 049/374] cmd: bdinfo: Enable dumping lmb data when LMB is enabled The commit 9996cea75f5a ("lmb/bdinfo: dump lmb info via bdinfo") added support for dumping LMB information as the part of bdinfo. But code itself should be called only when LMB is enabled. Signed-off-by: Michal Simek Reviewed-by: Simon Glass Link: https://lore.kernel.org/r/3e40c8bb77550dfca9f7eb48fe644a018d971411.1662537127.git.michal.simek@amd.com --- cmd/bdinfo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/bdinfo.c b/cmd/bdinfo.c index 37cd8a57eb..8a1bea4e34 100644 --- a/cmd/bdinfo.c +++ b/cmd/bdinfo.c @@ -123,7 +123,7 @@ int do_bdinfo(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) #if CONFIG_IS_ENABLED(MULTI_DTB_FIT) bdinfo_print_num_l("multi_dtb_fit", (ulong)gd->multi_dtb_fit); #endif - if (gd->fdt_blob) { + if (IS_ENABLED(CONFIG_LMB) && gd->fdt_blob) { struct lmb lmb; lmb_init_and_reserve(&lmb, gd->bd, (void *)gd->fdt_blob); From d434921defdcde9f858de8e4dd9380156dc60ad1 Mon Sep 17 00:00:00 2001 From: Ashok Reddy Soma Date: Fri, 5 Aug 2022 11:19:55 +0200 Subject: [PATCH 050/374] xilinx: zynqmp: Disable LMB for mini u-boot LMB is not required for mini u-boot which runs out of on chip memory. Disable CONFIG_LMB from mini u-boot defconfig's. Signed-off-by: Ashok Reddy Soma Signed-off-by: Michal Simek Link: https://lore.kernel.org/r/45fad28825f0f236ad45e700aca1f39afbb22236.1659691195.git.michal.simek@amd.com --- configs/xilinx_zynqmp_mini_nand_defconfig | 1 + configs/xilinx_zynqmp_mini_nand_single_defconfig | 1 + 2 files changed, 2 insertions(+) diff --git a/configs/xilinx_zynqmp_mini_nand_defconfig b/configs/xilinx_zynqmp_mini_nand_defconfig index a2405f24ef..e6054fe177 100644 --- a/configs/xilinx_zynqmp_mini_nand_defconfig +++ b/configs/xilinx_zynqmp_mini_nand_defconfig @@ -65,3 +65,4 @@ CONFIG_SYS_NAND_MAX_CHIPS=2 CONFIG_ARM_DCC=y CONFIG_PANIC_HANG=y # CONFIG_GZIP is not set +# CONFIG_LMB is not set diff --git a/configs/xilinx_zynqmp_mini_nand_single_defconfig b/configs/xilinx_zynqmp_mini_nand_single_defconfig index e6ebc12ed7..aa35b48c72 100644 --- a/configs/xilinx_zynqmp_mini_nand_single_defconfig +++ b/configs/xilinx_zynqmp_mini_nand_single_defconfig @@ -64,3 +64,4 @@ CONFIG_SYS_NAND_ONFI_DETECTION=y CONFIG_ARM_DCC=y CONFIG_PANIC_HANG=y # CONFIG_GZIP is not set +# CONFIG_LMB is not set From 91687c4c3c0c919f120f0cc120b739c6fb26b993 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Tue, 6 Sep 2022 12:41:10 +0200 Subject: [PATCH 051/374] xilinx: zynq: Disable LMB for mini configurations There shouldn't be a reason to have LMB on for these configurations. LMB was already disabled for ZynqMP by commit 0063487a5b60 ("configs: zynqmp: Disable LMB for mini u-boot"). Signed-off-by: Michal Simek Link: https://lore.kernel.org/r/07d95f619a15672d1a234eddcfbb54c0ab382eaa.1662460867.git.michal.simek@amd.com --- configs/zynq_cse_nand_defconfig | 1 + configs/zynq_cse_nor_defconfig | 1 + configs/zynq_cse_qspi_defconfig | 1 + 3 files changed, 3 insertions(+) diff --git a/configs/zynq_cse_nand_defconfig b/configs/zynq_cse_nand_defconfig index b69c8b92a4..22f7456d33 100644 --- a/configs/zynq_cse_nand_defconfig +++ b/configs/zynq_cse_nand_defconfig @@ -79,3 +79,4 @@ CONFIG_NAND_ZYNQ=y CONFIG_SYS_NAND_ONFI_DETECTION=y CONFIG_ARM_DCC=y # CONFIG_GZIP is not set +# CONFIG_LMB is not set diff --git a/configs/zynq_cse_nor_defconfig b/configs/zynq_cse_nor_defconfig index 59cd19ef2d..9f2d33782f 100644 --- a/configs/zynq_cse_nor_defconfig +++ b/configs/zynq_cse_nor_defconfig @@ -81,3 +81,4 @@ CONFIG_SYS_FLASH_CFI=y CONFIG_SYS_FLASH_QUIET_TEST=y CONFIG_ARM_DCC=y # CONFIG_GZIP is not set +# CONFIG_LMB is not set diff --git a/configs/zynq_cse_qspi_defconfig b/configs/zynq_cse_qspi_defconfig index 49dd5ad606..a767224795 100644 --- a/configs/zynq_cse_qspi_defconfig +++ b/configs/zynq_cse_qspi_defconfig @@ -91,3 +91,4 @@ CONFIG_SPI_FLASH_WINBOND=y CONFIG_ARM_DCC=y CONFIG_ZYNQ_QSPI=y # CONFIG_GZIP is not set +# CONFIG_LMB is not set From 2aa11884678654a1bffc20c8ec11fa0fae163bb2 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 6 Aug 2022 17:51:45 -0600 Subject: [PATCH 052/374] test: Fix test_pinmux to run in parallel At present test_pinmux_status() assumes that test_pinmux_dev() has run beforehand. Drop this assumption so we can run the tests in parallel. Signed-off-by: Simon Glass --- test/py/tests/test_pinmux.py | 1 + 1 file changed, 1 insertion(+) diff --git a/test/py/tests/test_pinmux.py b/test/py/tests/test_pinmux.py index b3ae2ab024..794994e12d 100644 --- a/test/py/tests/test_pinmux.py +++ b/test/py/tests/test_pinmux.py @@ -68,6 +68,7 @@ def test_pinmux_dev(u_boot_console): def test_pinmux_status(u_boot_console): """Test that 'pinmux status' displays selected pincontroller's pin muxing descriptions.""" + u_boot_console.run_command('pinmux dev pinctrl') output = u_boot_console.run_command('pinmux status') assert (not 'pinctrl-gpio:' in output) From 44384c70f9e93faa1a494bbf96a9b6c273a996ca Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 6 Aug 2022 17:51:46 -0600 Subject: [PATCH 053/374] test: Fix bootm_test_subst_var() running independently This test relies on the silent_linux env variable being set. Add this to the code so it can run without relying on other bootm tests having been run first. Signed-off-by: Simon Glass --- test/bootm.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/bootm.c b/test/bootm.c index 7d03e1e0c6..4bb3ca0655 100644 --- a/test/bootm.c +++ b/test/bootm.c @@ -208,7 +208,8 @@ BOOTM_TEST(bootm_test_silent_var, 0); /* Test substitution processing in the bootargs variable */ static int bootm_test_subst_var(struct unit_test_state *uts) { - env_set("bootargs", NULL); + ut_assertok(env_set("silent_linux", "yes")); + ut_assertok(env_set("bootargs", NULL)); ut_assertok(bootm_process_cmdline_env(BOOTM_CL_SILENT)); ut_asserteq_str("console=ttynull", env_get("bootargs")); From cc85d905cd28581ccad51f1f4579962ee08989ae Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 6 Aug 2022 17:51:47 -0600 Subject: [PATCH 054/374] test/py: Allow tests to be marked single-threaded only Add a new 'singlethread' marker to allow tests to be skipped when running in parallel. Signed-off-by: Simon Glass --- test/py/conftest.py | 17 +++++++++++++++++ test/py/pytest.ini | 1 + 2 files changed, 18 insertions(+) diff --git a/test/py/conftest.py b/test/py/conftest.py index 2ba34479e0..dbe1acd9e3 100644 --- a/test/py/conftest.py +++ b/test/py/conftest.py @@ -521,6 +521,22 @@ def setup_requiredtool(item): if not tool_is_in_path(tool): pytest.skip('tool "%s" not in $PATH' % tool) +def setup_singlethread(item): + """Process any 'singlethread' marker for a test. + + Skip this test if running in parallel. + + Args: + item: The pytest test item. + + Returns: + Nothing. + """ + for single in item.iter_markers('singlethread'): + worker_id = os.environ.get("PYTEST_XDIST_WORKER") + if worker_id and worker_id != 'master': + pytest.skip('must run single-threaded') + def start_test_section(item): anchors[item.name] = log.start_section(item.name) @@ -541,6 +557,7 @@ def pytest_runtest_setup(item): setup_boardspec(item) setup_buildconfigspec(item) setup_requiredtool(item) + setup_singlethread(item) def pytest_runtest_protocol(item, nextitem): """pytest hook: Called to execute a test. diff --git a/test/py/pytest.ini b/test/py/pytest.ini index e93d010f1f..26d83f83e0 100644 --- a/test/py/pytest.ini +++ b/test/py/pytest.ini @@ -11,3 +11,4 @@ markers = notbuildconfigspec: U-Boot: Describes required disabled Kconfig options. requiredtool: U-Boot: Required host tools for a test. slow: U-Boot: Specific test will run slowly. + singlethread: Cannot run in parallel From 78ac0deafd8d39c17d5ffa1cd64cd5f4ccb7193c Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 6 Aug 2022 17:51:48 -0600 Subject: [PATCH 055/374] test: Make test_bind_unbind_with_uclass() single-threaded This test seems to rely on the other test in this file. Mark it single-threaded to avoid any problems. Signed-off-by: Simon Glass --- test/py/tests/test_bind.py | 1 + 1 file changed, 1 insertion(+) diff --git a/test/py/tests/test_bind.py b/test/py/tests/test_bind.py index c90c54d266..1376ab5ed2 100644 --- a/test/py/tests/test_bind.py +++ b/test/py/tests/test_bind.py @@ -119,6 +119,7 @@ def get_next_line(tree, name): @pytest.mark.boardspec('sandbox') @pytest.mark.buildconfigspec('cmd_bind') +@pytest.mark.singlethread def test_bind_unbind_with_uclass(u_boot_console): #bind /bind-test response = u_boot_console.run_command('bind /bind-test simple_bus') From c620ea45a799b2d18fd567105d60860e86434023 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 6 Aug 2022 17:51:49 -0600 Subject: [PATCH 056/374] test: Update FIT tests to run in parallel Use a different temporary dir for each test, to allow them to run in parallel. Signed-off-by: Simon Glass --- test/py/tests/test_fit_ecdsa.py | 4 +++- test/py/tests/test_fit_hashes.py | 5 ++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/test/py/tests/test_fit_ecdsa.py b/test/py/tests/test_fit_ecdsa.py index 87b6081222..cc6c0c4dc4 100644 --- a/test/py/tests/test_fit_ecdsa.py +++ b/test/py/tests/test_fit_ecdsa.py @@ -10,6 +10,7 @@ signature is then extracted, and verified against pyCryptodome. This test doesn't run the sandbox. It only checks the host tool 'mkimage' """ +import os import pytest import u_boot_utils as util from Cryptodome.Hash import SHA256 @@ -84,7 +85,8 @@ def test_fit_ecdsa(u_boot_console): cons = u_boot_console mkimage = cons.config.build_dir + '/tools/mkimage' datadir = cons.config.source_dir + '/test/py/tests/vboot/' - tempdir = cons.config.result_dir + tempdir = os.path.join(cons.config.result_dir, 'ecdsa') + os.makedirs(tempdir, exist_ok=True) key_file = f'{tempdir}/ecdsa-test-key.pem' fit_file = f'{tempdir}/test.fit' dtc('sandbox-kernel.dts') diff --git a/test/py/tests/test_fit_hashes.py b/test/py/tests/test_fit_hashes.py index e228ea96d3..4891e77ca2 100644 --- a/test/py/tests/test_fit_hashes.py +++ b/test/py/tests/test_fit_hashes.py @@ -10,6 +10,7 @@ output of a fixed data block with known good hashes. This test doesn't run the sandbox. It only checks the host tool 'mkimage' """ +import os import pytest import u_boot_utils as util @@ -93,7 +94,9 @@ def test_mkimage_hashes(u_boot_console): cons = u_boot_console mkimage = cons.config.build_dir + '/tools/mkimage' datadir = cons.config.source_dir + '/test/py/tests/vboot/' - tempdir = cons.config.result_dir + tempdir = os.path.join(cons.config.result_dir, 'hashes') + os.makedirs(tempdir, exist_ok=True) + fit_file = f'{tempdir}/test.fit' dtc('sandbox-kernel.dts') From e2c5113523426362b20650c10a022b6e56e86cf3 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 6 Aug 2022 17:51:50 -0600 Subject: [PATCH 057/374] test: Make test_sqfs_ls() single-threaded This test seems to interfere with the other test in this file. Mark it single-threaded to avoid any problems. Signed-off-by: Simon Glass --- test/py/tests/test_fs/test_squashfs/test_sqfs_ls.py | 1 + 1 file changed, 1 insertion(+) diff --git a/test/py/tests/test_fs/test_squashfs/test_sqfs_ls.py b/test/py/tests/test_fs/test_squashfs/test_sqfs_ls.py index 9eb00d6888..527a556ed8 100644 --- a/test/py/tests/test_fs/test_squashfs/test_sqfs_ls.py +++ b/test/py/tests/test_fs/test_squashfs/test_sqfs_ls.py @@ -105,6 +105,7 @@ def sqfs_run_all_ls_tests(u_boot_console): @pytest.mark.buildconfigspec('cmd_squashfs') @pytest.mark.buildconfigspec('fs_squashfs') @pytest.mark.requiredtool('mksquashfs') +@pytest.mark.singlethread def test_sqfs_ls(u_boot_console): """ Executes the sqfsls test suite. From a1f620eb4f3a05505452cfe2a297aca6d77c2df7 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 6 Aug 2022 17:51:51 -0600 Subject: [PATCH 058/374] test: Make test_efi_bootmgr() single-threaded This test seems to fail when run in parallel. Mark it single-threaded to avoid any problems. Signed-off-by: Simon Glass --- test/py/tests/test_efi_bootmgr/test_efi_bootmgr.py | 1 + 1 file changed, 1 insertion(+) diff --git a/test/py/tests/test_efi_bootmgr/test_efi_bootmgr.py b/test/py/tests/test_efi_bootmgr/test_efi_bootmgr.py index 75a6e7c962..1bb59d8fcf 100644 --- a/test/py/tests/test_efi_bootmgr/test_efi_bootmgr.py +++ b/test/py/tests/test_efi_bootmgr/test_efi_bootmgr.py @@ -7,6 +7,7 @@ import pytest @pytest.mark.boardspec('sandbox') @pytest.mark.buildconfigspec('cmd_efidebug') @pytest.mark.buildconfigspec('cmd_bootefi_bootmgr') +@pytest.mark.singlethread def test_efi_bootmgr(u_boot_console, efi_bootmgr_data): """ Unit test for UEFI bootmanager The efidebug command is used to set up UEFI load options. From c7c113dc133b0833cde1366820ecfcc3c3869fad Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 6 Aug 2022 17:51:52 -0600 Subject: [PATCH 059/374] test: Mark all but the first vboot test as slow When doing a quick check we don't need to run all the vboot tests. Just run the first one, which is enough to catch most problems. Signed-off-by: Simon Glass --- test/py/tests/test_vboot.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/test/py/tests/test_vboot.py b/test/py/tests/test_vboot.py index 040147d88b..e3e7ca4b21 100644 --- a/test/py/tests/test_vboot.py +++ b/test/py/tests/test_vboot.py @@ -42,7 +42,7 @@ import vboot_evil # Only run the full suite on a few combinations, since it doesn't add any more # test coverage. -TESTDATA = [ +TESTDATA_IN = [ ['sha1-basic', 'sha1', '', None, False, True, False, False], ['sha1-pad', 'sha1', '', '-E -p 0x10000', False, False, False, False], ['sha1-pss', 'sha1', '-pss', None, False, False, False, False], @@ -60,6 +60,10 @@ TESTDATA = [ ['sha256-global-sign-pss', 'sha256', '-pss', '', False, False, False, True], ] +# Mark all but the first test as slow, so they are not run with '-k not slow' +TESTDATA = [TESTDATA_IN[0]] +TESTDATA += [pytest.param(*v, marks=pytest.mark.slow) for v in TESTDATA_IN[1:]] + @pytest.mark.boardspec('sandbox') @pytest.mark.buildconfigspec('fit_signature') @pytest.mark.requiredtool('dtc') From d401187fecc16d68e816832d0cace53e872c6afe Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 6 Aug 2022 17:51:53 -0600 Subject: [PATCH 060/374] test: Mark test_gpt tests as slow Mark all the tests in this file as slow, since they take a while. Signed-off-by: Simon Glass --- test/py/tests/test_gpt.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/py/tests/test_gpt.py b/test/py/tests/test_gpt.py index f707d9f253..cb44e1d789 100644 --- a/test/py/tests/test_gpt.py +++ b/test/py/tests/test_gpt.py @@ -13,6 +13,9 @@ These tests rely on a 4 MB disk image, which is automatically created by the test. """ +# Mark all tests here as slow +pytestmark = pytest.mark.slow + class GptTestDiskImage(object): """Disk Image used by the GPT tests.""" From b681669aa533346b648995ae8c4bd9d257ea920a Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 6 Aug 2022 17:51:54 -0600 Subject: [PATCH 061/374] test: Make test_gpio_read() independent This assumes that the GPIO starts as 0 but it does not if test_gpio_input() ran first and test_gpio_exit_statuses() was skipped. This can happen when running tests in parallel. Fix it. Signed-off-by: Simon Glass --- test/py/tests/test_gpio.py | 1 + 1 file changed, 1 insertion(+) diff --git a/test/py/tests/test_gpio.py b/test/py/tests/test_gpio.py index fa0af5f82b..0af186f236 100644 --- a/test/py/tests/test_gpio.py +++ b/test/py/tests/test_gpio.py @@ -51,6 +51,7 @@ def test_gpio_exit_statuses(u_boot_console): def test_gpio_read(u_boot_console): """Test that gpio read correctly sets the variable to the value of a gpio pin.""" + u_boot_console.run_command('gpio clear 0') response = u_boot_console.run_command('gpio read var 0; echo val:$var,rc:$?') expected_response = 'val:0,rc:0' assert(expected_response in response) From f6e6022ff1b13260ce60123dc6b2ecc369c0234f Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 6 Aug 2022 17:51:55 -0600 Subject: [PATCH 062/374] test: Refactor arg parsing for the run script Tidy up this code a little. Also use '-k' consistently, since -m is more limited in what it can accept. Signed-off-by: Simon Glass --- test/run | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/test/run b/test/run index 869406cd8d..0c8aeb5b0a 100755 --- a/test/run +++ b/test/run @@ -13,9 +13,12 @@ run_test() { [ $? -ne 0 ] && failures=$((failures+1)) } -# SKip slow tests if requested -[ "$1" == "quick" ] && mark_expr="not slow" -[ "$1" == "quick" ] && skip=--skip-net-tests +# Select test attributes +if [ "$1" = "quick" ]; then + mark_expr="not slow" + skip=--skip-net-tests +fi + [ "$1" == "tools" ] && tools_only=y failures=0 @@ -23,7 +26,7 @@ failures=0 if [ -z "$tools_only" ]; then # Run all tests that the standard sandbox build can support run_test "sandbox" ./test/py/test.py --bd sandbox --build \ - -m "${mark_expr}" + -k "${mark_expr}" fi # Run tests which require sandbox_spl From 486680272e38890f4938ec2a8673c66f42cc5c45 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 6 Aug 2022 17:51:56 -0600 Subject: [PATCH 063/374] test/py: Move U-Boot building into a function This is a lot of code in a function that is too long. Split out the building code. Signed-off-by: Simon Glass --- test/py/conftest.py | 60 +++++++++++++++++++++++++++------------------ 1 file changed, 36 insertions(+), 24 deletions(-) diff --git a/test/py/conftest.py b/test/py/conftest.py index dbe1acd9e3..906387db1c 100644 --- a/test/py/conftest.py +++ b/test/py/conftest.py @@ -76,6 +76,41 @@ def pytest_addoption(parser): help='Run sandbox under gdbserver. The argument is the channel '+ 'over which gdbserver should communicate, e.g. localhost:1234') +def run_build(config, source_dir, build_dir, board_type, log): + """run_build: Build U-Boot + + Args: + config: The pytest configuration. + soruce_dir (str): Directory containing source code + build_dir (str): Directory to build in + board_type (str): board_type parameter (e.g. 'sandbox') + log (Logfile): Log file to use + """ + if config.getoption('buildman'): + if build_dir != source_dir: + dest_args = ['-o', build_dir, '-w'] + else: + dest_args = ['-i'] + cmds = (['buildman', '--board', board_type] + dest_args,) + name = 'buildman' + else: + if build_dir != source_dir: + o_opt = 'O=%s' % build_dir + else: + o_opt = '' + cmds = ( + ['make', o_opt, '-s', board_type + '_defconfig'], + ['make', o_opt, '-s', '-j{}'.format(os.cpu_count())], + ) + name = 'make' + + with log.section(name): + runner = log.get_runner(name, sys.stdout) + for cmd in cmds: + runner.run(cmd, cwd=source_dir) + runner.close() + log.status_pass('OK') + def pytest_configure(config): """pytest hook: Perform custom initialization at startup time. @@ -142,30 +177,7 @@ def pytest_configure(config): log = multiplexed_log.Logfile(result_dir + '/test-log.html') if config.getoption('build'): - if config.getoption('buildman'): - if build_dir != source_dir: - dest_args = ['-o', build_dir, '-w'] - else: - dest_args = ['-i'] - cmds = (['buildman', '--board', board_type] + dest_args,) - name = 'buildman' - else: - if build_dir != source_dir: - o_opt = 'O=%s' % build_dir - else: - o_opt = '' - cmds = ( - ['make', o_opt, '-s', board_type + '_defconfig'], - ['make', o_opt, '-s', '-j{}'.format(os.cpu_count())], - ) - name = 'make' - - with log.section(name): - runner = log.get_runner(name, sys.stdout) - for cmd in cmds: - runner.run(cmd, cwd=source_dir) - runner.close() - log.status_pass('OK') + run_build(config, source_dir, build_dir, board_type, log) class ArbitraryAttributeContainer(object): pass From 45a226a16b99f0e7c86e7dcb2cd4035195f69e7f Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 6 Aug 2022 17:51:57 -0600 Subject: [PATCH 064/374] test/py: Support --build when running tests in parallel At present when -n is used, all workers try to build U-Boot at once. Add a lock to ensure that only one of them builds, with the others using the build that is produced. The lock file is removed on startup. Signed-off-by: Simon Glass --- test/py/conftest.py | 29 +++++++++++++++++++++++++---- test/py/requirements.txt | 2 ++ 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/test/py/conftest.py b/test/py/conftest.py index 906387db1c..304e93164a 100644 --- a/test/py/conftest.py +++ b/test/py/conftest.py @@ -15,9 +15,11 @@ import atexit import configparser import errno +import filelock import io import os import os.path +from pathlib import Path import pytest import re from _pytest.runner import runtestprotocol @@ -27,6 +29,8 @@ import sys log = None console = None +TEST_PY_DIR = os.path.dirname(os.path.abspath(__file__)) + def mkdir_p(path): """Create a directory path. @@ -111,6 +115,18 @@ def run_build(config, source_dir, build_dir, board_type, log): runner.close() log.status_pass('OK') +def pytest_xdist_setupnodes(config, specs): + """Clear out any 'done' file from a previous build""" + global build_done_file + build_dir = config.getoption('build_dir') + board_type = config.getoption('board_type') + source_dir = os.path.dirname(os.path.dirname(TEST_PY_DIR)) + if not build_dir: + build_dir = source_dir + '/build-' + board_type + build_done_file = Path(build_dir) / 'build.done' + if build_done_file.exists(): + os.remove(build_done_file) + def pytest_configure(config): """pytest hook: Perform custom initialization at startup time. @@ -145,8 +161,7 @@ def pytest_configure(config): global console global ubconfig - test_py_dir = os.path.dirname(os.path.abspath(__file__)) - source_dir = os.path.dirname(os.path.dirname(test_py_dir)) + source_dir = os.path.dirname(os.path.dirname(TEST_PY_DIR)) board_type = config.getoption('board_type') board_type_filename = board_type.replace('-', '_') @@ -177,7 +192,13 @@ def pytest_configure(config): log = multiplexed_log.Logfile(result_dir + '/test-log.html') if config.getoption('build'): - run_build(config, source_dir, build_dir, board_type, log) + worker_id = os.environ.get("PYTEST_XDIST_WORKER") + with filelock.FileLock(os.path.join(build_dir, 'build.lock')): + build_done_file = Path(build_dir) / 'build.done' + if (not worker_id or worker_id == 'master' or + not build_done_file.exists()): + run_build(config, source_dir, build_dir, board_type, log) + build_done_file.touch() class ArbitraryAttributeContainer(object): pass @@ -209,7 +230,7 @@ def pytest_configure(config): else: parse_config('include/autoconf.mk') - ubconfig.test_py_dir = test_py_dir + ubconfig.test_py_dir = TEST_PY_DIR ubconfig.source_dir = source_dir ubconfig.build_dir = build_dir ubconfig.result_dir = result_dir diff --git a/test/py/requirements.txt b/test/py/requirements.txt index ead92ed8b4..1bf77b59d8 100644 --- a/test/py/requirements.txt +++ b/test/py/requirements.txt @@ -2,6 +2,7 @@ atomicwrites==1.4.1 attrs==19.3.0 coverage==4.5.4 extras==1.0.0 +filelock==3.0.12 fixtures==3.0.0 importlib-metadata==0.23 linecache2==1.0.0 @@ -15,6 +16,7 @@ pyelftools==0.27 pygit2==1.9.2 pyparsing==2.4.2 pytest==6.2.5 +pytest-xdist==2.5.0 python-mimeparse==1.6.0 python-subunit==1.3.0 requests==2.25.1 From e1c0811114ea383e8f0cdd1e3535a25421f2619b Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 6 Aug 2022 17:51:58 -0600 Subject: [PATCH 065/374] dtoc: Drop sys.exit() in test_fdt This breaks using pytest to run the tests. Drop it. Signed-off-by: Simon Glass --- tools/dtoc/test_fdt.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tools/dtoc/test_fdt.py b/tools/dtoc/test_fdt.py index 8a990b8bd7..a3e36ea363 100755 --- a/tools/dtoc/test_fdt.py +++ b/tools/dtoc/test_fdt.py @@ -851,4 +851,3 @@ def main(): if __name__ == '__main__': sys.exit(main()) -sys.exit(1) From d1962ac7978559735ce172dc2d1822952d89e0a8 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 6 Aug 2022 17:51:59 -0600 Subject: [PATCH 066/374] Makefile: Add a pcheck option to run tests in parallel Running tests in parallel is much faster, e.g. 15 seconds to run the tests on sandbox (only), instead of 100 seconds (on a 16-core machine). Add a 'make pcheck' option to access this feature. Note that the tools/ tests still run each tool's tests once after the other, although within that, they do run in parallel. So for example, the buildman tests run in parallel, then the binman tests run in parallel. There would be a signiificant advantage to running them all in parallel together, but that would require a large amount of refactoring, e.g. with more use of pytest fixtures. Update the documentation to represent the current state. Signed-off-by: Simon Glass --- Makefile | 8 ++++++-- doc/develop/py_testing.rst | 37 ++++++++++++++++++++--------------- doc/develop/testing.rst | 6 +++++- test/run | 40 ++++++++++++++++++++++++++++++-------- 4 files changed, 64 insertions(+), 27 deletions(-) diff --git a/Makefile b/Makefile index 27375f033f..0b8079cf81 100644 --- a/Makefile +++ b/Makefile @@ -521,8 +521,8 @@ env_h := include/generated/environment.h no-dot-config-targets := clean clobber mrproper distclean \ help %docs check% coccicheck \ - ubootversion backup tests check qcheck tcheck pylint \ - pylint_err + ubootversion backup tests check pcheck qcheck tcheck \ + pylint pylint_err config-targets := 0 mixed-targets := 0 @@ -2364,6 +2364,7 @@ help: @echo 'Test targets:' @echo '' @echo ' check - Run all automated tests that use sandbox' + @echo ' pcheck - Run quick automated tests in parallel' @echo ' qcheck - Run quick automated tests that use sandbox' @echo ' tcheck - Run quick automated tests on tools' @echo ' pylint - Run pylint on all Python files' @@ -2409,6 +2410,9 @@ help: tests check: $(srctree)/test/run +pcheck: + $(srctree)/test/run parallel + qcheck: $(srctree)/test/run quick diff --git a/doc/develop/py_testing.rst b/doc/develop/py_testing.rst index 06f919609b..92fbd22721 100644 --- a/doc/develop/py_testing.rst +++ b/doc/develop/py_testing.rst @@ -121,31 +121,36 @@ more options. Running tests in parallel ~~~~~~~~~~~~~~~~~~~~~~~~~ -Note: This does not fully work yet and is documented only so you can try to -fix the problems. +Note: Not all tests can run in parallel at present, so the usual approach is +to just run those that can. First install support for parallel tests:: + sudo apt install python3-pytest-xdist + +or::: + pip3 install pytest-xdist -Then build sandbox in a suitable build directory. It is not possible to use -the --build flag with xdist. +Then run the tests in parallel using the -n flag:: -Finally, run the tests in parallel using the -n flag:: + test/py/test.py -B sandbox --build --build-dir /tmp/b/sandbox -q -k \ + 'not slow and not bootstd and not spi_flash' -n16 - # build sandbox first, in a suitable build directory. It is not possible - # to use the --build flag with -n - test/py/test.py -B sandbox --build-dir /tmp/b/sandbox -q -k 'not slow' -n32 +You can also use `make pcheck` to run all tests in parallel. This uses a maximum +of 16 threads, since the setup time is significant and there are under 1000 +tests. -At least the following non-slow tests are known to fail: +Note that the `test-log.html` output does not work correctly at present with +parallel testing. All the threads write to it at once, so it is garbled. -- test_fit_ecdsa -- test_bind_unbind_with_uclass -- ut_dm_spi_flash -- test_gpt_rename_partition -- test_gpt_swap_partitions -- test_pinmux_status -- test_sqfs_load +Note that the `tools/` tests still run each tool's tests once after the other, +although within that, they do run in parallel. So for example, the buildman +tests run in parallel, then the binman tests run in parallel. There would be a +significant advantage to running them all in parallel together, but that would +require a large amount of refactoring, e.g. with more use of pytest fixtures. +The code-coverage tests are omitted since they cannot run in parallel due to a +Python limitation. Testing under a debugger diff --git a/doc/develop/testing.rst b/doc/develop/testing.rst index 1abe4d7f0f..5afeb42f69 100644 --- a/doc/develop/testing.rst +++ b/doc/develop/testing.rst @@ -28,8 +28,12 @@ run. Type this:: make tcheck +You can also run a selection tests in parallel with:: + + make pcheck + All of the above use the test/run script with a paremeter to select which tests -are run. +are run. See :doc:`py_testing` for more information. Sandbox diff --git a/test/run b/test/run index 0c8aeb5b0a..810b47e08d 100755 --- a/test/run +++ b/test/run @@ -14,27 +14,46 @@ run_test() { } # Select test attributes +ut_mark_expr=test_ut if [ "$1" = "quick" ]; then mark_expr="not slow" + ut_mark_expr="test_ut and not slow" skip=--skip-net-tests fi [ "$1" == "tools" ] && tools_only=y +if [ "$1" = "parallel" ]; then + if ! echo 'import xdist' | python3 2>/dev/null; then + echo "Please install python3-pytest-xdist - see doc/develop/py_testing.rst" + exit 1 + fi + jobs="$(($(nproc) > 16 ? 16 : $(nproc)))" + para="-n${jobs} -q" + prompt="Building and..." + skip=--skip-net-tests + mark_expr="not slow and not bootstd and not spi_flash" + ut_mark_expr="test_ut and not slow and not bootstd and not spi_flash" + echo "Note: test log is garbled with parallel tests" +fi + failures=0 if [ -z "$tools_only" ]; then # Run all tests that the standard sandbox build can support - run_test "sandbox" ./test/py/test.py --bd sandbox --build \ + echo "${prompt}" + run_test "sandbox" ./test/py/test.py --bd sandbox --build ${para} \ -k "${mark_expr}" fi # Run tests which require sandbox_spl -run_test "sandbox_spl" ./test/py/test.py --bd sandbox_spl --build \ +echo "${prompt}" +run_test "sandbox_spl" ./test/py/test.py --bd sandbox_spl --build ${para} \ -k 'test_ofplatdata or test_handoff or test_spl' # Run the sane tests with sandbox_noinst (i.e. without OF_PLATDATA_INST) -run_test "sandbox_spl" ./test/py/test.py --bd sandbox_noinst --build \ +echo "${prompt}" +run_test "sandbox_spl" ./test/py/test.py --bd sandbox_noinst --build ${para} \ -k 'test_ofplatdata or test_handoff or test_spl' if [ -z "$tools_only" ]; then @@ -42,8 +61,9 @@ if [ -z "$tools_only" ]; then # build which does not enable CONFIG_OF_LIVE for the live device tree, so we can # check that functionality is the same. The standard sandbox build (above) uses # CONFIG_OF_LIVE. + echo "${prompt}" run_test "sandbox_flattree" ./test/py/test.py --bd sandbox_flattree \ - --build -k test_ut + ${para} --build -k "${ut_mark_expr}" fi # Set up a path to dtc (device-tree compiler) and libfdt.py, a library it @@ -64,10 +84,14 @@ run_test "dtoc" ./tools/dtoc/dtoc -t # This needs you to set up Python test coverage tools. # To enable Python test coverage on Debian-type distributions (e.g. Ubuntu): # $ sudo apt-get install python-pytest python-coverage -export PATH=$PATH:${TOOLS_DIR} -run_test "binman code coverage" ./tools/binman/binman test -T -run_test "dtoc code coverage" ./tools/dtoc/dtoc -T -run_test "fdt code coverage" ./tools/dtoc/test_fdt -T + +# Code-coverage tests cannot run in parallel, so skip them in that case +if [ -z "${para}" ]; then + export PATH=$PATH:${TOOLS_DIR} + run_test "binman code coverage" ./tools/binman/binman test -T + run_test "dtoc code coverage" ./tools/dtoc/dtoc -T + run_test "fdt code coverage" ./tools/dtoc/test_fdt -T +fi if [ $failures == 0 ]; then echo "Tests passed!" From ad8024e0406404bc63dd4468ac75c87eaec5cca0 Mon Sep 17 00:00:00 2001 From: Ashok Reddy Soma Date: Fri, 5 Aug 2022 11:19:56 +0200 Subject: [PATCH 067/374] firmware: zynqmp: Skip loading config object for Versal SET_CONFIGURATION is not yet implemented for Versal platforms. Skip loading config object for Versal until support is added. Signed-off-by: Ashok Reddy Soma Signed-off-by: Michal Simek Link: https://lore.kernel.org/r/eb7ef6c6de36a1f7d056de43042f96fe3639f18e.1659691195.git.michal.simek@amd.com --- drivers/power/domain/zynqmp-power-domain.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/power/domain/zynqmp-power-domain.c b/drivers/power/domain/zynqmp-power-domain.c index 6943658be4..adbbb5fdd9 100644 --- a/drivers/power/domain/zynqmp-power-domain.c +++ b/drivers/power/domain/zynqmp-power-domain.c @@ -25,7 +25,10 @@ static int zynqmp_power_domain_request(struct power_domain *power_domain) { dev_dbg(power_domain->dev, "Request for id: %ld\n", power_domain->id); - return zynqmp_pmufw_node(power_domain->id); + if (IS_ENABLED(CONFIG_ARCH_ZYNQMP)) + return zynqmp_pmufw_node(power_domain->id); + + return 0; } static int zynqmp_power_domain_free(struct power_domain *power_domain) From 4a72f803686d44a9f2965845b4d931f02b1f23ab Mon Sep 17 00:00:00 2001 From: Ashok Reddy Soma Date: Fri, 5 Aug 2022 11:19:57 +0200 Subject: [PATCH 068/374] xilinx: versal: Enable power domain driver Enable power domain driver to request node for all the IP's that are enabled in DT. Signed-off-by: Ashok Reddy Soma Signed-off-by: Michal Simek Link: https://lore.kernel.org/r/dbed54df622d647b8d520d8ce5289cd69ba66e0b.1659691195.git.michal.simek@amd.com --- configs/xilinx_versal_virt_defconfig | 2 ++ 1 file changed, 2 insertions(+) diff --git a/configs/xilinx_versal_virt_defconfig b/configs/xilinx_versal_virt_defconfig index c4d7aac7b5..762ceb5e9f 100644 --- a/configs/xilinx_versal_virt_defconfig +++ b/configs/xilinx_versal_virt_defconfig @@ -104,6 +104,8 @@ CONFIG_PHY_GIGE=y CONFIG_XILINX_AXIEMAC=y CONFIG_XILINX_AXIMRMAC=y CONFIG_ZYNQ_GEM=y +CONFIG_POWER_DOMAIN=y +CONFIG_ZYNQMP_POWER_DOMAIN=y CONFIG_DM_RESET=y CONFIG_RESET_ZYNQMP=y CONFIG_ARM_DCC=y From 64c71d1c7333cfda99873372874a706becdbcf39 Mon Sep 17 00:00:00 2001 From: Ashok Reddy Soma Date: Fri, 5 Aug 2022 11:19:58 +0200 Subject: [PATCH 069/374] xilinx: versal: Define CONFIG_CQSPI_REF_CLK With commit 55b3ba4c2ba4 ("spi: cadence_qspi: Migrate CONFIG_CQSPI_REF_CLK to Kconfig") CONFIG_CQSPI_REF_CLK is moved to Kconfig. The static value via Kconfig is a fallback option in case of clock framework is not enabled or fails for some reason. Signed-off-by: Ashok Reddy Soma Signed-off-by: Michal Simek Link: https://lore.kernel.org/r/fe7c38a19e878c307d5b75311bbfd8cf6c1f601e.1659691195.git.michal.simek@amd.com --- configs/xilinx_versal_virt_defconfig | 2 ++ 1 file changed, 2 insertions(+) diff --git a/configs/xilinx_versal_virt_defconfig b/configs/xilinx_versal_virt_defconfig index 762ceb5e9f..ffd8bea81c 100644 --- a/configs/xilinx_versal_virt_defconfig +++ b/configs/xilinx_versal_virt_defconfig @@ -115,6 +115,8 @@ CONFIG_SOC_XILINX_VERSAL=y CONFIG_SPI=y CONFIG_DM_SPI=y CONFIG_CADENCE_QSPI=y +CONFIG_HAS_CQSPI_REF_CLK=y +CONFIG_CQSPI_REF_CLK=200000000 CONFIG_CADENCE_OSPI_VERSAL=y CONFIG_ZYNQ_SPI=y CONFIG_USB=y From 79f0151389396f310bd6441d444e2c2a54b6039c Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Tue, 9 Aug 2022 16:32:51 +0200 Subject: [PATCH 070/374] xilinx: zynq: Enable mkeficapsule tools compilation Zynq can use efi capsule infrastructure that's why enable it by default. For capsule generation for zynq you can use: pushd spl ../tools/mkeficapsule -g "1ba29a15-9969-40aa-b424-e86121618664" boot.bin \ --index 1 ../capsule1.bin popd ./tools/mkeficapsule -g "1a5178f0-87d3-4f36-ac63-3b31a23be305" u-boot.img \ --index 2 capsule2.bin Signed-off-by: Michal Simek Link: https://lore.kernel.org/r/a8194ecfa7932f2d8ada5ee508b2a026c782f15e.1660055571.git.michal.simek@amd.com --- configs/xilinx_zynq_virt_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/configs/xilinx_zynq_virt_defconfig b/configs/xilinx_zynq_virt_defconfig index 7beb5915fc..e6f8e221a5 100644 --- a/configs/xilinx_zynq_virt_defconfig +++ b/configs/xilinx_zynq_virt_defconfig @@ -149,3 +149,4 @@ CONFIG_DISPLAY=y CONFIG_SPL_GZIP=y CONFIG_EFI_RUNTIME_UPDATE_CAPSULE=y CONFIG_EFI_CAPSULE_FIRMWARE_RAW=y +CONFIG_TOOLS_MKEFICAPSULE=y From ce183fd79ce5218a89dd5c73cd77bad6464ee5a2 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Tue, 9 Aug 2022 16:32:52 +0200 Subject: [PATCH 071/374] xilinx: Fix logic when dfu_alt_info is generated Generate dfu_alt_info only when it is not defined. Signed-off-by: Michal Simek Link: https://lore.kernel.org/r/464e4b325c644e52a660df9cf44eeb4d80427f6a.1660055571.git.michal.simek@amd.com --- board/xilinx/zynq/board.c | 3 +-- board/xilinx/zynqmp/zynqmp.c | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/board/xilinx/zynq/board.c b/board/xilinx/zynq/board.c index 63aff0474b..26ef048835 100644 --- a/board/xilinx/zynq/board.c +++ b/board/xilinx/zynq/board.c @@ -168,8 +168,7 @@ void set_dfu_alt_info(char *interface, char *devstr) { ALLOC_CACHE_ALIGN_BUFFER(char, buf, DFU_ALT_BUF_LEN); - if (!CONFIG_IS_ENABLED(EFI_HAVE_CAPSULE_SUPPORT) && - env_get("dfu_alt_info")) + if (env_get("dfu_alt_info")) return; memset(buf, 0, sizeof(buf)); diff --git a/board/xilinx/zynqmp/zynqmp.c b/board/xilinx/zynqmp/zynqmp.c index 57259b60a0..29a6e3675f 100644 --- a/board/xilinx/zynqmp/zynqmp.c +++ b/board/xilinx/zynqmp/zynqmp.c @@ -641,8 +641,7 @@ void set_dfu_alt_info(char *interface, char *devstr) ALLOC_CACHE_ALIGN_BUFFER(char, buf, DFU_ALT_BUF_LEN); - if (!CONFIG_IS_ENABLED(EFI_HAVE_CAPSULE_SUPPORT) && - env_get("dfu_alt_info")) + if (env_get("dfu_alt_info")) return; memset(buf, 0, sizeof(buf)); From 93020aa3dc2f3428564cfc6ad232077706c508a7 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Tue, 9 Aug 2022 16:32:53 +0200 Subject: [PATCH 072/374] xilinx: zynq: Use CONFIG_SPL_FS_LOAD_PAYLOAD_NAME for dfu_alt_info CONFIG_SPL_FS_LOAD_PAYLOAD_NAME stores the name of firmware file to be loaded by SPL. Name can be selected via Kconfig that's why use the macro. Signed-off-by: Michal Simek Link: https://lore.kernel.org/r/601fbc2dfd16b4708fc6b5f86954e10add43334e.1660055571.git.michal.simek@amd.com --- board/xilinx/zynq/board.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/board/xilinx/zynq/board.c b/board/xilinx/zynq/board.c index 26ef048835..3ab63fa76e 100644 --- a/board/xilinx/zynq/board.c +++ b/board/xilinx/zynq/board.c @@ -177,12 +177,13 @@ void set_dfu_alt_info(char *interface, char *devstr) case ZYNQ_BM_SD: snprintf(buf, DFU_ALT_BUF_LEN, "mmc 0:1=boot.bin fat 0 1;" - "u-boot.img fat 0 1"); + "%s fat 0 1", CONFIG_SPL_FS_LOAD_PAYLOAD_NAME); break; case ZYNQ_BM_QSPI: snprintf(buf, DFU_ALT_BUF_LEN, "sf 0:0=boot.bin raw 0 0x1500000;" - "u-boot.img raw 0x%x 0x500000", + "%s raw 0x%x 0x500000", + CONFIG_SPL_FS_LOAD_PAYLOAD_NAME, CONFIG_SYS_SPI_U_BOOT_OFFS); break; default: From 88eaca26f6a2d2e591cdc79b71c1dc3e92e6224e Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Tue, 9 Aug 2022 16:32:54 +0200 Subject: [PATCH 073/374] xilinx: Define only mmc devnum not partition The commit 53b406369e9d ("DFU: Check the number of arguments and argument string strictly") added strict control over string that 0:1 partition definition is not valid anymore that's why use only device number without partition ID. Device is specified by 2nd parameter and partition by 3rd. Signed-off-by: Michal Simek Link: https://lore.kernel.org/r/840eca944f4f2abeeb63b5d724f9ba5fe9a9213b.1660055571.git.michal.simek@amd.com --- board/xilinx/zynq/board.c | 2 +- board/xilinx/zynqmp/zynqmp.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/board/xilinx/zynq/board.c b/board/xilinx/zynq/board.c index 3ab63fa76e..c96433be69 100644 --- a/board/xilinx/zynq/board.c +++ b/board/xilinx/zynq/board.c @@ -176,7 +176,7 @@ void set_dfu_alt_info(char *interface, char *devstr) switch ((zynq_slcr_get_boot_mode()) & ZYNQ_BM_MASK) { case ZYNQ_BM_SD: snprintf(buf, DFU_ALT_BUF_LEN, - "mmc 0:1=boot.bin fat 0 1;" + "mmc 0=boot.bin fat 0 1;" "%s fat 0 1", CONFIG_SPL_FS_LOAD_PAYLOAD_NAME); break; case ZYNQ_BM_QSPI: diff --git a/board/xilinx/zynqmp/zynqmp.c b/board/xilinx/zynqmp/zynqmp.c index 29a6e3675f..21bcc26682 100644 --- a/board/xilinx/zynqmp/zynqmp.c +++ b/board/xilinx/zynqmp/zynqmp.c @@ -661,13 +661,13 @@ void set_dfu_alt_info(char *interface, char *devstr) bootseq = mmc_get_env_dev(); if (!multiboot) snprintf(buf, DFU_ALT_BUF_LEN, - "mmc %d:1=boot.bin fat %d 1;" + "mmc %d=boot.bin fat %d 1;" "%s fat %d 1", bootseq, bootseq, CONFIG_SPL_FS_LOAD_PAYLOAD_NAME, bootseq); else snprintf(buf, DFU_ALT_BUF_LEN, - "mmc %d:1=boot%04d.bin fat %d 1;" + "mmc %d=boot%04d.bin fat %d 1;" "%s fat %d 1", bootseq, multiboot, bootseq, CONFIG_SPL_FS_LOAD_PAYLOAD_NAME, bootseq); From c8630167e0dcd816a9ed6870df550aa1270d7b7a Mon Sep 17 00:00:00 2001 From: Amit Kumar Mahapatra Date: Tue, 23 Aug 2022 10:18:03 +0200 Subject: [PATCH 074/374] arm64: zynqmp: Add mtd partition for secure OS storage area Update MTD partitions of Kria device trees to allocate 128KB of QSPI memory for secure OS. Increased "SHA256" partition size & changed starting address of "User" partition to accommodate the new partition "Secure OS Storage" Signed-off-by: Amit Kumar Mahapatra Signed-off-by: Michal Simek Link: https://lore.kernel.org/r/9cc64b8c731d11439de73d0af54c65080068f00b.1661242681.git.michal.simek@amd.com --- arch/arm/dts/zynqmp-sm-k26-revA.dts | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/arch/arm/dts/zynqmp-sm-k26-revA.dts b/arch/arm/dts/zynqmp-sm-k26-revA.dts index ac349a9dcc..bae24aabdb 100644 --- a/arch/arm/dts/zynqmp-sm-k26-revA.dts +++ b/arch/arm/dts/zynqmp-sm-k26-revA.dts @@ -214,13 +214,17 @@ }; partition@2240000 { label = "SHA256"; - reg = <0x2240000 0x10000>; /* 256B but 64KB sector */ + reg = <0x2240000 0x40000>; /* 256B but 256KB sector */ read-only; lock; }; - partition@2250000 { + partition@2280000 { + label = "Secure OS Storage"; + reg = <0x2280000 0x20000>; /* 128KB */ + }; + partition@22A0000 { label = "User"; - reg = <0x2250000 0x1db0000>; /* 29.5 MB */ + reg = <0x22A0000 0x1db0000>; /* 29.5 MB */ }; }; }; From ddcc161c4e161480e5cdd5eea37a05ed290b19bf Mon Sep 17 00:00:00 2001 From: Harini Katakam Date: Tue, 23 Aug 2022 14:59:20 +0200 Subject: [PATCH 075/374] arm: dts: Add xlnx prefix to GEM compatible string cdns,zynq/zynqmp were recentle deprecated in Linux in favour of xlnx prefix. Add this new compatible string and retain the existing string for compatibility with uboot drivers. Signed-off-by: Harini Katakam Signed-off-by: Michal Simek Link: https://lore.kernel.org/r/a38b1b55132fc026cc09224dba61e42fd03b1a36.1661259558.git.michal.simek@amd.com --- arch/arm/dts/zynq-7000.dtsi | 4 ++-- arch/arm/dts/zynqmp.dtsi | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/arch/arm/dts/zynq-7000.dtsi b/arch/arm/dts/zynq-7000.dtsi index a7ca00fb76..b4aa09d149 100644 --- a/arch/arm/dts/zynq-7000.dtsi +++ b/arch/arm/dts/zynq-7000.dtsi @@ -247,7 +247,7 @@ }; gem0: ethernet@e000b000 { - compatible = "cdns,zynq-gem", "cdns,gem"; + compatible = "xlnx,zynq-gem", "cdns,zynq-gem", "cdns,gem"; reg = <0xe000b000 0x1000>; status = "disabled"; interrupts = <0 22 4>; @@ -258,7 +258,7 @@ }; gem1: ethernet@e000c000 { - compatible = "cdns,zynq-gem", "cdns,gem"; + compatible = "xlnx,zynq-gem", "cdns,zynq-gem", "cdns,gem"; reg = <0xe000c000 0x1000>; status = "disabled"; interrupts = <0 45 4>; diff --git a/arch/arm/dts/zynqmp.dtsi b/arch/arm/dts/zynqmp.dtsi index fbc6e752da..2aaec6cf5a 100644 --- a/arch/arm/dts/zynqmp.dtsi +++ b/arch/arm/dts/zynqmp.dtsi @@ -529,7 +529,7 @@ }; gem0: ethernet@ff0b0000 { - compatible = "cdns,zynqmp-gem", "cdns,gem"; + compatible = "xlnx,zynqmp-gem", "cdns,zynqmp-gem", "cdns,gem"; status = "disabled"; interrupt-parent = <&gic>; interrupts = <0 57 4>, <0 57 4>; @@ -543,7 +543,7 @@ }; gem1: ethernet@ff0c0000 { - compatible = "cdns,zynqmp-gem", "cdns,gem"; + compatible = "xlnx,zynqmp-gem", "cdns,zynqmp-gem", "cdns,gem"; status = "disabled"; interrupt-parent = <&gic>; interrupts = <0 59 4>, <0 59 4>; @@ -557,7 +557,7 @@ }; gem2: ethernet@ff0d0000 { - compatible = "cdns,zynqmp-gem", "cdns,gem"; + compatible = "xlnx,zynqmp-gem", "cdns,zynqmp-gem", "cdns,gem"; status = "disabled"; interrupt-parent = <&gic>; interrupts = <0 61 4>, <0 61 4>; @@ -571,7 +571,7 @@ }; gem3: ethernet@ff0e0000 { - compatible = "cdns,zynqmp-gem", "cdns,gem"; + compatible = "xlnx,zynqmp-gem", "cdns,zynqmp-gem", "cdns,gem"; status = "disabled"; interrupt-parent = <&gic>; interrupts = <0 63 4>, <0 63 4>; From fd9c9f293201b4f819b1fbdc5e85e70ca9cdc231 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Tue, 23 Aug 2022 15:00:25 +0200 Subject: [PATCH 076/374] arm64: zynqmp: Add missing tca6416 to zynqmp SC Add missing tca6416 i2c gpio controller to SC dts file. Signed-off-by: Michal Simek Link: https://lore.kernel.org/r/a19c191d0dffb213d9dc8809d22728d79cf73a22.1661259623.git.michal.simek@amd.com --- arch/arm/dts/zynqmp-e-a2197-00-revA.dts | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/arch/arm/dts/zynqmp-e-a2197-00-revA.dts b/arch/arm/dts/zynqmp-e-a2197-00-revA.dts index 37c56181c9..4940825b00 100644 --- a/arch/arm/dts/zynqmp-e-a2197-00-revA.dts +++ b/arch/arm/dts/zynqmp-e-a2197-00-revA.dts @@ -203,6 +203,18 @@ &i2c0 { /* MIO 34-35 - can't stay here */ status = "okay"; clock-frequency = <400000>; + + tca6416_u233: gpio@20 { /* u233 */ + compatible = "ti,tca6416"; + reg = <0x20>; + gpio-controller; /* interrupt not connected */ + #gpio-cells = <2>; + gpio-line-names = "MAX6643_OT_B", "MAX6643_FANFAIL_B", "", "", /* 0 - 3 */ + "PMBUS2_INA226_ALERT", "", "", "MAX6643_FULLSPD", /* 4 - 7 */ + "FMCP1_FMC_PRSNT_M2C_B", "FMCP2_FMC_PRSNT_M2C_B", "FMCP1_FMCP_PRSNT_M2C_B", "FMCP2_FMCP_PRSNT_M2C_B", /* 10 - 13 */ + "VCCINT_VRHOT_B", "8A34001_EXP_RST_B", "PMBUS_ALERT", "PMBUS1_INA226_ALERT"; /* 14 - 17 */ + }; + i2c-mux@74 { /* u33 */ compatible = "nxp,pca9548"; #address-cells = <1>; From 1bff67eda73dbeec00ae6b8fbf6bd3a824578578 Mon Sep 17 00:00:00 2001 From: Piyush Mehta Date: Tue, 23 Aug 2022 15:03:31 +0200 Subject: [PATCH 077/374] arm64: zynqmp: add ref_clk property for REFCLKPER calculation Added ref_clk 'ref' property for GUCTL_REFCLKPER and GFLADJ_REFCLK_FLADJ calculation. This property configure correct value for SOF/ITP counter and period of ref_clk. This patch adds 'ref' property for both dwc3_0 and dwc3_1 cores. Signed-off-by: Piyush Mehta Signed-off-by: Michal Simek Link: https://lore.kernel.org/r/417545b948ea12a9301a5e80851f98523be2b443.1661259809.git.michal.simek@amd.com --- arch/arm/dts/zynqmp-clk-ccf.dtsi | 8 ++++++++ arch/arm/dts/zynqmp.dtsi | 2 ++ 2 files changed, 10 insertions(+) diff --git a/arch/arm/dts/zynqmp-clk-ccf.dtsi b/arch/arm/dts/zynqmp-clk-ccf.dtsi index 7b09d75151..b99eb07b00 100644 --- a/arch/arm/dts/zynqmp-clk-ccf.dtsi +++ b/arch/arm/dts/zynqmp-clk-ccf.dtsi @@ -260,11 +260,19 @@ assigned-clocks = <&zynqmp_clk USB0_BUS_REF>, <&zynqmp_clk USB3_DUAL_REF>; }; +&dwc3_0 { + clocks = <&zynqmp_clk USB3_DUAL_REF>; +}; + &usb1 { clocks = <&zynqmp_clk USB1_BUS_REF>, <&zynqmp_clk USB3_DUAL_REF>; assigned-clocks = <&zynqmp_clk USB1_BUS_REF>, <&zynqmp_clk USB3_DUAL_REF>; }; +&dwc3_1 { + clocks = <&zynqmp_clk USB3_DUAL_REF>; +}; + &watchdog0 { clocks = <&zynqmp_clk WDT>; }; diff --git a/arch/arm/dts/zynqmp.dtsi b/arch/arm/dts/zynqmp.dtsi index 2aaec6cf5a..f4184f79a5 100644 --- a/arch/arm/dts/zynqmp.dtsi +++ b/arch/arm/dts/zynqmp.dtsi @@ -869,6 +869,7 @@ iommus = <&smmu 0x860>; snps,quirk-frame-length-adjustment = <0x20>; snps,refclk_fladj; + clock-names = "ref"; snps,enable_guctl1_resume_quirk; snps,enable_guctl1_ipd_quirk; snps,xhci-stream-quirk; @@ -900,6 +901,7 @@ iommus = <&smmu 0x861>; snps,quirk-frame-length-adjustment = <0x20>; snps,refclk_fladj; + clock-names = "ref"; snps,enable_guctl1_resume_quirk; snps,enable_guctl1_ipd_quirk; snps,xhci-stream-quirk; From ce8808628e18cd3d71fbc001edb15e59ee824d91 Mon Sep 17 00:00:00 2001 From: T Karthik Reddy Date: Wed, 24 Aug 2022 13:23:26 +0200 Subject: [PATCH 078/374] xilinx: Add env redund offset ENV_OFFSET_REDUND config is by default set to 0 for flashes. Saving the env variables is overwriting data at 0 offset, which is wrong. So add default redund env offset for Zynq, ZynqMP, Versal and microblaze platforms. Configured ENV_OFFSET_REDUND offsets by ENV_OFFSET + (2 * ENV_SIZE). In case of versal, we configured ENV_OFFSET_REDUND at 0x7F00000 instead of 0x7F80000. As BOOT_SCRIPT_OFFSET is already configured at 0x7F80000. Added ENV_OFFSET_REDUND in Kconfig for microblaze due to dependency of ENV_IS_IN_SPI_FLASH config. Below table specifies platform specific env and env redund offsets. PLAT ENV_OFFSET ENV_OFFSET_REDUND ---- ---------- ----------------- ZYNQ 0xE0000 0xE40000 ZYNQMP 0x1E00000 0x1E80000 VERSAL 0x7F40000 0x7F00000 MICROBLAZE 0x1080000 0x10C0000 Signed-off-by: T Karthik Reddy Signed-off-by: Michal Simek Link: https://lore.kernel.org/r/92656dc08f0f5a749d62b71ca6e77fe1be72e9e0.1661340204.git.michal.simek@amd.com --- configs/xilinx_versal_virt_defconfig | 1 + configs/xilinx_zynq_virt_defconfig | 1 + configs/xilinx_zynqmp_virt_defconfig | 1 + env/Kconfig | 1 + 4 files changed, 4 insertions(+) diff --git a/configs/xilinx_versal_virt_defconfig b/configs/xilinx_versal_virt_defconfig index ffd8bea81c..7b96c4fbd9 100644 --- a/configs/xilinx_versal_virt_defconfig +++ b/configs/xilinx_versal_virt_defconfig @@ -7,6 +7,7 @@ CONFIG_SYS_TEXT_BASE=0x8000000 CONFIG_SYS_MALLOC_F_LEN=0x100000 CONFIG_DEFAULT_DEVICE_TREE="xilinx-versal-virt" CONFIG_SYS_PROMPT="Versal> " +CONFIG_ENV_OFFSET_REDUND=0x7F00000 CONFIG_CMD_FRU=y CONFIG_DEFINE_TCM_OCM_MMAP=y CONFIG_SYS_LOAD_ADDR=0x8000000 diff --git a/configs/xilinx_zynq_virt_defconfig b/configs/xilinx_zynq_virt_defconfig index e6f8e221a5..b8e16cab6e 100644 --- a/configs/xilinx_zynq_virt_defconfig +++ b/configs/xilinx_zynq_virt_defconfig @@ -8,6 +8,7 @@ CONFIG_DM_GPIO=y CONFIG_DEFAULT_DEVICE_TREE="zynq-zc706" CONFIG_SPL_STACK_R_ADDR=0x200000 CONFIG_SPL=y +CONFIG_ENV_OFFSET_REDUND=0xE40000 CONFIG_CMD_FRU=y CONFIG_CMD_ZYNQ_AES=y CONFIG_SYS_LOAD_ADDR=0x0 diff --git a/configs/xilinx_zynqmp_virt_defconfig b/configs/xilinx_zynqmp_virt_defconfig index e5ac26e038..e242884d3f 100644 --- a/configs/xilinx_zynqmp_virt_defconfig +++ b/configs/xilinx_zynqmp_virt_defconfig @@ -10,6 +10,7 @@ CONFIG_SPL_STACK_R_ADDR=0x18000000 CONFIG_SPL_SIZE_LIMIT=0x2a000 CONFIG_SPL_SIZE_LIMIT_PROVIDE_STACK=0x0 CONFIG_SPL=y +CONFIG_ENV_OFFSET_REDUND=0x1E80000 CONFIG_SPL_SPI_FLASH_SUPPORT=y CONFIG_SPL_SPI=y CONFIG_ZYNQ_MAC_IN_EEPROM=y diff --git a/env/Kconfig b/env/Kconfig index 238e4c70cf..5329f7585b 100644 --- a/env/Kconfig +++ b/env/Kconfig @@ -570,6 +570,7 @@ config ENV_OFFSET_REDUND hex "Redundant environment offset" depends on (ENV_IS_IN_EEPROM || ENV_IS_IN_MMC || ENV_IS_IN_NAND || \ ENV_IS_IN_SPI_FLASH) && SYS_REDUNDAND_ENVIRONMENT + default 0x10C0000 if MICROBLAZE default 0 help Offset from the start of the device (or partition) of the redundant From a27278f054309aa9192c858154869fa25bdff5ec Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Wed, 24 Aug 2022 13:28:35 +0200 Subject: [PATCH 079/374] xilinx: Enable CMD_GREPENV/SETEXPR by default Enable both of these commands in Xilinx SoCs to be able to use them in boot scripts. Signed-off-by: Michal Simek Link: https://lore.kernel.org/r/1a612be7e09e9bc502f30e1f025441ccf8accba5.1661340513.git.michal.simek@amd.com --- configs/microblaze-generic_defconfig | 2 +- configs/xilinx_versal_virt_defconfig | 1 + configs/xilinx_zynq_virt_defconfig | 2 +- configs/xilinx_zynqmp_virt_defconfig | 1 + 4 files changed, 4 insertions(+), 2 deletions(-) diff --git a/configs/microblaze-generic_defconfig b/configs/microblaze-generic_defconfig index b5c5efe596..01c93d5c4e 100644 --- a/configs/microblaze-generic_defconfig +++ b/configs/microblaze-generic_defconfig @@ -43,9 +43,9 @@ CONFIG_SYS_BOOTM_LEN=0x4000000 CONFIG_CMD_IMLS=y CONFIG_CMD_SPL=y CONFIG_CMD_ASKENV=y +CONFIG_CMD_GREPENV=y CONFIG_CMD_GPIO=y CONFIG_CMD_SAVES=y -# CONFIG_CMD_SETEXPR is not set CONFIG_BOOTP_BOOTFILESIZE=y CONFIG_CMD_TFTPPUT=y CONFIG_CMD_CACHE=y diff --git a/configs/xilinx_versal_virt_defconfig b/configs/xilinx_versal_virt_defconfig index 7b96c4fbd9..c3fa913b20 100644 --- a/configs/xilinx_versal_virt_defconfig +++ b/configs/xilinx_versal_virt_defconfig @@ -26,6 +26,7 @@ CONFIG_SYS_MAXARGS=64 CONFIG_SYS_PBSIZE=2073 CONFIG_SYS_BOOTM_LEN=0x6400000 CONFIG_CMD_BOOTMENU=y +CONFIG_CMD_GREPENV=y CONFIG_CMD_NVEDIT_EFI=y CONFIG_CMD_MEMTEST=y CONFIG_SYS_ALT_MEMTEST=y diff --git a/configs/xilinx_zynq_virt_defconfig b/configs/xilinx_zynq_virt_defconfig index b8e16cab6e..c12a1cbbc8 100644 --- a/configs/xilinx_zynq_virt_defconfig +++ b/configs/xilinx_zynq_virt_defconfig @@ -51,6 +51,7 @@ CONFIG_SYS_PBSIZE=2071 CONFIG_SYS_BOOTM_LEN=0x3c00000 CONFIG_CMD_IMLS=y CONFIG_CMD_THOR_DOWNLOAD=y +CONFIG_CMD_GREPENV=y CONFIG_CMD_MEMTEST=y CONFIG_SYS_ALT_MEMTEST=y CONFIG_CMD_DFU=y @@ -65,7 +66,6 @@ CONFIG_CMD_MTD=y CONFIG_CMD_NAND_LOCK_UNLOCK=y CONFIG_CMD_SF_TEST=y CONFIG_CMD_USB=y -# CONFIG_CMD_SETEXPR is not set CONFIG_BOOTP_MAY_FAIL=y CONFIG_CMD_TFTPPUT=y CONFIG_CMD_CACHE=y diff --git a/configs/xilinx_zynqmp_virt_defconfig b/configs/xilinx_zynqmp_virt_defconfig index e242884d3f..1591f221b5 100644 --- a/configs/xilinx_zynqmp_virt_defconfig +++ b/configs/xilinx_zynqmp_virt_defconfig @@ -57,6 +57,7 @@ CONFIG_SYS_PBSIZE=2073 CONFIG_SYS_BOOTM_LEN=0x6400000 CONFIG_CMD_BOOTMENU=y CONFIG_CMD_THOR_DOWNLOAD=y +CONFIG_CMD_GREPENV=y CONFIG_CMD_NVEDIT_EFI=y CONFIG_CMD_MEMTEST=y CONFIG_SYS_ALT_MEMTEST=y From be3a73c0c42c548bb892faed5b4e8e4fe7cd3295 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Wed, 31 Aug 2022 11:28:59 +0200 Subject: [PATCH 080/374] ARM: zynq: Align bss and end of u-boot image to 64bits The main reason is that DT memory reserved code is expecting DT to be 64bit aligned. For more information take a look at commit 5bd5ee02b23b ("xilinx: zynqmp: Check that DT is 64bit aligned"). Signed-off-by: Michal Simek Link: https://lore.kernel.org/r/9f3688cda188d8ea0b462df2aa08a10ddcc9c149.1661938136.git.michal.simek@amd.com --- arch/arm/mach-zynq/u-boot.lds | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-zynq/u-boot.lds b/arch/arm/mach-zynq/u-boot.lds index a5169fd915..3b7c9d515f 100644 --- a/arch/arm/mach-zynq/u-boot.lds +++ b/arch/arm/mach-zynq/u-boot.lds @@ -75,7 +75,7 @@ SECTIONS *(.__efi_runtime_rel_stop) } - . = ALIGN(4); + . = ALIGN(8); .image_copy_end : { *(.__image_copy_end) @@ -114,7 +114,7 @@ SECTIONS .bss __bss_base (OVERLAY) : { *(.bss*) - . = ALIGN(4); + . = ALIGN(8); __bss_limit = .; } From a32c3e9e4fb6932f80a165f56dc52e7afcffb2b2 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Thu, 25 Aug 2022 14:23:10 +0200 Subject: [PATCH 081/374] arm64: xilinx: Move board_get_usable_ram_top() to common location The commit ce39ee28ec31 ("zynqmp: Do not place u-boot to reserved memory location") adds functionality for ZynqMP to read reserved memory node and do not place U-Boot to reserved location. This functionality is generic across all Xilinx SOCs that's why move it to common location to be used by all Xilinx SOCs. On zynq platform this is also fixing issue where U-Boot was placed to locating which was reserved already which ends up with error message "ERROR: reserving fdt memory region failed (addr=30000000 size=10000000 flags=4)" which is shown when bdinfo is called. Tested on vck190, zcu102, zc706 and kc705 to cover all platforms. Signed-off-by: Michal Simek Link: https://lore.kernel.org/r/b0817807912f7c7af6a8e1cf9ee04e5ab5de5f6a.1661430188.git.michal.simek@amd.com --- board/xilinx/common/board.c | 29 +++++++++++++++++++ .../microblaze-generic/microblaze-generic.c | 21 -------------- board/xilinx/versal/board.c | 23 --------------- board/xilinx/zynqmp/zynqmp.c | 29 ------------------- 4 files changed, 29 insertions(+), 73 deletions(-) diff --git a/board/xilinx/common/board.c b/board/xilinx/common/board.c index 9b4aded466..5e36386361 100644 --- a/board/xilinx/common/board.c +++ b/board/xilinx/common/board.c @@ -8,6 +8,8 @@ #include #include #include +#include +#include #include #include #include @@ -602,3 +604,30 @@ int embedded_dtb_select(void) return 0; } #endif + +#if defined(CONFIG_LMB) +ulong board_get_usable_ram_top(ulong total_size) +{ + phys_size_t size; + phys_addr_t reg; + struct lmb lmb; + + if (!total_size) + return gd->ram_top; + + if (!IS_ALIGNED((ulong)gd->fdt_blob, 0x8)) + panic("Not 64bit aligned DT location: %p\n", gd->fdt_blob); + + /* found enough not-reserved memory to relocated U-Boot */ + lmb_init(&lmb); + lmb_add(&lmb, gd->ram_base, gd->ram_size); + boot_fdt_add_mem_rsv_regions(&lmb, (void *)gd->fdt_blob); + size = ALIGN(CONFIG_SYS_MALLOC_LEN + total_size, MMU_SECTION_SIZE); + reg = lmb_alloc(&lmb, size, MMU_SECTION_SIZE); + + if (!reg) + reg = gd->ram_top - size; + + return reg + size; +} +#endif diff --git a/board/xilinx/microblaze-generic/microblaze-generic.c b/board/xilinx/microblaze-generic/microblaze-generic.c index f58ecd1590..a427ac94a1 100644 --- a/board/xilinx/microblaze-generic/microblaze-generic.c +++ b/board/xilinx/microblaze-generic/microblaze-generic.c @@ -14,8 +14,6 @@ #include #include #include -#include -#include #include #include #include @@ -38,25 +36,6 @@ int dram_init(void) return 0; }; -ulong board_get_usable_ram_top(ulong total_size) -{ - phys_size_t size; - phys_addr_t reg; - struct lmb lmb; - - /* found enough not-reserved memory to relocated U-Boot */ - lmb_init(&lmb); - lmb_add(&lmb, gd->ram_base, gd->ram_size); - boot_fdt_add_mem_rsv_regions(&lmb, (void *)gd->fdt_blob); - size = ALIGN(CONFIG_SYS_MALLOC_LEN + total_size, MMU_SECTION_SIZE); - reg = lmb_alloc(&lmb, size, MMU_SECTION_SIZE); - - if (!reg) - reg = gd->ram_top - size; - - return reg + size; -} - int board_late_init(void) { ulong max_size; diff --git a/board/xilinx/versal/board.c b/board/xilinx/versal/board.c index d8f39be56c..f9f5457ed2 100644 --- a/board/xilinx/versal/board.c +++ b/board/xilinx/versal/board.c @@ -9,7 +9,6 @@ #include #include #include -#include #include #include #include @@ -270,28 +269,6 @@ int dram_init(void) return 0; } -ulong board_get_usable_ram_top(ulong total_size) -{ - phys_size_t size; - phys_addr_t reg; - struct lmb lmb; - - if (!total_size) - return gd->ram_top; - - /* found enough not-reserved memory to relocated U-Boot */ - lmb_init(&lmb); - lmb_add(&lmb, gd->ram_base, gd->ram_size); - boot_fdt_add_mem_rsv_regions(&lmb, (void *)gd->fdt_blob); - size = ALIGN(CONFIG_SYS_MALLOC_LEN + total_size, MMU_SECTION_SIZE); - reg = lmb_alloc(&lmb, size, MMU_SECTION_SIZE); - - if (!reg) - reg = gd->ram_top - size; - - return reg + size; -} - void reset_cpu(void) { } diff --git a/board/xilinx/zynqmp/zynqmp.c b/board/xilinx/zynqmp/zynqmp.c index 21bcc26682..62537760df 100644 --- a/board/xilinx/zynqmp/zynqmp.c +++ b/board/xilinx/zynqmp/zynqmp.c @@ -12,8 +12,6 @@ #include #include #include -#include -#include #include #include #include @@ -256,33 +254,6 @@ int dram_init(void) return 0; } -#if defined(CONFIG_LMB) -ulong board_get_usable_ram_top(ulong total_size) -{ - phys_size_t size; - phys_addr_t reg; - struct lmb lmb; - - if (!total_size) - return gd->ram_top; - - if (!IS_ALIGNED((ulong)gd->fdt_blob, 0x8)) - panic("Not 64bit aligned DT location: %p\n", gd->fdt_blob); - - /* found enough not-reserved memory to relocated U-Boot */ - lmb_init(&lmb); - lmb_add(&lmb, gd->ram_base, gd->ram_size); - boot_fdt_add_mem_rsv_regions(&lmb, (void *)gd->fdt_blob); - size = ALIGN(CONFIG_SYS_MALLOC_LEN + total_size, MMU_SECTION_SIZE); - reg = lmb_alloc(&lmb, size, MMU_SECTION_SIZE); - - if (!reg) - reg = gd->ram_top - size; - - return reg + size; -} -#endif - #else int dram_init_banksize(void) { From aaf0793be36f83f1458623bb1eef0670e02e8b82 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Tue, 6 Sep 2022 12:41:34 +0200 Subject: [PATCH 082/374] xilinx: versal: Disable LMB for mini configurations There shouldn't be a reason to have LMB on for these configurations. LMB was already disabled for ZynqMP by commit 0063487a5b60 ("configs: zynqmp: Disable LMB for mini u-boot"). Signed-off-by: Michal Simek Link: https://lore.kernel.org/r/17d1e9b50b2fd032352911f94f4f213828e0a3f7.1662460892.git.michal.simek@amd.com --- configs/xilinx_versal_mini_defconfig | 1 + configs/xilinx_versal_mini_emmc0_defconfig | 1 + configs/xilinx_versal_mini_emmc1_defconfig | 1 + 3 files changed, 3 insertions(+) diff --git a/configs/xilinx_versal_mini_defconfig b/configs/xilinx_versal_mini_defconfig index a78ee631e4..7a0557a22e 100644 --- a/configs/xilinx_versal_mini_defconfig +++ b/configs/xilinx_versal_mini_defconfig @@ -66,3 +66,4 @@ CONFIG_SYS_RELOC_GD_ENV_ADDR=y # CONFIG_MMC is not set CONFIG_ARM_DCC=y # CONFIG_GZIP is not set +# CONFIG_LMB is not set diff --git a/configs/xilinx_versal_mini_emmc0_defconfig b/configs/xilinx_versal_mini_emmc0_defconfig index ef73579dca..4b626d3465 100644 --- a/configs/xilinx_versal_mini_emmc0_defconfig +++ b/configs/xilinx_versal_mini_emmc0_defconfig @@ -67,3 +67,4 @@ CONFIG_ARM_DCC=y CONFIG_FAT_WRITE=y # CONFIG_GZIP is not set # CONFIG_EFI_LOADER is not set +# CONFIG_LMB is not set diff --git a/configs/xilinx_versal_mini_emmc1_defconfig b/configs/xilinx_versal_mini_emmc1_defconfig index fb7c5cfdbb..6fe2ebf876 100644 --- a/configs/xilinx_versal_mini_emmc1_defconfig +++ b/configs/xilinx_versal_mini_emmc1_defconfig @@ -67,3 +67,4 @@ CONFIG_ARM_DCC=y CONFIG_FAT_WRITE=y # CONFIG_GZIP is not set # CONFIG_EFI_LOADER is not set +# CONFIG_LMB is not set From bae7d37e526f29504dd7765c80d664c0482c94dd Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Fri, 26 Aug 2022 10:30:47 +0200 Subject: [PATCH 083/374] net: gem: Check rate before setting it up On QEMU setting rate for fixed clock is failing. That's why check a rate first if the rate is the same there is no need to ask for the change. Signed-off-by: Michal Simek Link: https://lore.kernel.org/r/bc465ffd4904bfd65208b782daa06732b915db54.1661502645.git.michal.simek@amd.com --- drivers/net/zynq_gem.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/net/zynq_gem.c b/drivers/net/zynq_gem.c index 4e8dd4badd..61a6c83e33 100644 --- a/drivers/net/zynq_gem.c +++ b/drivers/net/zynq_gem.c @@ -500,10 +500,13 @@ static int zynq_gem_init(struct udevice *dev) } #endif - ret = clk_set_rate(&priv->tx_clk, clk_rate); - if (IS_ERR_VALUE(ret)) { - dev_err(dev, "failed to set tx clock rate\n"); - return ret; + ret = clk_get_rate(&priv->tx_clk); + if (ret != clk_rate) { + ret = clk_set_rate(&priv->tx_clk, clk_rate); + if (IS_ERR_VALUE(ret)) { + dev_err(dev, "failed to set tx clock rate %ld\n", clk_rate); + return ret; + } } ret = clk_enable(&priv->tx_clk); From 3a6948ce711b8c7692a3e717021cc2b47e69fce7 Mon Sep 17 00:00:00 2001 From: Ovidiu Panait Date: Mon, 29 Aug 2022 20:02:02 +0300 Subject: [PATCH 084/374] microblaze: drop CONFIG_SYS_INIT_RAM_ADDR and CONFIG_SYS_INIT_RAM_SIZE These macros are not used anymore in microblaze code since commit f113d7d303467 ("Convert CONFIG_SPL_STACK to Kconfig"), so remove them. Fixes: f113d7d303467 ("Convert CONFIG_SPL_STACK to Kconfig") Signed-off-by: Ovidiu Panait Link: https://lore.kernel.org/r/20220829170205.1274484-1-ovpanait@gmail.com Signed-off-by: Michal Simek --- include/configs/microblaze-generic.h | 6 ------ 1 file changed, 6 deletions(-) diff --git a/include/configs/microblaze-generic.h b/include/configs/microblaze-generic.h index 8eaac4f8bc..dfae8cea7b 100644 --- a/include/configs/microblaze-generic.h +++ b/include/configs/microblaze-generic.h @@ -97,10 +97,4 @@ #define CONFIG_SYS_UBOOT_BASE CONFIG_SYS_TEXT_BASE -/* SP location before relocation, must use scratch RAM */ -/* BRAM start */ -#define CONFIG_SYS_INIT_RAM_ADDR 0x0 -/* BRAM size - will be generated */ -#define CONFIG_SYS_INIT_RAM_SIZE 0x100000 - #endif /* __CONFIG_H */ From 3f351cd358a3581844f3cacdfe60710bf925d75d Mon Sep 17 00:00:00 2001 From: Ovidiu Panait Date: Mon, 29 Aug 2022 20:02:03 +0300 Subject: [PATCH 085/374] cpu: microblaze: add error handling in microblaze_cpu_get_desc() Check snprintf() return value for errors. Make microblaze_cpu_get_desc() directly return snprintf() error code if ret < 0. Otherwise, if the return value is greater than or equal to size, the resulting string is truncated, so return -ENOSPC. Fixes: 816226d27e ("cpu: add CPU driver for microblaze") Signed-off-by: Ovidiu Panait Link: https://lore.kernel.org/r/20220829170205.1274484-2-ovpanait@gmail.com Signed-off-by: Michal Simek --- drivers/cpu/microblaze_cpu.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/cpu/microblaze_cpu.c b/drivers/cpu/microblaze_cpu.c index 969a1047e5..b9d0792822 100644 --- a/drivers/cpu/microblaze_cpu.c +++ b/drivers/cpu/microblaze_cpu.c @@ -97,8 +97,10 @@ static int microblaze_cpu_get_desc(const struct udevice *dev, char *buf, ret = snprintf(buf, size, "MicroBlaze @ %uMHz, Rev: %s, FPGA family: %s", cpu_freq_mhz, cpu_ver, fpga_family); + if (ret < 0) + return ret; - return 0; + return (ret >= size) ? -ENOSPC : 0; } static int microblaze_cpu_get_info(const struct udevice *dev, From ae90d16ac78a2d7bd0327f71c26b46b5182315d3 Mon Sep 17 00:00:00 2001 From: Ovidiu Panait Date: Mon, 29 Aug 2022 20:02:04 +0300 Subject: [PATCH 086/374] cmd: bdinfo: introduce bdinfo_print_size() helper Add bdinfo_print_size() helper to display size variables (such as cache sizes) in bdinfo format. The size is printed as "xxx Bytes", "xxx KiB", "xxx MiB", "xxx GiB", etc as needed; Reviewed-by: Simon Glass Signed-off-by: Ovidiu Panait Reviewed-by: Jason Liu Link: https://lore.kernel.org/r/20220829170205.1274484-3-ovpanait@gmail.com Signed-off-by: Michal Simek --- cmd/bdinfo.c | 7 +++++++ include/init.h | 13 +++++++++++++ 2 files changed, 20 insertions(+) diff --git a/cmd/bdinfo.c b/cmd/bdinfo.c index 8a1bea4e34..af2e9757db 100644 --- a/cmd/bdinfo.c +++ b/cmd/bdinfo.c @@ -16,9 +16,16 @@ #include #include #include +#include DECLARE_GLOBAL_DATA_PTR; +void bdinfo_print_size(const char *name, uint64_t size) +{ + printf("%-12s= ", name); + print_size(size, "\n"); +} + void bdinfo_print_num_l(const char *name, ulong value) { printf("%-12s= 0x%0*lx\n", name, 2 * (int)sizeof(value), value); diff --git a/include/init.h b/include/init.h index 7b8f62c121..02bb4ce13e 100644 --- a/include/init.h +++ b/include/init.h @@ -343,6 +343,19 @@ void bdinfo_print_num_ll(const char *name, unsigned long long value); /* Print a clock speed in MHz */ void bdinfo_print_mhz(const char *name, unsigned long hz); +/** + * bdinfo_print_size - print size variables in bdinfo format + * @name: string to print before the size + * @size: size to print + * + * Helper function for displaying size variables as properly formatted bdinfo + * entries. The size is printed as "xxx Bytes", "xxx KiB", "xxx MiB", + * "xxx GiB", etc. as needed; + * + * For use in arch_print_bdinfo(). + */ +void bdinfo_print_size(const char *name, uint64_t size); + /* Show arch-specific information for the 'bd' command */ void arch_print_bdinfo(void); From f459986e86458a9980a3d0f4de1d4a44a549c00c Mon Sep 17 00:00:00 2001 From: Ovidiu Panait Date: Mon, 29 Aug 2022 20:02:05 +0300 Subject: [PATCH 087/374] microblaze: add arch_print_bdinfo() implementation Allow bdinfo command to print icache/dcache information: U-Boot-mONStR> bdinfo boot_params = 0x00000000 DRAM bank = 0x00000000 -> start = 0x04000000 -> size = 0x04000000 flashstart = 0x00000000 flashsize = 0x00000000 flashoffset = 0x00000000 baudrate = 9600 bps relocaddr = 0x07f76000 reloc off = 0x02f76000 Build = 32-bit current eth = unknown ethaddr = (not set) IP addr = fdt_blob = 0x07fec7e0 new_fdt = 0x00000000 fdt_size = 0x00000000 lmb_dump_all: memory.cnt = 0x1 memory[0] [0x4000000-0x7ffffff], 0x04000000 bytes flags: 0 reserved.cnt = 0x1 reserved[0] [0x7e94b8c-0x7ffffff], 0x0016b474 bytes flags: 0 devicetree = embed icache = 32 KiB icache line = 4 Bytes dcache = 32 KiB dcache line = 4 Bytes Signed-off-by: Ovidiu Panait Link: https://lore.kernel.org/r/20220829170205.1274484-4-ovpanait@gmail.com Signed-off-by: Michal Simek --- arch/microblaze/lib/Makefile | 1 + arch/microblaze/lib/bdinfo.c | 24 ++++++++++++++++++++++++ 2 files changed, 25 insertions(+) create mode 100644 arch/microblaze/lib/bdinfo.c diff --git a/arch/microblaze/lib/Makefile b/arch/microblaze/lib/Makefile index 05f447abba..dfd8135f4f 100644 --- a/arch/microblaze/lib/Makefile +++ b/arch/microblaze/lib/Makefile @@ -4,4 +4,5 @@ # Wolfgang Denk, DENX Software Engineering, wd@denx.de. obj-$(CONFIG_CMD_BOOTM) += bootm.o +obj-$(CONFIG_CMD_BDI) += bdinfo.o obj-y += muldi3.o diff --git a/arch/microblaze/lib/bdinfo.c b/arch/microblaze/lib/bdinfo.c new file mode 100644 index 0000000000..41b7a216a4 --- /dev/null +++ b/arch/microblaze/lib/bdinfo.c @@ -0,0 +1,24 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2022, Ovidiu Panait + */ +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +void arch_print_bdinfo(void) +{ + struct microblaze_cpuinfo *ci = gd_cpuinfo(); + + if (ci->icache_size) { + bdinfo_print_size("icache", ci->icache_size); + bdinfo_print_size("icache line", ci->icache_line_length); + } + + if (ci->dcache_size) { + bdinfo_print_size("dcache", ci->dcache_size); + bdinfo_print_size("dcache line", ci->dcache_line_length); + } +} From 68852f3241af7d2f3e7cf85fbcd2268fd8c22b1e Mon Sep 17 00:00:00 2001 From: Ashok Reddy Soma Date: Wed, 24 Aug 2022 05:38:45 -0600 Subject: [PATCH 088/374] spi: cadence-qspi: Correct flash reset function name In cadence_spi_probe, cadence_qspi_versal_flash_reset() is called to reset the flash device. Looks like there is a mistake in previous series of patches where it is defined as cadence_spi_versal_flash_reset() but called as cadence_qspi_versal_flash_reset. Since there is a weak function defined with the same name this issue was not caught. Fix the issue by renaming cadence_spi_versal_flash_reset as cadence_qspi_versal_flash_reset(). Signed-off-by: Ashok Reddy Soma Link: https://lore.kernel.org/r/20220824113847.7482-2-ashok.reddy.soma@xilinx.com Signed-off-by: Michal Simek --- drivers/spi/cadence_ospi_versal.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/spi/cadence_ospi_versal.c b/drivers/spi/cadence_ospi_versal.c index 52bcad053f..c756a854bc 100644 --- a/drivers/spi/cadence_ospi_versal.c +++ b/drivers/spi/cadence_ospi_versal.c @@ -128,7 +128,7 @@ int cadence_qspi_apb_wait_for_dma_cmplt(struct cadence_spi_plat *plat) } #if defined(CONFIG_DM_GPIO) -int cadence_spi_versal_flash_reset(struct udevice *dev) +int cadence_qspi_versal_flash_reset(struct udevice *dev) { struct gpio_desc gpio; u32 reset_gpio; @@ -169,7 +169,7 @@ int cadence_spi_versal_flash_reset(struct udevice *dev) return 0; } #else -int cadence_spi_versal_flash_reset(struct udevice *dev) +int cadence_qspi_versal_flash_reset(struct udevice *dev) { /* CRP WPROT */ writel(0, WPROT_CRP); From d0003b5edf11b0fc2a050e2a0eaac39ba921d85e Mon Sep 17 00:00:00 2001 From: Ashok Reddy Soma Date: Wed, 24 Aug 2022 05:38:46 -0600 Subject: [PATCH 089/374] spi: cadence_qspi: Call read_setup for STIG_READ In cadence_spi_read_id we are using STIG mode to read flash id's. Call cadence_qspi_apb_command_read_setup() to setup cmd, addr and data bus width properly before cadence_qspi_apb_command_read(). Signed-off-by: Ashok Reddy Soma Link: https://lore.kernel.org/r/20220824113847.7482-3-ashok.reddy.soma@xilinx.com Signed-off-by: Michal Simek --- drivers/spi/cadence_qspi.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/spi/cadence_qspi.c b/drivers/spi/cadence_qspi.c index 907f5dadc4..6e50b94e14 100644 --- a/drivers/spi/cadence_qspi.c +++ b/drivers/spi/cadence_qspi.c @@ -59,12 +59,17 @@ static int cadence_spi_write_speed(struct udevice *bus, uint hz) static int cadence_spi_read_id(struct cadence_spi_plat *plat, u8 len, u8 *idcode) { + int err; struct spi_mem_op op = SPI_MEM_OP(SPI_MEM_OP_CMD(0x9F, 1), SPI_MEM_OP_NO_ADDR, SPI_MEM_OP_NO_DUMMY, SPI_MEM_OP_DATA_IN(len, idcode, 1)); - return cadence_qspi_apb_command_read(plat, &op); + err = cadence_qspi_apb_command_read_setup(plat, &op); + if (!err) + err = cadence_qspi_apb_command_read(plat, &op); + + return err; } /* Calibration sequence to determine the read data capture delay register */ From f7d4cab1b3059089e0bb16bc26849b2aad57fa17 Mon Sep 17 00:00:00 2001 From: Ashok Reddy Soma Date: Wed, 24 Aug 2022 05:38:47 -0600 Subject: [PATCH 090/374] spi: cadence-qspi: Use priv instead of plat across the driver As per driver model we should enumerate plat structure only in of_to_plat() and should be used only in probe(). Copy required plat structure info into priv structure in probe() and use priv structure across the driver. So replace plat with priv structure across the driver. Signed-off-by: Ashok Reddy Soma Link: https://lore.kernel.org/r/20220824113847.7482-4-ashok.reddy.soma@xilinx.com Signed-off-by: Michal Simek --- drivers/spi/cadence_ospi_versal.c | 52 +++---- drivers/spi/cadence_qspi.c | 101 +++++++------ drivers/spi/cadence_qspi.h | 56 +++++--- drivers/spi/cadence_qspi_apb.c | 231 +++++++++++++++--------------- 4 files changed, 236 insertions(+), 204 deletions(-) diff --git a/drivers/spi/cadence_ospi_versal.c b/drivers/spi/cadence_ospi_versal.c index c756a854bc..a25c50bc50 100644 --- a/drivers/spi/cadence_ospi_versal.c +++ b/drivers/spi/cadence_ospi_versal.c @@ -21,7 +21,7 @@ #define CMD_4BYTE_READ 0x13 #define CMD_4BYTE_FAST_READ 0x0C -int cadence_qspi_apb_dma_read(struct cadence_spi_plat *plat, +int cadence_qspi_apb_dma_read(struct cadence_spi_priv *priv, const struct spi_mem_op *op) { u32 reg, ret, rx_rem, n_rx, bytes_to_dma, data; @@ -34,86 +34,86 @@ int cadence_qspi_apb_dma_read(struct cadence_spi_plat *plat, if (bytes_to_dma) { cadence_qspi_apb_enable_linear_mode(false); - reg = readl(plat->regbase + CQSPI_REG_CONFIG); + reg = readl(priv->regbase + CQSPI_REG_CONFIG); reg |= CQSPI_REG_CONFIG_ENBL_DMA; - writel(reg, plat->regbase + CQSPI_REG_CONFIG); + writel(reg, priv->regbase + CQSPI_REG_CONFIG); - writel(bytes_to_dma, plat->regbase + CQSPI_REG_INDIRECTRDBYTES); + writel(bytes_to_dma, priv->regbase + CQSPI_REG_INDIRECTRDBYTES); writel(CQSPI_DFLT_INDIR_TRIG_ADDR_RANGE, - plat->regbase + CQSPI_REG_INDIR_TRIG_ADDR_RANGE); + priv->regbase + CQSPI_REG_INDIR_TRIG_ADDR_RANGE); writel(CQSPI_DFLT_DMA_PERIPH_CFG, - plat->regbase + CQSPI_REG_DMA_PERIPH_CFG); - writel((unsigned long)rxbuf, plat->regbase + + priv->regbase + CQSPI_REG_DMA_PERIPH_CFG); + writel((unsigned long)rxbuf, priv->regbase + CQSPI_DMA_DST_ADDR_REG); - writel(plat->trigger_address, plat->regbase + + writel(priv->trigger_address, priv->regbase + CQSPI_DMA_SRC_RD_ADDR_REG); - writel(bytes_to_dma, plat->regbase + + writel(bytes_to_dma, priv->regbase + CQSPI_DMA_DST_SIZE_REG); flush_dcache_range((unsigned long)rxbuf, (unsigned long)rxbuf + bytes_to_dma); writel(CQSPI_DFLT_DST_CTRL_REG_VAL, - plat->regbase + CQSPI_DMA_DST_CTRL_REG); + priv->regbase + CQSPI_DMA_DST_CTRL_REG); /* Start the indirect read transfer */ - writel(CQSPI_REG_INDIRECTRD_START, plat->regbase + + writel(CQSPI_REG_INDIRECTRD_START, priv->regbase + CQSPI_REG_INDIRECTRD); /* Wait for dma to complete transfer */ - ret = cadence_qspi_apb_wait_for_dma_cmplt(plat); + ret = cadence_qspi_apb_wait_for_dma_cmplt(priv); if (ret) return ret; /* Clear indirect completion status */ - writel(CQSPI_REG_INDIRECTRD_DONE, plat->regbase + + writel(CQSPI_REG_INDIRECTRD_DONE, priv->regbase + CQSPI_REG_INDIRECTRD); rxbuf += bytes_to_dma; } if (rx_rem) { - reg = readl(plat->regbase + CQSPI_REG_CONFIG); + reg = readl(priv->regbase + CQSPI_REG_CONFIG); reg &= ~CQSPI_REG_CONFIG_ENBL_DMA; - writel(reg, plat->regbase + CQSPI_REG_CONFIG); + writel(reg, priv->regbase + CQSPI_REG_CONFIG); - reg = readl(plat->regbase + CQSPI_REG_INDIRECTRDSTARTADDR); + reg = readl(priv->regbase + CQSPI_REG_INDIRECTRDSTARTADDR); reg += bytes_to_dma; - writel(reg, plat->regbase + CQSPI_REG_CMDADDRESS); + writel(reg, priv->regbase + CQSPI_REG_CMDADDRESS); - addr_bytes = readl(plat->regbase + CQSPI_REG_SIZE) & + addr_bytes = readl(priv->regbase + CQSPI_REG_SIZE) & CQSPI_REG_SIZE_ADDRESS_MASK; opcode = CMD_4BYTE_FAST_READ; dummy_cycles = 8; writel((dummy_cycles << CQSPI_REG_RD_INSTR_DUMMY_LSB) | opcode, - plat->regbase + CQSPI_REG_RD_INSTR); + priv->regbase + CQSPI_REG_RD_INSTR); reg = opcode << CQSPI_REG_CMDCTRL_OPCODE_LSB; reg |= (0x1 << CQSPI_REG_CMDCTRL_RD_EN_LSB); reg |= (addr_bytes & CQSPI_REG_CMDCTRL_ADD_BYTES_MASK) << CQSPI_REG_CMDCTRL_ADD_BYTES_LSB; reg |= (0x1 << CQSPI_REG_CMDCTRL_ADDR_EN_LSB); - dummy_cycles = (readl(plat->regbase + CQSPI_REG_RD_INSTR) >> + dummy_cycles = (readl(priv->regbase + CQSPI_REG_RD_INSTR) >> CQSPI_REG_RD_INSTR_DUMMY_LSB) & CQSPI_REG_RD_INSTR_DUMMY_MASK; reg |= (dummy_cycles & CQSPI_REG_CMDCTRL_DUMMY_MASK) << CQSPI_REG_CMDCTRL_DUMMY_LSB; reg |= (((rx_rem - 1) & CQSPI_REG_CMDCTRL_RD_BYTES_MASK) << CQSPI_REG_CMDCTRL_RD_BYTES_LSB); - ret = cadence_qspi_apb_exec_flash_cmd(plat->regbase, reg); + ret = cadence_qspi_apb_exec_flash_cmd(priv->regbase, reg); if (ret) return ret; - data = readl(plat->regbase + CQSPI_REG_CMDREADDATALOWER); + data = readl(priv->regbase + CQSPI_REG_CMDREADDATALOWER); memcpy(rxbuf, &data, rx_rem); } return 0; } -int cadence_qspi_apb_wait_for_dma_cmplt(struct cadence_spi_plat *plat) +int cadence_qspi_apb_wait_for_dma_cmplt(struct cadence_spi_priv *priv) { u32 timeout = CQSPI_DMA_TIMEOUT; - while (!(readl(plat->regbase + CQSPI_DMA_DST_I_STS_REG) & + while (!(readl(priv->regbase + CQSPI_DMA_DST_I_STS_REG) & CQSPI_DMA_DST_I_STS_DONE) && timeout--) udelay(1); @@ -122,8 +122,8 @@ int cadence_qspi_apb_wait_for_dma_cmplt(struct cadence_spi_plat *plat) return -ETIMEDOUT; } - writel(readl(plat->regbase + CQSPI_DMA_DST_I_STS_REG), - plat->regbase + CQSPI_DMA_DST_I_STS_REG); + writel(readl(priv->regbase + CQSPI_DMA_DST_I_STS_REG), + priv->regbase + CQSPI_DMA_DST_I_STS_REG); return 0; } diff --git a/drivers/spi/cadence_qspi.c b/drivers/spi/cadence_qspi.c index 6e50b94e14..ab0a681c83 100644 --- a/drivers/spi/cadence_qspi.c +++ b/drivers/spi/cadence_qspi.c @@ -29,7 +29,7 @@ #define CQSPI_READ 2 #define CQSPI_WRITE 3 -__weak int cadence_qspi_apb_dma_read(struct cadence_spi_plat *plat, +__weak int cadence_qspi_apb_dma_read(struct cadence_spi_priv *priv, const struct spi_mem_op *op) { return 0; @@ -42,32 +42,32 @@ __weak int cadence_qspi_versal_flash_reset(struct udevice *dev) static int cadence_spi_write_speed(struct udevice *bus, uint hz) { - struct cadence_spi_plat *plat = dev_get_plat(bus); struct cadence_spi_priv *priv = dev_get_priv(bus); cadence_qspi_apb_config_baudrate_div(priv->regbase, - plat->ref_clk_hz, hz); + priv->ref_clk_hz, hz); /* Reconfigure delay timing if speed is changed. */ - cadence_qspi_apb_delay(priv->regbase, plat->ref_clk_hz, hz, - plat->tshsl_ns, plat->tsd2d_ns, - plat->tchsh_ns, plat->tslch_ns); + cadence_qspi_apb_delay(priv->regbase, priv->ref_clk_hz, hz, + priv->tshsl_ns, priv->tsd2d_ns, + priv->tchsh_ns, priv->tslch_ns); return 0; } -static int cadence_spi_read_id(struct cadence_spi_plat *plat, u8 len, +static int cadence_spi_read_id(struct cadence_spi_priv *priv, u8 len, u8 *idcode) { int err; + struct spi_mem_op op = SPI_MEM_OP(SPI_MEM_OP_CMD(0x9F, 1), SPI_MEM_OP_NO_ADDR, SPI_MEM_OP_NO_DUMMY, SPI_MEM_OP_DATA_IN(len, idcode, 1)); - err = cadence_qspi_apb_command_read_setup(plat, &op); + err = cadence_qspi_apb_command_read_setup(priv, &op); if (!err) - err = cadence_qspi_apb_command_read(plat, &op); + err = cadence_qspi_apb_command_read(priv, &op); return err; } @@ -76,7 +76,6 @@ static int cadence_spi_read_id(struct cadence_spi_plat *plat, u8 len, static int spi_calibration(struct udevice *bus, uint hz) { struct cadence_spi_priv *priv = dev_get_priv(bus); - struct cadence_spi_plat *plat = dev_get_plat(bus); void *base = priv->regbase; unsigned int idcode = 0, temp = 0; int err = 0, i, range_lo = -1, range_hi = -1; @@ -91,7 +90,7 @@ static int spi_calibration(struct udevice *bus, uint hz) cadence_qspi_apb_controller_enable(base); /* read the ID which will be our golden value */ - err = cadence_spi_read_id(plat, 3, (u8 *)&idcode); + err = cadence_spi_read_id(priv, 3, (u8 *)&idcode); if (err) { puts("SF: Calibration failed (read)\n"); return err; @@ -110,7 +109,7 @@ static int spi_calibration(struct udevice *bus, uint hz) cadence_qspi_apb_controller_enable(base); /* issue a RDID to get the ID value */ - err = cadence_spi_read_id(plat, 3, (u8 *)&temp); + err = cadence_spi_read_id(priv, 3, (u8 *)&temp); if (err) { puts("SF: Calibration failed (read)\n"); return err; @@ -152,13 +151,11 @@ static int spi_calibration(struct udevice *bus, uint hz) static int cadence_spi_set_speed(struct udevice *bus, uint hz) { - struct cadence_spi_plat *plat = dev_get_plat(bus); struct cadence_spi_priv *priv = dev_get_priv(bus); int err; - if (!hz || hz > plat->max_hz) - hz = plat->max_hz; - + if (!hz || hz > priv->max_hz) + hz = priv->max_hz; /* Disable QSPI */ cadence_qspi_apb_controller_disable(priv->regbase); @@ -166,10 +163,10 @@ static int cadence_spi_set_speed(struct udevice *bus, uint hz) * If the device tree already provides a read delay value, use that * instead of calibrating. */ - if (plat->read_delay >= 0) { + if (priv->read_delay >= 0) { cadence_spi_write_speed(bus, hz); cadence_qspi_apb_readdata_capture(priv->regbase, 1, - plat->read_delay); + priv->read_delay); } else if (priv->previous_hz != hz || priv->qspi_calibrated_hz != hz || priv->qspi_calibrated_cs != spi_chip_select(bus)) { @@ -200,29 +197,44 @@ static int cadence_spi_probe(struct udevice *bus) struct clk clk; int ret; - priv->regbase = plat->regbase; - priv->ahbbase = plat->ahbbase; + priv->regbase = plat->regbase; + priv->ahbbase = plat->ahbbase; + priv->is_dma = plat->is_dma; + priv->is_decoded_cs = plat->is_decoded_cs; + priv->fifo_depth = plat->fifo_depth; + priv->fifo_width = plat->fifo_width; + priv->trigger_address = plat->trigger_address; + priv->read_delay = plat->read_delay; + priv->ahbsize = plat->ahbsize; + priv->max_hz = plat->max_hz; + + priv->page_size = plat->page_size; + priv->block_size = plat->block_size; + priv->tshsl_ns = plat->tshsl_ns; + priv->tsd2d_ns = plat->tsd2d_ns; + priv->tchsh_ns = plat->tchsh_ns; + priv->tslch_ns = plat->tslch_ns; if (CONFIG_IS_ENABLED(ZYNQMP_FIRMWARE)) xilinx_pm_request(PM_REQUEST_NODE, PM_DEV_OSPI, ZYNQMP_PM_CAPABILITY_ACCESS, ZYNQMP_PM_MAX_QOS, ZYNQMP_PM_REQUEST_ACK_NO, NULL); - if (plat->ref_clk_hz == 0) { + if (priv->ref_clk_hz == 0) { ret = clk_get_by_index(bus, 0, &clk); if (ret) { #ifdef CONFIG_HAS_CQSPI_REF_CLK - plat->ref_clk_hz = CONFIG_CQSPI_REF_CLK; + priv->ref_clk_hz = CONFIG_CQSPI_REF_CLK; #elif defined(CONFIG_ARCH_SOCFPGA) - plat->ref_clk_hz = cm_get_qspi_controller_clk_hz(); + priv->ref_clk_hz = cm_get_qspi_controller_clk_hz(); #else return ret; #endif } else { - plat->ref_clk_hz = clk_get_rate(&clk); + priv->ref_clk_hz = clk_get_rate(&clk); clk_free(&clk); - if (IS_ERR_VALUE(plat->ref_clk_hz)) - return plat->ref_clk_hz; + if (IS_ERR_VALUE(priv->ref_clk_hz)) + return priv->ref_clk_hz; } } @@ -231,16 +243,16 @@ static int cadence_spi_probe(struct udevice *bus) reset_deassert_bulk(priv->resets); if (!priv->qspi_is_init) { - cadence_qspi_apb_controller_init(plat); + cadence_qspi_apb_controller_init(priv); priv->qspi_is_init = 1; } - plat->wr_delay = 50 * DIV_ROUND_UP(NSEC_PER_SEC, plat->ref_clk_hz); + priv->wr_delay = 50 * DIV_ROUND_UP(NSEC_PER_SEC, priv->ref_clk_hz); if (CONFIG_IS_ENABLED(ARCH_VERSAL)) { /* Versal platform uses spi calibration to set read delay */ - if (plat->read_delay >= 0) - plat->read_delay = -1; + if (priv->read_delay >= 0) + priv->read_delay = -1; /* Reset ospi flash device */ ret = cadence_qspi_versal_flash_reset(bus); if (ret) @@ -263,7 +275,6 @@ static int cadence_spi_remove(struct udevice *dev) static int cadence_spi_set_mode(struct udevice *bus, uint mode) { - struct cadence_spi_plat *plat = dev_get_plat(bus); struct cadence_spi_priv *priv = dev_get_priv(bus); /* Disable QSPI */ @@ -273,7 +284,7 @@ static int cadence_spi_set_mode(struct udevice *bus, uint mode) cadence_qspi_apb_set_clk_mode(priv->regbase, mode); /* Enable Direct Access Controller */ - if (plat->use_dac_mode) + if (priv->use_dac_mode) cadence_qspi_apb_dac_mode_enable(priv->regbase); /* Enable QSPI */ @@ -286,7 +297,6 @@ static int cadence_spi_mem_exec_op(struct spi_slave *spi, const struct spi_mem_op *op) { struct udevice *bus = spi->dev->parent; - struct cadence_spi_plat *plat = dev_get_plat(bus); struct cadence_spi_priv *priv = dev_get_priv(bus); void *base = priv->regbase; int err = 0; @@ -294,7 +304,7 @@ static int cadence_spi_mem_exec_op(struct spi_slave *spi, /* Set Chip select */ cadence_qspi_apb_chipselect(base, spi_chip_select(spi->dev), - plat->is_decoded_cs); + priv->is_decoded_cs); if (op->data.dir == SPI_MEM_DATA_IN && op->data.buf.in) { if (!op->addr.nbytes) @@ -310,28 +320,28 @@ static int cadence_spi_mem_exec_op(struct spi_slave *spi, switch (mode) { case CQSPI_STIG_READ: - err = cadence_qspi_apb_command_read_setup(plat, op); + err = cadence_qspi_apb_command_read_setup(priv, op); if (!err) - err = cadence_qspi_apb_command_read(plat, op); + err = cadence_qspi_apb_command_read(priv, op); break; case CQSPI_STIG_WRITE: - err = cadence_qspi_apb_command_write_setup(plat, op); + err = cadence_qspi_apb_command_write_setup(priv, op); if (!err) - err = cadence_qspi_apb_command_write(plat, op); + err = cadence_qspi_apb_command_write(priv, op); break; case CQSPI_READ: - err = cadence_qspi_apb_read_setup(plat, op); + err = cadence_qspi_apb_read_setup(priv, op); if (!err) { - if (plat->is_dma) - err = cadence_qspi_apb_dma_read(plat, op); + if (priv->is_dma) + err = cadence_qspi_apb_dma_read(priv, op); else - err = cadence_qspi_apb_read_execute(plat, op); + err = cadence_qspi_apb_read_execute(priv, op); } break; case CQSPI_WRITE: - err = cadence_qspi_apb_write_setup(plat, op); + err = cadence_qspi_apb_write_setup(priv, op); if (!err) - err = cadence_qspi_apb_write_execute(plat, op); + err = cadence_qspi_apb_write_execute(priv, op); break; default: err = -1; @@ -364,6 +374,7 @@ static bool cadence_spi_mem_supports_op(struct spi_slave *slave, static int cadence_spi_of_to_plat(struct udevice *bus) { struct cadence_spi_plat *plat = dev_get_plat(bus); + struct cadence_spi_priv *priv = dev_get_priv(bus); ofnode subnode; plat->regbase = (void *)devfdt_get_addr_index(bus, 0); @@ -377,7 +388,7 @@ static int cadence_spi_of_to_plat(struct udevice *bus) 0); /* Use DAC mode only when MMIO window is at least 8M wide */ if (plat->ahbsize >= SZ_8M) - plat->use_dac_mode = true; + priv->use_dac_mode = true; plat->is_dma = dev_read_bool(bus, "cdns,is-dma"); diff --git a/drivers/spi/cadence_qspi.h b/drivers/spi/cadence_qspi.h index c8d16bb0e4..1c59d1a9d9 100644 --- a/drivers/spi/cadence_qspi.h +++ b/drivers/spi/cadence_qspi.h @@ -198,7 +198,6 @@ CQSPI_REG_SDRAMLEVEL_WR_LSB) & CQSPI_REG_SDRAMLEVEL_WR_MASK) struct cadence_spi_plat { - unsigned int ref_clk_hz; unsigned int max_hz; void *regbase; void *ahbbase; @@ -209,7 +208,6 @@ struct cadence_spi_plat { fdt_addr_t ahbsize; bool use_dac_mode; int read_delay; - u32 wr_delay; /* Flash parameters */ u32 page_size; @@ -219,17 +217,18 @@ struct cadence_spi_plat { u32 tchsh_ns; u32 tslch_ns; - /* Transaction protocol parameters. */ - u8 inst_width; - u8 addr_width; - u8 data_width; - bool dtr; bool is_dma; }; struct cadence_spi_priv { + unsigned int ref_clk_hz; + unsigned int max_hz; void *regbase; void *ahbbase; + unsigned int fifo_depth; + unsigned int fifo_width; + unsigned int trigger_address; + fdt_addr_t ahbsize; size_t cmd_len; u8 cmd_buf[32]; size_t data_len; @@ -238,32 +237,53 @@ struct cadence_spi_priv { unsigned int qspi_calibrated_hz; unsigned int qspi_calibrated_cs; unsigned int previous_hz; + u32 wr_delay; + int read_delay; struct reset_ctl_bulk *resets; + u32 page_size; + u32 block_size; + u32 tshsl_ns; + u32 tsd2d_ns; + u32 tchsh_ns; + u32 tslch_ns; + u8 edge_mode; + u8 dll_mode; + bool extra_dummy; + bool ddr_init; + bool is_decoded_cs; + bool use_dac_mode; + bool is_dma; + + /* Transaction protocol parameters. */ + u8 inst_width; + u8 addr_width; + u8 data_width; + bool dtr; }; /* Functions call declaration */ -void cadence_qspi_apb_controller_init(struct cadence_spi_plat *plat); +void cadence_qspi_apb_controller_init(struct cadence_spi_priv *priv); void cadence_qspi_apb_controller_enable(void *reg_base_addr); void cadence_qspi_apb_controller_disable(void *reg_base_addr); void cadence_qspi_apb_dac_mode_enable(void *reg_base); -int cadence_qspi_apb_command_read_setup(struct cadence_spi_plat *plat, +int cadence_qspi_apb_command_read_setup(struct cadence_spi_priv *priv, const struct spi_mem_op *op); -int cadence_qspi_apb_command_read(struct cadence_spi_plat *plat, +int cadence_qspi_apb_command_read(struct cadence_spi_priv *priv, const struct spi_mem_op *op); -int cadence_qspi_apb_command_write_setup(struct cadence_spi_plat *plat, +int cadence_qspi_apb_command_write_setup(struct cadence_spi_priv *priv, const struct spi_mem_op *op); -int cadence_qspi_apb_command_write(struct cadence_spi_plat *plat, +int cadence_qspi_apb_command_write(struct cadence_spi_priv *priv, const struct spi_mem_op *op); -int cadence_qspi_apb_read_setup(struct cadence_spi_plat *plat, +int cadence_qspi_apb_read_setup(struct cadence_spi_priv *priv, const struct spi_mem_op *op); -int cadence_qspi_apb_read_execute(struct cadence_spi_plat *plat, +int cadence_qspi_apb_read_execute(struct cadence_spi_priv *priv, const struct spi_mem_op *op); -int cadence_qspi_apb_write_setup(struct cadence_spi_plat *plat, +int cadence_qspi_apb_write_setup(struct cadence_spi_priv *priv, const struct spi_mem_op *op); -int cadence_qspi_apb_write_execute(struct cadence_spi_plat *plat, +int cadence_qspi_apb_write_execute(struct cadence_spi_priv *priv, const struct spi_mem_op *op); void cadence_qspi_apb_chipselect(void *reg_base, @@ -279,9 +299,9 @@ void cadence_qspi_apb_enter_xip(void *reg_base, char xip_dummy); void cadence_qspi_apb_readdata_capture(void *reg_base, unsigned int bypass, unsigned int delay); unsigned int cm_get_qspi_controller_clk_hz(void); -int cadence_qspi_apb_dma_read(struct cadence_spi_plat *plat, +int cadence_qspi_apb_dma_read(struct cadence_spi_priv *priv, const struct spi_mem_op *op); -int cadence_qspi_apb_wait_for_dma_cmplt(struct cadence_spi_plat *plat); +int cadence_qspi_apb_wait_for_dma_cmplt(struct cadence_spi_priv *priv); int cadence_qspi_apb_exec_flash_cmd(void *reg_base, unsigned int reg); int cadence_qspi_versal_flash_reset(struct udevice *dev); void cadence_qspi_apb_enable_linear_mode(bool enable); diff --git a/drivers/spi/cadence_qspi_apb.c b/drivers/spi/cadence_qspi_apb.c index c00755050e..cfae5dcbda 100644 --- a/drivers/spi/cadence_qspi_apb.c +++ b/drivers/spi/cadence_qspi_apb.c @@ -83,13 +83,13 @@ static unsigned int cadence_qspi_calc_dummy(const struct spi_mem_op *op, return dummy_clk; } -static u32 cadence_qspi_calc_rdreg(struct cadence_spi_plat *plat) +static u32 cadence_qspi_calc_rdreg(struct cadence_spi_priv *priv) { u32 rdreg = 0; - rdreg |= plat->inst_width << CQSPI_REG_RD_INSTR_TYPE_INSTR_LSB; - rdreg |= plat->addr_width << CQSPI_REG_RD_INSTR_TYPE_ADDR_LSB; - rdreg |= plat->data_width << CQSPI_REG_RD_INSTR_TYPE_DATA_LSB; + rdreg |= priv->inst_width << CQSPI_REG_RD_INSTR_TYPE_INSTR_LSB; + rdreg |= priv->addr_width << CQSPI_REG_RD_INSTR_TYPE_ADDR_LSB; + rdreg |= priv->data_width << CQSPI_REG_RD_INSTR_TYPE_DATA_LSB; return rdreg; } @@ -115,27 +115,27 @@ static int cadence_qspi_buswidth_to_inst_type(u8 buswidth) } } -static int cadence_qspi_set_protocol(struct cadence_spi_plat *plat, +static int cadence_qspi_set_protocol(struct cadence_spi_priv *priv, const struct spi_mem_op *op) { int ret; - plat->dtr = op->data.dtr && op->cmd.dtr && op->addr.dtr; + priv->dtr = op->data.dtr && op->cmd.dtr && op->addr.dtr; ret = cadence_qspi_buswidth_to_inst_type(op->cmd.buswidth); if (ret < 0) return ret; - plat->inst_width = ret; + priv->inst_width = ret; ret = cadence_qspi_buswidth_to_inst_type(op->addr.buswidth); if (ret < 0) return ret; - plat->addr_width = ret; + priv->addr_width = ret; ret = cadence_qspi_buswidth_to_inst_type(op->data.buswidth); if (ret < 0) return ret; - plat->data_width = ret; + priv->data_width = ret; return 0; } @@ -314,31 +314,31 @@ void cadence_qspi_apb_delay(void *reg_base, cadence_qspi_apb_controller_enable(reg_base); } -void cadence_qspi_apb_controller_init(struct cadence_spi_plat *plat) +void cadence_qspi_apb_controller_init(struct cadence_spi_priv *priv) { unsigned reg; - cadence_qspi_apb_controller_disable(plat->regbase); + cadence_qspi_apb_controller_disable(priv->regbase); /* Configure the device size and address bytes */ - reg = readl(plat->regbase + CQSPI_REG_SIZE); + reg = readl(priv->regbase + CQSPI_REG_SIZE); /* Clear the previous value */ reg &= ~(CQSPI_REG_SIZE_PAGE_MASK << CQSPI_REG_SIZE_PAGE_LSB); reg &= ~(CQSPI_REG_SIZE_BLOCK_MASK << CQSPI_REG_SIZE_BLOCK_LSB); - reg |= (plat->page_size << CQSPI_REG_SIZE_PAGE_LSB); - reg |= (plat->block_size << CQSPI_REG_SIZE_BLOCK_LSB); - writel(reg, plat->regbase + CQSPI_REG_SIZE); + reg |= (priv->page_size << CQSPI_REG_SIZE_PAGE_LSB); + reg |= (priv->block_size << CQSPI_REG_SIZE_BLOCK_LSB); + writel(reg, priv->regbase + CQSPI_REG_SIZE); /* Configure the remap address register, no remap */ - writel(0, plat->regbase + CQSPI_REG_REMAP); + writel(0, priv->regbase + CQSPI_REG_REMAP); /* Indirect mode configurations */ - writel(plat->fifo_depth / 2, plat->regbase + CQSPI_REG_SRAMPARTITION); + writel(priv->fifo_depth / 2, priv->regbase + CQSPI_REG_SRAMPARTITION); /* Disable all interrupts */ - writel(0, plat->regbase + CQSPI_REG_IRQMASK); + writel(0, priv->regbase + CQSPI_REG_IRQMASK); - cadence_qspi_apb_controller_enable(plat->regbase); + cadence_qspi_apb_controller_enable(priv->regbase); } int cadence_qspi_apb_exec_flash_cmd(void *reg_base, unsigned int reg) @@ -370,7 +370,7 @@ int cadence_qspi_apb_exec_flash_cmd(void *reg_base, unsigned int reg) return 0; } -static int cadence_qspi_setup_opcode_ext(struct cadence_spi_plat *plat, +static int cadence_qspi_setup_opcode_ext(struct cadence_spi_priv *priv, const struct spi_mem_op *op, unsigned int shift) { @@ -383,15 +383,15 @@ static int cadence_qspi_setup_opcode_ext(struct cadence_spi_plat *plat, /* Opcode extension is the LSB. */ ext = op->cmd.opcode & 0xff; - reg = readl(plat->regbase + CQSPI_REG_OP_EXT_LOWER); + reg = readl(priv->regbase + CQSPI_REG_OP_EXT_LOWER); reg &= ~(0xff << shift); reg |= ext << shift; - writel(reg, plat->regbase + CQSPI_REG_OP_EXT_LOWER); + writel(reg, priv->regbase + CQSPI_REG_OP_EXT_LOWER); return 0; } -static int cadence_qspi_enable_dtr(struct cadence_spi_plat *plat, +static int cadence_qspi_enable_dtr(struct cadence_spi_priv *priv, const struct spi_mem_op *op, unsigned int shift, bool enable) @@ -399,14 +399,14 @@ static int cadence_qspi_enable_dtr(struct cadence_spi_plat *plat, unsigned int reg; int ret; - reg = readl(plat->regbase + CQSPI_REG_CONFIG); + reg = readl(priv->regbase + CQSPI_REG_CONFIG); if (enable) { reg |= CQSPI_REG_CONFIG_DTR_PROTO; reg |= CQSPI_REG_CONFIG_DUAL_OPCODE; /* Set up command opcode extension. */ - ret = cadence_qspi_setup_opcode_ext(plat, op, shift); + ret = cadence_qspi_setup_opcode_ext(priv, op, shift); if (ret) return ret; } else { @@ -414,37 +414,37 @@ static int cadence_qspi_enable_dtr(struct cadence_spi_plat *plat, reg &= ~CQSPI_REG_CONFIG_DUAL_OPCODE; } - writel(reg, plat->regbase + CQSPI_REG_CONFIG); + writel(reg, priv->regbase + CQSPI_REG_CONFIG); return 0; } -int cadence_qspi_apb_command_read_setup(struct cadence_spi_plat *plat, +int cadence_qspi_apb_command_read_setup(struct cadence_spi_priv *priv, const struct spi_mem_op *op) { int ret; unsigned int reg; - ret = cadence_qspi_set_protocol(plat, op); + ret = cadence_qspi_set_protocol(priv, op); if (ret) return ret; - ret = cadence_qspi_enable_dtr(plat, op, CQSPI_REG_OP_EXT_STIG_LSB, - plat->dtr); + ret = cadence_qspi_enable_dtr(priv, op, CQSPI_REG_OP_EXT_STIG_LSB, + priv->dtr); if (ret) return ret; - reg = cadence_qspi_calc_rdreg(plat); - writel(reg, plat->regbase + CQSPI_REG_RD_INSTR); + reg = cadence_qspi_calc_rdreg(priv); + writel(reg, priv->regbase + CQSPI_REG_RD_INSTR); return 0; } /* For command RDID, RDSR. */ -int cadence_qspi_apb_command_read(struct cadence_spi_plat *plat, +int cadence_qspi_apb_command_read(struct cadence_spi_priv *priv, const struct spi_mem_op *op) { - void *reg_base = plat->regbase; + void *reg_base = priv->regbase; unsigned int reg; unsigned int read_len; int status; @@ -458,7 +458,7 @@ int cadence_qspi_apb_command_read(struct cadence_spi_plat *plat, return -EINVAL; } - if (plat->dtr) + if (priv->dtr) opcode = op->cmd.opcode >> 8; else opcode = op->cmd.opcode; @@ -466,7 +466,7 @@ int cadence_qspi_apb_command_read(struct cadence_spi_plat *plat, reg = opcode << CQSPI_REG_CMDCTRL_OPCODE_LSB; /* Set up dummy cycles. */ - dummy_clk = cadence_qspi_calc_dummy(op, plat->dtr); + dummy_clk = cadence_qspi_calc_dummy(op, priv->dtr); if (dummy_clk > CQSPI_DUMMY_CLKS_MAX) return -ENOTSUPP; @@ -499,29 +499,29 @@ int cadence_qspi_apb_command_read(struct cadence_spi_plat *plat, return 0; } -int cadence_qspi_apb_command_write_setup(struct cadence_spi_plat *plat, +int cadence_qspi_apb_command_write_setup(struct cadence_spi_priv *priv, const struct spi_mem_op *op) { int ret; unsigned int reg; - ret = cadence_qspi_set_protocol(plat, op); + ret = cadence_qspi_set_protocol(priv, op); if (ret) return ret; - ret = cadence_qspi_enable_dtr(plat, op, CQSPI_REG_OP_EXT_STIG_LSB, - plat->dtr); + ret = cadence_qspi_enable_dtr(priv, op, CQSPI_REG_OP_EXT_STIG_LSB, + priv->dtr); if (ret) return ret; - reg = cadence_qspi_calc_rdreg(plat); - writel(reg, plat->regbase + CQSPI_REG_RD_INSTR); + reg = cadence_qspi_calc_rdreg(priv); + writel(reg, priv->regbase + CQSPI_REG_RD_INSTR); return 0; } /* For commands: WRSR, WREN, WRDI, CHIP_ERASE, BE, etc. */ -int cadence_qspi_apb_command_write(struct cadence_spi_plat *plat, +int cadence_qspi_apb_command_write(struct cadence_spi_priv *priv, const struct spi_mem_op *op) { unsigned int reg = 0; @@ -529,7 +529,7 @@ int cadence_qspi_apb_command_write(struct cadence_spi_plat *plat, unsigned int wr_len; unsigned int txlen = op->data.nbytes; const void *txbuf = op->data.buf.out; - void *reg_base = plat->regbase; + void *reg_base = priv->regbase; u32 addr; u8 opcode; @@ -547,7 +547,7 @@ int cadence_qspi_apb_command_write(struct cadence_spi_plat *plat, return -EINVAL; } - if (plat->dtr) + if (priv->dtr) opcode = op->cmd.opcode >> 8; else opcode = op->cmd.opcode; @@ -579,7 +579,7 @@ int cadence_qspi_apb_command_write(struct cadence_spi_plat *plat, } /* Opcode + Address (3/4 bytes) + dummy bytes (0-4 bytes) */ -int cadence_qspi_apb_read_setup(struct cadence_spi_plat *plat, +int cadence_qspi_apb_read_setup(struct cadence_spi_priv *priv, const struct spi_mem_op *op) { unsigned int reg; @@ -589,33 +589,33 @@ int cadence_qspi_apb_read_setup(struct cadence_spi_plat *plat, int ret; u8 opcode; - ret = cadence_qspi_set_protocol(plat, op); + ret = cadence_qspi_set_protocol(priv, op); if (ret) return ret; - ret = cadence_qspi_enable_dtr(plat, op, CQSPI_REG_OP_EXT_READ_LSB, - plat->dtr); + ret = cadence_qspi_enable_dtr(priv, op, CQSPI_REG_OP_EXT_READ_LSB, + priv->dtr); if (ret) return ret; /* Setup the indirect trigger address */ - writel(plat->trigger_address, - plat->regbase + CQSPI_REG_INDIRECTTRIGGER); + writel(priv->trigger_address, + priv->regbase + CQSPI_REG_INDIRECTTRIGGER); /* Configure the opcode */ - if (plat->dtr) + if (priv->dtr) opcode = op->cmd.opcode >> 8; else opcode = op->cmd.opcode; rd_reg = opcode << CQSPI_REG_RD_INSTR_OPCODE_LSB; - rd_reg |= cadence_qspi_calc_rdreg(plat); + rd_reg |= cadence_qspi_calc_rdreg(priv); - writel(op->addr.val, plat->regbase + CQSPI_REG_INDIRECTRDSTARTADDR); + writel(op->addr.val, priv->regbase + CQSPI_REG_INDIRECTRDSTARTADDR); if (dummy_bytes) { /* Convert to clock cycles. */ - dummy_clk = cadence_qspi_calc_dummy(op, plat->dtr); + dummy_clk = cadence_qspi_calc_dummy(op, priv->dtr); if (dummy_clk > CQSPI_DUMMY_CLKS_MAX) return -ENOTSUPP; @@ -625,30 +625,30 @@ int cadence_qspi_apb_read_setup(struct cadence_spi_plat *plat, << CQSPI_REG_RD_INSTR_DUMMY_LSB; } - writel(rd_reg, plat->regbase + CQSPI_REG_RD_INSTR); + writel(rd_reg, priv->regbase + CQSPI_REG_RD_INSTR); /* set device size */ - reg = readl(plat->regbase + CQSPI_REG_SIZE); + reg = readl(priv->regbase + CQSPI_REG_SIZE); reg &= ~CQSPI_REG_SIZE_ADDRESS_MASK; reg |= (op->addr.nbytes - 1); - writel(reg, plat->regbase + CQSPI_REG_SIZE); + writel(reg, priv->regbase + CQSPI_REG_SIZE); return 0; } -static u32 cadence_qspi_get_rd_sram_level(struct cadence_spi_plat *plat) +static u32 cadence_qspi_get_rd_sram_level(struct cadence_spi_priv *priv) { - u32 reg = readl(plat->regbase + CQSPI_REG_SDRAMLEVEL); + u32 reg = readl(priv->regbase + CQSPI_REG_SDRAMLEVEL); reg >>= CQSPI_REG_SDRAMLEVEL_RD_LSB; return reg & CQSPI_REG_SDRAMLEVEL_RD_MASK; } -static int cadence_qspi_wait_for_data(struct cadence_spi_plat *plat) +static int cadence_qspi_wait_for_data(struct cadence_spi_priv *priv) { unsigned int timeout = 10000; u32 reg; while (timeout--) { - reg = cadence_qspi_get_rd_sram_level(plat); + reg = cadence_qspi_get_rd_sram_level(priv); if (reg) return reg; udelay(1); @@ -658,21 +658,21 @@ static int cadence_qspi_wait_for_data(struct cadence_spi_plat *plat) } static int -cadence_qspi_apb_indirect_read_execute(struct cadence_spi_plat *plat, +cadence_qspi_apb_indirect_read_execute(struct cadence_spi_priv *priv, unsigned int n_rx, u8 *rxbuf) { unsigned int remaining = n_rx; unsigned int bytes_to_read = 0; int ret; - writel(n_rx, plat->regbase + CQSPI_REG_INDIRECTRDBYTES); + writel(n_rx, priv->regbase + CQSPI_REG_INDIRECTRDBYTES); /* Start the indirect read transfer */ writel(CQSPI_REG_INDIRECTRD_START, - plat->regbase + CQSPI_REG_INDIRECTRD); + priv->regbase + CQSPI_REG_INDIRECTRD); while (remaining > 0) { - ret = cadence_qspi_wait_for_data(plat); + ret = cadence_qspi_wait_for_data(priv); if (ret < 0) { printf("Indirect write timed out (%i)\n", ret); goto failrd; @@ -681,7 +681,7 @@ cadence_qspi_apb_indirect_read_execute(struct cadence_spi_plat *plat, bytes_to_read = ret; while (bytes_to_read != 0) { - bytes_to_read *= plat->fifo_width; + bytes_to_read *= priv->fifo_width; bytes_to_read = bytes_to_read > remaining ? remaining : bytes_to_read; /* @@ -689,18 +689,18 @@ cadence_qspi_apb_indirect_read_execute(struct cadence_spi_plat *plat, * data abort. */ if (((uintptr_t)rxbuf % 4) || (bytes_to_read % 4)) - readsb(plat->ahbbase, rxbuf, bytes_to_read); + readsb(priv->ahbbase, rxbuf, bytes_to_read); else - readsl(plat->ahbbase, rxbuf, + readsl(priv->ahbbase, rxbuf, bytes_to_read >> 2); rxbuf += bytes_to_read; remaining -= bytes_to_read; - bytes_to_read = cadence_qspi_get_rd_sram_level(plat); + bytes_to_read = cadence_qspi_get_rd_sram_level(priv); } } /* Check indirect done status */ - ret = wait_for_bit_le32(plat->regbase + CQSPI_REG_INDIRECTRD, + ret = wait_for_bit_le32(priv->regbase + CQSPI_REG_INDIRECTRD, CQSPI_REG_INDIRECTRD_DONE, 1, 10, 0); if (ret) { printf("Indirect read completion error (%i)\n", ret); @@ -709,10 +709,10 @@ cadence_qspi_apb_indirect_read_execute(struct cadence_spi_plat *plat, /* Clear indirect completion status */ writel(CQSPI_REG_INDIRECTRD_DONE, - plat->regbase + CQSPI_REG_INDIRECTRD); + priv->regbase + CQSPI_REG_INDIRECTRD); /* Check indirect done status */ - ret = wait_for_bit_le32(plat->regbase + CQSPI_REG_INDIRECTRD, + ret = wait_for_bit_le32(priv->regbase + CQSPI_REG_INDIRECTRD, CQSPI_REG_INDIRECTRD_DONE, 0, 10, 0); if (ret) { printf("Indirect read clear completion error (%i)\n", ret); @@ -724,11 +724,11 @@ cadence_qspi_apb_indirect_read_execute(struct cadence_spi_plat *plat, failrd: /* Cancel the indirect read */ writel(CQSPI_REG_INDIRECTRD_CANCEL, - plat->regbase + CQSPI_REG_INDIRECTRD); + priv->regbase + CQSPI_REG_INDIRECTRD); return ret; } -int cadence_qspi_apb_read_execute(struct cadence_spi_plat *plat, +int cadence_qspi_apb_read_execute(struct cadence_spi_priv *priv, const struct spi_mem_op *op) { u64 from = op->addr.val; @@ -738,57 +738,57 @@ int cadence_qspi_apb_read_execute(struct cadence_spi_plat *plat, if (CONFIG_IS_ENABLED(ARCH_VERSAL)) cadence_qspi_apb_enable_linear_mode(true); - if (plat->use_dac_mode && (from + len < plat->ahbsize)) { + if (priv->use_dac_mode && (from + len < priv->ahbsize)) { if (len < 256 || - dma_memcpy(buf, plat->ahbbase + from, len) < 0) { - memcpy_fromio(buf, plat->ahbbase + from, len); + dma_memcpy(buf, priv->ahbbase + from, len) < 0) { + memcpy_fromio(buf, priv->ahbbase + from, len); } - if (!cadence_qspi_wait_idle(plat->regbase)) + if (!cadence_qspi_wait_idle(priv->regbase)) return -EIO; return 0; } - return cadence_qspi_apb_indirect_read_execute(plat, len, buf); + return cadence_qspi_apb_indirect_read_execute(priv, len, buf); } /* Opcode + Address (3/4 bytes) */ -int cadence_qspi_apb_write_setup(struct cadence_spi_plat *plat, +int cadence_qspi_apb_write_setup(struct cadence_spi_priv *priv, const struct spi_mem_op *op) { unsigned int reg; int ret; u8 opcode; - ret = cadence_qspi_set_protocol(plat, op); + ret = cadence_qspi_set_protocol(priv, op); if (ret) return ret; - ret = cadence_qspi_enable_dtr(plat, op, CQSPI_REG_OP_EXT_WRITE_LSB, - plat->dtr); + ret = cadence_qspi_enable_dtr(priv, op, CQSPI_REG_OP_EXT_WRITE_LSB, + priv->dtr); if (ret) return ret; /* Setup the indirect trigger address */ - writel(plat->trigger_address, - plat->regbase + CQSPI_REG_INDIRECTTRIGGER); + writel(priv->trigger_address, + priv->regbase + CQSPI_REG_INDIRECTTRIGGER); /* Configure the opcode */ - if (plat->dtr) + if (priv->dtr) opcode = op->cmd.opcode >> 8; else opcode = op->cmd.opcode; reg = opcode << CQSPI_REG_WR_INSTR_OPCODE_LSB; - reg |= plat->data_width << CQSPI_REG_WR_INSTR_TYPE_DATA_LSB; - reg |= plat->addr_width << CQSPI_REG_WR_INSTR_TYPE_ADDR_LSB; - writel(reg, plat->regbase + CQSPI_REG_WR_INSTR); + reg |= priv->data_width << CQSPI_REG_WR_INSTR_TYPE_DATA_LSB; + reg |= priv->addr_width << CQSPI_REG_WR_INSTR_TYPE_ADDR_LSB; + writel(reg, priv->regbase + CQSPI_REG_WR_INSTR); - reg = cadence_qspi_calc_rdreg(plat); - writel(reg, plat->regbase + CQSPI_REG_RD_INSTR); + reg = cadence_qspi_calc_rdreg(priv); + writel(reg, priv->regbase + CQSPI_REG_RD_INSTR); - writel(op->addr.val, plat->regbase + CQSPI_REG_INDIRECTWRSTARTADDR); + writel(op->addr.val, priv->regbase + CQSPI_REG_INDIRECTWRSTARTADDR); - if (plat->dtr) { + if (priv->dtr) { /* * Some flashes like the cypress Semper flash expect a 4-byte * dummy address with the Read SR command in DTR mode, but this @@ -797,23 +797,23 @@ int cadence_qspi_apb_write_setup(struct cadence_spi_plat *plat, * controller's side. spi-nor will take care of polling the * status register. */ - reg = readl(plat->regbase + CQSPI_REG_WR_COMPLETION_CTRL); + reg = readl(priv->regbase + CQSPI_REG_WR_COMPLETION_CTRL); reg |= CQSPI_REG_WR_DISABLE_AUTO_POLL; - writel(reg, plat->regbase + CQSPI_REG_WR_COMPLETION_CTRL); + writel(reg, priv->regbase + CQSPI_REG_WR_COMPLETION_CTRL); } - reg = readl(plat->regbase + CQSPI_REG_SIZE); + reg = readl(priv->regbase + CQSPI_REG_SIZE); reg &= ~CQSPI_REG_SIZE_ADDRESS_MASK; reg |= (op->addr.nbytes - 1); - writel(reg, plat->regbase + CQSPI_REG_SIZE); + writel(reg, priv->regbase + CQSPI_REG_SIZE); return 0; } static int -cadence_qspi_apb_indirect_write_execute(struct cadence_spi_plat *plat, +cadence_qspi_apb_indirect_write_execute(struct cadence_spi_priv *priv, unsigned int n_tx, const u8 *txbuf) { - unsigned int page_size = plat->page_size; + unsigned int page_size = priv->page_size; unsigned int remaining = n_tx; const u8 *bb_txbuf = txbuf; void *bounce_buf = NULL; @@ -833,27 +833,27 @@ cadence_qspi_apb_indirect_write_execute(struct cadence_spi_plat *plat, } /* Configure the indirect read transfer bytes */ - writel(n_tx, plat->regbase + CQSPI_REG_INDIRECTWRBYTES); + writel(n_tx, priv->regbase + CQSPI_REG_INDIRECTWRBYTES); /* Start the indirect write transfer */ writel(CQSPI_REG_INDIRECTWR_START, - plat->regbase + CQSPI_REG_INDIRECTWR); + priv->regbase + CQSPI_REG_INDIRECTWR); /* * Some delay is required for the above bit to be internally * synchronized by the QSPI module. */ - ndelay(plat->wr_delay); + ndelay(priv->wr_delay); while (remaining > 0) { write_bytes = remaining > page_size ? page_size : remaining; - writesl(plat->ahbbase, bb_txbuf, write_bytes >> 2); + writesl(priv->ahbbase, bb_txbuf, write_bytes >> 2); if (write_bytes % 4) - writesb(plat->ahbbase, + writesb(priv->ahbbase, bb_txbuf + rounddown(write_bytes, 4), write_bytes % 4); - ret = wait_for_bit_le32(plat->regbase + CQSPI_REG_SDRAMLEVEL, + ret = wait_for_bit_le32(priv->regbase + CQSPI_REG_SDRAMLEVEL, CQSPI_REG_SDRAMLEVEL_WR_MASK << CQSPI_REG_SDRAMLEVEL_WR_LSB, 0, 10, 0); if (ret) { @@ -866,7 +866,7 @@ cadence_qspi_apb_indirect_write_execute(struct cadence_spi_plat *plat, } /* Check indirect done status */ - ret = wait_for_bit_le32(plat->regbase + CQSPI_REG_INDIRECTWR, + ret = wait_for_bit_le32(priv->regbase + CQSPI_REG_INDIRECTWR, CQSPI_REG_INDIRECTWR_DONE, 1, 10, 0); if (ret) { printf("Indirect write completion error (%i)\n", ret); @@ -875,10 +875,10 @@ cadence_qspi_apb_indirect_write_execute(struct cadence_spi_plat *plat, /* Clear indirect completion status */ writel(CQSPI_REG_INDIRECTWR_DONE, - plat->regbase + CQSPI_REG_INDIRECTWR); + priv->regbase + CQSPI_REG_INDIRECTWR); /* Check indirect done status */ - ret = wait_for_bit_le32(plat->regbase + CQSPI_REG_INDIRECTWR, + ret = wait_for_bit_le32(priv->regbase + CQSPI_REG_INDIRECTWR, CQSPI_REG_INDIRECTWR_DONE, 0, 10, 0); if (ret) { printf("Indirect write clear completion error (%i)\n", ret); @@ -892,13 +892,13 @@ cadence_qspi_apb_indirect_write_execute(struct cadence_spi_plat *plat, failwr: /* Cancel the indirect write */ writel(CQSPI_REG_INDIRECTWR_CANCEL, - plat->regbase + CQSPI_REG_INDIRECTWR); + priv->regbase + CQSPI_REG_INDIRECTWR); if (bounce_buf) free(bounce_buf); return ret; } -int cadence_qspi_apb_write_execute(struct cadence_spi_plat *plat, +int cadence_qspi_apb_write_execute(struct cadence_spi_priv *priv, const struct spi_mem_op *op) { u32 to = op->addr.val; @@ -916,14 +916,15 @@ int cadence_qspi_apb_write_execute(struct cadence_spi_plat *plat, * mode. So, we can not use direct mode when in DTR mode for writing * data. */ - if (!plat->dtr && plat->use_dac_mode && (to + len < plat->ahbsize)) { - memcpy_toio(plat->ahbbase + to, buf, len); - if (!cadence_qspi_wait_idle(plat->regbase)) + cadence_qspi_apb_enable_linear_mode(true); + if (!priv->dtr && priv->use_dac_mode && (to + len < priv->ahbsize)) { + memcpy_toio(priv->ahbbase + to, buf, len); + if (!cadence_qspi_wait_idle(priv->regbase)) return -EIO; return 0; } - return cadence_qspi_apb_indirect_write_execute(plat, len, buf); + return cadence_qspi_apb_indirect_write_execute(priv, len, buf); } void cadence_qspi_apb_enter_xip(void *reg_base, char xip_dummy) From f4f1b65cc6b01a787b5efa61bb9be195254d0334 Mon Sep 17 00:00:00 2001 From: Ashok Reddy Soma Date: Thu, 25 Aug 2022 06:59:01 -0600 Subject: [PATCH 091/374] spi: zynqmp_gqspi: Add tap delays for Versal Add tap delays for Versal platform and re-align the tapdelays code. Signed-off-by: Ashok Reddy Soma Link: https://lore.kernel.org/r/20220825125906.11581-2-ashok.reddy.soma@amd.com Signed-off-by: Michal Simek --- drivers/spi/zynqmp_gqspi.c | 60 ++++++++++++++++++++++++-------------- 1 file changed, 38 insertions(+), 22 deletions(-) diff --git a/drivers/spi/zynqmp_gqspi.c b/drivers/spi/zynqmp_gqspi.c index c772bae3cc..958432c08d 100644 --- a/drivers/spi/zynqmp_gqspi.c +++ b/drivers/spi/zynqmp_gqspi.c @@ -22,6 +22,7 @@ #include #include #include +#include #define GQSPI_GFIFO_STRT_MODE_MASK BIT(29) #define GQSPI_CONFIG_MODE_EN_MASK (3 << 30) @@ -102,8 +103,10 @@ #define TAP_DLY_BYPASS_LQSPI_RX_VALUE 0x1 #define TAP_DLY_BYPASS_LQSPI_RX_SHIFT 2 #define GQSPI_DATA_DLY_ADJ_OFST 0x000001F8 -#define IOU_TAPDLY_BYPASS_OFST 0xFF180390 +#define IOU_TAPDLY_BYPASS_OFST !IS_ENABLED(CONFIG_ARCH_VERSAL) ? \ + 0xFF180390 : 0xF103003C #define GQSPI_LPBK_DLY_ADJ_LPBK_MASK 0x00000020 +#define GQSPI_FREQ_37_5MHZ 37500000 #define GQSPI_FREQ_40MHZ 40000000 #define GQSPI_FREQ_100MHZ 100000000 #define GQSPI_FREQ_150MHZ 150000000 @@ -297,28 +300,41 @@ void zynqmp_qspi_set_tapdelay(struct udevice *bus, u32 baudrateval) debug("%s, req_hz:%d, clk_rate:%d, baudrateval:%d\n", __func__, reqhz, clk_rate, baudrateval); - if (reqhz < GQSPI_FREQ_40MHZ) { - zynqmp_mmio_read(IOU_TAPDLY_BYPASS_OFST, &tapdlybypass); - tapdlybypass |= (TAP_DLY_BYPASS_LQSPI_RX_VALUE << - TAP_DLY_BYPASS_LQSPI_RX_SHIFT); - } else if (reqhz <= GQSPI_FREQ_100MHZ) { - zynqmp_mmio_read(IOU_TAPDLY_BYPASS_OFST, &tapdlybypass); - tapdlybypass |= (TAP_DLY_BYPASS_LQSPI_RX_VALUE << - TAP_DLY_BYPASS_LQSPI_RX_SHIFT); - lpbkdlyadj = readl(®s->lpbkdly); - lpbkdlyadj |= (GQSPI_LPBK_DLY_ADJ_LPBK_MASK); - datadlyadj = readl(®s->gqspidlyadj); - datadlyadj |= ((GQSPI_USE_DATA_DLY << GQSPI_USE_DATA_DLY_SHIFT) - | (GQSPI_DATA_DLY_ADJ_VALUE << - GQSPI_DATA_DLY_ADJ_SHIFT)); - } else if (reqhz <= GQSPI_FREQ_150MHZ) { - lpbkdlyadj = readl(®s->lpbkdly); - lpbkdlyadj |= ((GQSPI_LPBK_DLY_ADJ_LPBK_MASK) | - GQSPI_LPBK_DLY_ADJ_DLY_0); + if (!IS_ENABLED(CONFIG_ARCH_VERSAL)) { + if (reqhz <= GQSPI_FREQ_40MHZ) { + tapdlybypass = TAP_DLY_BYPASS_LQSPI_RX_VALUE << + TAP_DLY_BYPASS_LQSPI_RX_SHIFT; + } else if (reqhz <= GQSPI_FREQ_100MHZ) { + tapdlybypass = TAP_DLY_BYPASS_LQSPI_RX_VALUE << + TAP_DLY_BYPASS_LQSPI_RX_SHIFT; + lpbkdlyadj = GQSPI_LPBK_DLY_ADJ_LPBK_MASK; + datadlyadj = (GQSPI_USE_DATA_DLY << + GQSPI_USE_DATA_DLY_SHIFT) | + (GQSPI_DATA_DLY_ADJ_VALUE << + GQSPI_DATA_DLY_ADJ_SHIFT); + } else if (reqhz <= GQSPI_FREQ_150MHZ) { + lpbkdlyadj = GQSPI_LPBK_DLY_ADJ_LPBK_MASK | + GQSPI_LPBK_DLY_ADJ_DLY_0; + } + zynqmp_mmio_write(IOU_TAPDLY_BYPASS_OFST, + IOU_TAPDLY_BYPASS_MASK, tapdlybypass); + } else { + if (reqhz <= GQSPI_FREQ_37_5MHZ) { + tapdlybypass = TAP_DLY_BYPASS_LQSPI_RX_VALUE << + TAP_DLY_BYPASS_LQSPI_RX_SHIFT; + } else if (reqhz <= GQSPI_FREQ_100MHZ) { + tapdlybypass = TAP_DLY_BYPASS_LQSPI_RX_VALUE << + TAP_DLY_BYPASS_LQSPI_RX_SHIFT; + lpbkdlyadj = GQSPI_LPBK_DLY_ADJ_LPBK_MASK; + datadlyadj = GQSPI_USE_DATA_DLY << + GQSPI_USE_DATA_DLY_SHIFT; + } else if (reqhz <= GQSPI_FREQ_150MHZ) { + lpbkdlyadj = GQSPI_LPBK_DLY_ADJ_LPBK_MASK | + (GQSPI_LPBK_DLY_ADJ_DLY_1 << + GQSPI_LPBK_DLY_ADJ_DLY_1_SHIFT); + } + writel(tapdlybypass, IOU_TAPDLY_BYPASS_OFST); } - - zynqmp_mmio_write(IOU_TAPDLY_BYPASS_OFST, IOU_TAPDLY_BYPASS_MASK, - tapdlybypass); writel(lpbkdlyadj, ®s->lpbkdly); writel(datadlyadj, ®s->gqspidlyadj); } From 9e89e30d4de41a687cdff922e410b0a87d663348 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Thu, 25 Aug 2022 06:59:02 -0600 Subject: [PATCH 092/374] arm64: versal: Define zynqmp_mmio_write() for versal GQSPI driver is using it but this function is never called for Versal because it is removed by linker. But function should be declared to avoid this build warning: drivers/spi/zynqmp_gqspi.c: In function 'zynqmp_qspi_set_tapdelay': drivers/spi/zynqmp_gqspi.c:378:3: warning: implicit declaration of function 'zynqmp_mmio_write' [-Wimplicit-function-declaration] 378 | zynqmp_mmio_write(IOU_TAPDLY_BYPASS_OFST, Signed-off-by: Michal Simek Signed-off-by: Ashok Reddy Soma Link: https://lore.kernel.org/r/20220825125906.11581-3-ashok.reddy.soma@amd.com Signed-off-by: Michal Simek --- arch/arm/mach-versal/include/mach/sys_proto.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/arch/arm/mach-versal/include/mach/sys_proto.h b/arch/arm/mach-versal/include/mach/sys_proto.h index 05934c28d6..8e5712e0c9 100644 --- a/arch/arm/mach-versal/include/mach/sys_proto.h +++ b/arch/arm/mach-versal/include/mach/sys_proto.h @@ -3,6 +3,8 @@ * Copyright 2016 - 2018 Xilinx, Inc. */ +#include + enum { TCM_LOCK, TCM_SPLIT, @@ -10,3 +12,9 @@ enum { void tcm_init(u8 mode); void mem_map_fill(void); + +static inline int zynqmp_mmio_write(const u32 address, const u32 mask, const u32 value) +{ + BUILD_BUG(); + return -EINVAL; +} From d91b0f4a1851f5c7c651c6f6204417035c074a0a Mon Sep 17 00:00:00 2001 From: Ashok Reddy Soma Date: Thu, 25 Aug 2022 06:59:03 -0600 Subject: [PATCH 093/374] spi: zynqmp_gqspi: Add support for IO mode Add support for io-mode transfers. This is necessary for UBIFS to work properly with spi-nor devices. The driver will work in IO mode when "has-io-mode" is passed from device tree instead of DMA. Signed-off-by: Ashok Reddy Soma Link: https://lore.kernel.org/r/20220825125906.11581-4-ashok.reddy.soma@amd.com Signed-off-by: Michal Simek --- drivers/spi/zynqmp_gqspi.c | 81 +++++++++++++++++++++++++++++++++++--- 1 file changed, 76 insertions(+), 5 deletions(-) diff --git a/drivers/spi/zynqmp_gqspi.c b/drivers/spi/zynqmp_gqspi.c index 958432c08d..78a1b48731 100644 --- a/drivers/spi/zynqmp_gqspi.c +++ b/drivers/spi/zynqmp_gqspi.c @@ -166,6 +166,7 @@ struct zynqmp_qspi_plat { struct zynqmp_qspi_dma_regs *dma_regs; u32 frequency; u32 speed_hz; + unsigned int io_mode; }; struct zynqmp_qspi_priv { @@ -174,6 +175,7 @@ struct zynqmp_qspi_priv { const void *tx_buf; void *rx_buf; unsigned int len; + unsigned int io_mode; int bytes_to_transfer; int bytes_to_receive; const struct spi_mem_op *op; @@ -190,6 +192,8 @@ static int zynqmp_qspi_of_to_plat(struct udevice *bus) plat->dma_regs = (struct zynqmp_qspi_dma_regs *) (dev_read_addr(bus) + GQSPI_DMA_REG_OFFSET); + plat->io_mode = dev_read_bool(bus, "has-io-mode"); + return 0; } @@ -209,8 +213,11 @@ static void zynqmp_qspi_init_hw(struct zynqmp_qspi_priv *priv) config_reg = readl(®s->confr); config_reg &= ~(GQSPI_GFIFO_STRT_MODE_MASK | GQSPI_CONFIG_MODE_EN_MASK); - config_reg |= GQSPI_CONFIG_DMA_MODE | GQSPI_GFIFO_WP_HOLD | - GQSPI_DFLT_BAUD_RATE_DIV | GQSPI_GFIFO_STRT_MODE_MASK; + config_reg |= GQSPI_GFIFO_WP_HOLD | GQSPI_DFLT_BAUD_RATE_DIV; + config_reg |= GQSPI_GFIFO_STRT_MODE_MASK; + if (!priv->io_mode) + config_reg |= GQSPI_CONFIG_DMA_MODE; + writel(config_reg, ®s->confr); writel(GQSPI_ENABLE_ENABLE_MASK, ®s->enbr); @@ -388,6 +395,7 @@ static int zynqmp_qspi_probe(struct udevice *bus) priv->regs = plat->regs; priv->dma_regs = plat->dma_regs; + priv->io_mode = plat->io_mode; ret = clk_get_by_index(bus, 0, &clk); if (ret < 0) { @@ -592,6 +600,66 @@ static int zynqmp_qspi_genfifo_fill_tx(struct zynqmp_qspi_priv *priv) return ret; } +static int zynqmp_qspi_start_io(struct zynqmp_qspi_priv *priv, + u32 gen_fifo_cmd, u32 *buf) +{ + u32 len; + u32 actuallen = priv->len; + u32 config_reg, ier, isr; + u32 timeout = GQSPI_TIMEOUT; + struct zynqmp_qspi_regs *regs = priv->regs; + u32 last_bits; + u32 *traverse = buf; + + while (priv->len) { + len = zynqmp_qspi_calc_exp(priv, &gen_fifo_cmd); + /* If exponent bit is set, reset immediate to be 2^len */ + if (gen_fifo_cmd & GQSPI_GFIFO_EXP_MASK) + priv->bytes_to_receive = (1 << len); + else + priv->bytes_to_receive = len; + zynqmp_qspi_fill_gen_fifo(priv, gen_fifo_cmd); + debug("GFIFO_CMD_RX:0x%x\n", gen_fifo_cmd); + /* Manual start */ + config_reg = readl(®s->confr); + config_reg |= GQSPI_STRT_GEN_FIFO; + writel(config_reg, ®s->confr); + /* Enable RX interrupts for IO mode */ + ier = readl(®s->ier); + ier |= GQSPI_IXR_ALL_MASK; + writel(ier, ®s->ier); + while (priv->bytes_to_receive && timeout) { + isr = readl(®s->isr); + if (isr & GQSPI_IXR_RXNEMTY_MASK) { + if (priv->bytes_to_receive >= 4) { + *traverse = readl(®s->drxr); + traverse++; + priv->bytes_to_receive -= 4; + } else { + last_bits = readl(®s->drxr); + memcpy(traverse, &last_bits, + priv->bytes_to_receive); + priv->bytes_to_receive = 0; + } + timeout = GQSPI_TIMEOUT; + } else { + udelay(1); + timeout--; + } + } + + debug("buf:0x%lx, rxbuf:0x%lx, *buf:0x%x len: 0x%x\n", + (unsigned long)buf, (unsigned long)priv->rx_buf, + *buf, actuallen); + if (!timeout) { + printf("IO timeout: %d\n", readl(®s->isr)); + return -1; + } + } + + return 0; +} + static int zynqmp_qspi_start_dma(struct zynqmp_qspi_priv *priv, u32 gen_fifo_cmd, u32 *buf) { @@ -649,10 +717,13 @@ static int zynqmp_qspi_genfifo_fill_rx(struct zynqmp_qspi_priv *priv) * Check if receive buffer is aligned to 4 byte and length * is multiples of four byte as we are using dma to receive. */ - if (!((unsigned long)priv->rx_buf & (GQSPI_DMA_ALIGN - 1)) && - !(actuallen % GQSPI_DMA_ALIGN)) { + if ((!((unsigned long)priv->rx_buf & (GQSPI_DMA_ALIGN - 1)) && + !(actuallen % GQSPI_DMA_ALIGN)) || priv->io_mode) { buf = (u32 *)priv->rx_buf; - return zynqmp_qspi_start_dma(priv, gen_fifo_cmd, buf); + if (priv->io_mode) + return zynqmp_qspi_start_io(priv, gen_fifo_cmd, buf); + else + return zynqmp_qspi_start_dma(priv, gen_fifo_cmd, buf); } ALLOC_CACHE_ALIGN_BUFFER(u8, tmp, roundup(priv->len, From a3d4bfb427fb6e8c9396a744879796231deabc3d Mon Sep 17 00:00:00 2001 From: Ashok Reddy Soma Date: Thu, 25 Aug 2022 06:59:04 -0600 Subject: [PATCH 094/374] spi: zynqmp_gqspi: Fix issue of reading more than 32bits length As the flash sizes are increasing day by day, QSPI can have devices of size > 512MB. In qspi driver we are trying to read all the data at once using DMA. The DMA descriptor destination size is only 29bits long. QSPIDMA_DST_SIZE 0xFF0F0804 BITS: 1:0 Reserved to keep word alignment BITS: 28:2 Number of 4-byte words the DMA will transfer BITS: 31:29 Reserved: Returns 0 when read, writes ignored So we can only transfer data of 0x1FFFFFF0(512MB minus 4bytes) bytes. Anything above will overflow this register and will ignore higher bits above 29 bits. Change the DMA functionality if the requested size is greater than or equal to 512MB to read 256MB chunks. Signed-off-by: Ashok Reddy Soma Link: https://lore.kernel.org/r/20220825125906.11581-5-ashok.reddy.soma@amd.com Signed-off-by: Michal Simek --- drivers/spi/zynqmp_gqspi.c | 68 +++++++++++++++++++++++--------------- 1 file changed, 42 insertions(+), 26 deletions(-) diff --git a/drivers/spi/zynqmp_gqspi.c b/drivers/spi/zynqmp_gqspi.c index 78a1b48731..d5ccb48fde 100644 --- a/drivers/spi/zynqmp_gqspi.c +++ b/drivers/spi/zynqmp_gqspi.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #define GQSPI_GFIFO_STRT_MODE_MASK BIT(29) @@ -666,39 +667,54 @@ static int zynqmp_qspi_start_dma(struct zynqmp_qspi_priv *priv, u32 addr; u32 size; u32 actuallen = priv->len; + u32 totallen = priv->len; int ret = 0; struct zynqmp_qspi_dma_regs *dma_regs = priv->dma_regs; - writel((unsigned long)buf, &dma_regs->dmadst); - writel(roundup(priv->len, GQSPI_DMA_ALIGN), &dma_regs->dmasize); - writel(GQSPI_DMA_DST_I_STS_MASK, &dma_regs->dmaier); - addr = (unsigned long)buf; - size = roundup(priv->len, GQSPI_DMA_ALIGN); - flush_dcache_range(addr, addr + size); + while (totallen) { + if (totallen >= SZ_512M) + priv->len = SZ_256M; + else + priv->len = totallen; - while (priv->len) { - zynqmp_qspi_calc_exp(priv, &gen_fifo_cmd); - zynqmp_qspi_fill_gen_fifo(priv, gen_fifo_cmd); + totallen -= priv->len; /* Save remaining bytes length to read */ + actuallen = priv->len; /* Actual number of bytes reading */ - debug("GFIFO_CMD_RX:0x%x\n", gen_fifo_cmd); + writel((unsigned long)buf, &dma_regs->dmadst); + writel(roundup(priv->len, GQSPI_DMA_ALIGN), &dma_regs->dmasize); + writel(GQSPI_DMA_DST_I_STS_MASK, &dma_regs->dmaier); + addr = (unsigned long)buf; + size = roundup(priv->len, GQSPI_DMA_ALIGN); + flush_dcache_range(addr, addr + size); + + while (priv->len) { + zynqmp_qspi_calc_exp(priv, &gen_fifo_cmd); + zynqmp_qspi_fill_gen_fifo(priv, gen_fifo_cmd); + + debug("GFIFO_CMD_RX:0x%x\n", gen_fifo_cmd); + } + + ret = wait_for_bit_le32(&dma_regs->dmaisr, + GQSPI_DMA_DST_I_STS_DONE, 1, + GQSPI_TIMEOUT, 1); + if (ret) { + printf("DMA Timeout:0x%x\n", readl(&dma_regs->dmaisr)); + return -ETIMEDOUT; + } + + writel(GQSPI_DMA_DST_I_STS_DONE, &dma_regs->dmaisr); + + debug("buf:0x%lx, rxbuf:0x%lx, *buf:0x%x len: 0x%x\n", + (unsigned long)buf, (unsigned long)priv->rx_buf, *buf, + actuallen); + + if (buf != priv->rx_buf) + memcpy(priv->rx_buf, buf, actuallen); + + buf = (u32 *)((u8 *)buf + actuallen); + priv->rx_buf = (u8 *)priv->rx_buf + actuallen; } - ret = wait_for_bit_le32(&dma_regs->dmaisr, GQSPI_DMA_DST_I_STS_DONE, - 1, GQSPI_TIMEOUT, 1); - if (ret) { - printf("DMA Timeout:0x%x\n", readl(&dma_regs->dmaisr)); - return -ETIMEDOUT; - } - - writel(GQSPI_DMA_DST_I_STS_DONE, &dma_regs->dmaisr); - - debug("buf:0x%lx, rxbuf:0x%lx, *buf:0x%x len: 0x%x\n", - (unsigned long)buf, (unsigned long)priv->rx_buf, *buf, - actuallen); - - if (buf != priv->rx_buf) - memcpy(priv->rx_buf, buf, actuallen); - return 0; } From afe03866a0f0a95ee6554b404f218b4b69b36f0e Mon Sep 17 00:00:00 2001 From: Ashok Reddy Soma Date: Thu, 25 Aug 2022 06:59:05 -0600 Subject: [PATCH 095/374] spi: zynqmp_qspi: Code alignment Few lines are extented to next line though they can fit in 80 character limit, align them to single line. No functional change. Signed-off-by: Ashok Reddy Soma Link: https://lore.kernel.org/r/20220825125906.11581-6-ashok.reddy.soma@amd.com Signed-off-by: Michal Simek --- drivers/spi/zynqmp_gqspi.c | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/drivers/spi/zynqmp_gqspi.c b/drivers/spi/zynqmp_gqspi.c index d5ccb48fde..4e718c545c 100644 --- a/drivers/spi/zynqmp_gqspi.c +++ b/drivers/spi/zynqmp_gqspi.c @@ -434,8 +434,7 @@ static int zynqmp_qspi_set_mode(struct udevice *bus, uint mode) debug("%s\n", __func__); /* Set the SPI Clock phase and polarities */ confr = readl(®s->confr); - confr &= ~(GQSPI_CONFIG_CPHA_MASK | - GQSPI_CONFIG_CPOL_MASK); + confr &= ~(GQSPI_CONFIG_CPHA_MASK | GQSPI_CONFIG_CPOL_MASK); if (mode & SPI_CPHA) confr |= GQSPI_CONFIG_CPHA_MASK; @@ -579,8 +578,7 @@ static int zynqmp_qspi_genfifo_fill_tx(struct zynqmp_qspi_priv *priv) gen_fifo_cmd = zynqmp_qspi_bus_select(priv); gen_fifo_cmd |= zynqmp_qspi_genfifo_mode(priv->op->data.buswidth); - gen_fifo_cmd |= GQSPI_GFIFO_TX | - GQSPI_GFIFO_DATA_XFR_MASK; + gen_fifo_cmd |= GQSPI_GFIFO_TX | GQSPI_GFIFO_DATA_XFR_MASK; while (priv->len) { len = zynqmp_qspi_calc_exp(priv, &gen_fifo_cmd); @@ -589,11 +587,9 @@ static int zynqmp_qspi_genfifo_fill_tx(struct zynqmp_qspi_priv *priv) debug("GFIFO_CMD_TX:0x%x\n", gen_fifo_cmd); if (gen_fifo_cmd & GQSPI_GFIFO_EXP_MASK) - ret = zynqmp_qspi_fill_tx_fifo(priv, - 1 << len); + ret = zynqmp_qspi_fill_tx_fifo(priv, 1 << len); else - ret = zynqmp_qspi_fill_tx_fifo(priv, - len); + ret = zynqmp_qspi_fill_tx_fifo(priv, len); if (ret) return ret; @@ -726,8 +722,7 @@ static int zynqmp_qspi_genfifo_fill_rx(struct zynqmp_qspi_priv *priv) gen_fifo_cmd = zynqmp_qspi_bus_select(priv); gen_fifo_cmd |= zynqmp_qspi_genfifo_mode(priv->op->data.buswidth); - gen_fifo_cmd |= GQSPI_GFIFO_RX | - GQSPI_GFIFO_DATA_XFR_MASK; + gen_fifo_cmd |= GQSPI_GFIFO_RX | GQSPI_GFIFO_DATA_XFR_MASK; /* * Check if receive buffer is aligned to 4 byte and length @@ -742,8 +737,7 @@ static int zynqmp_qspi_genfifo_fill_rx(struct zynqmp_qspi_priv *priv) return zynqmp_qspi_start_dma(priv, gen_fifo_cmd, buf); } - ALLOC_CACHE_ALIGN_BUFFER(u8, tmp, roundup(priv->len, - GQSPI_DMA_ALIGN)); + ALLOC_CACHE_ALIGN_BUFFER(u8, tmp, roundup(priv->len, GQSPI_DMA_ALIGN)); buf = (u32 *)tmp; return zynqmp_qspi_start_dma(priv, gen_fifo_cmd, buf); } From cac07a4d7c66d4b18acb70c27ebb9a356bf8a6f4 Mon Sep 17 00:00:00 2001 From: Ashok Reddy Soma Date: Thu, 25 Aug 2022 06:59:06 -0600 Subject: [PATCH 096/374] arm64: versal: Enable zynqmp_gqspi driver Versal supports gqspi ip, so enable zynqmp_gqspi driver for Versal platforms. Signed-off-by: Ashok Reddy Soma Link: https://lore.kernel.org/r/20220825125906.11581-7-ashok.reddy.soma@amd.com Signed-off-by: Michal Simek --- configs/xilinx_versal_virt_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/configs/xilinx_versal_virt_defconfig b/configs/xilinx_versal_virt_defconfig index c3fa913b20..6afd06798d 100644 --- a/configs/xilinx_versal_virt_defconfig +++ b/configs/xilinx_versal_virt_defconfig @@ -121,6 +121,7 @@ CONFIG_HAS_CQSPI_REF_CLK=y CONFIG_CQSPI_REF_CLK=200000000 CONFIG_CADENCE_OSPI_VERSAL=y CONFIG_ZYNQ_SPI=y +CONFIG_ZYNQMP_GQSPI=y CONFIG_USB=y CONFIG_DM_USB_GADGET=y CONFIG_USB_XHCI_HCD=y From 41634fd24b6488889005421ce74394693077b010 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Tue, 6 Sep 2022 12:35:42 +0200 Subject: [PATCH 097/374] ARM: zynq: Align qspi node name with Linux kernel Nodes should follow generic rules where compatible and reg properties should be listed on the top of node. That's why sync it up. Signed-off-by: Michal Simek Link: https://lore.kernel.org/r/922dca6227cb0aa4f79e6d3595c5f280ba020684.1662460540.git.michal.simek@amd.com --- arch/arm/dts/zynq-7000.dtsi | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/arch/arm/dts/zynq-7000.dtsi b/arch/arm/dts/zynq-7000.dtsi index b4aa09d149..11fa0ef2bf 100644 --- a/arch/arm/dts/zynq-7000.dtsi +++ b/arch/arm/dts/zynq-7000.dtsi @@ -235,13 +235,13 @@ }; qspi: spi@e000d000 { - clock-names = "ref_clk", "pclk"; - clocks = <&clkc 10>, <&clkc 43>; compatible = "xlnx,zynq-qspi-1.0"; - status = "disabled"; + reg = <0xe000d000 0x1000>; interrupt-parent = <&intc>; interrupts = <0 19 4>; - reg = <0xe000d000 0x1000>; + clocks = <&clkc 10>, <&clkc 43>; + clock-names = "ref_clk", "pclk"; + status = "disabled"; #address-cells = <1>; #size-cells = <0>; }; @@ -378,9 +378,9 @@ devcfg: devcfg@f8007000 { compatible = "xlnx,zynq-devcfg-1.0"; + reg = <0xf8007000 0x100>; interrupt-parent = <&intc>; interrupts = <0 8 4>; - reg = <0xf8007000 0x100>; clocks = <&clkc 12>, <&clkc 15>, <&clkc 16>, <&clkc 17>, <&clkc 18>; clock-names = "ref_clk", "fclk0", "fclk1", "fclk2", "fclk3"; syscon = <&slcr>; From 5c341965dd9907203b8ab0b9717a95b2b0f831cd Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Tue, 6 Sep 2022 12:38:34 +0200 Subject: [PATCH 098/374] ARM: zynq: DT: List OCM memory Description OCM with mmio-sram driver. In 99% use cases OCM is mapped high that's why it is placed on fixed location. Signed-off-by: Michal Simek Link: https://lore.kernel.org/r/a951dbe885640197efe3e91bb9fa5caedb54b387.1662460712.git.michal.simek@amd.com --- arch/arm/dts/zynq-7000.dtsi | 11 +++++++++++ arch/arm/dts/zynq-zc702.dts | 13 ------------- 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/arch/arm/dts/zynq-7000.dtsi b/arch/arm/dts/zynq-7000.dtsi index 11fa0ef2bf..edc147d63f 100644 --- a/arch/arm/dts/zynq-7000.dtsi +++ b/arch/arm/dts/zynq-7000.dtsi @@ -192,6 +192,17 @@ reg = <0xf8006000 0x1000>; }; + ocm: sram@fffc0000 { + compatible = "mmio-sram"; + reg = <0xfffc0000 0x10000>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0xfffc0000 0x10000>; + ocm-sram@0 { + reg = <0x0 0x10000>; + }; + }; + uart0: serial@e0000000 { compatible = "xlnx,xuartps", "cdns,uart-r1p8"; status = "disabled"; diff --git a/arch/arm/dts/zynq-zc702.dts b/arch/arm/dts/zynq-zc702.dts index f2e05a55b9..1bd4f8c9f6 100644 --- a/arch/arm/dts/zynq-zc702.dts +++ b/arch/arm/dts/zynq-zc702.dts @@ -64,19 +64,6 @@ }; }; -&amba { - ocm: sram@fffc0000 { - compatible = "mmio-sram"; - reg = <0xfffc0000 0x10000>; - #address-cells = <1>; - #size-cells = <1>; - ranges = <0 0xfffc0000 0x10000>; - ocm-sram@0 { - reg = <0x0 0x10000>; - }; - }; -}; - &can0 { status = "okay"; pinctrl-names = "default"; From 4e168260281518abbb417dc08ec91d96cca715a1 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Tue, 6 Sep 2022 12:39:11 +0200 Subject: [PATCH 099/374] xilinx: Fix mdio bus description for vck190-sc Current behavior is that eth_phy_get_mdio_bus Net: FEC: can't find phy-handle ZYNQ GEM: ff0b0000, mdio bus ff0b0000, phyaddr 0, interface sgmii eth0: ethernet@ff0b0000 Net: ZYNQ GEM: ff0b0000, mdio bus ff0b0000, phyaddr 0, interface sgmii eth0: ethernet@ff0b0000 Signed-off-by: Michal Simek Link: https://lore.kernel.org/r/5b7da5808136b3f579c0cf7a3431b56c758655e9.1662460749.git.michal.simek@amd.com --- arch/arm/dts/zynqmp-e-a2197-00-revA.dts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/arch/arm/dts/zynqmp-e-a2197-00-revA.dts b/arch/arm/dts/zynqmp-e-a2197-00-revA.dts index 4940825b00..3fa18f560c 100644 --- a/arch/arm/dts/zynqmp-e-a2197-00-revA.dts +++ b/arch/arm/dts/zynqmp-e-a2197-00-revA.dts @@ -155,8 +155,12 @@ phy-handle = <&phy0>; phy-mode = "sgmii"; is-internal-pcspma; - phy0: ethernet-phy@0 { /* u131 M88E1512 */ - reg = <0>; + mdio: mdio { + #address-cells = <1>; + #size-cells = <0>; + phy0: ethernet-phy@0 { /* u131 M88E1512 */ + reg = <0>; + }; }; }; From 39d3c3cfaa4f5099a2d687de4530c9ca4bee256d Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Tue, 6 Sep 2022 12:40:41 +0200 Subject: [PATCH 100/374] xilinx: common: Add support for SOC detection Code supports board detection based on information available in EEPROM in legacy or FRU format. But this is not enough for emulation and simulation systems which are lacking these identification EEPROMs. But SOC itself has normally registers for SOC identification. Based on them it is possible to compose detected name. That's why prepare infrastructure in common location for SOC platform detection which is called before board platform detection. SOC platform detection shouldn't detect real silicon and should fallback to current existing mechanism to identify boards based on EEPROMs. Signed-off-by: Michal Simek Link: https://lore.kernel.org/r/329a8da338927b082e26a958bf69bb18af072420.1662460837.git.michal.simek@amd.com --- board/xilinx/common/board.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/board/xilinx/common/board.c b/board/xilinx/common/board.c index 5e36386361..e1f7104960 100644 --- a/board/xilinx/common/board.c +++ b/board/xilinx/common/board.c @@ -585,8 +585,33 @@ bool __maybe_unused __weak board_detection(void) return false; } +bool __maybe_unused __weak soc_detection(void) +{ + return false; +} + +char * __maybe_unused __weak soc_name_decode(void) +{ + return NULL; +} + int embedded_dtb_select(void) { + if (soc_detection()) { + char *soc_local_name; + + soc_local_name = soc_name_decode(); + if (soc_local_name) { + board_name = soc_local_name; + printf("Detected SOC name: %s\n", board_name); + + /* Time to change DTB on fly */ + /* Both ways should work here */ + /* fdtdec_resetup(&rescan); */ + return fdtdec_setup(); + } + } + if (board_detection()) { char *board_local_name; From a7e82204743c3095deeac73e3142152d325141f8 Mon Sep 17 00:00:00 2001 From: Chin-Ting Kuo Date: Fri, 19 Aug 2022 17:01:02 +0800 Subject: [PATCH 101/374] clk: aspeed: Get HCLK frequency support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit User can get correct HCLK frequency during driver probe stage by adding the following configuration in the device tree. "clocks = <&scu ASPEED_CLK_AHB>". Signed-off-by: Chin-Ting Kuo Reviewed-by: Cédric Le Goater --- drivers/clk/aspeed/clk_ast2500.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/drivers/clk/aspeed/clk_ast2500.c b/drivers/clk/aspeed/clk_ast2500.c index 623c6915b8..dc446ce9fb 100644 --- a/drivers/clk/aspeed/clk_ast2500.c +++ b/drivers/clk/aspeed/clk_ast2500.c @@ -30,6 +30,12 @@ #define D2PLL_DEFAULT_RATE (250 * 1000 * 1000) +/* + * AXI/AHB clock selection, taken from Aspeed SDK + */ +#define SCU_HWSTRAP_AXIAHB_DIV_SHIFT 9 +#define SCU_HWSTRAP_AXIAHB_DIV_MASK (0x7 << SCU_HWSTRAP_AXIAHB_DIV_SHIFT) + DECLARE_GLOBAL_DATA_PTR; /* @@ -86,6 +92,20 @@ static ulong ast2500_get_clkin(struct ast2500_scu *scu) ? 25 * 1000 * 1000 : 24 * 1000 * 1000; } +static u32 ast2500_get_hclk(ulong clkin, struct ast2500_scu *scu) +{ + u32 hpll_reg = readl(&scu->h_pll_param); + ulong axi_div = 2; + u32 rate; + ulong ahb_div = 1 + ((readl(&scu->hwstrap) + & SCU_HWSTRAP_AXIAHB_DIV_MASK) + >> SCU_HWSTRAP_AXIAHB_DIV_SHIFT); + + rate = ast2500_get_hpll_rate(clkin, hpll_reg); + + return (rate / axi_div / ahb_div); +} + /** * Get current rate or uart clock * @@ -147,6 +167,9 @@ static ulong ast2500_clk_get_rate(struct clk *clk) rate = rate / apb_div; } break; + case ASPEED_CLK_AHB: + rate = ast2500_get_hclk(clkin, priv->scu); + break; case ASPEED_CLK_SDIO: { ulong apb_div = 4 + 4 * ((readl(&priv->scu->clk_sel1) From cf2051ac4cc57ba194215ae095591b477af309b6 Mon Sep 17 00:00:00 2001 From: Chin-Ting Kuo Date: Fri, 19 Aug 2022 17:01:03 +0800 Subject: [PATCH 102/374] pinctrl: aspeed: FWSPICS1 and SPI1CS1 pin support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add FWSPICS1 and SPI1CS1 in AST2500 pinctrl group. On AST2500 EVB, FWSPICS1 can be supported by default. An extra jumper, J45, should be configured before enabling SPI1CS1. Signed-off-by: Chin-Ting Kuo Reviewed-by: Cédric Le Goater --- drivers/pinctrl/aspeed/pinctrl_ast2500.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/pinctrl/aspeed/pinctrl_ast2500.c b/drivers/pinctrl/aspeed/pinctrl_ast2500.c index 3c2e10b88e..93920a6389 100644 --- a/drivers/pinctrl/aspeed/pinctrl_ast2500.c +++ b/drivers/pinctrl/aspeed/pinctrl_ast2500.c @@ -61,6 +61,8 @@ static const struct ast2500_group_config ast2500_groups[] = { { "MDIO2", 5, (1 << 2) }, { "SD1", 5, (1 << 0) }, { "SD2", 5, (1 << 1) }, + { "FWSPICS1", 3, (1 << 24) }, + { "SPI1CS1", 1, (1 << 15) }, }; static int ast2500_pinctrl_get_groups_count(struct udevice *dev) From 4daa6bb6f76d3124e73cef22c98e7269140f42b0 Mon Sep 17 00:00:00 2001 From: Chin-Ting Kuo Date: Fri, 19 Aug 2022 17:01:04 +0800 Subject: [PATCH 103/374] spi: aspeed: Add ASPEED SPI controller driver Add ASPEED BMC FMC/SPI memory controller driver with spi-mem interface for AST2500 and AST2600 platform. There are three SPI memory controllers embedded in an ASPEED SoC. - FMC: Named as Firmware Memory Controller. After AC on, MCU ROM fetches initial device boot image from FMC chip select(CS) 0. - SPI1: Play the role of a SPI Master controller. Or, there is a dedicated path for HOST(X86) to access its BIOS flash mounted under BMC. spi-aspeed-smc.c implements the control sequence when SPI1 is a SPI master. - SPI2: It is a pure SPI flash controller. For most scenarios, flashes mounted under it are for pure storage purpose. ASPEED SPI controller supports 1-1-1, 1-1-2 and 1-1-4 SPI flash mode. Three types of command mode are supported, normal mode, command read/write mode and user mode. - Normal mode: Default mode. After power on, normal read command 03h or 13h is used to fetch boot image from SPI flash. - AST2500: Only 03h command can be used after power on or reset. - AST2600: If FMC04[6:4] is set, 13h command is used, otherwise, 03h command. The address length is decided by FMC04[2:0]. - Command mode: SPI controller can send command and address automatically when CPU read/write the related remapped or decoded address area. The command used by this mode can be configured by FMC10/14/18[23:16]. Also, the address length is decided by FMC04[2:0]. This mode will be implemented in the following patch series. - User mode: It is a traditional and pure SPI operation, where SPI transmission is controlled by CPU. It is the main mode in this patch. Each SPI controller in ASPEED SoC has its own decoded address mapping. Within each SPI controller decoded address, driver can assign a specific address region for each CS of a SPI controller. The decoded address cannot overlap to each other. With normal mode and command mode, the decoded address accessed by the CPU determines which CS is active. When user mode is adopted, the CS decoded address is a FIFO, CPU can send/receive any SPI transmission by accessing the related decoded address for the target CS. This patch only implements user mode initially. Command read/write mode will be implemented in the following patches. Signed-off-by: Chin-Ting Kuo --- MAINTAINERS | 7 + drivers/spi/Kconfig | 8 + drivers/spi/Makefile | 1 + drivers/spi/spi-aspeed-smc.c | 603 +++++++++++++++++++++++++++++++++++ 4 files changed, 619 insertions(+) create mode 100644 drivers/spi/spi-aspeed-smc.c diff --git a/MAINTAINERS b/MAINTAINERS index 36a2b69fcb..1ebcd368a6 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -724,6 +724,13 @@ S: Maintained F: drivers/pci/pcie_phytium.c F: arch/arm/dts/phytium-durian.dts +ASPEED FMC SPI DRIVER +M: Chin-Ting Kuo +M: Cédric Le Goater +R: Aspeed BMC SW team +S: Maintained +F: drivers/spi/spi-aspeed-smc.c + BINMAN M: Simon Glass M: Alper Nebi Yasak diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index 75b794548b..8ca9274ef4 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -401,6 +401,14 @@ config SANDBOX_SPI }; }; +config SPI_ASPEED_SMC + bool "ASPEED SPI flash controller driver" + depends on DM_SPI && SPI_MEM + default n + help + Enable ASPEED SPI flash controller driver for AST2500 + and AST2600 SoCs. + config SPI_SIFIVE bool "SiFive SPI driver" help diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index 4de77c260a..7ba953d2df 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile @@ -10,6 +10,7 @@ obj-$(CONFIG_CADENCE_QSPI) += cadence_qspi.o cadence_qspi_apb.o obj-$(CONFIG_CADENCE_OSPI_VERSAL) += cadence_ospi_versal.o obj-$(CONFIG_SANDBOX) += spi-emul-uclass.o obj-$(CONFIG_SOFT_SPI) += soft_spi.o +obj-$(CONFIG_SPI_ASPEED_SMC) += spi-aspeed-smc.o obj-$(CONFIG_SPI_MEM) += spi-mem.o obj-$(CONFIG_TI_QSPI) += ti_qspi.o obj-$(CONFIG_FSL_QSPI) += fsl_qspi.o diff --git a/drivers/spi/spi-aspeed-smc.c b/drivers/spi/spi-aspeed-smc.c new file mode 100644 index 0000000000..25b490bcf4 --- /dev/null +++ b/drivers/spi/spi-aspeed-smc.c @@ -0,0 +1,603 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * ASPEED FMC/SPI Controller driver + * + * Copyright (c) 2022 ASPEED Corporation. + * Copyright (c) 2022 IBM Corporation. + * + * Author: + * Chin-Ting Kuo + * Cedric Le Goater + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define ASPEED_SPI_MAX_CS 3 + +#define CTRL_IO_SINGLE_DATA 0 +#define CTRL_IO_QUAD_DATA BIT(30) +#define CTRL_IO_DUAL_DATA BIT(29) + +#define CTRL_IO_MODE_USER GENMASK(1, 0) +#define CTRL_IO_MODE_CMD_READ BIT(0) +#define CTRL_IO_MODE_CMD_WRITE BIT(1) +#define CTRL_STOP_ACTIVE BIT(2) + +struct aspeed_spi_regs { + u32 conf; /* 0x00 CE Type Setting */ + u32 ctrl; /* 0x04 CE Control */ + u32 intr_ctrl; /* 0x08 Interrupt Control and Status */ + u32 cmd_ctrl; /* 0x0c Command Control */ + u32 ce_ctrl[ASPEED_SPI_MAX_CS]; /* 0x10 .. 0x18 CEx Control */ + u32 _reserved0[5]; /* .. */ + u32 segment_addr[ASPEED_SPI_MAX_CS]; /* 0x30 .. 0x38 Segment Address */ + u32 _reserved1[5]; /* .. */ + u32 soft_rst_cmd_ctrl; /* 0x50 Auto Soft-Reset Command Control */ + u32 _reserved2[11]; /* .. */ + u32 dma_ctrl; /* 0x80 DMA Control/Status */ + u32 dma_flash_addr; /* 0x84 DMA Flash Side Address */ + u32 dma_dram_addr; /* 0x88 DMA DRAM Side Address */ + u32 dma_len; /* 0x8c DMA Length Register */ + u32 dma_checksum; /* 0x90 Checksum Calculation Result */ + u32 timings[ASPEED_SPI_MAX_CS]; /* 0x94 Read Timing Compensation */ +}; + +struct aspeed_spi_plat { + u8 max_cs; + void __iomem *ahb_base; /* AHB address base for all flash devices. */ + fdt_size_t ahb_sz; /* Overall AHB window size for all flash device. */ +}; + +struct aspeed_spi_flash { + void __iomem *ahb_base; + u32 ahb_decoded_sz; + u32 ce_ctrl_user; + u32 ce_ctrl_read; +}; + +struct aspeed_spi_priv { + u32 num_cs; + struct aspeed_spi_regs *regs; + struct aspeed_spi_info *info; + struct aspeed_spi_flash flashes[ASPEED_SPI_MAX_CS]; +}; + +struct aspeed_spi_info { + u32 io_mode_mask; + u32 max_bus_width; + u32 min_decoded_sz; + void (*set_4byte)(struct udevice *bus, u32 cs); + u32 (*segment_start)(struct udevice *bus, u32 reg); + u32 (*segment_end)(struct udevice *bus, u32 reg); + u32 (*segment_reg)(u32 start, u32 end); +}; + +static u32 aspeed_spi_get_io_mode(u32 bus_width) +{ + switch (bus_width) { + case 1: + return CTRL_IO_SINGLE_DATA; + case 2: + return CTRL_IO_DUAL_DATA; + case 4: + return CTRL_IO_QUAD_DATA; + default: + /* keep in default value */ + return CTRL_IO_SINGLE_DATA; + } +} + +static u32 ast2500_spi_segment_start(struct udevice *bus, u32 reg) +{ + struct aspeed_spi_plat *plat = dev_get_plat(bus); + u32 start_offset = ((reg >> 16) & 0xff) << 23; + + if (start_offset == 0) + return (u32)plat->ahb_base; + + return (u32)plat->ahb_base + start_offset; +} + +static u32 ast2500_spi_segment_end(struct udevice *bus, u32 reg) +{ + struct aspeed_spi_plat *plat = dev_get_plat(bus); + u32 end_offset = ((reg >> 24) & 0xff) << 23; + + /* Meaningless end_offset, set to physical ahb base. */ + if (end_offset == 0) + return (u32)plat->ahb_base; + + return (u32)plat->ahb_base + end_offset; +} + +static u32 ast2500_spi_segment_reg(u32 start, u32 end) +{ + if (start == end) + return 0; + + return ((((start) >> 23) & 0xff) << 16) | ((((end) >> 23) & 0xff) << 24); +} + +static void ast2500_spi_chip_set_4byte(struct udevice *bus, u32 cs) +{ + struct aspeed_spi_priv *priv = dev_get_priv(bus); + u32 reg_val; + + reg_val = readl(&priv->regs->ctrl); + reg_val |= 0x1 << cs; + writel(reg_val, &priv->regs->ctrl); +} + +static u32 ast2600_spi_segment_start(struct udevice *bus, u32 reg) +{ + struct aspeed_spi_plat *plat = dev_get_plat(bus); + u32 start_offset = (reg << 16) & 0x0ff00000; + + if (start_offset == 0) + return (u32)plat->ahb_base; + + return (u32)plat->ahb_base + start_offset; +} + +static u32 ast2600_spi_segment_end(struct udevice *bus, u32 reg) +{ + struct aspeed_spi_plat *plat = dev_get_plat(bus); + u32 end_offset = reg & 0x0ff00000; + + /* Meaningless end_offset, set to physical ahb base. */ + if (end_offset == 0) + return (u32)plat->ahb_base; + + return (u32)plat->ahb_base + end_offset + 0x100000; +} + +static u32 ast2600_spi_segment_reg(u32 start, u32 end) +{ + if (start == end) + return 0; + + return ((start & 0x0ff00000) >> 16) | ((end - 0x100000) & 0x0ff00000); +} + +static void ast2600_spi_chip_set_4byte(struct udevice *bus, u32 cs) +{ + struct aspeed_spi_priv *priv = dev_get_priv(bus); + u32 reg_val; + + reg_val = readl(&priv->regs->ctrl); + reg_val |= 0x11 << cs; + writel(reg_val, &priv->regs->ctrl); +} + +static int aspeed_spi_read_from_ahb(void __iomem *ahb_base, void *buf, + size_t len) +{ + size_t offset = 0; + + if (IS_ALIGNED((uintptr_t)ahb_base, sizeof(uintptr_t)) && + IS_ALIGNED((uintptr_t)buf, sizeof(uintptr_t))) { + readsl(ahb_base, buf, len >> 2); + offset = len & ~0x3; + len -= offset; + } + + readsb(ahb_base, (u8 *)buf + offset, len); + + return 0; +} + +static int aspeed_spi_write_to_ahb(void __iomem *ahb_base, const void *buf, + size_t len) +{ + size_t offset = 0; + + if (IS_ALIGNED((uintptr_t)ahb_base, sizeof(uintptr_t)) && + IS_ALIGNED((uintptr_t)buf, sizeof(uintptr_t))) { + writesl(ahb_base, buf, len >> 2); + offset = len & ~0x3; + len -= offset; + } + + writesb(ahb_base, (u8 *)buf + offset, len); + + return 0; +} + +/* + * Currently, only support 1-1-1, 1-1-2 or 1-1-4 + * SPI NOR flash operation format. + */ +static bool aspeed_spi_supports_op(struct spi_slave *slave, + const struct spi_mem_op *op) +{ + struct udevice *bus = slave->dev->parent; + struct aspeed_spi_priv *priv = dev_get_priv(bus); + + if (op->cmd.buswidth > 1) + return false; + + if (op->addr.nbytes != 0) { + if (op->addr.buswidth > 1) + return false; + if (op->addr.nbytes < 3 || op->addr.nbytes > 4) + return false; + } + + if (op->dummy.nbytes != 0) { + if (op->dummy.buswidth > 1 || op->dummy.nbytes > 7) + return false; + } + + if (op->data.nbytes != 0 && + op->data.buswidth > priv->info->max_bus_width) + return false; + + if (!spi_mem_default_supports_op(slave, op)) + return false; + + return true; +} + +static int aspeed_spi_exec_op_user_mode(struct spi_slave *slave, + const struct spi_mem_op *op) +{ + struct udevice *dev = slave->dev; + struct udevice *bus = dev->parent; + struct aspeed_spi_priv *priv = dev_get_priv(bus); + struct dm_spi_slave_plat *slave_plat = dev_get_parent_plat(slave->dev); + u32 cs = slave_plat->cs; + u32 ce_ctrl_reg = (u32)&priv->regs->ce_ctrl[cs]; + u32 ce_ctrl_val; + struct aspeed_spi_flash *flash = &priv->flashes[cs]; + u8 dummy_data[16] = {0}; + u8 addr[4] = {0}; + int i; + + dev_dbg(dev, "cmd:%x(%d),addr:%llx(%d),dummy:%d(%d),data_len:0x%x(%d)\n", + op->cmd.opcode, op->cmd.buswidth, op->addr.val, + op->addr.buswidth, op->dummy.nbytes, op->dummy.buswidth, + op->data.nbytes, op->data.buswidth); + + /* + * Set controller to 4-byte address mode + * if flash is in 4-byte address mode. + */ + if (op->cmd.opcode == SPINOR_OP_EN4B) + priv->info->set_4byte(bus, cs); + + /* Start user mode */ + ce_ctrl_val = flash->ce_ctrl_user; + writel(ce_ctrl_val, ce_ctrl_reg); + ce_ctrl_val &= (~CTRL_STOP_ACTIVE); + writel(ce_ctrl_val, ce_ctrl_reg); + + /* Send command */ + aspeed_spi_write_to_ahb(flash->ahb_base, &op->cmd.opcode, 1); + + /* Send address */ + for (i = op->addr.nbytes; i > 0; i--) { + addr[op->addr.nbytes - i] = + ((u32)op->addr.val >> ((i - 1) * 8)) & 0xff; + } + + /* Change io_mode */ + ce_ctrl_val &= ~priv->info->io_mode_mask; + ce_ctrl_val |= aspeed_spi_get_io_mode(op->addr.buswidth); + writel(ce_ctrl_val, ce_ctrl_reg); + aspeed_spi_write_to_ahb(flash->ahb_base, addr, op->addr.nbytes); + + /* Send dummy cycles */ + aspeed_spi_write_to_ahb(flash->ahb_base, dummy_data, op->dummy.nbytes); + + /* Change io_mode */ + ce_ctrl_val &= ~priv->info->io_mode_mask; + ce_ctrl_val |= aspeed_spi_get_io_mode(op->data.buswidth); + writel(ce_ctrl_val, ce_ctrl_reg); + + /* Send data */ + if (op->data.dir == SPI_MEM_DATA_OUT) { + aspeed_spi_write_to_ahb(flash->ahb_base, op->data.buf.out, + op->data.nbytes); + } else { + aspeed_spi_read_from_ahb(flash->ahb_base, op->data.buf.in, + op->data.nbytes); + } + + ce_ctrl_val |= CTRL_STOP_ACTIVE; + writel(ce_ctrl_val, ce_ctrl_reg); + + /* Restore controller setting. */ + writel(flash->ce_ctrl_read, ce_ctrl_reg); + + return 0; +} + +static struct aspeed_spi_flash *aspeed_spi_get_flash(struct udevice *dev) +{ + struct udevice *bus = dev->parent; + struct dm_spi_slave_plat *slave_plat = dev_get_parent_plat(dev); + struct aspeed_spi_plat *plat = dev_get_plat(bus); + struct aspeed_spi_priv *priv = dev_get_priv(bus); + u32 cs = slave_plat->cs; + + if (cs >= plat->max_cs) { + dev_err(dev, "invalid CS %u\n", cs); + return NULL; + } + + return &priv->flashes[cs]; +} + +static void aspeed_spi_decoded_base_calculate(struct udevice *bus) +{ + struct aspeed_spi_plat *plat = dev_get_plat(bus); + struct aspeed_spi_priv *priv = dev_get_priv(bus); + u32 cs; + + priv->flashes[0].ahb_base = plat->ahb_base; + + for (cs = 1; cs < plat->max_cs; cs++) { + priv->flashes[cs].ahb_base = + priv->flashes[cs - 1].ahb_base + + priv->flashes[cs - 1].ahb_decoded_sz; + } +} + +static void aspeed_spi_decoded_range_set(struct udevice *bus) +{ + struct aspeed_spi_plat *plat = dev_get_plat(bus); + struct aspeed_spi_priv *priv = dev_get_priv(bus); + u32 decoded_reg_val; + u32 start_addr, end_addr; + u32 cs; + + for (cs = 0; cs < plat->max_cs; cs++) { + start_addr = (u32)priv->flashes[cs].ahb_base; + end_addr = (u32)priv->flashes[cs].ahb_base + + priv->flashes[cs].ahb_decoded_sz; + + decoded_reg_val = priv->info->segment_reg(start_addr, end_addr); + + writel(decoded_reg_val, &priv->regs->segment_addr[cs]); + + dev_dbg(bus, "cs: %d, decoded_reg: 0x%x, start: 0x%x, end: 0x%x\n", + cs, decoded_reg_val, start_addr, end_addr); + } +} + +static int aspeed_spi_decoded_range_config(struct udevice *bus) +{ + aspeed_spi_decoded_base_calculate(bus); + aspeed_spi_decoded_range_set(bus); + + return 0; +} + +/* + * Initialize SPI controller for each chip select. + * Here, only the minimum decode range is configured + * in order to get device (SPI NOR flash) information + * at the early stage. + */ +static int aspeed_spi_ctrl_init(struct udevice *bus) +{ + int ret; + struct aspeed_spi_plat *plat = dev_get_plat(bus); + struct aspeed_spi_priv *priv = dev_get_priv(bus); + u32 cs; + u32 reg_val; + u32 decoded_sz; + + /* Enable write capability for all CS. */ + reg_val = readl(&priv->regs->conf); + writel(reg_val | (GENMASK(plat->max_cs - 1, 0) << 16), + &priv->regs->conf); + + memset(priv->flashes, 0x0, + sizeof(struct aspeed_spi_flash) * ASPEED_SPI_MAX_CS); + + /* Initial user mode. */ + for (cs = 0; cs < priv->num_cs; cs++) { + priv->flashes[cs].ce_ctrl_user = + (CTRL_STOP_ACTIVE | CTRL_IO_MODE_USER); + } + + /* Assign basic AHB decoded size for each CS. */ + for (cs = 0; cs < plat->max_cs; cs++) { + reg_val = readl(&priv->regs->segment_addr[cs]); + decoded_sz = priv->info->segment_end(bus, reg_val) - + priv->info->segment_start(bus, reg_val); + + if (decoded_sz < priv->info->min_decoded_sz) + decoded_sz = priv->info->min_decoded_sz; + + priv->flashes[cs].ahb_decoded_sz = decoded_sz; + } + + ret = aspeed_spi_decoded_range_config(bus); + + return ret; +} + +static const struct aspeed_spi_info ast2500_fmc_info = { + .io_mode_mask = 0x70000000, + .max_bus_width = 2, + .min_decoded_sz = 0x800000, + .set_4byte = ast2500_spi_chip_set_4byte, + .segment_start = ast2500_spi_segment_start, + .segment_end = ast2500_spi_segment_end, + .segment_reg = ast2500_spi_segment_reg, +}; + +/* + * There are some different between FMC and SPI controllers. + * For example, DMA operation, but this isn't implemented currently. + */ +static const struct aspeed_spi_info ast2500_spi_info = { + .io_mode_mask = 0x70000000, + .max_bus_width = 2, + .min_decoded_sz = 0x800000, + .set_4byte = ast2500_spi_chip_set_4byte, + .segment_start = ast2500_spi_segment_start, + .segment_end = ast2500_spi_segment_end, + .segment_reg = ast2500_spi_segment_reg, +}; + +static const struct aspeed_spi_info ast2600_fmc_info = { + .io_mode_mask = 0xf0000000, + .max_bus_width = 4, + .min_decoded_sz = 0x200000, + .set_4byte = ast2600_spi_chip_set_4byte, + .segment_start = ast2600_spi_segment_start, + .segment_end = ast2600_spi_segment_end, + .segment_reg = ast2600_spi_segment_reg, +}; + +static const struct aspeed_spi_info ast2600_spi_info = { + .io_mode_mask = 0xf0000000, + .max_bus_width = 4, + .min_decoded_sz = 0x200000, + .set_4byte = ast2600_spi_chip_set_4byte, + .segment_start = ast2600_spi_segment_start, + .segment_end = ast2600_spi_segment_end, + .segment_reg = ast2600_spi_segment_reg, +}; + +static int aspeed_spi_claim_bus(struct udevice *dev) +{ + struct udevice *bus = dev->parent; + struct dm_spi_slave_plat *slave_plat = dev_get_parent_plat(dev); + + dev_dbg(bus, "%s: claim bus CS%u\n", bus->name, slave_plat->cs); + + return 0; +} + +static int aspeed_spi_release_bus(struct udevice *dev) +{ + struct udevice *bus = dev->parent; + struct dm_spi_slave_plat *slave_plat = dev_get_parent_plat(dev); + + dev_dbg(bus, "%s: release bus CS%u\n", bus->name, slave_plat->cs); + + if (!aspeed_spi_get_flash(dev)) + return -ENODEV; + + return 0; +} + +static int aspeed_spi_set_mode(struct udevice *bus, uint mode) +{ + dev_dbg(bus, "%s: setting mode to %x\n", bus->name, mode); + + return 0; +} + +static int aspeed_spi_set_speed(struct udevice *bus, uint hz) +{ + dev_dbg(bus, "%s: setting speed to %u\n", bus->name, hz); + /* + * ASPEED SPI controller supports multiple CS with different + * clock frequency. We cannot distinguish which CS here. + * Thus, the related implementation is postponed to claim_bus. + */ + + return 0; +} + +static int apseed_spi_of_to_plat(struct udevice *bus) +{ + struct aspeed_spi_plat *plat = dev_get_plat(bus); + struct aspeed_spi_priv *priv = dev_get_priv(bus); + + priv->regs = (void __iomem *)devfdt_get_addr_index(bus, 0); + if ((u32)priv->regs == FDT_ADDR_T_NONE) { + dev_err(bus, "wrong ctrl base\n"); + return -ENODEV; + } + + plat->ahb_base = + (void __iomem *)devfdt_get_addr_size_index(bus, 1, &plat->ahb_sz); + if ((u32)plat->ahb_base == FDT_ADDR_T_NONE) { + dev_err(bus, "wrong AHB base\n"); + return -ENODEV; + } + + plat->max_cs = dev_read_u32_default(bus, "num-cs", ASPEED_SPI_MAX_CS); + if (plat->max_cs > ASPEED_SPI_MAX_CS) + return -EINVAL; + + dev_dbg(bus, "ctrl_base = 0x%x, ahb_base = 0x%p, size = 0x%lx\n", + (u32)priv->regs, plat->ahb_base, plat->ahb_sz); + dev_dbg(bus, "max_cs = %d\n", plat->max_cs); + + return 0; +} + +static int aspeed_spi_probe(struct udevice *bus) +{ + int ret; + struct aspeed_spi_priv *priv = dev_get_priv(bus); + struct udevice *dev; + + priv->info = (struct aspeed_spi_info *)dev_get_driver_data(bus); + + priv->num_cs = 0; + for (device_find_first_child(bus, &dev); dev; + device_find_next_child(&dev)) { + priv->num_cs++; + } + + if (priv->num_cs > ASPEED_SPI_MAX_CS) + return -EINVAL; + + ret = aspeed_spi_ctrl_init(bus); + + return ret; +} + +static const struct spi_controller_mem_ops aspeed_spi_mem_ops = { + .supports_op = aspeed_spi_supports_op, + .exec_op = aspeed_spi_exec_op_user_mode, +}; + +static const struct dm_spi_ops aspeed_spi_ops = { + .claim_bus = aspeed_spi_claim_bus, + .release_bus = aspeed_spi_release_bus, + .set_speed = aspeed_spi_set_speed, + .set_mode = aspeed_spi_set_mode, + .mem_ops = &aspeed_spi_mem_ops, +}; + +static const struct udevice_id aspeed_spi_ids[] = { + { .compatible = "aspeed,ast2500-fmc", .data = (ulong)&ast2500_fmc_info, }, + { .compatible = "aspeed,ast2500-spi", .data = (ulong)&ast2500_spi_info, }, + { .compatible = "aspeed,ast2600-fmc", .data = (ulong)&ast2600_fmc_info, }, + { .compatible = "aspeed,ast2600-spi", .data = (ulong)&ast2600_spi_info, }, + { } +}; + +U_BOOT_DRIVER(aspeed_spi) = { + .name = "aspeed_spi_smc", + .id = UCLASS_SPI, + .of_match = aspeed_spi_ids, + .ops = &aspeed_spi_ops, + .of_to_plat = apseed_spi_of_to_plat, + .plat_auto = sizeof(struct aspeed_spi_plat), + .priv_auto = sizeof(struct aspeed_spi_priv), + .probe = aspeed_spi_probe, +}; From 456f716f36578bcb86596b73750aa55d5851b4de Mon Sep 17 00:00:00 2001 From: Chin-Ting Kuo Date: Fri, 19 Aug 2022 17:01:05 +0800 Subject: [PATCH 104/374] configs: aspeed: Enable SPI flash features - Enable ASPEED SPI controller driver. - Enable SPI flash memory configurations. - Enable configurations for SPI flash manufacturers supported on both ASPEED AST2500 and AST2600 AVL. Signed-off-by: Chin-Ting Kuo --- configs/evb-ast2500_defconfig | 13 +++++++++++++ configs/evb-ast2600_defconfig | 13 +++++++++++++ 2 files changed, 26 insertions(+) diff --git a/configs/evb-ast2500_defconfig b/configs/evb-ast2500_defconfig index 0bef043ea6..dfcf74ae01 100644 --- a/configs/evb-ast2500_defconfig +++ b/configs/evb-ast2500_defconfig @@ -39,6 +39,16 @@ CONFIG_SYS_I2C_ASPEED=y CONFIG_I2C_EEPROM=y CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI_ASPEED=y +CONFIG_DM_SPI_FLASH=y +CONFIG_SPI_FLASH_SFDP_SUPPORT=y +CONFIG_SPI_FLASH_GIGADEVICE=y +CONFIG_SPI_FLASH_ISSI=y +CONFIG_SPI_FLASH_MACRONIX=y +CONFIG_SPI_FLASH_SPANSION=y +CONFIG_SPI_FLASH_STMICRO=y +CONFIG_SPI_FLASH_SST=y +CONFIG_SPI_FLASH_WINBOND=y +# CONFIG_SPI_FLASH_USE_4K_SECTORS is not set CONFIG_PHY_REALTEK=y CONFIG_FTGMAC100=y CONFIG_PHY=y @@ -47,6 +57,9 @@ CONFIG_RAM=y CONFIG_DM_RESET=y CONFIG_DM_SERIAL=y CONFIG_SYS_NS16550=y +CONFIG_SPI=y +CONFIG_DM_SPI=y +CONFIG_SPI_ASPEED_SMC=y CONFIG_SYSRESET=y CONFIG_TIMER=y CONFIG_WDT=y diff --git a/configs/evb-ast2600_defconfig b/configs/evb-ast2600_defconfig index 1284d51918..ebe58d7abd 100644 --- a/configs/evb-ast2600_defconfig +++ b/configs/evb-ast2600_defconfig @@ -87,6 +87,16 @@ CONFIG_SYS_I2C_ASPEED=y CONFIG_I2C_EEPROM=y CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI_ASPEED=y +CONFIG_DM_SPI_FLASH=y +CONFIG_SPI_FLASH_SFDP_SUPPORT=y +CONFIG_SPI_FLASH_GIGADEVICE=y +CONFIG_SPI_FLASH_ISSI=y +CONFIG_SPI_FLASH_MACRONIX=y +CONFIG_SPI_FLASH_SPANSION=y +CONFIG_SPI_FLASH_STMICRO=y +CONFIG_SPI_FLASH_SST=y +CONFIG_SPI_FLASH_WINBOND=y +# CONFIG_SPI_FLASH_USE_4K_SECTORS is not set CONFIG_PHY_REALTEK=y CONFIG_DM_MDIO=y CONFIG_FTGMAC100=y @@ -98,6 +108,9 @@ CONFIG_SPL_RAM=y CONFIG_DM_RESET=y CONFIG_DM_SERIAL=y CONFIG_SYS_NS16550=y +CONFIG_SPI=y +CONFIG_DM_SPI=y +CONFIG_SPI_ASPEED_SMC=y CONFIG_SYSRESET=y CONFIG_SPL_SYSRESET=y CONFIG_WDT=y From 5150e908f54c3bd0fdd30eefdffaf49c826881ba Mon Sep 17 00:00:00 2001 From: Chin-Ting Kuo Date: Fri, 19 Aug 2022 17:01:06 +0800 Subject: [PATCH 105/374] spi: aspeed: Support AST2400 platform Although AST2400 is EOL officially, in order to achieve sustainability and completeness, AST2400 part is added. For AST2400, - Five CSs are supported by FMC controller. - SPI1 controller only supports single CS and there is no address segment address register. The CE control register of SPI1 is located at the offset 0x04 and the 4-byte address mode control bit is bit 13 of this register. Signed-off-by: Chin-Ting Kuo --- drivers/spi/spi-aspeed-smc.c | 105 ++++++++++++++++++++++++++++++++--- 1 file changed, 98 insertions(+), 7 deletions(-) diff --git a/drivers/spi/spi-aspeed-smc.c b/drivers/spi/spi-aspeed-smc.c index 25b490bcf4..f858d36023 100644 --- a/drivers/spi/spi-aspeed-smc.c +++ b/drivers/spi/spi-aspeed-smc.c @@ -26,7 +26,7 @@ #include #include -#define ASPEED_SPI_MAX_CS 3 +#define ASPEED_SPI_MAX_CS 5 #define CTRL_IO_SINGLE_DATA 0 #define CTRL_IO_QUAD_DATA BIT(30) @@ -42,10 +42,10 @@ struct aspeed_spi_regs { u32 ctrl; /* 0x04 CE Control */ u32 intr_ctrl; /* 0x08 Interrupt Control and Status */ u32 cmd_ctrl; /* 0x0c Command Control */ - u32 ce_ctrl[ASPEED_SPI_MAX_CS]; /* 0x10 .. 0x18 CEx Control */ - u32 _reserved0[5]; /* .. */ - u32 segment_addr[ASPEED_SPI_MAX_CS]; /* 0x30 .. 0x38 Segment Address */ - u32 _reserved1[5]; /* .. */ + u32 ce_ctrl[ASPEED_SPI_MAX_CS]; /* 0x10 .. 0x20 CEx Control */ + u32 _reserved0[3]; /* .. */ + u32 segment_addr[ASPEED_SPI_MAX_CS]; /* 0x30 .. 0x40 Segment Address */ + u32 _reserved1[3]; /* .. */ u32 soft_rst_cmd_ctrl; /* 0x50 Auto Soft-Reset Command Control */ u32 _reserved2[11]; /* .. */ u32 dma_ctrl; /* 0x80 DMA Control/Status */ @@ -86,6 +86,8 @@ struct aspeed_spi_info { u32 (*segment_reg)(u32 start, u32 end); }; +static const struct aspeed_spi_info ast2400_spi_info; + static u32 aspeed_spi_get_io_mode(u32 bus_width) { switch (bus_width) { @@ -101,6 +103,56 @@ static u32 aspeed_spi_get_io_mode(u32 bus_width) } } +static u32 ast2400_spi_segment_start(struct udevice *bus, u32 reg) +{ + struct aspeed_spi_plat *plat = dev_get_plat(bus); + u32 start_offset = ((reg >> 16) & 0xff) << 23; + + if (start_offset == 0) + return (u32)plat->ahb_base; + + return (u32)plat->ahb_base + start_offset; +} + +static u32 ast2400_spi_segment_end(struct udevice *bus, u32 reg) +{ + struct aspeed_spi_plat *plat = dev_get_plat(bus); + u32 end_offset = ((reg >> 24) & 0xff) << 23; + + /* Meaningless end_offset, set to physical ahb base. */ + if (end_offset == 0) + return (u32)plat->ahb_base; + + return (u32)plat->ahb_base + end_offset; +} + +static u32 ast2400_spi_segment_reg(u32 start, u32 end) +{ + if (start == end) + return 0; + + return ((((start) >> 23) & 0xff) << 16) | ((((end) >> 23) & 0xff) << 24); +} + +static void ast2400_fmc_chip_set_4byte(struct udevice *bus, u32 cs) +{ + struct aspeed_spi_priv *priv = dev_get_priv(bus); + u32 reg_val; + + reg_val = readl(&priv->regs->ctrl); + reg_val |= 0x1 << cs; + writel(reg_val, &priv->regs->ctrl); +} + +static void ast2400_spi_chip_set_4byte(struct udevice *bus, u32 cs) +{ + struct aspeed_spi_priv *priv = dev_get_priv(bus); + struct aspeed_spi_flash *flash = &priv->flashes[cs]; + + flash->ce_ctrl_read |= BIT(13); + writel(flash->ce_ctrl_read, &priv->regs->ctrl); +} + static u32 ast2500_spi_segment_start(struct udevice *bus, u32 reg) { struct aspeed_spi_plat *plat = dev_get_plat(bus); @@ -272,6 +324,9 @@ static int aspeed_spi_exec_op_user_mode(struct spi_slave *slave, op->addr.buswidth, op->dummy.nbytes, op->dummy.buswidth, op->data.nbytes, op->data.buswidth); + if (priv->info == &ast2400_spi_info) + ce_ctrl_reg = (u32)&priv->regs->ctrl; + /* * Set controller to 4-byte address mode * if flash is in 4-byte address mode. @@ -404,8 +459,12 @@ static int aspeed_spi_ctrl_init(struct udevice *bus) /* Enable write capability for all CS. */ reg_val = readl(&priv->regs->conf); - writel(reg_val | (GENMASK(plat->max_cs - 1, 0) << 16), - &priv->regs->conf); + if (priv->info == &ast2400_spi_info) { + writel(reg_val | BIT(0), &priv->regs->conf); + } else { + writel(reg_val | (GENMASK(plat->max_cs - 1, 0) << 16), + &priv->regs->conf); + } memset(priv->flashes, 0x0, sizeof(struct aspeed_spi_flash) * ASPEED_SPI_MAX_CS); @@ -416,6 +475,16 @@ static int aspeed_spi_ctrl_init(struct udevice *bus) (CTRL_STOP_ACTIVE | CTRL_IO_MODE_USER); } + /* + * SPI1 on AST2400 only supports CS0. + * It is unnecessary to configure segment address register. + */ + if (priv->info == &ast2400_spi_info) { + priv->flashes[cs].ahb_base = plat->ahb_base; + priv->flashes[cs].ahb_decoded_sz = 0x10000000; + return 0; + } + /* Assign basic AHB decoded size for each CS. */ for (cs = 0; cs < plat->max_cs; cs++) { reg_val = readl(&priv->regs->segment_addr[cs]); @@ -433,6 +502,26 @@ static int aspeed_spi_ctrl_init(struct udevice *bus) return ret; } +static const struct aspeed_spi_info ast2400_fmc_info = { + .io_mode_mask = 0x70000000, + .max_bus_width = 2, + .min_decoded_sz = 0x800000, + .set_4byte = ast2400_fmc_chip_set_4byte, + .segment_start = ast2400_spi_segment_start, + .segment_end = ast2400_spi_segment_end, + .segment_reg = ast2400_spi_segment_reg, +}; + +static const struct aspeed_spi_info ast2400_spi_info = { + .io_mode_mask = 0x70000000, + .max_bus_width = 2, + .min_decoded_sz = 0x800000, + .set_4byte = ast2400_spi_chip_set_4byte, + .segment_start = ast2400_spi_segment_start, + .segment_end = ast2400_spi_segment_end, + .segment_reg = ast2400_spi_segment_reg, +}; + static const struct aspeed_spi_info ast2500_fmc_info = { .io_mode_mask = 0x70000000, .max_bus_width = 2, @@ -584,6 +673,8 @@ static const struct dm_spi_ops aspeed_spi_ops = { }; static const struct udevice_id aspeed_spi_ids[] = { + { .compatible = "aspeed,ast2400-fmc", .data = (ulong)&ast2400_fmc_info, }, + { .compatible = "aspeed,ast2400-spi", .data = (ulong)&ast2400_spi_info, }, { .compatible = "aspeed,ast2500-fmc", .data = (ulong)&ast2500_fmc_info, }, { .compatible = "aspeed,ast2500-spi", .data = (ulong)&ast2500_spi_info, }, { .compatible = "aspeed,ast2600-fmc", .data = (ulong)&ast2600_fmc_info, }, From d37b4f37ea40243ad3a126a152920339189afb52 Mon Sep 17 00:00:00 2001 From: Chin-Ting Kuo Date: Fri, 19 Aug 2022 17:01:07 +0800 Subject: [PATCH 106/374] arm: dts: aspeed: Update SPI flash node settings For both AST2500 and AST2600, there are three SPI controllers, FMC(Firmware Memory Controller), SPI1 and SPI2. The clock source is HCLK. Following is the basic information for ASPEED SPI controller. AST2500: - FMC: CS number: 3 controller reg: 0x1e620000 - 0x1e62ffff decoded address: 0x20000000 - 0x2fffffff - SPI1: CS number: 2 controller reg: 0x1e630000 - 0x1e630fff decoded address: 0x30000000 - 0x37ffffff - SPI2: CS number: 2 controller reg: 0x1e631000 - 0x1e631fff decoded address: 0x38000000 - 0x3fffffff AST2600: - FMC: CS number: 3 controller reg: 0x1e620000 - 0x1e62ffff decoded address: 0x20000000 - 0x2fffffff - SPI1: CS number: 2 controller reg: 0x1e630000 - 0x1e630fff decoded address: 0x30000000 - 0x3fffffff - SPI2: CS number: 3 controller reg: 0x1e631000 - 0x1e631fff decoded address: 0x50000000 - 0x5fffffff Signed-off-by: Chin-Ting Kuo --- arch/arm/dts/ast2500-evb.dts | 33 +++++++++++++++++++++++++++++++++ arch/arm/dts/ast2500.dtsi | 23 ++++++++++++++++------- arch/arm/dts/ast2600-evb.dts | 8 -------- arch/arm/dts/ast2600.dtsi | 34 +++++++++++++++++++--------------- 4 files changed, 68 insertions(+), 30 deletions(-) diff --git a/arch/arm/dts/ast2500-evb.dts b/arch/arm/dts/ast2500-evb.dts index cc577761fa..1fbacf985f 100644 --- a/arch/arm/dts/ast2500-evb.dts +++ b/arch/arm/dts/ast2500-evb.dts @@ -78,6 +78,39 @@ pinctrl-0 = <&pinctrl_sd2_default>; }; +&fmc { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fwspics1_default>; + + flash@0 { + status = "okay"; + spi-max-frequency = <50000000>; + spi-tx-bus-width = <2>; + spi-rx-bus-width = <2>; + }; + + flash@1 { + status = "okay"; + spi-max-frequency = <50000000>; + spi-tx-bus-width = <2>; + spi-rx-bus-width = <2>; + }; +}; + +&spi1 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_spi1cs1_default>; + + flash@0 { + status = "okay"; + spi-max-frequency = <50000000>; + spi-tx-bus-width = <2>; + spi-rx-bus-width = <2>; + }; +}; + &i2c3 { status = "okay"; diff --git a/arch/arm/dts/ast2500.dtsi b/arch/arm/dts/ast2500.dtsi index cea08e6f08..320d2e5340 100644 --- a/arch/arm/dts/ast2500.dtsi +++ b/arch/arm/dts/ast2500.dtsi @@ -57,23 +57,26 @@ ranges; fmc: flash-controller@1e620000 { - reg = < 0x1e620000 0xc4 - 0x20000000 0x10000000 >; + reg = <0x1e620000 0xc4>, <0x20000000 0x10000000>; #address-cells = <1>; #size-cells = <0>; compatible = "aspeed,ast2500-fmc"; + clocks = <&scu ASPEED_CLK_AHB>; + num-cs = <3>; status = "disabled"; - interrupts = <19>; + flash@0 { reg = < 0 >; compatible = "jedec,spi-nor"; status = "disabled"; }; + flash@1 { reg = < 1 >; compatible = "jedec,spi-nor"; status = "disabled"; }; + flash@2 { reg = < 2 >; compatible = "jedec,spi-nor"; @@ -82,17 +85,20 @@ }; spi1: flash-controller@1e630000 { - reg = < 0x1e630000 0xc4 - 0x30000000 0x08000000 >; + reg = <0x1e630000 0xc4>, <0x30000000 0x08000000>; #address-cells = <1>; #size-cells = <0>; compatible = "aspeed,ast2500-spi"; + clocks = <&scu ASPEED_CLK_AHB>; + num-cs = <2>; status = "disabled"; + flash@0 { reg = < 0 >; compatible = "jedec,spi-nor"; status = "disabled"; }; + flash@1 { reg = < 1 >; compatible = "jedec,spi-nor"; @@ -101,17 +107,20 @@ }; spi2: flash-controller@1e631000 { - reg = < 0x1e631000 0xc4 - 0x38000000 0x08000000 >; + reg = <0x1e631000 0xc4>, <0x38000000 0x08000000>; #address-cells = <1>; #size-cells = <0>; compatible = "aspeed,ast2500-spi"; + clocks = <&scu ASPEED_CLK_AHB>; + num-cs = <2>; status = "disabled"; + flash@0 { reg = < 0 >; compatible = "jedec,spi-nor"; status = "disabled"; }; + flash@1 { reg = < 1 >; compatible = "jedec,spi-nor"; diff --git a/arch/arm/dts/ast2600-evb.dts b/arch/arm/dts/ast2600-evb.dts index a9bba96816..a097f320e4 100644 --- a/arch/arm/dts/ast2600-evb.dts +++ b/arch/arm/dts/ast2600-evb.dts @@ -72,12 +72,10 @@ &fmc { status = "okay"; - pinctrl-names = "default"; pinctrl-0 = <&pinctrl_fmcquad_default>; flash@0 { - compatible = "spi-flash", "sst,w25q256"; status = "okay"; spi-max-frequency = <50000000>; spi-tx-bus-width = <4>; @@ -85,7 +83,6 @@ }; flash@1 { - compatible = "spi-flash", "sst,w25q256"; status = "okay"; spi-max-frequency = <50000000>; spi-tx-bus-width = <4>; @@ -93,7 +90,6 @@ }; flash@2 { - compatible = "spi-flash", "sst,w25q256"; status = "okay"; spi-max-frequency = <50000000>; spi-tx-bus-width = <4>; @@ -103,14 +99,12 @@ &spi1 { status = "okay"; - pinctrl-names = "default"; pinctrl-0 = <&pinctrl_spi1_default &pinctrl_spi1abr_default &pinctrl_spi1cs1_default &pinctrl_spi1wp_default &pinctrl_spi1wp_default &pinctrl_spi1quad_default>; flash@0 { - compatible = "spi-flash", "sst,w25q256"; status = "okay"; spi-max-frequency = <50000000>; spi-tx-bus-width = <4>; @@ -120,13 +114,11 @@ &spi2 { status = "okay"; - pinctrl-names = "default"; pinctrl-0 = <&pinctrl_spi2_default &pinctrl_spi2cs1_default &pinctrl_spi2cs2_default &pinctrl_spi2quad_default>; flash@0 { - compatible = "spi-flash", "sst,w25q256"; status = "okay"; spi-max-frequency = <50000000>; spi-tx-bus-width = <4>; diff --git a/arch/arm/dts/ast2600.dtsi b/arch/arm/dts/ast2600.dtsi index ac8cd4d67d..8d91eedc17 100644 --- a/arch/arm/dts/ast2600.dtsi +++ b/arch/arm/dts/ast2600.dtsi @@ -129,74 +129,78 @@ }; fmc: flash-controller@1e620000 { - reg = < 0x1e620000 0xc4 - 0x20000000 0x10000000 >; + reg = <0x1e620000 0xc4>, <0x20000000 0x10000000>; #address-cells = <1>; #size-cells = <0>; compatible = "aspeed,ast2600-fmc"; status = "disabled"; - interrupts = ; clocks = <&scu ASPEED_CLK_AHB>; num-cs = <3>; + flash@0 { - reg = < 0 >; + reg = <0>; compatible = "jedec,spi-nor"; status = "disabled"; }; + flash@1 { - reg = < 1 >; + reg = <1>; compatible = "jedec,spi-nor"; status = "disabled"; }; + flash@2 { - reg = < 2 >; + reg = <2>; compatible = "jedec,spi-nor"; status = "disabled"; }; }; spi1: flash-controller@1e630000 { - reg = < 0x1e630000 0xc4 - 0x30000000 0x08000000 >; + reg = <0x1e630000 0xc4>, <0x30000000 0x10000000>; #address-cells = <1>; #size-cells = <0>; compatible = "aspeed,ast2600-spi"; clocks = <&scu ASPEED_CLK_AHB>; num-cs = <2>; status = "disabled"; + flash@0 { - reg = < 0 >; + reg = <0>; compatible = "jedec,spi-nor"; status = "disabled"; }; + flash@1 { - reg = < 1 >; + reg = <1>; compatible = "jedec,spi-nor"; status = "disabled"; }; }; spi2: flash-controller@1e631000 { - reg = < 0x1e631000 0xc4 - 0x50000000 0x08000000 >; + reg = <0x1e631000 0xc4>, <0x50000000 0x10000000>; #address-cells = <1>; #size-cells = <0>; compatible = "aspeed,ast2600-spi"; clocks = <&scu ASPEED_CLK_AHB>; num-cs = <3>; status = "disabled"; + flash@0 { - reg = < 0 >; + reg = <0>; compatible = "jedec,spi-nor"; status = "disabled"; }; + flash@1 { - reg = < 1 >; + reg = <1>; compatible = "jedec,spi-nor"; status = "disabled"; }; + flash@2 { - reg = < 2 >; + reg = <2>; compatible = "jedec,spi-nor"; status = "disabled"; }; From f7e1de4c6a43beec438bce04571469145086efed Mon Sep 17 00:00:00 2001 From: Chin-Ting Kuo Date: Fri, 19 Aug 2022 17:01:08 +0800 Subject: [PATCH 107/374] spi-mem: Add dirmap API from Linux This adds the dirmap API originally introduced in Linux commit aa167f3fed0c ("spi: spi-mem: Add a new API to support direct mapping"). This also includes several follow-up patches and fixes. Changes from Linux include: * Added Kconfig option * Changed struct device to struct udevice * Changed struct spi_mem to struct spi_slave This patch is obtained from the following patch https://patchwork.ozlabs.org/project/uboot/patch/20210205043924.149504-3-seanga2@gmail.com/ The corresponding Linux kernel SHA1 is aa167f3fed0c. Signed-off-by: Chin-Ting Kuo Signed-off-by: Sean Anderson Acked-by: Pratyush Yadav --- drivers/spi/Kconfig | 10 ++ drivers/spi/spi-mem.c | 268 ++++++++++++++++++++++++++++++++++++++++++ include/spi-mem.h | 79 +++++++++++++ 3 files changed, 357 insertions(+) diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index 8ca9274ef4..ac91d82258 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -40,6 +40,16 @@ config SPI_MEM This extension is meant to simplify interaction with SPI memories by providing an high-level interface to send memory-like commands. +config SPI_DIRMAP + bool "SPI direct mapping" + depends on SPI_MEM + help + Enable the SPI direct mapping API. Most modern SPI controllers can + directly map a SPI memory (or a portion of the SPI memory) in the CPU + address space. Most of the time this brings significant performance + improvements as it automates the whole process of sending SPI memory + operations every time a new region is accessed. + if DM_SPI config ALTERA_SPI diff --git a/drivers/spi/spi-mem.c b/drivers/spi/spi-mem.c index 9c1ede1b61..8e8995fc53 100644 --- a/drivers/spi/spi-mem.c +++ b/drivers/spi/spi-mem.c @@ -21,6 +21,8 @@ #include #include #include +#include +#include #endif #ifndef __UBOOT__ @@ -491,6 +493,272 @@ int spi_mem_adjust_op_size(struct spi_slave *slave, struct spi_mem_op *op) } EXPORT_SYMBOL_GPL(spi_mem_adjust_op_size); +static ssize_t spi_mem_no_dirmap_read(struct spi_mem_dirmap_desc *desc, + u64 offs, size_t len, void *buf) +{ + struct spi_mem_op op = desc->info.op_tmpl; + int ret; + + op.addr.val = desc->info.offset + offs; + op.data.buf.in = buf; + op.data.nbytes = len; + ret = spi_mem_adjust_op_size(desc->slave, &op); + if (ret) + return ret; + + ret = spi_mem_exec_op(desc->slave, &op); + if (ret) + return ret; + + return op.data.nbytes; +} + +static ssize_t spi_mem_no_dirmap_write(struct spi_mem_dirmap_desc *desc, + u64 offs, size_t len, const void *buf) +{ + struct spi_mem_op op = desc->info.op_tmpl; + int ret; + + op.addr.val = desc->info.offset + offs; + op.data.buf.out = buf; + op.data.nbytes = len; + ret = spi_mem_adjust_op_size(desc->slave, &op); + if (ret) + return ret; + + ret = spi_mem_exec_op(desc->slave, &op); + if (ret) + return ret; + + return op.data.nbytes; +} + +/** + * spi_mem_dirmap_create() - Create a direct mapping descriptor + * @mem: SPI mem device this direct mapping should be created for + * @info: direct mapping information + * + * This function is creating a direct mapping descriptor which can then be used + * to access the memory using spi_mem_dirmap_read() or spi_mem_dirmap_write(). + * If the SPI controller driver does not support direct mapping, this function + * falls back to an implementation using spi_mem_exec_op(), so that the caller + * doesn't have to bother implementing a fallback on his own. + * + * Return: a valid pointer in case of success, and ERR_PTR() otherwise. + */ +struct spi_mem_dirmap_desc * +spi_mem_dirmap_create(struct spi_slave *slave, + const struct spi_mem_dirmap_info *info) +{ + struct udevice *bus = slave->dev->parent; + struct dm_spi_ops *ops = spi_get_ops(bus); + struct spi_mem_dirmap_desc *desc; + int ret = -EOPNOTSUPP; + + /* Make sure the number of address cycles is between 1 and 8 bytes. */ + if (!info->op_tmpl.addr.nbytes || info->op_tmpl.addr.nbytes > 8) + return ERR_PTR(-EINVAL); + + /* data.dir should either be SPI_MEM_DATA_IN or SPI_MEM_DATA_OUT. */ + if (info->op_tmpl.data.dir == SPI_MEM_NO_DATA) + return ERR_PTR(-EINVAL); + + desc = kzalloc(sizeof(*desc), GFP_KERNEL); + if (!desc) + return ERR_PTR(-ENOMEM); + + desc->slave = slave; + desc->info = *info; + if (ops->mem_ops && ops->mem_ops->dirmap_create) + ret = ops->mem_ops->dirmap_create(desc); + + if (ret) { + desc->nodirmap = true; + if (!spi_mem_supports_op(desc->slave, &desc->info.op_tmpl)) + ret = -EOPNOTSUPP; + else + ret = 0; + } + + if (ret) { + kfree(desc); + return ERR_PTR(ret); + } + + return desc; +} +EXPORT_SYMBOL_GPL(spi_mem_dirmap_create); + +/** + * spi_mem_dirmap_destroy() - Destroy a direct mapping descriptor + * @desc: the direct mapping descriptor to destroy + * + * This function destroys a direct mapping descriptor previously created by + * spi_mem_dirmap_create(). + */ +void spi_mem_dirmap_destroy(struct spi_mem_dirmap_desc *desc) +{ + struct udevice *bus = desc->slave->dev->parent; + struct dm_spi_ops *ops = spi_get_ops(bus); + + if (!desc->nodirmap && ops->mem_ops && ops->mem_ops->dirmap_destroy) + ops->mem_ops->dirmap_destroy(desc); + + kfree(desc); +} +EXPORT_SYMBOL_GPL(spi_mem_dirmap_destroy); + +#ifndef __UBOOT__ +static void devm_spi_mem_dirmap_release(struct udevice *dev, void *res) +{ + struct spi_mem_dirmap_desc *desc = *(struct spi_mem_dirmap_desc **)res; + + spi_mem_dirmap_destroy(desc); +} + +/** + * devm_spi_mem_dirmap_create() - Create a direct mapping descriptor and attach + * it to a device + * @dev: device the dirmap desc will be attached to + * @mem: SPI mem device this direct mapping should be created for + * @info: direct mapping information + * + * devm_ variant of the spi_mem_dirmap_create() function. See + * spi_mem_dirmap_create() for more details. + * + * Return: a valid pointer in case of success, and ERR_PTR() otherwise. + */ +struct spi_mem_dirmap_desc * +devm_spi_mem_dirmap_create(struct udevice *dev, struct spi_slave *slave, + const struct spi_mem_dirmap_info *info) +{ + struct spi_mem_dirmap_desc **ptr, *desc; + + ptr = devres_alloc(devm_spi_mem_dirmap_release, sizeof(*ptr), + GFP_KERNEL); + if (!ptr) + return ERR_PTR(-ENOMEM); + + desc = spi_mem_dirmap_create(slave, info); + if (IS_ERR(desc)) { + devres_free(ptr); + } else { + *ptr = desc; + devres_add(dev, ptr); + } + + return desc; +} +EXPORT_SYMBOL_GPL(devm_spi_mem_dirmap_create); + +static int devm_spi_mem_dirmap_match(struct udevice *dev, void *res, void *data) +{ + struct spi_mem_dirmap_desc **ptr = res; + + if (WARN_ON(!ptr || !*ptr)) + return 0; + + return *ptr == data; +} + +/** + * devm_spi_mem_dirmap_destroy() - Destroy a direct mapping descriptor attached + * to a device + * @dev: device the dirmap desc is attached to + * @desc: the direct mapping descriptor to destroy + * + * devm_ variant of the spi_mem_dirmap_destroy() function. See + * spi_mem_dirmap_destroy() for more details. + */ +void devm_spi_mem_dirmap_destroy(struct udevice *dev, + struct spi_mem_dirmap_desc *desc) +{ + devres_release(dev, devm_spi_mem_dirmap_release, + devm_spi_mem_dirmap_match, desc); +} +EXPORT_SYMBOL_GPL(devm_spi_mem_dirmap_destroy); +#endif /* __UBOOT__ */ + +/** + * spi_mem_dirmap_read() - Read data through a direct mapping + * @desc: direct mapping descriptor + * @offs: offset to start reading from. Note that this is not an absolute + * offset, but the offset within the direct mapping which already has + * its own offset + * @len: length in bytes + * @buf: destination buffer. This buffer must be DMA-able + * + * This function reads data from a memory device using a direct mapping + * previously instantiated with spi_mem_dirmap_create(). + * + * Return: the amount of data read from the memory device or a negative error + * code. Note that the returned size might be smaller than @len, and the caller + * is responsible for calling spi_mem_dirmap_read() again when that happens. + */ +ssize_t spi_mem_dirmap_read(struct spi_mem_dirmap_desc *desc, + u64 offs, size_t len, void *buf) +{ + struct udevice *bus = desc->slave->dev->parent; + struct dm_spi_ops *ops = spi_get_ops(bus); + ssize_t ret; + + if (desc->info.op_tmpl.data.dir != SPI_MEM_DATA_IN) + return -EINVAL; + + if (!len) + return 0; + + if (desc->nodirmap) + ret = spi_mem_no_dirmap_read(desc, offs, len, buf); + else if (ops->mem_ops && ops->mem_ops->dirmap_read) + ret = ops->mem_ops->dirmap_read(desc, offs, len, buf); + else + ret = -EOPNOTSUPP; + + return ret; +} +EXPORT_SYMBOL_GPL(spi_mem_dirmap_read); + +/** + * spi_mem_dirmap_write() - Write data through a direct mapping + * @desc: direct mapping descriptor + * @offs: offset to start writing from. Note that this is not an absolute + * offset, but the offset within the direct mapping which already has + * its own offset + * @len: length in bytes + * @buf: source buffer. This buffer must be DMA-able + * + * This function writes data to a memory device using a direct mapping + * previously instantiated with spi_mem_dirmap_create(). + * + * Return: the amount of data written to the memory device or a negative error + * code. Note that the returned size might be smaller than @len, and the caller + * is responsible for calling spi_mem_dirmap_write() again when that happens. + */ +ssize_t spi_mem_dirmap_write(struct spi_mem_dirmap_desc *desc, + u64 offs, size_t len, const void *buf) +{ + struct udevice *bus = desc->slave->dev->parent; + struct dm_spi_ops *ops = spi_get_ops(bus); + ssize_t ret; + + if (desc->info.op_tmpl.data.dir != SPI_MEM_DATA_OUT) + return -EINVAL; + + if (!len) + return 0; + + if (desc->nodirmap) + ret = spi_mem_no_dirmap_write(desc, offs, len, buf); + else if (ops->mem_ops && ops->mem_ops->dirmap_write) + ret = ops->mem_ops->dirmap_write(desc, offs, len, buf); + else + ret = -EOPNOTSUPP; + + return ret; +} +EXPORT_SYMBOL_GPL(spi_mem_dirmap_write); + #ifndef __UBOOT__ static inline struct spi_mem_driver *to_spi_mem_drv(struct device_driver *drv) { diff --git a/include/spi-mem.h b/include/spi-mem.h index 32ffdc2e0f..b07cf2ed83 100644 --- a/include/spi-mem.h +++ b/include/spi-mem.h @@ -134,6 +134,48 @@ struct spi_mem_op { .dummy = __dummy, \ .data = __data, \ } +/** + * struct spi_mem_dirmap_info - Direct mapping information + * @op_tmpl: operation template that should be used by the direct mapping when + * the memory device is accessed + * @offset: absolute offset this direct mapping is pointing to + * @length: length in byte of this direct mapping + * + * This information is used by the controller specific implementation to know + * the portion of memory that is directly mapped and the spi_mem_op that should + * be used to access the device. + * A direct mapping is only valid for one direction (read or write) and this + * direction is directly encoded in the ->op_tmpl.data.dir field. + */ +struct spi_mem_dirmap_info { + struct spi_mem_op op_tmpl; + u64 offset; + u64 length; +}; + +/** + * struct spi_mem_dirmap_desc - Direct mapping descriptor + * @mem: the SPI memory device this direct mapping is attached to + * @info: information passed at direct mapping creation time + * @nodirmap: set to 1 if the SPI controller does not implement + * ->mem_ops->dirmap_create() or when this function returned an + * error. If @nodirmap is true, all spi_mem_dirmap_{read,write}() + * calls will use spi_mem_exec_op() to access the memory. This is a + * degraded mode that allows spi_mem drivers to use the same code + * no matter whether the controller supports direct mapping or not + * @priv: field pointing to controller specific data + * + * Common part of a direct mapping descriptor. This object is created by + * spi_mem_dirmap_create() and controller implementation of ->create_dirmap() + * can create/attach direct mapping resources to the descriptor in the ->priv + * field. + */ +struct spi_mem_dirmap_desc { + struct spi_slave *slave; + struct spi_mem_dirmap_info info; + unsigned int nodirmap; + void *priv; +}; #ifndef __UBOOT__ /** @@ -183,10 +225,32 @@ static inline void *spi_mem_get_drvdata(struct spi_mem *mem) * limitations) * @supports_op: check if an operation is supported by the controller * @exec_op: execute a SPI memory operation + * @dirmap_create: create a direct mapping descriptor that can later be used to + * access the memory device. This method is optional + * @dirmap_destroy: destroy a memory descriptor previous created by + * ->dirmap_create() + * @dirmap_read: read data from the memory device using the direct mapping + * created by ->dirmap_create(). The function can return less + * data than requested (for example when the request is crossing + * the currently mapped area), and the caller of + * spi_mem_dirmap_read() is responsible for calling it again in + * this case. + * @dirmap_write: write data to the memory device using the direct mapping + * created by ->dirmap_create(). The function can return less + * data than requested (for example when the request is crossing + * the currently mapped area), and the caller of + * spi_mem_dirmap_write() is responsible for calling it again in + * this case. * * This interface should be implemented by SPI controllers providing an * high-level interface to execute SPI memory operation, which is usually the * case for QSPI controllers. + * + * Note on ->dirmap_{read,write}(): drivers should avoid accessing the direct + * mapping from the CPU because doing that can stall the CPU waiting for the + * SPI mem transaction to finish, and this will make real-time maintainers + * unhappy and might make your system less reactive. Instead, drivers should + * use DMA to access this direct mapping. */ struct spi_controller_mem_ops { int (*adjust_op_size)(struct spi_slave *slave, struct spi_mem_op *op); @@ -194,6 +258,12 @@ struct spi_controller_mem_ops { const struct spi_mem_op *op); int (*exec_op)(struct spi_slave *slave, const struct spi_mem_op *op); + int (*dirmap_create)(struct spi_mem_dirmap_desc *desc); + void (*dirmap_destroy)(struct spi_mem_dirmap_desc *desc); + ssize_t (*dirmap_read)(struct spi_mem_dirmap_desc *desc, + u64 offs, size_t len, void *buf); + ssize_t (*dirmap_write)(struct spi_mem_dirmap_desc *desc, + u64 offs, size_t len, const void *buf); }; #ifndef __UBOOT__ @@ -260,6 +330,15 @@ int spi_mem_exec_op(struct spi_slave *slave, const struct spi_mem_op *op); bool spi_mem_default_supports_op(struct spi_slave *mem, const struct spi_mem_op *op); +struct spi_mem_dirmap_desc * +spi_mem_dirmap_create(struct spi_slave *mem, + const struct spi_mem_dirmap_info *info); +void spi_mem_dirmap_destroy(struct spi_mem_dirmap_desc *desc); +ssize_t spi_mem_dirmap_read(struct spi_mem_dirmap_desc *desc, + u64 offs, size_t len, void *buf); +ssize_t spi_mem_dirmap_write(struct spi_mem_dirmap_desc *desc, + u64 offs, size_t len, const void *buf); + #ifndef __UBOOT__ int spi_mem_driver_register_with_owner(struct spi_mem_driver *drv, struct module *owner); From 463cdf66632a0d67bf824cb43b6c1b41782d0765 Mon Sep 17 00:00:00 2001 From: Chin-Ting Kuo Date: Fri, 19 Aug 2022 17:01:09 +0800 Subject: [PATCH 108/374] mtd: spi-nor: Use spi-mem dirmap API This adds support for the dirmap API to the spi-nor subsystem, as introduced in Linux commit df5c21002cf4 ("mtd: spi-nor: use spi-mem dirmap API"). This patch is synchronize from the following patch https://patchwork.ozlabs.org/project/uboot/patch/20210205043924.149504-4-seanga2@gmail.com/ The corresponding Linux kernel SHA1 is df5c21002cf4. Signed-off-by: Chin-Ting Kuo Signed-off-by: Sean Anderson Acked-by: Pratyush Yadav --- drivers/mtd/spi/sf_probe.c | 76 ++++++++++++++++++++++++++++++++++ drivers/mtd/spi/spi-nor-core.c | 55 +++++++++++++++++------- include/linux/mtd/spi-nor.h | 18 ++++++++ 3 files changed, 133 insertions(+), 16 deletions(-) diff --git a/drivers/mtd/spi/sf_probe.c b/drivers/mtd/spi/sf_probe.c index f461082e03..e192f97efd 100644 --- a/drivers/mtd/spi/sf_probe.c +++ b/drivers/mtd/spi/sf_probe.c @@ -10,13 +10,69 @@ #include #include #include +#include #include #include #include #include +#include #include "sf_internal.h" +static int spi_nor_create_read_dirmap(struct spi_nor *nor) +{ + struct spi_mem_dirmap_info info = { + .op_tmpl = SPI_MEM_OP(SPI_MEM_OP_CMD(nor->read_opcode, 0), + SPI_MEM_OP_ADDR(nor->addr_width, 0, 0), + SPI_MEM_OP_DUMMY(nor->read_dummy, 0), + SPI_MEM_OP_DATA_IN(0, NULL, 0)), + .offset = 0, + .length = nor->mtd.size, + }; + struct spi_mem_op *op = &info.op_tmpl; + + /* get transfer protocols. */ + spi_nor_setup_op(nor, op, nor->read_proto); + op->data.buswidth = spi_nor_get_protocol_data_nbits(nor->read_proto); + + /* convert the dummy cycles to the number of bytes */ + op->dummy.nbytes = (nor->read_dummy * op->dummy.buswidth) / 8; + if (spi_nor_protocol_is_dtr(nor->read_proto)) + op->dummy.nbytes *= 2; + + nor->dirmap.rdesc = spi_mem_dirmap_create(nor->spi, &info); + if (IS_ERR(nor->dirmap.rdesc)) + return PTR_ERR(nor->dirmap.rdesc); + + return 0; +} + +static int spi_nor_create_write_dirmap(struct spi_nor *nor) +{ + struct spi_mem_dirmap_info info = { + .op_tmpl = SPI_MEM_OP(SPI_MEM_OP_CMD(nor->program_opcode, 0), + SPI_MEM_OP_ADDR(nor->addr_width, 0, 0), + SPI_MEM_OP_NO_DUMMY, + SPI_MEM_OP_DATA_OUT(0, NULL, 0)), + .offset = 0, + .length = nor->mtd.size, + }; + struct spi_mem_op *op = &info.op_tmpl; + + /* get transfer protocols. */ + spi_nor_setup_op(nor, op, nor->write_proto); + op->data.buswidth = spi_nor_get_protocol_data_nbits(nor->write_proto); + + if (nor->program_opcode == SPINOR_OP_AAI_WP && nor->sst_write_second) + op->addr.nbytes = 0; + + nor->dirmap.wdesc = spi_mem_dirmap_create(nor->spi, &info); + if (IS_ERR(nor->dirmap.wdesc)) + return PTR_ERR(nor->dirmap.wdesc); + + return 0; +} + /** * spi_flash_probe_slave() - Probe for a SPI flash device on a bus * @@ -45,6 +101,16 @@ static int spi_flash_probe_slave(struct spi_flash *flash) if (ret) goto err_read_id; + if (CONFIG_IS_ENABLED(SPI_DIRMAP)) { + ret = spi_nor_create_read_dirmap(flash); + if (ret) + return ret; + + ret = spi_nor_create_write_dirmap(flash); + if (ret) + return ret; + } + if (CONFIG_IS_ENABLED(SPI_FLASH_MTD)) ret = spi_flash_mtd_register(flash); @@ -83,6 +149,11 @@ struct spi_flash *spi_flash_probe(unsigned int busnum, unsigned int cs, void spi_flash_free(struct spi_flash *flash) { + if (CONFIG_IS_ENABLED(SPI_DIRMAP)) { + spi_mem_dirmap_destroy(flash->dirmap.wdesc); + spi_mem_dirmap_destroy(flash->dirmap.rdesc); + } + if (CONFIG_IS_ENABLED(SPI_FLASH_MTD)) spi_flash_mtd_unregister(flash); @@ -153,6 +224,11 @@ static int spi_flash_std_remove(struct udevice *dev) struct spi_flash *flash = dev_get_uclass_priv(dev); int ret; + if (CONFIG_IS_ENABLED(SPI_DIRMAP)) { + spi_mem_dirmap_destroy(flash->dirmap.wdesc); + spi_mem_dirmap_destroy(flash->dirmap.rdesc); + } + ret = spi_nor_remove(flash); if (ret) return ret; diff --git a/drivers/mtd/spi/spi-nor-core.c b/drivers/mtd/spi/spi-nor-core.c index e3c86e080a..f236e87510 100644 --- a/drivers/mtd/spi/spi-nor-core.c +++ b/drivers/mtd/spi/spi-nor-core.c @@ -246,9 +246,9 @@ static u8 spi_nor_get_cmd_ext(const struct spi_nor *nor, * need to be initialized. * @proto: the protocol from which the properties need to be set. */ -static void spi_nor_setup_op(const struct spi_nor *nor, - struct spi_mem_op *op, - const enum spi_nor_protocol proto) +void spi_nor_setup_op(const struct spi_nor *nor, + struct spi_mem_op *op, + const enum spi_nor_protocol proto) { u8 ext; @@ -369,13 +369,29 @@ static ssize_t spi_nor_read_data(struct spi_nor *nor, loff_t from, size_t len, while (remaining) { op.data.nbytes = remaining < UINT_MAX ? remaining : UINT_MAX; - ret = spi_mem_adjust_op_size(nor->spi, &op); - if (ret) - return ret; - ret = spi_mem_exec_op(nor->spi, &op); - if (ret) - return ret; + if (CONFIG_IS_ENABLED(SPI_DIRMAP) && nor->dirmap.rdesc) { + /* + * Record current operation information which may be used + * when the address or data length exceeds address mapping. + */ + memcpy(&nor->dirmap.rdesc->info.op_tmpl, &op, + sizeof(struct spi_mem_op)); + ret = spi_mem_dirmap_read(nor->dirmap.rdesc, + op.addr.val, op.data.nbytes, + op.data.buf.in); + if (ret < 0) + return ret; + op.data.nbytes = ret; + } else { + ret = spi_mem_adjust_op_size(nor->spi, &op); + if (ret) + return ret; + + ret = spi_mem_exec_op(nor->spi, &op); + if (ret) + return ret; + } op.addr.val += op.data.nbytes; remaining -= op.data.nbytes; @@ -400,14 +416,21 @@ static ssize_t spi_nor_write_data(struct spi_nor *nor, loff_t to, size_t len, spi_nor_setup_op(nor, &op, nor->write_proto); - ret = spi_mem_adjust_op_size(nor->spi, &op); - if (ret) - return ret; - op.data.nbytes = len < op.data.nbytes ? len : op.data.nbytes; + if (CONFIG_IS_ENABLED(SPI_DIRMAP) && nor->dirmap.wdesc) { + memcpy(&nor->dirmap.wdesc->info.op_tmpl, &op, + sizeof(struct spi_mem_op)); + op.data.nbytes = spi_mem_dirmap_write(nor->dirmap.wdesc, op.addr.val, + op.data.nbytes, op.data.buf.out); + } else { + ret = spi_mem_adjust_op_size(nor->spi, &op); + if (ret) + return ret; + op.data.nbytes = len < op.data.nbytes ? len : op.data.nbytes; - ret = spi_mem_exec_op(nor->spi, &op); - if (ret) - return ret; + ret = spi_mem_exec_op(nor->spi, &op); + if (ret) + return ret; + } return op.data.nbytes; } diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h index 2595bad9df..638d807ee5 100644 --- a/include/linux/mtd/spi-nor.h +++ b/include/linux/mtd/spi-nor.h @@ -11,6 +11,7 @@ #include #include #include +#include /* * Manufacturer IDs @@ -522,6 +523,7 @@ struct spi_flash { * @quad_enable: [FLASH-SPECIFIC] enables SPI NOR quad mode * @octal_dtr_enable: [FLASH-SPECIFIC] enables SPI NOR octal DTR mode. * @ready: [FLASH-SPECIFIC] check if the flash is ready + * @dirmap: pointers to struct spi_mem_dirmap_desc for reads/writes. * @priv: the private data */ struct spi_nor { @@ -572,6 +574,11 @@ struct spi_nor { int (*octal_dtr_enable)(struct spi_nor *nor); int (*ready)(struct spi_nor *nor); + struct { + struct spi_mem_dirmap_desc *rdesc; + struct spi_mem_dirmap_desc *wdesc; + } dirmap; + void *priv; char mtd_name[MTD_NAME_SIZE(MTD_DEV_TYPE_NOR)]; /* Compatibility for spi_flash, remove once sf layer is merged with mtd */ @@ -595,6 +602,17 @@ device_node *spi_nor_get_flash_node(struct spi_nor *nor) } #endif /* __UBOOT__ */ +/** + * spi_nor_setup_op() - Set up common properties of a spi-mem op. + * @nor: pointer to a 'struct spi_nor' + * @op: pointer to the 'struct spi_mem_op' whose properties + * need to be initialized. + * @proto: the protocol from which the properties need to be set. + */ +void spi_nor_setup_op(const struct spi_nor *nor, + struct spi_mem_op *op, + const enum spi_nor_protocol proto); + /** * spi_nor_scan() - scan the SPI NOR * @nor: the spi_nor structure From 992d02ea737895dc67246bbf7065084bb2721d6b Mon Sep 17 00:00:00 2001 From: Chin-Ting Kuo Date: Fri, 19 Aug 2022 17:01:10 +0800 Subject: [PATCH 109/374] spi: aspeed: SPI dirmap read support From the HW point of view, the performance of command read mode is greater than user mode slightly. Thus, dirmap read framework is introduced to achieve this goal. In dirmap_create, command read mode is configured. Usually, the decoded address area with flash size is assigned to each CS. CPU can thus access the SPI flash as normal memory in dirmap_read function. Signed-off-by: Chin-Ting Kuo --- drivers/spi/spi-aspeed-smc.c | 88 ++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) diff --git a/drivers/spi/spi-aspeed-smc.c b/drivers/spi/spi-aspeed-smc.c index f858d36023..6099b85255 100644 --- a/drivers/spi/spi-aspeed-smc.c +++ b/drivers/spi/spi-aspeed-smc.c @@ -87,6 +87,7 @@ struct aspeed_spi_info { }; static const struct aspeed_spi_info ast2400_spi_info; +static int aspeed_spi_decoded_range_config(struct udevice *bus); static u32 aspeed_spi_get_io_mode(u32 bus_width) { @@ -381,6 +382,91 @@ static int aspeed_spi_exec_op_user_mode(struct spi_slave *slave, return 0; } +static int aspeed_spi_dirmap_create(struct spi_mem_dirmap_desc *desc) +{ + int ret = 0; + struct udevice *dev = desc->slave->dev; + struct udevice *bus = dev->parent; + struct aspeed_spi_priv *priv = dev_get_priv(bus); + struct dm_spi_slave_plat *slave_plat = dev_get_parent_plat(dev); + const struct aspeed_spi_info *info = priv->info; + struct spi_mem_op op_tmpl = desc->info.op_tmpl; + u32 i; + u32 cs = slave_plat->cs; + u32 reg_val; + u32 ce_ctrl_reg; + + if (desc->info.op_tmpl.data.dir == SPI_MEM_DATA_OUT) { + /* + * dirmap_write is not supported currently due to a HW + * limitation for command write mode: The written data + * length should be multiple of 4-byte. + */ + return -EOPNOTSUPP; + } + + ce_ctrl_reg = (u32)&priv->regs->ce_ctrl[cs]; + if (info == &ast2400_spi_info) + ce_ctrl_reg = (u32)&priv->regs->ctrl; + + if (desc->info.length > 0x1000000) + priv->info->set_4byte(bus, cs); + + /* AST2400 SPI1 doesn't have decoded address segment register. */ + if (info != &ast2400_spi_info) { + priv->flashes[cs].ahb_decoded_sz = desc->info.length; + + for (i = 0; i < priv->num_cs; i++) { + dev_dbg(dev, "cs: %d, sz: 0x%x\n", i, + priv->flashes[cs].ahb_decoded_sz); + } + + ret = aspeed_spi_decoded_range_config(bus); + if (ret) + return ret; + } + + reg_val = aspeed_spi_get_io_mode(op_tmpl.data.buswidth) | + op_tmpl.cmd.opcode << 16 | + ((op_tmpl.dummy.nbytes) & 0x3) << 6 | + ((op_tmpl.dummy.nbytes) & 0x4) << 14 | + CTRL_IO_MODE_CMD_READ; + + writel(reg_val, ce_ctrl_reg); + + priv->flashes[cs].ce_ctrl_read = reg_val; + + dev_dbg(dev, "read bus width: %d ce_ctrl_val: 0x%08x\n", + op_tmpl.data.buswidth, priv->flashes[cs].ce_ctrl_read); + + return ret; +} + +static ssize_t aspeed_spi_dirmap_read(struct spi_mem_dirmap_desc *desc, + u64 offs, size_t len, void *buf) +{ + struct udevice *dev = desc->slave->dev; + struct aspeed_spi_priv *priv = dev_get_priv(dev->parent); + struct dm_spi_slave_plat *slave_plat = dev_get_parent_plat(dev); + u32 cs = slave_plat->cs; + int ret; + + dev_dbg(dev, "read op:0x%x, addr:0x%llx, len:0x%x\n", + desc->info.op_tmpl.cmd.opcode, offs, len); + + if (priv->flashes[cs].ahb_decoded_sz < offs + len || + (offs % 4) != 0) { + ret = aspeed_spi_exec_op_user_mode(desc->slave, + &desc->info.op_tmpl); + if (ret != 0) + return 0; + } else { + memcpy_fromio(buf, priv->flashes[cs].ahb_base + offs, len); + } + + return len; +} + static struct aspeed_spi_flash *aspeed_spi_get_flash(struct udevice *dev) { struct udevice *bus = dev->parent; @@ -662,6 +748,8 @@ static int aspeed_spi_probe(struct udevice *bus) static const struct spi_controller_mem_ops aspeed_spi_mem_ops = { .supports_op = aspeed_spi_supports_op, .exec_op = aspeed_spi_exec_op_user_mode, + .dirmap_create = aspeed_spi_dirmap_create, + .dirmap_read = aspeed_spi_dirmap_read, }; static const struct dm_spi_ops aspeed_spi_ops = { From 99325ee0568aa12f79b044ffcfc80c8ff348841d Mon Sep 17 00:00:00 2001 From: Chin-Ting Kuo Date: Fri, 19 Aug 2022 17:01:11 +0800 Subject: [PATCH 110/374] configs: aspeed: Enable CONFIG_SPI_DIRMAP Enable CONFIG_SPI_DIRMAP on ASPEED platforms. Signed-off-by: Chin-Ting Kuo --- configs/evb-ast2500_defconfig | 1 + configs/evb-ast2600_defconfig | 1 + 2 files changed, 2 insertions(+) diff --git a/configs/evb-ast2500_defconfig b/configs/evb-ast2500_defconfig index dfcf74ae01..3061cbec41 100644 --- a/configs/evb-ast2500_defconfig +++ b/configs/evb-ast2500_defconfig @@ -59,6 +59,7 @@ CONFIG_DM_SERIAL=y CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_DM_SPI=y +CONFIG_SPI_DIRMAP=y CONFIG_SPI_ASPEED_SMC=y CONFIG_SYSRESET=y CONFIG_TIMER=y diff --git a/configs/evb-ast2600_defconfig b/configs/evb-ast2600_defconfig index ebe58d7abd..1981f895d6 100644 --- a/configs/evb-ast2600_defconfig +++ b/configs/evb-ast2600_defconfig @@ -110,6 +110,7 @@ CONFIG_DM_SERIAL=y CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_DM_SPI=y +CONFIG_SPI_DIRMAP=y CONFIG_SPI_ASPEED_SMC=y CONFIG_SYSRESET=y CONFIG_SPL_SYSRESET=y From 15a5c806a31522ab940f4ed252c917d7a77f8200 Mon Sep 17 00:00:00 2001 From: Chin-Ting Kuo Date: Fri, 19 Aug 2022 17:01:12 +0800 Subject: [PATCH 111/374] spi: aspeed: Adjust decoded range size support There are some known HW problems about decoded range register configurations on existing AST2500 and AST2600 platforms. Additional callback function, adjust_decoded_sz, is added to solve these problems on each platform. Besides, aspeed_spi_trim_decoded_size function is added to modify overall decoded address size for fitting the maximum AHB decoded size. Signed-off-by: Chin-Ting Kuo --- drivers/spi/spi-aspeed-smc.c | 144 ++++++++++++++++++++++++++++++++++- 1 file changed, 143 insertions(+), 1 deletion(-) diff --git a/drivers/spi/spi-aspeed-smc.c b/drivers/spi/spi-aspeed-smc.c index 6099b85255..4287f5d8c0 100644 --- a/drivers/spi/spi-aspeed-smc.c +++ b/drivers/spi/spi-aspeed-smc.c @@ -84,10 +84,12 @@ struct aspeed_spi_info { u32 (*segment_start)(struct udevice *bus, u32 reg); u32 (*segment_end)(struct udevice *bus, u32 reg); u32 (*segment_reg)(u32 start, u32 end); + int (*adjust_decoded_sz)(struct udevice *bus); }; static const struct aspeed_spi_info ast2400_spi_info; static int aspeed_spi_decoded_range_config(struct udevice *bus); +static int aspeed_spi_trim_decoded_size(struct udevice *bus); static u32 aspeed_spi_get_io_mode(u32 bus_width) { @@ -195,6 +197,53 @@ static void ast2500_spi_chip_set_4byte(struct udevice *bus, u32 cs) writel(reg_val, &priv->regs->ctrl); } +/* + * For AST2500, the minimum address decoded size for each CS + * is 8MB instead of zero. This address decoded size is + * mandatory for each CS no matter whether it will be used. + * This is a HW limitation. + */ +static int ast2500_adjust_decoded_size(struct udevice *bus) +{ + struct aspeed_spi_plat *plat = dev_get_plat(bus); + struct aspeed_spi_priv *priv = dev_get_priv(bus); + struct aspeed_spi_flash *flashes = &priv->flashes[0]; + int ret; + int i; + int cs; + u32 pre_sz; + u32 lack_sz; + + /* Assign min_decoded_sz to unused CS. */ + for (cs = priv->num_cs; cs < plat->max_cs; cs++) + flashes[cs].ahb_decoded_sz = priv->info->min_decoded_sz; + + /* + * If commnad mode or normal mode is used, the start address of a + * decoded range should be multiple of its related flash size. + * Namely, the total decoded size from flash 0 to flash N should + * be multiple of the size of flash (N + 1). + */ + for (cs = priv->num_cs - 1; cs >= 0; cs--) { + pre_sz = 0; + for (i = 0; i < cs; i++) + pre_sz += flashes[i].ahb_decoded_sz; + + if (flashes[cs].ahb_decoded_sz != 0 && + (pre_sz % flashes[cs].ahb_decoded_sz) != 0) { + lack_sz = flashes[cs].ahb_decoded_sz - + (pre_sz % flashes[cs].ahb_decoded_sz); + flashes[0].ahb_decoded_sz += lack_sz; + } + } + + ret = aspeed_spi_trim_decoded_size(bus); + if (ret != 0) + return ret; + + return 0; +} + static u32 ast2600_spi_segment_start(struct udevice *bus, u32 reg) { struct aspeed_spi_plat *plat = dev_get_plat(bus); @@ -236,6 +285,86 @@ static void ast2600_spi_chip_set_4byte(struct udevice *bus, u32 cs) writel(reg_val, &priv->regs->ctrl); } +static int ast2600_adjust_decoded_size(struct udevice *bus) +{ + struct aspeed_spi_plat *plat = dev_get_plat(bus); + struct aspeed_spi_priv *priv = dev_get_priv(bus); + struct aspeed_spi_flash *flashes = &priv->flashes[0]; + int ret; + int i; + int cs; + u32 pre_sz; + u32 lack_sz; + + /* Close unused CS. */ + for (cs = priv->num_cs; cs < plat->max_cs; cs++) + flashes[cs].ahb_decoded_sz = 0; + + /* + * If commnad mode or normal mode is used, the start address of a + * decoded range should be multiple of its related flash size. + * Namely, the total decoded size from flash 0 to flash N should + * be multiple of the size of flash (N + 1). + */ + for (cs = priv->num_cs - 1; cs >= 0; cs--) { + pre_sz = 0; + for (i = 0; i < cs; i++) + pre_sz += flashes[i].ahb_decoded_sz; + + if (flashes[cs].ahb_decoded_sz != 0 && + (pre_sz % flashes[cs].ahb_decoded_sz) != 0) { + lack_sz = flashes[cs].ahb_decoded_sz - + (pre_sz % flashes[cs].ahb_decoded_sz); + flashes[0].ahb_decoded_sz += lack_sz; + } + } + + ret = aspeed_spi_trim_decoded_size(bus); + if (ret != 0) + return ret; + + return 0; +} + +/* + * As the flash size grows up, we need to trim some decoded + * size if needed for the sake of conforming the maximum + * decoded size. We trim the decoded size from the largest + * CS in order to avoid affecting the default boot up sequence + * from CS0 where command mode or normal mode is used. + * Notice, if a CS decoded size is trimmed, command mode may + * not work perfectly on that CS. + */ +static int aspeed_spi_trim_decoded_size(struct udevice *bus) +{ + struct aspeed_spi_plat *plat = dev_get_plat(bus); + struct aspeed_spi_priv *priv = dev_get_priv(bus); + struct aspeed_spi_flash *flashes = &priv->flashes[0]; + u32 total_sz; + int cs = plat->max_cs - 1; + u32 i; + + do { + total_sz = 0; + for (i = 0; i < plat->max_cs; i++) + total_sz += flashes[i].ahb_decoded_sz; + + if (flashes[cs].ahb_decoded_sz <= priv->info->min_decoded_sz) + cs--; + + if (cs < 0) + return -ENOMEM; + + if (total_sz > plat->ahb_sz) { + flashes[cs].ahb_decoded_sz -= + priv->info->min_decoded_sz; + total_sz -= priv->info->min_decoded_sz; + } + } while (total_sz > plat->ahb_sz); + + return 0; +} + static int aspeed_spi_read_from_ahb(void __iomem *ahb_base, void *buf, size_t len) { @@ -522,10 +651,19 @@ static void aspeed_spi_decoded_range_set(struct udevice *bus) static int aspeed_spi_decoded_range_config(struct udevice *bus) { + int ret = 0; + struct aspeed_spi_priv *priv = dev_get_priv(bus); + + if (priv->info->adjust_decoded_sz) { + ret = priv->info->adjust_decoded_sz(bus); + if (ret != 0) + return ret; + } + aspeed_spi_decoded_base_calculate(bus); aspeed_spi_decoded_range_set(bus); - return 0; + return ret; } /* @@ -616,6 +754,7 @@ static const struct aspeed_spi_info ast2500_fmc_info = { .segment_start = ast2500_spi_segment_start, .segment_end = ast2500_spi_segment_end, .segment_reg = ast2500_spi_segment_reg, + .adjust_decoded_sz = ast2500_adjust_decoded_size, }; /* @@ -630,6 +769,7 @@ static const struct aspeed_spi_info ast2500_spi_info = { .segment_start = ast2500_spi_segment_start, .segment_end = ast2500_spi_segment_end, .segment_reg = ast2500_spi_segment_reg, + .adjust_decoded_sz = ast2500_adjust_decoded_size, }; static const struct aspeed_spi_info ast2600_fmc_info = { @@ -640,6 +780,7 @@ static const struct aspeed_spi_info ast2600_fmc_info = { .segment_start = ast2600_spi_segment_start, .segment_end = ast2600_spi_segment_end, .segment_reg = ast2600_spi_segment_reg, + .adjust_decoded_sz = ast2600_adjust_decoded_size, }; static const struct aspeed_spi_info ast2600_spi_info = { @@ -650,6 +791,7 @@ static const struct aspeed_spi_info ast2600_spi_info = { .segment_start = ast2600_spi_segment_start, .segment_end = ast2600_spi_segment_end, .segment_reg = ast2600_spi_segment_reg, + .adjust_decoded_sz = ast2600_adjust_decoded_size, }; static int aspeed_spi_claim_bus(struct udevice *dev) From dd29cee8d83588e631bbd87f1d6cbf9b2fb960b8 Mon Sep 17 00:00:00 2001 From: Chin-Ting Kuo Date: Fri, 19 Aug 2022 17:01:13 +0800 Subject: [PATCH 112/374] spi: aspeed: Support customized decoded address ranges If "decoded-ranges" is defined in the device tree, the driver will apply the decoded address ranges from this property to the controller during probe stage. This patch refers to the following OpenBMC u-boot patch. https://patchwork.ozlabs.org/project/openbmc/list/?series=306969 Signed-off-by: Chin-Ting Kuo --- drivers/spi/spi-aspeed-smc.c | 136 ++++++++++++++++++++++++++++++++--- 1 file changed, 127 insertions(+), 9 deletions(-) diff --git a/drivers/spi/spi-aspeed-smc.c b/drivers/spi/spi-aspeed-smc.c index 4287f5d8c0..2b6c4b48bd 100644 --- a/drivers/spi/spi-aspeed-smc.c +++ b/drivers/spi/spi-aspeed-smc.c @@ -74,6 +74,7 @@ struct aspeed_spi_priv { struct aspeed_spi_regs *regs; struct aspeed_spi_info *info; struct aspeed_spi_flash flashes[ASPEED_SPI_MAX_CS]; + bool fixed_decoded_range; }; struct aspeed_spi_info { @@ -87,7 +88,15 @@ struct aspeed_spi_info { int (*adjust_decoded_sz)(struct udevice *bus); }; +struct aspeed_spi_decoded_range { + u32 cs; + u32 ahb_base; + u32 sz; +}; + static const struct aspeed_spi_info ast2400_spi_info; +static const struct aspeed_spi_info ast2500_fmc_info; +static const struct aspeed_spi_info ast2500_spi_info; static int aspeed_spi_decoded_range_config(struct udevice *bus); static int aspeed_spi_trim_decoded_size(struct udevice *bus); @@ -618,6 +627,9 @@ static void aspeed_spi_decoded_base_calculate(struct udevice *bus) struct aspeed_spi_priv *priv = dev_get_priv(bus); u32 cs; + if (priv->fixed_decoded_range) + return; + priv->flashes[0].ahb_base = plat->ahb_base; for (cs = 1; cs < plat->max_cs; cs++) { @@ -654,7 +666,8 @@ static int aspeed_spi_decoded_range_config(struct udevice *bus) int ret = 0; struct aspeed_spi_priv *priv = dev_get_priv(bus); - if (priv->info->adjust_decoded_sz) { + if (priv->info->adjust_decoded_sz && + !priv->fixed_decoded_range) { ret = priv->info->adjust_decoded_sz(bus); if (ret != 0) return ret; @@ -666,6 +679,104 @@ static int aspeed_spi_decoded_range_config(struct udevice *bus) return ret; } +static int aspeed_spi_decoded_ranges_sanity(struct udevice *bus) +{ + struct aspeed_spi_plat *plat = dev_get_plat(bus); + struct aspeed_spi_priv *priv = dev_get_priv(bus); + u32 cs; + u32 total_sz = 0; + + /* Check overall size. */ + for (cs = 0; cs < plat->max_cs; cs++) + total_sz += priv->flashes[cs].ahb_decoded_sz; + + if (total_sz > plat->ahb_sz) { + dev_err(bus, "invalid total size 0x%08x\n", total_sz); + return -EINVAL; + } + + /* Check each decoded range size for AST2500. */ + if (priv->info == &ast2500_fmc_info || + priv->info == &ast2500_spi_info) { + for (cs = 0; cs < plat->max_cs; cs++) { + if (priv->flashes[cs].ahb_decoded_sz < + priv->info->min_decoded_sz) { + dev_err(bus, "insufficient decoded range.\n"); + return -EINVAL; + } + } + } + + /* + * Check overlay. Here, we assume the deccded ranges and + * address base are monotonic increasing with CE#. + */ + for (cs = plat->max_cs - 1; cs > 0; cs--) { + if ((u32)priv->flashes[cs].ahb_base != 0 && + (u32)priv->flashes[cs].ahb_base < + (u32)priv->flashes[cs - 1].ahb_base + + priv->flashes[cs - 1].ahb_decoded_sz) { + dev_err(bus, "decoded range overlay 0x%08x 0x%08x\n", + (u32)priv->flashes[cs].ahb_base, + (u32)priv->flashes[cs - 1].ahb_base); + return -EINVAL; + } + } + + return 0; +} + +static int aspeed_spi_read_fixed_decoded_ranges(struct udevice *bus) +{ + int ret = 0; + struct aspeed_spi_plat *plat = dev_get_plat(bus); + struct aspeed_spi_priv *priv = dev_get_priv(bus); + const char *range_prop = "decoded-ranges"; + struct aspeed_spi_decoded_range ranges[ASPEED_SPI_MAX_CS]; + const struct property *prop; + u32 prop_sz; + u32 count; + u32 i; + + priv->fixed_decoded_range = false; + + prop = dev_read_prop(bus, range_prop, &prop_sz); + if (!prop) + return 0; + + count = prop_sz / sizeof(struct aspeed_spi_decoded_range); + if (count > plat->max_cs || count < priv->num_cs) { + dev_err(bus, "invalid '%s' property %d %d\n", + range_prop, count, priv->num_cs); + return -EINVAL; + } + + ret = dev_read_u32_array(bus, range_prop, (u32 *)ranges, count * 3); + if (ret) + return ret; + + for (i = 0; i < count; i++) { + priv->flashes[ranges[i].cs].ahb_base = + (void __iomem *)ranges[i].ahb_base; + priv->flashes[ranges[i].cs].ahb_decoded_sz = + ranges[i].sz; + } + + for (i = 0; i < plat->max_cs; i++) { + dev_dbg(bus, "ahb_base: 0x%p, size: 0x%08x\n", + priv->flashes[i].ahb_base, + priv->flashes[i].ahb_decoded_sz); + } + + ret = aspeed_spi_decoded_ranges_sanity(bus); + if (ret != 0) + return ret; + + priv->fixed_decoded_range = true; + + return 0; +} + /* * Initialize SPI controller for each chip select. * Here, only the minimum decode range is configured @@ -709,16 +820,23 @@ static int aspeed_spi_ctrl_init(struct udevice *bus) return 0; } - /* Assign basic AHB decoded size for each CS. */ - for (cs = 0; cs < plat->max_cs; cs++) { - reg_val = readl(&priv->regs->segment_addr[cs]); - decoded_sz = priv->info->segment_end(bus, reg_val) - - priv->info->segment_start(bus, reg_val); - if (decoded_sz < priv->info->min_decoded_sz) - decoded_sz = priv->info->min_decoded_sz; + ret = aspeed_spi_read_fixed_decoded_ranges(bus); + if (ret != 0) + return ret; - priv->flashes[cs].ahb_decoded_sz = decoded_sz; + if (!priv->fixed_decoded_range) { + /* Assign basic AHB decoded size for each CS. */ + for (cs = 0; cs < plat->max_cs; cs++) { + reg_val = readl(&priv->regs->segment_addr[cs]); + decoded_sz = priv->info->segment_end(bus, reg_val) - + priv->info->segment_start(bus, reg_val); + + if (decoded_sz < priv->info->min_decoded_sz) + decoded_sz = priv->info->min_decoded_sz; + + priv->flashes[cs].ahb_decoded_sz = decoded_sz; + } } ret = aspeed_spi_decoded_range_config(bus); From 9a163720237e5e0d9989e4411f70b61414f3711e Mon Sep 17 00:00:00 2001 From: Chin-Ting Kuo Date: Fri, 19 Aug 2022 17:01:14 +0800 Subject: [PATCH 113/374] spi: aspeed: Clock frequency adjustment support Driver can configure the SPI clock frequnecy to the target value of "spi-max-frequency" property in the device tree. The frequency is divided from HCLK, 200MHz. Usually, the ASPEED SPI clock frequency range is between 12.5MHz and 100MHz. On AST2600, the lowest SPI clock frequency can be about 780kHz. Signed-off-by: Chin-Ting Kuo --- drivers/spi/spi-aspeed-smc.c | 196 +++++++++++++++++++++++++++++++++-- 1 file changed, 186 insertions(+), 10 deletions(-) diff --git a/drivers/spi/spi-aspeed-smc.c b/drivers/spi/spi-aspeed-smc.c index 2b6c4b48bd..a3c9633382 100644 --- a/drivers/spi/spi-aspeed-smc.c +++ b/drivers/spi/spi-aspeed-smc.c @@ -60,6 +60,7 @@ struct aspeed_spi_plat { u8 max_cs; void __iomem *ahb_base; /* AHB address base for all flash devices. */ fdt_size_t ahb_sz; /* Overall AHB window size for all flash device. */ + u32 hclk_rate; /* AHB clock rate */ }; struct aspeed_spi_flash { @@ -67,6 +68,7 @@ struct aspeed_spi_flash { u32 ahb_decoded_sz; u32 ce_ctrl_user; u32 ce_ctrl_read; + u32 max_freq; }; struct aspeed_spi_priv { @@ -81,11 +83,13 @@ struct aspeed_spi_info { u32 io_mode_mask; u32 max_bus_width; u32 min_decoded_sz; + u32 clk_ctrl_mask; void (*set_4byte)(struct udevice *bus, u32 cs); u32 (*segment_start)(struct udevice *bus, u32 reg); u32 (*segment_end)(struct udevice *bus, u32 reg); u32 (*segment_reg)(u32 start, u32 end); int (*adjust_decoded_sz)(struct udevice *bus); + u32 (*get_clk_setting)(struct udevice *dev, uint hz); }; struct aspeed_spi_decoded_range { @@ -165,6 +169,44 @@ static void ast2400_spi_chip_set_4byte(struct udevice *bus, u32 cs) writel(flash->ce_ctrl_read, &priv->regs->ctrl); } +/* Transfer maximum clock frequency to register setting */ +static u32 ast2400_get_clk_setting(struct udevice *dev, uint max_hz) +{ + struct aspeed_spi_plat *plat = dev_get_plat(dev->parent); + struct aspeed_spi_priv *priv = dev_get_priv(dev->parent); + struct dm_spi_slave_plat *slave_plat = dev_get_parent_plat(dev); + u32 hclk_clk = plat->hclk_rate; + u32 hclk_div = 0x0000; /* default value */ + u32 i; + bool found = false; + /* HCLK/1 .. HCLK/16 */ + u32 hclk_masks[] = {15, 7, 14, 6, 13, 5, 12, 4, + 11, 3, 10, 2, 9, 1, 8, 0}; + + /* FMC/SPIR10[11:8] */ + for (i = 0; i < ARRAY_SIZE(hclk_masks); i++) { + if (hclk_clk / (i + 1) <= max_hz) { + found = true; + break; + } + } + + if (found) { + hclk_div = hclk_masks[i] << 8; + priv->flashes[slave_plat->cs].max_freq = hclk_clk / (i + 1); + } + + dev_dbg(dev, "found: %s, hclk: %d, max_clk: %d\n", found ? "yes" : "no", + hclk_clk, max_hz); + + if (found) { + dev_dbg(dev, "h_div: %d (mask %x), speed: %d\n", + i + 1, hclk_masks[i], priv->flashes[slave_plat->cs].max_freq); + } + + return hclk_div; +} + static u32 ast2500_spi_segment_start(struct udevice *bus, u32 reg) { struct aspeed_spi_plat *plat = dev_get_plat(bus); @@ -253,6 +295,58 @@ static int ast2500_adjust_decoded_size(struct udevice *bus) return 0; } +static u32 ast2500_get_clk_setting(struct udevice *dev, uint max_hz) +{ + struct aspeed_spi_plat *plat = dev_get_plat(dev->parent); + struct aspeed_spi_priv *priv = dev_get_priv(dev->parent); + struct dm_spi_slave_plat *slave_plat = dev_get_parent_plat(dev); + u32 hclk_clk = plat->hclk_rate; + u32 hclk_div = 0x0000; /* default value */ + u32 i; + bool found = false; + /* HCLK/1 .. HCLK/16 */ + u32 hclk_masks[] = {15, 7, 14, 6, 13, 5, 12, 4, + 11, 3, 10, 2, 9, 1, 8, 0}; + + /* FMC/SPIR10[11:8] */ + for (i = 0; i < ARRAY_SIZE(hclk_masks); i++) { + if (hclk_clk / (i + 1) <= max_hz) { + found = true; + priv->flashes[slave_plat->cs].max_freq = + hclk_clk / (i + 1); + break; + } + } + + if (found) { + hclk_div = hclk_masks[i] << 8; + goto end; + } + + for (i = 0; i < ARRAY_SIZE(hclk_masks); i++) { + if (hclk_clk / ((i + 1) * 4) <= max_hz) { + found = true; + priv->flashes[slave_plat->cs].max_freq = + hclk_clk / ((i + 1) * 4); + break; + } + } + + if (found) + hclk_div = BIT(13) | (hclk_masks[i] << 8); + +end: + dev_dbg(dev, "found: %s, hclk: %d, max_clk: %d\n", found ? "yes" : "no", + hclk_clk, max_hz); + + if (found) { + dev_dbg(dev, "h_div: %d (mask %x), speed: %d\n", + i + 1, hclk_masks[i], priv->flashes[slave_plat->cs].max_freq); + } + + return hclk_div; +} + static u32 ast2600_spi_segment_start(struct udevice *bus, u32 reg) { struct aspeed_spi_plat *plat = dev_get_plat(bus); @@ -335,6 +429,51 @@ static int ast2600_adjust_decoded_size(struct udevice *bus) return 0; } +static u32 ast2600_get_clk_setting(struct udevice *dev, uint max_hz) +{ + struct aspeed_spi_plat *plat = dev_get_plat(dev->parent); + struct aspeed_spi_priv *priv = dev_get_priv(dev->parent); + struct dm_spi_slave_plat *slave_plat = dev_get_parent_plat(dev); + u32 hclk_clk = plat->hclk_rate; + u32 hclk_div = 0x0400; /* default value */ + u32 i, j; + bool found = false; + /* HCLK/1 .. HCLK/16 */ + u32 hclk_masks[] = {15, 7, 14, 6, 13, 5, 12, 4, + 11, 3, 10, 2, 9, 1, 8, 0}; + + /* FMC/SPIR10[27:24] */ + for (j = 0; j < 0xf; j++) { + /* FMC/SPIR10[11:8] */ + for (i = 0; i < ARRAY_SIZE(hclk_masks); i++) { + if (i == 0 && j == 0) + continue; + + if (hclk_clk / (i + 1 + (j * 16)) <= max_hz) { + found = true; + break; + } + } + + if (found) { + hclk_div = ((j << 24) | hclk_masks[i] << 8); + priv->flashes[slave_plat->cs].max_freq = + hclk_clk / (i + 1 + j * 16); + break; + } + } + + dev_dbg(dev, "found: %s, hclk: %d, max_clk: %d\n", found ? "yes" : "no", + hclk_clk, max_hz); + + if (found) { + dev_dbg(dev, "base_clk: %d, h_div: %d (mask %x), speed: %d\n", + j, i + 1, hclk_masks[i], priv->flashes[slave_plat->cs].max_freq); + } + + return hclk_div; +} + /* * As the flash size grows up, we need to trim some decoded * size if needed for the sake of conforming the maximum @@ -531,7 +670,7 @@ static int aspeed_spi_dirmap_create(struct spi_mem_dirmap_desc *desc) struct spi_mem_op op_tmpl = desc->info.op_tmpl; u32 i; u32 cs = slave_plat->cs; - u32 reg_val; + u32 cmd_io_conf; u32 ce_ctrl_reg; if (desc->info.op_tmpl.data.dir == SPI_MEM_DATA_OUT) { @@ -564,15 +703,16 @@ static int aspeed_spi_dirmap_create(struct spi_mem_dirmap_desc *desc) return ret; } - reg_val = aspeed_spi_get_io_mode(op_tmpl.data.buswidth) | - op_tmpl.cmd.opcode << 16 | - ((op_tmpl.dummy.nbytes) & 0x3) << 6 | - ((op_tmpl.dummy.nbytes) & 0x4) << 14 | - CTRL_IO_MODE_CMD_READ; + cmd_io_conf = aspeed_spi_get_io_mode(op_tmpl.data.buswidth) | + op_tmpl.cmd.opcode << 16 | + ((op_tmpl.dummy.nbytes) & 0x3) << 6 | + ((op_tmpl.dummy.nbytes) & 0x4) << 14 | + CTRL_IO_MODE_CMD_READ; - writel(reg_val, ce_ctrl_reg); + priv->flashes[cs].ce_ctrl_read &= priv->info->clk_ctrl_mask; + priv->flashes[cs].ce_ctrl_read |= cmd_io_conf; - priv->flashes[cs].ce_ctrl_read = reg_val; + writel(priv->flashes[cs].ce_ctrl_read, ce_ctrl_reg); dev_dbg(dev, "read bus width: %d ce_ctrl_val: 0x%08x\n", op_tmpl.data.buswidth, priv->flashes[cs].ce_ctrl_read); @@ -806,7 +946,8 @@ static int aspeed_spi_ctrl_init(struct udevice *bus) /* Initial user mode. */ for (cs = 0; cs < priv->num_cs; cs++) { - priv->flashes[cs].ce_ctrl_user = + priv->flashes[cs].ce_ctrl_user &= priv->info->clk_ctrl_mask; + priv->flashes[cs].ce_ctrl_user |= (CTRL_STOP_ACTIVE | CTRL_IO_MODE_USER); } @@ -848,31 +989,37 @@ static const struct aspeed_spi_info ast2400_fmc_info = { .io_mode_mask = 0x70000000, .max_bus_width = 2, .min_decoded_sz = 0x800000, + .clk_ctrl_mask = 0x00002f00, .set_4byte = ast2400_fmc_chip_set_4byte, .segment_start = ast2400_spi_segment_start, .segment_end = ast2400_spi_segment_end, .segment_reg = ast2400_spi_segment_reg, + .get_clk_setting = ast2400_get_clk_setting, }; static const struct aspeed_spi_info ast2400_spi_info = { .io_mode_mask = 0x70000000, .max_bus_width = 2, .min_decoded_sz = 0x800000, + .clk_ctrl_mask = 0x00000f00, .set_4byte = ast2400_spi_chip_set_4byte, .segment_start = ast2400_spi_segment_start, .segment_end = ast2400_spi_segment_end, .segment_reg = ast2400_spi_segment_reg, + .get_clk_setting = ast2400_get_clk_setting, }; static const struct aspeed_spi_info ast2500_fmc_info = { .io_mode_mask = 0x70000000, .max_bus_width = 2, .min_decoded_sz = 0x800000, + .clk_ctrl_mask = 0x00002f00, .set_4byte = ast2500_spi_chip_set_4byte, .segment_start = ast2500_spi_segment_start, .segment_end = ast2500_spi_segment_end, .segment_reg = ast2500_spi_segment_reg, .adjust_decoded_sz = ast2500_adjust_decoded_size, + .get_clk_setting = ast2500_get_clk_setting, }; /* @@ -883,42 +1030,59 @@ static const struct aspeed_spi_info ast2500_spi_info = { .io_mode_mask = 0x70000000, .max_bus_width = 2, .min_decoded_sz = 0x800000, + .clk_ctrl_mask = 0x00002f00, .set_4byte = ast2500_spi_chip_set_4byte, .segment_start = ast2500_spi_segment_start, .segment_end = ast2500_spi_segment_end, .segment_reg = ast2500_spi_segment_reg, .adjust_decoded_sz = ast2500_adjust_decoded_size, + .get_clk_setting = ast2500_get_clk_setting, }; static const struct aspeed_spi_info ast2600_fmc_info = { .io_mode_mask = 0xf0000000, .max_bus_width = 4, .min_decoded_sz = 0x200000, + .clk_ctrl_mask = 0x0f000f00, .set_4byte = ast2600_spi_chip_set_4byte, .segment_start = ast2600_spi_segment_start, .segment_end = ast2600_spi_segment_end, .segment_reg = ast2600_spi_segment_reg, .adjust_decoded_sz = ast2600_adjust_decoded_size, + .get_clk_setting = ast2600_get_clk_setting, }; static const struct aspeed_spi_info ast2600_spi_info = { .io_mode_mask = 0xf0000000, .max_bus_width = 4, .min_decoded_sz = 0x200000, + .clk_ctrl_mask = 0x0f000f00, .set_4byte = ast2600_spi_chip_set_4byte, .segment_start = ast2600_spi_segment_start, .segment_end = ast2600_spi_segment_end, .segment_reg = ast2600_spi_segment_reg, .adjust_decoded_sz = ast2600_adjust_decoded_size, + .get_clk_setting = ast2600_get_clk_setting, }; static int aspeed_spi_claim_bus(struct udevice *dev) { struct udevice *bus = dev->parent; struct dm_spi_slave_plat *slave_plat = dev_get_parent_plat(dev); + struct aspeed_spi_priv *priv = dev_get_priv(dev->parent); + struct aspeed_spi_flash *flash = &priv->flashes[slave_plat->cs]; + u32 clk_setting; dev_dbg(bus, "%s: claim bus CS%u\n", bus->name, slave_plat->cs); + if (flash->max_freq == 0) { + clk_setting = priv->info->get_clk_setting(dev, slave_plat->max_hz); + flash->ce_ctrl_user &= ~(priv->info->clk_ctrl_mask); + flash->ce_ctrl_user |= clk_setting; + flash->ce_ctrl_read &= ~(priv->info->clk_ctrl_mask); + flash->ce_ctrl_read |= clk_setting; + } + return 0; } @@ -958,6 +1122,8 @@ static int apseed_spi_of_to_plat(struct udevice *bus) { struct aspeed_spi_plat *plat = dev_get_plat(bus); struct aspeed_spi_priv *priv = dev_get_priv(bus); + int ret; + struct clk hclk; priv->regs = (void __iomem *)devfdt_get_addr_index(bus, 0); if ((u32)priv->regs == FDT_ADDR_T_NONE) { @@ -976,9 +1142,19 @@ static int apseed_spi_of_to_plat(struct udevice *bus) if (plat->max_cs > ASPEED_SPI_MAX_CS) return -EINVAL; + ret = clk_get_by_index(bus, 0, &hclk); + if (ret < 0) { + dev_err(bus, "%s could not get clock: %d\n", bus->name, ret); + return ret; + } + + plat->hclk_rate = clk_get_rate(&hclk); + clk_free(&hclk); + dev_dbg(bus, "ctrl_base = 0x%x, ahb_base = 0x%p, size = 0x%lx\n", (u32)priv->regs, plat->ahb_base, plat->ahb_sz); - dev_dbg(bus, "max_cs = %d\n", plat->max_cs); + dev_dbg(bus, "hclk = %dMHz, max_cs = %d\n", + plat->hclk_rate / 1000000, plat->max_cs); return 0; } From c184aca7b061f81681fc10d777c936f9a787a317 Mon Sep 17 00:00:00 2001 From: Chin-Ting Kuo Date: Fri, 19 Aug 2022 17:01:15 +0800 Subject: [PATCH 114/374] mtd: spi-nor-ids: Add Winbond W25Q512JVQ ID MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add ID for Winbond W25Q512JVQ device which is supported on AST2600 EVB by default. Signed-off-by: Chin-Ting Kuo Reviewed-by: Cédric Le Goater --- drivers/mtd/spi/spi-nor-ids.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/mtd/spi/spi-nor-ids.c b/drivers/mtd/spi/spi-nor-ids.c index 4fe8b0d92c..65eb35a918 100644 --- a/drivers/mtd/spi/spi-nor-ids.c +++ b/drivers/mtd/spi/spi-nor-ids.c @@ -424,6 +424,11 @@ const struct flash_info spi_nor_ids[] = { SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) }, + { + INFO("w25q512jvq", 0xef4020, 0, 64 * 1024, 1024, + SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | + SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) + }, { INFO("w25q01jv", 0xef4021, 0, 64 * 1024, 2048, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | From e29178eda1ed5fe3b3796af12ce0b8d0a0337992 Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Fri, 2 Sep 2022 13:57:47 +0200 Subject: [PATCH 115/374] time: Import time_after64() and friends from Linux When using us times it makes sense to use 64bit variables for storage. The currently implemented time_after() and friends functions only handle 32bit variables. This patch now includes the 64bit variants as well from Linux. This will be used by the upcoming generic cyclic function infrastructure. These macros were copied from include/linux/jiffies.h of Linux 5.18. Signed-off-by: Stefan Roese Reviewed-by: Simon Glass --- include/time.h | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/include/time.h b/include/time.h index 9deb2cf61c..3b2ba09124 100644 --- a/include/time.h +++ b/include/time.h @@ -83,6 +83,25 @@ uint64_t usec_to_tick(unsigned long usec); (time_after_eq(a,b) && \ time_before(a,c)) +/* Same as above, but does so with platform independent 64bit types. + * These must be used when utilizing jiffies_64 (i.e. return value of + * get_jiffies_64() */ +#define time_after64(a,b) \ + (typecheck(__u64, a) && \ + typecheck(__u64, b) && \ + ((__s64)((b) - (a)) < 0)) +#define time_before64(a,b) time_after64(b,a) + +#define time_after_eq64(a,b) \ + (typecheck(__u64, a) && \ + typecheck(__u64, b) && \ + ((__s64)((a) - (b)) >= 0)) +#define time_before_eq64(a,b) time_after_eq64(b,a) + +#define time_in_range64(a, b, c) \ + (time_after_eq64(a, b) && \ + time_before_eq64(a, c)) + /** * usec2ticks() - Convert microseconds to internal ticks * From c2c6971888784cac01e625ef7f436d20e5fb23ba Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Fri, 2 Sep 2022 13:57:48 +0200 Subject: [PATCH 116/374] cyclic: Add basic support for cyclic function execution infrastruture Add the basic infrastructure to periodically execute code, e.g. all 100ms. Examples for such functions might be LED blinking etc. The functions that are hooked into this cyclic list should be small timewise as otherwise the execution of the other code that relies on a high frequent polling (e.g. UART rx char ready check) might be delayed too much. This patch also adds the Kconfig option CONFIG_CYCLIC_MAX_CPU_TIME_US, which configures the max allowed time for such a cyclic function. If it's execution time exceeds this time, this cyclic function will get removed from the cyclic list. How is this cyclic functionality executed? The following patch integrates the main function responsible for calling all registered cyclic functions cyclic_run() into the common WATCHDOG_RESET macro. This guarantees that cyclic_run() is executed very often, which is necessary for the cyclic functions to get scheduled and executed at their configured periods. This cyclic infrastructure will be used by a board specific function on the NIC23 MIPS Octeon board, which needs to check periodically, if a PCIe FLR has occurred. Signed-off-by: Stefan Roese Reviewed-by: Simon Glass --- MAINTAINERS | 6 ++ common/Kconfig | 20 +++++ common/Makefile | 1 + common/cyclic.c | 123 ++++++++++++++++++++++++++ include/asm-generic/global_data.h | 7 ++ include/cyclic.h | 138 ++++++++++++++++++++++++++++++ 6 files changed, 295 insertions(+) create mode 100644 common/cyclic.c create mode 100644 include/cyclic.h diff --git a/MAINTAINERS b/MAINTAINERS index 1ebcd368a6..4af527e639 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -795,6 +795,12 @@ T: git https://source.denx.de/u-boot/custodians/u-boot-coldfire.git F: arch/m68k/ F: doc/arch/m68k.rst +CYCLIC +M: Stefan Roese +S: Maintained +F: common/cyclic.c +F: include/cyclic.h + DFU M: Lukasz Majewski S: Maintained diff --git a/common/Kconfig b/common/Kconfig index 2c3f7f4274..3e44acd2be 100644 --- a/common/Kconfig +++ b/common/Kconfig @@ -545,6 +545,26 @@ config DISPLAY_BOARDINFO_LATE menu "Start-up hooks" +config CYCLIC + bool "General-purpose cyclic execution mechanism" + help + This enables a general-purpose cyclic execution infrastructure, + to allow "small" (run-time wise) functions to be executed at + a specified frequency. Things like LED blinking or watchdog + triggering are examples for such tasks. + +if CYCLIC + +config CYCLIC_MAX_CPU_TIME_US + int "Sets the max allowed time for a cyclic function in us" + default 1000 + help + The max allowed time for a cyclic function in us. If a functions + takes longer than this duration this function will get unregistered + automatically. + +endif # CYCLIC + config EVENT bool "General-purpose event-handling mechanism" default y if SANDBOX diff --git a/common/Makefile b/common/Makefile index 2ed8672c3a..1d56c9f289 100644 --- a/common/Makefile +++ b/common/Makefile @@ -84,6 +84,7 @@ obj-y += malloc_simple.o endif endif +obj-$(CONFIG_CYCLIC) += cyclic.o obj-$(CONFIG_$(SPL_TPL_)EVENT) += event.o obj-$(CONFIG_$(SPL_TPL_)HASH) += hash.o diff --git a/common/cyclic.c b/common/cyclic.c new file mode 100644 index 0000000000..cd5dcb1f2b --- /dev/null +++ b/common/cyclic.c @@ -0,0 +1,123 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * A general-purpose cyclic execution infrastructure, to allow "small" + * (run-time wise) functions to be executed at a specified frequency. + * Things like LED blinking or watchdog triggering are examples for such + * tasks. + * + * Copyright (C) 2022 Stefan Roese + */ + +#include +#include +#include +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +struct list_head *cyclic_get_list(void) +{ + return &gd->cyclic->cyclic_list; +} + +struct cyclic_info *cyclic_register(cyclic_func_t func, uint64_t delay_us, + const char *name, void *ctx) +{ + struct cyclic_info *cyclic; + + if (!gd->cyclic->cyclic_ready) { + pr_debug("Cyclic IF not ready yet\n"); + return NULL; + } + + cyclic = calloc(1, sizeof(struct cyclic_info)); + if (!cyclic) { + pr_debug("Memory allocation error\n"); + return NULL; + } + + /* Store values in struct */ + cyclic->func = func; + cyclic->ctx = ctx; + cyclic->name = strdup(name); + cyclic->delay_us = delay_us; + cyclic->start_time_us = timer_get_us(); + list_add_tail(&cyclic->list, &gd->cyclic->cyclic_list); + + return cyclic; +} + +int cyclic_unregister(struct cyclic_info *cyclic) +{ + list_del(&cyclic->list); + free(cyclic); + + return 0; +} + +void cyclic_run(void) +{ + struct cyclic_info *cyclic, *tmp; + uint64_t now, cpu_time; + + /* Prevent recursion */ + if (gd->cyclic->cyclic_running) + return; + + gd->cyclic->cyclic_running = true; + list_for_each_entry_safe(cyclic, tmp, &gd->cyclic->cyclic_list, list) { + /* + * Check if this cyclic function needs to get called, e.g. + * do not call the cyclic func too often + */ + now = timer_get_us(); + if (time_after_eq64(now, cyclic->next_call)) { + /* Call cyclic function and account it's cpu-time */ + cyclic->next_call = now + cyclic->delay_us; + cyclic->func(cyclic->ctx); + cyclic->run_cnt++; + cpu_time = timer_get_us() - now; + cyclic->cpu_time_us += cpu_time; + + /* Check if cpu-time exceeds max allowed time */ + if (cpu_time > CONFIG_CYCLIC_MAX_CPU_TIME_US) { + pr_err("cyclic function %s took too long: %lldus vs %dus max, disabling\n", + cyclic->name, cpu_time, + CONFIG_CYCLIC_MAX_CPU_TIME_US); + + /* Unregister this cyclic function */ + cyclic_unregister(cyclic); + } + } + } + gd->cyclic->cyclic_running = false; +} + +int cyclic_uninit(void) +{ + struct cyclic_info *cyclic, *tmp; + + list_for_each_entry_safe(cyclic, tmp, &gd->cyclic->cyclic_list, list) + cyclic_unregister(cyclic); + gd->cyclic->cyclic_ready = false; + + return 0; +} + +int cyclic_init(void) +{ + int size = sizeof(struct cyclic_drv); + + gd->cyclic = (struct cyclic_drv *)malloc(size); + if (!gd->cyclic) + return -ENOMEM; + + memset(gd->cyclic, '\0', size); + INIT_LIST_HEAD(&gd->cyclic->cyclic_list); + gd->cyclic->cyclic_ready = true; + + return 0; +} diff --git a/include/asm-generic/global_data.h b/include/asm-generic/global_data.h index 805a6fd679..9006c76927 100644 --- a/include/asm-generic/global_data.h +++ b/include/asm-generic/global_data.h @@ -20,6 +20,7 @@ */ #ifndef __ASSEMBLY__ +#include #include #include #include @@ -473,6 +474,12 @@ struct global_data { * @event_state: Points to the current state of events */ struct event_state event_state; +#endif +#ifdef CONFIG_CYCLIC + /** + * @cyclic: cyclic driver data + */ + struct cyclic_drv *cyclic; #endif /** * @dmtag_list: List of DM tags diff --git a/include/cyclic.h b/include/cyclic.h new file mode 100644 index 0000000000..23902234cc --- /dev/null +++ b/include/cyclic.h @@ -0,0 +1,138 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * A general-purpose cyclic execution infrastructure, to allow "small" + * (run-time wise) functions to be executed at a specified frequency. + * Things like LED blinking or watchdog triggering are examples for such + * tasks. + * + * Copyright (C) 2022 Stefan Roese + */ + +#ifndef __cyclic_h +#define __cyclic_h + +#include +#include + +/** + * struct cyclic_drv - Cyclic driver internal data + * + * @cyclic_list: Cylic list node + * @cyclic_ready: Flag if cyclic infrastructure is ready + * @cyclic_running: Flag if cyclic infrastructure is running + */ +struct cyclic_drv { + struct list_head cyclic_list; + bool cyclic_ready; + bool cyclic_running; +}; + +/** + * struct cyclic_info - Information about cyclic execution function + * + * @func: Function to call periodically + * @ctx: Context pointer to get passed to this function + * @name: Name of the cyclic function, e.g. shown in the commands + * @delay_ns: Delay is ns after which this function shall get executed + * @start_time_us: Start time in us, when this function started its execution + * @cpu_time_us: Total CPU time of this function + * @run_cnt: Counter of executions occurances + * @next_call: Next time in us, when the function shall be executed again + * @list: List node + */ +struct cyclic_info { + void (*func)(void *ctx); + void *ctx; + char *name; + uint64_t delay_us; + uint64_t start_time_us; + uint64_t cpu_time_us; + uint64_t run_cnt; + uint64_t next_call; + struct list_head list; +}; + +/** Function type for cyclic functions */ +typedef void (*cyclic_func_t)(void *ctx); + +#if defined(CONFIG_CYCLIC) +/** + * cyclic_register - Register a new cyclic function + * + * @func: Function to call periodically + * @delay_us: Delay is us after which this function shall get executed + * @name: Cyclic function name/id + * @ctx: Context to pass to the function + * @return: pointer to cyclic_struct if OK, NULL on error + */ +struct cyclic_info *cyclic_register(cyclic_func_t func, uint64_t delay_us, + const char *name, void *ctx); + +/** + * cyclic_unregister - Unregister a cyclic function + * + * @cyclic: Pointer to cyclic_struct of the function that shall be removed + * @return: 0 if OK, -ve on error + */ +int cyclic_unregister(struct cyclic_info *cyclic); + +/** + * cyclic_init() - Set up cyclic functions + * + * Init a list of cyclic functions, so that these can be added as needed + */ +int cyclic_init(void); + +/** + * cyclic_uninit() - Clean up cyclic functions + * + * This removes all cyclic functions + */ +int cyclic_uninit(void); + +/** + * cyclic_get_list() - Get cyclic list pointer + * + * Return the cyclic list pointer + * + * @return: pointer to cyclic_list + */ +struct list_head *cyclic_get_list(void); + +/** + * cyclic_run() - Interate over all registered cyclic functions + * + * Interate over all registered cyclic functions and if the it's function + * needs to be executed, then call into these registered functions. + */ +void cyclic_run(void); +#else +static inline struct cyclic_info *cyclic_register(cyclic_func_t func, + uint64_t delay_us, + const char *name, + void *ctx) +{ + return NULL; +} + +static inline int cyclic_unregister(struct cyclic_info *cyclic) +{ + return 0; +} + +static inline void cyclic_run(void) +{ +} + +static inline int cyclic_init(void) +{ + return 0; +} + +static inline int cyclic_uninit(void) +{ + return 0; +} +#endif + +#endif From 661cdaa79d961248bc8290f421d9cf3eb8defffd Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Fri, 2 Sep 2022 13:57:49 +0200 Subject: [PATCH 117/374] cyclic: Integrate cyclic infrastructure into WATCHDOG_RESET This patch integrates the main function responsible for calling all registered cyclic functions cyclic_run() into the common WATCHDOG_RESET macro. This guarantees that cyclic_run() is executed very often, which is necessary for the cyclic functions to get scheduled and executed at their configured periods. If CONFIG_WATCHDOG is not enabled, only cyclic_run() without calling watchdog_reset(). This guarantees that the cyclic functionality does not rely on CONFIG_WATCHDOG being enabled. Signed-off-by: Stefan Roese Reviewed-by: Simon Glass --- fs/cramfs/uncompress.c | 2 +- include/watchdog.h | 23 ++++++++++++++++++++--- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/fs/cramfs/uncompress.c b/fs/cramfs/uncompress.c index f431cc46c1..38e10e2e44 100644 --- a/fs/cramfs/uncompress.c +++ b/fs/cramfs/uncompress.c @@ -62,7 +62,7 @@ int cramfs_uncompress_init (void) stream.avail_in = 0; #if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG) - stream.outcb = (cb_func) WATCHDOG_RESET; + stream.outcb = (cb_func)watchdog_reset_func; #else stream.outcb = Z_NULL; #endif /* CONFIG_HW_WATCHDOG */ diff --git a/include/watchdog.h b/include/watchdog.h index 813cc8f2a5..0a9777edcb 100644 --- a/include/watchdog.h +++ b/include/watchdog.h @@ -11,6 +11,8 @@ #define _WATCHDOG_H_ #if !defined(__ASSEMBLY__) +#include + /* * Reset the watchdog timer, always returns 0 * @@ -60,11 +62,16 @@ int init_func_watchdog_reset(void); /* Don't require the watchdog to be enabled in SPL */ #if defined(CONFIG_SPL_BUILD) && \ !defined(CONFIG_SPL_WATCHDOG) - #define WATCHDOG_RESET() {} + #define WATCHDOG_RESET() { \ + cyclic_run(); \ + } #else extern void watchdog_reset(void); - #define WATCHDOG_RESET watchdog_reset + #define WATCHDOG_RESET() { \ + watchdog_reset(); \ + cyclic_run(); \ + } #endif #endif #else @@ -74,11 +81,21 @@ int init_func_watchdog_reset(void); #if defined(__ASSEMBLY__) #define WATCHDOG_RESET /*XXX DO_NOT_DEL_THIS_COMMENT*/ #else - #define WATCHDOG_RESET() {} + #define WATCHDOG_RESET() { \ + cyclic_run(); \ + } #endif /* __ASSEMBLY__ */ #endif /* CONFIG_WATCHDOG && !__ASSEMBLY__ */ #endif /* CONFIG_HW_WATCHDOG */ +#if !defined(__ASSEMBLY__) +/* Currently only needed for fs/cramfs/uncompress.c */ +static inline void watchdog_reset_func(void) +{ + WATCHDOG_RESET(); +} +#endif + /* * Prototypes from $(CPU)/cpu.c. */ From 70545642a0fdc5d7eb1664174dbd4d06a1a62e81 Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Fri, 2 Sep 2022 13:57:50 +0200 Subject: [PATCH 118/374] cyclic: Integrate cyclic functionality at bootup in board_r/f This patch adds a call to cyclic_init() to board_f/r.c, enabling the common cyclic infrastructure. After this it's possible to add cyclic functions via cyclic_register(). Signed-off-by: Stefan Roese Reviewed-by: Simon Glass --- common/board_f.c | 2 ++ common/board_r.c | 2 ++ 2 files changed, 4 insertions(+) diff --git a/common/board_f.c b/common/board_f.c index 18e2246733..deb46be182 100644 --- a/common/board_f.c +++ b/common/board_f.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -828,6 +829,7 @@ static const init_fnc_t init_sequence_f[] = { initf_malloc, log_init, initf_bootstage, /* uses its own timer, so does not need DM */ + cyclic_init, event_init, #ifdef CONFIG_BLOBLIST bloblist_init, diff --git a/common/board_r.c b/common/board_r.c index 56eb60fa27..062bc3e688 100644 --- a/common/board_r.c +++ b/common/board_r.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #ifdef CONFIG_MTD_NOR_FLASH @@ -611,6 +612,7 @@ static init_fnc_t init_sequence_r[] = { #endif initr_barrier, initr_malloc, + cyclic_init, log_init, initr_bootstage, /* Needs malloc() but has its own timer */ #if defined(CONFIG_CONSOLE_RECORD) From 1f865ee0baa3009bda3d9dd7808d0473424fae11 Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Fri, 2 Sep 2022 13:57:51 +0200 Subject: [PATCH 119/374] cyclic: Add 'cyclic list' and 'cyclic demo' commands This patch adds the cyclic command, which currently only supports the 'list' subcommand, to list all currently registered cyclic functions. Here an example: => cyclic list function: cyclic_demo, cpu-time: 7010 us, frequency: 99.80 times/s function: cyclic_demo2, cpu-time: 1 us, frequency: 1.13 times/s As you can see, the cpu-time is accounted, so that cyclic functions that take too long might be discovered. Additionally the frequency is logged. The 'cyclic demo' commands registers the cyclic_demo() function to be executed all 'cycletime_ms' milliseconds. The only thing this function does is delaying by 'delay_us' microseconds. Signed-off-by: Stefan Roese Reviewed-by: Simon Glass --- MAINTAINERS | 1 + cmd/Kconfig | 16 ++++++++++ cmd/Makefile | 1 + cmd/cyclic.c | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 102 insertions(+) create mode 100644 cmd/cyclic.c diff --git a/MAINTAINERS b/MAINTAINERS index 4af527e639..25a11a06c6 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -798,6 +798,7 @@ F: doc/arch/m68k.rst CYCLIC M: Stefan Roese S: Maintained +F: cmd/cyclic.c F: common/cyclic.c F: include/cyclic.h diff --git a/cmd/Kconfig b/cmd/Kconfig index 67c7d2512f..7d574d4ab7 100644 --- a/cmd/Kconfig +++ b/cmd/Kconfig @@ -2511,6 +2511,22 @@ config CMD_CBSYSINFO memory by coreboot before jumping to U-Boot. It can be useful for debugging the beaaviour of coreboot or U-Boot. +config CMD_CYCLIC + bool "cyclic - Show information about cyclic functions" + depends on CYCLIC + default y + help + This enables the 'cyclic' command which provides information about + cyclic execution functions. This infrastructure allows registering + functions to be executed cyclically, e.g. every 100ms. These commands + are supported: + + cyclic list - list cyclic functions + cyclic cyclic demo - register cyclic + demo function + + See doc/develop/cyclic.rst for more details. + config CMD_DIAG bool "diag - Board diagnostics" help diff --git a/cmd/Makefile b/cmd/Makefile index 7abe1d3630..b2df59baef 100644 --- a/cmd/Makefile +++ b/cmd/Makefile @@ -56,6 +56,7 @@ obj-$(CONFIG_CMD_DIAG) += diag.o endif obj-$(CONFIG_CMD_ADTIMG) += adtimg.o obj-$(CONFIG_CMD_ABOOTIMG) += abootimg.o +obj-$(CONFIG_CMD_CYCLIC) += cyclic.o obj-$(CONFIG_CMD_EVENT) += event.o obj-$(CONFIG_CMD_EXTENSION) += extension_board.o obj-$(CONFIG_CMD_ECHO) += echo.o diff --git a/cmd/cyclic.c b/cmd/cyclic.c new file mode 100644 index 0000000000..c1bc556aad --- /dev/null +++ b/cmd/cyclic.c @@ -0,0 +1,84 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * A general-purpose cyclic execution infrastructure, to allow "small" + * (run-time wise) functions to be executed at a specified frequency. + * Things like LED blinking or watchdog triggering are examples for such + * tasks. + * + * Copyright (C) 2022 Stefan Roese + */ + +#include +#include +#include +#include +#include +#include + +struct cyclic_demo_info { + uint delay_us; +}; + +static void cyclic_demo(void *ctx) +{ + struct cyclic_demo_info *info = ctx; + + /* Just a small dummy delay here */ + udelay(info->delay_us); +} + +static int do_cyclic_demo(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) +{ + struct cyclic_demo_info *info; + struct cyclic_info *cyclic; + uint time_ms; + + if (argc < 3) + return CMD_RET_USAGE; + + info = malloc(sizeof(struct cyclic_demo_info)); + if (!info) { + printf("out of memory\n"); + return CMD_RET_FAILURE; + } + + time_ms = simple_strtoul(argv[1], NULL, 0); + info->delay_us = simple_strtoul(argv[2], NULL, 0); + + /* Register demo cyclic function */ + cyclic = cyclic_register(cyclic_demo, time_ms * 1000, "cyclic_demo", + info); + if (!cyclic) + printf("Registering of cyclic_demo failed\n"); + + printf("Registered function \"%s\" to be executed all %dms\n", + "cyclic_demo", time_ms); + + return 0; +} + +static int do_cyclic_list(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) +{ + struct cyclic_info *cyclic, *tmp; + u64 cnt, freq; + + list_for_each_entry_safe(cyclic, tmp, cyclic_get_list(), list) { + cnt = cyclic->run_cnt * 1000000ULL * 100ULL; + freq = lldiv(cnt, timer_get_us() - cyclic->start_time_us); + printf("function: %s, cpu-time: %lld us, frequency: %lld.%02d times/s\n", + cyclic->name, cyclic->cpu_time_us, + lldiv(freq, 100), do_div(freq, 100)); + } + + return 0; +} + +static char cyclic_help_text[] = + "cyclic demo - register cyclic demo function\n" + "cyclic list - list cyclic functions\n"; + +U_BOOT_CMD_WITH_SUBCMDS(cyclic, "Cyclic", cyclic_help_text, + U_BOOT_SUBCMD_MKENT(demo, 3, 1, do_cyclic_demo), + U_BOOT_SUBCMD_MKENT(list, 1, 1, do_cyclic_list)); From 5ee0fa722c300d443b82d214a67583b36ae40909 Mon Sep 17 00:00:00 2001 From: Aaron Williams Date: Fri, 2 Sep 2022 13:57:52 +0200 Subject: [PATCH 120/374] mips: octeon_nic23: Add PCIe FLR fixup via cyclic infrastructure This patch adds a fixup function related to a PCIe FLR (Function Level Reset) problem on the NIC23 PCIe board. This function is imported from the Marvell Octeon 2013 U-Boot version as a (nearly) verbatim copy. It uses the newly introduced cyclic infrastructure, so that this function gets called every 100us, which is needed to detect this FLR issue. Signed-off-by: Aaron Williams Signed-off-by: Stefan Roese --- board/Marvell/octeon_nic23/board.c | 197 +++++++++++++++++++++++++++++ configs/octeon_nic23_defconfig | 3 + 2 files changed, 200 insertions(+) diff --git a/board/Marvell/octeon_nic23/board.c b/board/Marvell/octeon_nic23/board.c index 3e2c544443..08b1aa4b6e 100644 --- a/board/Marvell/octeon_nic23/board.c +++ b/board/Marvell/octeon_nic23/board.c @@ -3,8 +3,10 @@ * Copyright (C) 2021-2022 Stefan Roese */ +#include #include #include +#include #include #include @@ -15,11 +17,90 @@ #include #include #include +#include #include "board_ddr.h" +/** + * cvmx_spem#_cfg_rd + * + * This register allows read access to the configuration in the PCIe core. + * + */ +union cvmx_spemx_cfg_rd { + u64 u64; + struct cvmx_spemx_cfg_rd_s { + u64 data : 32; + u64 addr : 32; + } s; + struct cvmx_spemx_cfg_rd_s cn73xx; +}; + +/** + * cvmx_spem#_cfg_wr + * + * This register allows write access to the configuration in the PCIe core. + * + */ +union cvmx_spemx_cfg_wr { + u64 u64; + struct cvmx_spemx_cfg_wr_s { + u64 data : 32; + u64 addr : 32; + } s; + struct cvmx_spemx_cfg_wr_s cn73xx; +}; + +/** + * cvmx_spem#_flr_pf_stopreq + * + * PF function level reset stop outbound requests register. + * Hardware automatically sets the STOPREQ bit for the PF when it enters a + * function level reset (FLR). Software is responsible for clearing the STOPREQ + * bit but must not do so prior to hardware taking down the FLR, which could be + * as long as 100ms. It may be appropriate for software to wait longer before clearing + * STOPREQ, software may need to drain deep DPI queues for example. + * Whenever SPEM receives a PF or child VF request mastered by CNXXXX over S2M (i.e. P or NP), + * when STOPREQ is set for the function, SPEM will discard the outgoing request + * before sending it to the PCIe core. If a NP, SPEM will schedule an immediate + * SWI_RSP_ERROR completion for the request - no timeout is required. + * In both cases, SPEM()_DBG_PF()_INFO[P()_BMD_E] will be set and a error + * interrupt is generated. + * + * STOPREQ mimics the behavior of PCIEEP()_CFG001[ME] for outbound requests that will + * master the PCIe bus (P and NP). + * + * STOPREQ will have no effect on completions returned by CNXXXX over the S2M, + * nor on M2S traffic. + * + * When a PF()_STOPREQ is set, none of the associated + * PEM()_FLR_PF()_VF_STOPREQ[VF_STOPREQ] will be set. + * + * STOPREQ is reset when the MAC is reset, and is not reset after a chip soft reset. + */ +union cvmx_spemx_flr_pf_stopreq { + u64 u64; + struct cvmx_spemx_flr_pf_stopreq_s { + u64 reserved_3_63 : 61; + u64 pf2_stopreq : 1; + u64 pf1_stopreq : 1; + u64 pf0_stopreq : 1; + } s; + struct cvmx_spemx_flr_pf_stopreq_s cn73xx; +}; + +#define CVMX_SPEMX_CFG_WR(offset) 0x00011800C0000028ull +#define CVMX_SPEMX_CFG_RD(offset) 0x00011800C0000030ull +#define CVMX_SPEMX_FLR_PF_STOPREQ(offset) 0x00011800C0000218ull + +#define DTX_SELECT_LTSSM 0x0 +#define DTX_SELECT_LTSSM_ENA 0x3ff +#define LTSSM_L0 0x11 + #define NIC23_DEF_DRAM_FREQ 800 +static u32 pci_cfgspace_reg0[2] = { 0, 0 }; + static u8 octeon_nic23_cfg0_spd_values[512] = { OCTEON_NIC23_CFG0_SPD_VALUES }; @@ -145,8 +226,118 @@ void board_configure_qlms(void) cvmx_qlm_measure_clock(4), cvmx_qlm_measure_clock(5)); } +/** + * If there is a PF FLR then the PCI EEPROM is not re-read. In this case + * we need to re-program the vendor and device ID immediately after hardware + * completes FLR. + * + * PCI spec requires FLR to be completed within 100ms. The user who triggered + * FLR expects hardware to finish FLR within 100ms, otherwise the user will + * end up reading DEVICE_ID incorrectly from the reset value. + * CN23XX exits FLR at any point between 66 and 99ms, so U-Boot has to wait + * 99ms to let hardware finish its part, then finish reprogramming the + * correct device ID before the end of 100ms. + * + * Note: this solution only works properly when there is no other activity + * within U-Boot for 100ms from the time FLR is triggered. + * + * This function gets called every 100usec. If FLR happens during any + * other activity like bootloader/image update then it is possible that + * this function does not get called for more than the FLR period which will + * cause the PF device ID restore to happen after whoever initiated the FLR to + * read the incorrect device ID 0x9700 (reset value) instead of 0x9702 + * (restored value). + */ +static void octeon_board_restore_pf(void *ctx) +{ + union cvmx_spemx_flr_pf_stopreq stopreq; + static bool start_initialized[2] = {false, false}; + bool pf0_flag, pf1_flag; + u64 ltssm_bits; + const u64 pf_flr_wait_usecs = 99700; + u64 elapsed_usecs; + union cvmx_spemx_cfg_wr cfg_wr; + union cvmx_spemx_cfg_rd cfg_rd; + static u64 start_us[2]; + int pf_num; + + csr_wr(CVMX_DTX_SPEM_SELX(0), DTX_SELECT_LTSSM); + csr_rd(CVMX_DTX_SPEM_SELX(0)); + csr_wr(CVMX_DTX_SPEM_ENAX(0), DTX_SELECT_LTSSM_ENA); + csr_rd(CVMX_DTX_SPEM_ENAX(0)); + ltssm_bits = csr_rd(CVMX_DTX_SPEM_DATX(0)); + if (((ltssm_bits >> 3) & 0x3f) != LTSSM_L0) + return; + + stopreq.u64 = csr_rd(CVMX_SPEMX_FLR_PF_STOPREQ(0)); + pf0_flag = stopreq.s.pf0_stopreq; + pf1_flag = stopreq.s.pf1_stopreq; + /* See if PF interrupt happened */ + if (!(pf0_flag || pf1_flag)) + return; + + if (pf0_flag && !start_initialized[0]) { + start_initialized[0] = true; + start_us[0] = get_timer_us(0); + } + + /* Store programmed PCIe DevID SPEM0 PF0 */ + if (pf0_flag && !pci_cfgspace_reg0[0]) { + cfg_rd.s.addr = (0 << 24) | 0x0; + csr_wr(CVMX_SPEMX_CFG_RD(0), cfg_rd.u64); + cfg_rd.u64 = csr_rd(CVMX_SPEMX_CFG_RD(0)); + pci_cfgspace_reg0[0] = cfg_rd.s.data; + } + + if (pf1_flag && !start_initialized[1]) { + start_initialized[1] = true; + start_us[1] = get_timer_us(0); + } + + /* Store programmed PCIe DevID SPEM0 PF1 */ + if (pf1_flag && !pci_cfgspace_reg0[1]) { + cfg_rd.s.addr = (1 << 24) | 0x0; + csr_wr(CVMX_SPEMX_CFG_RD(0), cfg_rd.u64); + cfg_rd.u64 = csr_rd(CVMX_SPEMX_CFG_RD(0)); + pci_cfgspace_reg0[1] = cfg_rd.s.data; + } + + /* For PF, rewrite pci config space reg 0 */ + for (pf_num = 0; pf_num < 2; pf_num++) { + if (!start_initialized[pf_num]) + continue; + + elapsed_usecs = get_timer_us(0) - start_us[pf_num]; + + if (elapsed_usecs > pf_flr_wait_usecs) { + /* Here, our measured FLR duration has passed; + * check if device ID has been reset, + * which indicates FLR completion (per MA team). + */ + cfg_rd.s.addr = (pf_num << 24) | 0x0; + csr_wr(CVMX_SPEMX_CFG_RD(0), cfg_rd.u64); + cfg_rd.u64 = csr_rd(CVMX_SPEMX_CFG_RD(0)); + /* if DevID has NOT been reset, FLR is not yet + * complete + */ + if (cfg_rd.s.data != pci_cfgspace_reg0[pf_num]) { + stopreq.s.pf0_stopreq = (pf_num == 0) ? 1 : 0; + stopreq.s.pf1_stopreq = (pf_num == 1) ? 1 : 0; + csr_wr(CVMX_SPEMX_FLR_PF_STOPREQ(0), stopreq.u64); + + cfg_wr.u64 = 0; + cfg_wr.s.addr = (pf_num << 24) | 0; + cfg_wr.s.data = pci_cfgspace_reg0[pf_num]; + csr_wr(CVMX_SPEMX_CFG_WR(0), cfg_wr.u64); + start_initialized[pf_num] = false; + } + } + } +} + int board_late_init(void) { + struct cyclic_info *cyclic; struct gpio_desc gpio = {}; ofnode node; @@ -164,6 +355,12 @@ int board_late_init(void) board_configure_qlms(); + /* Register cyclic function for PCIe FLR fixup */ + cyclic = cyclic_register(octeon_board_restore_pf, 100, + "pcie_flr_fix", NULL); + if (!cyclic) + printf("Registering of cyclic function failed\n"); + return 0; } diff --git a/configs/octeon_nic23_defconfig b/configs/octeon_nic23_defconfig index 95e98c1161..098831e0b1 100644 --- a/configs/octeon_nic23_defconfig +++ b/configs/octeon_nic23_defconfig @@ -20,6 +20,8 @@ CONFIG_AHCI=y CONFIG_OF_BOARD_FIXUP=y CONFIG_SYS_CONSOLE_ENV_OVERWRITE=y # CONFIG_SYS_DEVICE_NULLDEV is not set +CONFIG_CYCLIC=y +CONFIG_CYCLIC_MAX_CPU_TIME_US=5000 CONFIG_ARCH_MISC_INIT=y CONFIG_BOARD_EARLY_INIT_F=y CONFIG_BOARD_LATE_INIT=y @@ -41,6 +43,7 @@ CONFIG_CMD_TIME=y CONFIG_CMD_EXT4=y CONFIG_CMD_FAT=y CONFIG_CMD_FS_GENERIC=y +CONFIG_CMD_CYCLIC=y CONFIG_EFI_PARTITION=y CONFIG_ENV_IS_IN_SPI_FLASH=y CONFIG_TFTP_TSIZE=y From 00275f5ead89dcbed583da2a698b7ba2c6384d0d Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Fri, 2 Sep 2022 13:57:53 +0200 Subject: [PATCH 121/374] cyclic: Add documentation Add documentation for the cyclic function infrastructure, including the cyclic command. Signed-off-by: Stefan Roese Reviewed-by: Simon Glass --- doc/develop/cyclic.rst | 50 ++++++++++++++++++++++++++++++++++++++++ doc/develop/index.rst | 1 + doc/usage/cmd/cyclic.rst | 45 ++++++++++++++++++++++++++++++++++++ doc/usage/index.rst | 1 + 4 files changed, 97 insertions(+) create mode 100644 doc/develop/cyclic.rst create mode 100644 doc/usage/cmd/cyclic.rst diff --git a/doc/develop/cyclic.rst b/doc/develop/cyclic.rst new file mode 100644 index 0000000000..43bedacb9f --- /dev/null +++ b/doc/develop/cyclic.rst @@ -0,0 +1,50 @@ +.. SPDX-License-Identifier: GPL-2.0+ + +Cyclic functions +================ + +The cyclic function execution infrastruture provides a way to periodically +execute code, e.g. every 100ms. Examples for such functions might be LED +blinking etc. The functions that are hooked into this cyclic list should +be small timewise as otherwise the execution of the other code that relies +on a high frequent polling (e.g. UART rx char ready check) might be +delayed too much. To detect cyclic functions with a too long execution +time, the Kconfig option `CONFIG_CYCLIC_MAX_CPU_TIME_US` is introduced, +which configures the max allowed time for such a cyclic function. If it's +execution time exceeds this time, this cyclic function will get removed +from the cyclic list. + +Registering a cyclic function +----------------------------- + +To register a cyclic function, use something like this:: + + static void cyclic_demo(void *ctx) + { + /* Just a small dummy delay here */ + udelay(10); + } + + int board_init(void) + { + struct cyclic_info *cyclic; + + /* Register demo cyclic function */ + cyclic = cyclic_register(cyclic_demo, 10 * 1000, "cyclic_demo", NULL); + if (!cyclic) + printf("Registering of cyclic_demo failed\n"); + + return 0; + } + +This will register the function `cyclic_demo()` to be periodically +executed all 10ms. + +How is this cyclic functionality integrated / executed? +-------------------------------------------------------- + +The cyclic infrastructure integrates the main function responsible for +calling all registered cyclic functions cyclic_run() into the common +WATCHDOG_RESET macro. This guarantees that cyclic_run() is executed +very often, which is necessary for the cyclic functions to get scheduled +and executed at their configured periods. diff --git a/doc/develop/index.rst b/doc/develop/index.rst index f7ee09db24..ce6b38e576 100644 --- a/doc/develop/index.rst +++ b/doc/develop/index.rst @@ -27,6 +27,7 @@ Implementation ci_testing commands config_binding + cyclic devicetree/index distro driver-model/index diff --git a/doc/usage/cmd/cyclic.rst b/doc/usage/cmd/cyclic.rst new file mode 100644 index 0000000000..3085cc7204 --- /dev/null +++ b/doc/usage/cmd/cyclic.rst @@ -0,0 +1,45 @@ +.. SPDX-License-Identifier: GPL-2.0+ + +cyclic command +============== + +Synopsis +-------- + +:: + + cyclic list + +Description +----------- + +The cyclic list command provides a list of the currently registered +cyclic functions. + +This shows the following information: + +Function + Function name + +cpu-time + Total time spent in this cyclic function. + +Frequency + Frequency of execution of this function, e.g. 100 times/s for a + pediod of 10ms. + + +See :doc:`../../develop/cyclic` for more information on cyclic functions. + +Example +------- + +:: + + => cyclic list + function: cyclic_demo, cpu-time: 52906 us, frequency: 99.20 times/s + +Configuration +------------- + +The cyclic command is only available if CONFIG_CMD_CYCLIC=y. diff --git a/doc/usage/index.rst b/doc/usage/index.rst index 5170fa8b4a..10313f83dd 100644 --- a/doc/usage/index.rst +++ b/doc/usage/index.rst @@ -33,6 +33,7 @@ Shell commands cmd/bootz cmd/cbsysinfo cmd/conitrace + cmd/cyclic cmd/dm cmd/echo cmd/env From af042c211d017f5a1c324fea9e817e33bfd2a475 Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Fri, 2 Sep 2022 13:57:54 +0200 Subject: [PATCH 122/374] cyclic: Add a simple test Add a test for cyclic function registration and activation. Signed-off-by: Stefan Roese Reviewed-by: Simon Glass --- test/common/Makefile | 1 + test/common/cyclic.c | 35 +++++++++++++++++++++++++++++++++++ test/test-main.c | 3 +++ 3 files changed, 39 insertions(+) create mode 100644 test/common/cyclic.c diff --git a/test/common/Makefile b/test/common/Makefile index 9087788ba6..cc918f64e5 100644 --- a/test/common/Makefile +++ b/test/common/Makefile @@ -1,4 +1,5 @@ # SPDX-License-Identifier: GPL-2.0+ obj-y += cmd_ut_common.o obj-$(CONFIG_AUTOBOOT) += test_autoboot.o +obj-$(CONFIG_CYCLIC) += cyclic.o obj-$(CONFIG_EVENT) += event.o diff --git a/test/common/cyclic.c b/test/common/cyclic.c new file mode 100644 index 0000000000..a5c4e78989 --- /dev/null +++ b/test/common/cyclic.c @@ -0,0 +1,35 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2022 Stefan Roese + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/* Test that cyclic function is called */ +static bool cyclic_active = false; + +static void cyclic_test(void *ctx) +{ + cyclic_active = true; +} + +static int dm_test_cyclic_running(struct unit_test_state *uts) +{ + cyclic_active = false; + ut_assertnonnull(cyclic_register(cyclic_test, 10 * 1000, "cyclic_demo", + NULL)); + + /* Execute all registered cyclic functions */ + WATCHDOG_RESET(); + ut_asserteq(true, cyclic_active); + + return 0; +} +COMMON_TEST(dm_test_cyclic_running, 0); diff --git a/test/test-main.c b/test/test-main.c index 4f1c54b0f9..ae34002a3d 100644 --- a/test/test-main.c +++ b/test/test-main.c @@ -6,6 +6,7 @@ #include #include +#include #include #include #include @@ -220,6 +221,7 @@ static int dm_test_restore(struct device_node *of_root) static int test_pre_run(struct unit_test_state *uts, struct unit_test *test) { ut_assertok(event_init()); + ut_assertok(cyclic_init()); if (test->flags & UT_TESTF_DM) ut_assertok(dm_test_pre_run(uts)); @@ -265,6 +267,7 @@ static int test_post_run(struct unit_test_state *uts, struct unit_test *test) ut_unsilence_console(uts); if (test->flags & UT_TESTF_DM) ut_assertok(dm_test_post_run(uts)); + ut_assertok(cyclic_uninit()); ut_assertok(event_uninit()); return 0; From 87d791423ac69affec43dfb834965adcb0aa02e6 Mon Sep 17 00:00:00 2001 From: Masahisa Kojima Date: Mon, 12 Sep 2022 17:33:50 +0900 Subject: [PATCH 123/374] eficonfig: menu-driven addition of UEFI boot option This commit add the "eficonfig" command. The "eficonfig" command implements the menu-driven UEFI boot option maintenance feature. This commit implements the addition of new boot option. User can select the block device volume having efi_simple_file_system_protocol and select the file corresponding to the Boot#### variable. User can also enter the description and optional_data of the BOOT#### variable in utf8. This commit adds "include/efi_config.h", it contains the common definition to be used from other menus such as UEFI Secure Boot key management. Signed-off-by: Masahisa Kojima --- cmd/Kconfig | 7 + cmd/Makefile | 1 + cmd/eficonfig.c | 1608 +++++++++++++++++++++++++++++++++ include/efi_config.h | 96 ++ include/efi_loader.h | 37 + lib/efi_loader/efi_bootmgr.c | 3 + lib/efi_loader/efi_boottime.c | 52 +- lib/efi_loader/efi_console.c | 70 ++ lib/efi_loader/efi_disk.c | 50 + lib/efi_loader/efi_file.c | 75 +- 10 files changed, 1952 insertions(+), 47 deletions(-) create mode 100644 cmd/eficonfig.c create mode 100644 include/efi_config.h diff --git a/cmd/Kconfig b/cmd/Kconfig index 67c7d2512f..ea506a0ac5 100644 --- a/cmd/Kconfig +++ b/cmd/Kconfig @@ -1928,6 +1928,13 @@ config CMD_EFIDEBUG particularly for managing boot parameters as well as examining various EFI status for debugging. +config CMD_EFICONFIG + bool "eficonfig - provide menu-driven uefi variables maintenance interface" + depends on CMD_BOOTEFI_BOOTMGR + help + Enable the 'eficonfig' command which provides the menu-driven UEFI + variable maintenance interface. + config CMD_EXCEPTION bool "exception - raise exception" depends on ARM || RISCV || SANDBOX || X86 diff --git a/cmd/Makefile b/cmd/Makefile index 7abe1d3630..3b027d31ba 100644 --- a/cmd/Makefile +++ b/cmd/Makefile @@ -63,6 +63,7 @@ obj-$(CONFIG_ENV_IS_IN_EEPROM) += eeprom.o obj-$(CONFIG_CMD_EEPROM) += eeprom.o obj-$(CONFIG_EFI) += efi.o obj-$(CONFIG_CMD_EFIDEBUG) += efidebug.o +obj-$(CONFIG_CMD_EFICONFIG) += eficonfig.o obj-$(CONFIG_CMD_ELF) += elf.o obj-$(CONFIG_CMD_EROFS) += erofs.o obj-$(CONFIG_HUSH_PARSER) += exit.o diff --git a/cmd/eficonfig.c b/cmd/eficonfig.c new file mode 100644 index 0000000000..2d142c4c9b --- /dev/null +++ b/cmd/eficonfig.c @@ -0,0 +1,1608 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Menu-driven UEFI Variable maintenance + * + * Copyright (c) 2022 Masahisa Kojima, Linaro Limited + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static struct efi_simple_text_input_protocol *cin; + +#define EFICONFIG_DESCRIPTION_MAX 32 +#define EFICONFIG_OPTIONAL_DATA_MAX 64 + +/** + * struct eficonfig_filepath_info - structure to be used to store file path + * + * @name: file or directory name + * @list: list structure + */ +struct eficonfig_filepath_info { + char *name; + struct list_head list; +}; + +/** + * struct eficonfig_boot_option - structure to be used for updating UEFI boot option + * + * @file_info: user selected file info + * @initrd_info: user selected initrd file info + * @boot_index: index of the boot option + * @description: pointer to the description string + * @optional_data: pointer to the optional_data + * @edit_completed: flag indicates edit complete + */ +struct eficonfig_boot_option { + struct eficonfig_select_file_info file_info; + struct eficonfig_select_file_info initrd_info; + unsigned int boot_index; + u16 *description; + u16 *optional_data; + bool edit_completed; +}; + +/** + * struct eficonfig_volume_entry_data - structure to be used to store volume info + * + * @file_info: pointer to file info structure + * @v: pointer to the protocol interface + * @dp: pointer to the device path + */ +struct eficonfig_volume_entry_data { + struct eficonfig_select_file_info *file_info; + struct efi_simple_file_system_protocol *v; + struct efi_device_path *dp; +}; + +/** + * struct eficonfig_file_entry_data - structure to be used to store file info + * + * @file_info: pointer to file info structure + * @is_directory: flag to identify the directory or file + * @file_name: name of directory or file + */ +struct eficonfig_file_entry_data { + struct eficonfig_select_file_info *file_info; + bool is_directory; + char *file_name; +}; + +/** + * eficonfig_print_msg() - print message + * + * display the message to the user, user proceeds the screen + * with any key press. + * + * @items: pointer to the structure of each menu entry + * @count: the number of menu entry + * @menu_header: pointer to the menu header string + * Return: status code + */ +void eficonfig_print_msg(char *msg) +{ + /* Flush input */ + while (tstc()) + getchar(); + + printf(ANSI_CURSOR_HIDE + ANSI_CLEAR_CONSOLE + ANSI_CURSOR_POSITION + "%s\n\n Press any key to continue", 3, 4, msg); + + getchar(); +} + +/** + * eficonfig_print_entry() - print each menu entry + * + * @data: pointer to the data associated with each menu entry + */ +static void eficonfig_print_entry(void *data) +{ + struct eficonfig_entry *entry = data; + int reverse = (entry->efi_menu->active == entry->num); + + /* TODO: support scroll or page for many entries */ + + /* + * Move cursor to line where the entry will be drawn (entry->num) + * First 3 lines(menu header) + 1 empty line + */ + printf(ANSI_CURSOR_POSITION, entry->num + 4, 7); + + if (reverse) + puts(ANSI_COLOR_REVERSE); + + printf("%s", entry->title); + + if (reverse) + puts(ANSI_COLOR_RESET); +} + +/** + * eficonfig_display_statusline() - print status line + * + * @m: pointer to the menu structure + */ +static void eficonfig_display_statusline(struct menu *m) +{ + struct eficonfig_entry *entry; + + if (menu_default_choice(m, (void *)&entry) < 0) + return; + + printf(ANSI_CURSOR_POSITION + "\n%s\n" + ANSI_CURSOR_POSITION ANSI_CLEAR_LINE ANSI_CURSOR_POSITION + " Press UP/DOWN to move, ENTER to select, ESC/CTRL+C to quit" + ANSI_CLEAR_LINE_TO_END ANSI_CURSOR_POSITION ANSI_CLEAR_LINE, + 1, 1, entry->efi_menu->menu_header, entry->efi_menu->count + 5, 1, + entry->efi_menu->count + 6, 1, entry->efi_menu->count + 7, 1); +} + +/** + * eficonfig_choice_entry() - user key input handler + * + * @data: pointer to the efimenu structure + * Return: key string to identify the selected entry + */ +static char *eficonfig_choice_entry(void *data) +{ + int esc = 0; + struct list_head *pos, *n; + struct eficonfig_entry *entry; + enum bootmenu_key key = KEY_NONE; + struct efimenu *efi_menu = data; + + while (1) { + bootmenu_loop((struct bootmenu_data *)efi_menu, &key, &esc); + + switch (key) { + case KEY_UP: + if (efi_menu->active > 0) + --efi_menu->active; + /* no menu key selected, regenerate menu */ + return NULL; + case KEY_DOWN: + if (efi_menu->active < efi_menu->count - 1) + ++efi_menu->active; + /* no menu key selected, regenerate menu */ + return NULL; + case KEY_SELECT: + list_for_each_safe(pos, n, &efi_menu->list) { + entry = list_entry(pos, struct eficonfig_entry, list); + if (entry->num == efi_menu->active) + return entry->key; + } + break; + case KEY_QUIT: + /* Quit by choosing the last entry */ + entry = list_last_entry(&efi_menu->list, struct eficonfig_entry, list); + return entry->key; + default: + /* Pressed key is not valid, no need to regenerate the menu */ + break; + } + } +} + +/** + * eficonfig_destroy() - destroy efimenu + * + * @efi_menu: pointer to the efimenu structure + */ +void eficonfig_destroy(struct efimenu *efi_menu) +{ + struct list_head *pos, *n; + struct eficonfig_entry *entry; + + if (!efi_menu) + return; + + list_for_each_safe(pos, n, &efi_menu->list) { + entry = list_entry(pos, struct eficonfig_entry, list); + free(entry->title); + list_del(&entry->list); + free(entry); + } + free(efi_menu->menu_header); + free(efi_menu); +} + +/** + * eficonfig_process_quit() - callback function for "Quit" entry + * + * @data: pointer to the data + * Return: status code + */ +efi_status_t eficonfig_process_quit(void *data) +{ + return EFI_ABORTED; +} + +/** + * append_entry() - append menu item + * + * @efi_menu: pointer to the efimenu structure + * @title: pointer to the entry title + * @func: callback of each entry + * @data: pointer to the data to be passed to each entry callback + * Return: status code + */ +static efi_status_t append_entry(struct efimenu *efi_menu, + char *title, eficonfig_entry_func func, void *data) +{ + struct eficonfig_entry *entry; + + if (efi_menu->count >= EFICONFIG_ENTRY_NUM_MAX) + return EFI_OUT_OF_RESOURCES; + + entry = calloc(1, sizeof(struct eficonfig_entry)); + if (!entry) + return EFI_OUT_OF_RESOURCES; + + entry->title = title; + sprintf(entry->key, "%d", efi_menu->count); + entry->efi_menu = efi_menu; + entry->func = func; + entry->data = data; + entry->num = efi_menu->count++; + list_add_tail(&entry->list, &efi_menu->list); + + return EFI_SUCCESS; +} + +/** + * append_quit_entry() - append quit entry + * + * @efi_menu: pointer to the efimenu structure + * Return: status code + */ +static efi_status_t append_quit_entry(struct efimenu *efi_menu) +{ + char *title; + efi_status_t ret; + + title = strdup("Quit"); + if (!title) + return EFI_OUT_OF_RESOURCES; + + ret = append_entry(efi_menu, title, eficonfig_process_quit, NULL); + if (ret != EFI_SUCCESS) + free(title); + + return ret; +} + +/** + * eficonfig_create_fixed_menu() - create fixed entry menu structure + * + * @items: pointer to the menu entry item + * @count: the number of menu entry + * Return: pointer to the efimenu structure + */ +void *eficonfig_create_fixed_menu(const struct eficonfig_item *items, int count) +{ + u32 i; + char *title; + efi_status_t ret; + struct efimenu *efi_menu; + const struct eficonfig_item *iter = items; + + efi_menu = calloc(1, sizeof(struct efimenu)); + if (!efi_menu) + return NULL; + + INIT_LIST_HEAD(&efi_menu->list); + for (i = 0; i < count; i++, iter++) { + title = strdup(iter->title); + if (!title) + goto out; + + ret = append_entry(efi_menu, title, iter->func, iter->data); + if (ret != EFI_SUCCESS) { + free(title); + goto out; + } + } + + return efi_menu; +out: + eficonfig_destroy(efi_menu); + + return NULL; +} + +/** + * eficonfig_process_common() - main handler for UEFI menu + * + * Construct the structures required to show the menu, then handle + * the user input interacting with u-boot menu functions. + * + * @efi_menu: pointer to the efimenu structure + * @menu_header: pointer to the menu header string + * Return: status code + */ +efi_status_t eficonfig_process_common(struct efimenu *efi_menu, char *menu_header) +{ + struct menu *menu; + void *choice = NULL; + struct list_head *pos, *n; + struct eficonfig_entry *entry; + efi_status_t ret = EFI_SUCCESS; + + if (efi_menu->count > EFICONFIG_ENTRY_NUM_MAX) + return EFI_OUT_OF_RESOURCES; + + efi_menu->delay = -1; + efi_menu->active = 0; + + if (menu_header) { + efi_menu->menu_header = strdup(menu_header); + if (!efi_menu->menu_header) + return EFI_OUT_OF_RESOURCES; + } + + menu = menu_create(NULL, 0, 1, eficonfig_display_statusline, + eficonfig_print_entry, eficonfig_choice_entry, + efi_menu); + if (!menu) + return EFI_INVALID_PARAMETER; + + list_for_each_safe(pos, n, &efi_menu->list) { + entry = list_entry(pos, struct eficonfig_entry, list); + if (!menu_item_add(menu, entry->key, entry)) { + ret = EFI_INVALID_PARAMETER; + goto out; + } + } + + entry = list_first_entry_or_null(&efi_menu->list, struct eficonfig_entry, list); + if (entry) + menu_default_set(menu, entry->key); + + printf(ANSI_CURSOR_HIDE + ANSI_CLEAR_CONSOLE + ANSI_CURSOR_POSITION, 1, 1); + + if (menu_get_choice(menu, &choice)) { + entry = choice; + if (entry->func) + ret = entry->func(entry->data); + } +out: + menu_destroy(menu); + + printf(ANSI_CLEAR_CONSOLE + ANSI_CURSOR_POSITION + ANSI_CURSOR_SHOW, 1, 1); + + return ret; +} + +/** + * eficonfig_volume_selected() - handler of volume selection + * + * @data: pointer to the data of selected entry + * Return: status code + */ +static efi_status_t eficonfig_volume_selected(void *data) +{ + struct eficonfig_volume_entry_data *info = data; + + if (info) { + info->file_info->current_volume = info->v; + info->file_info->dp_volume = info->dp; + } + + return EFI_SUCCESS; +} + +/** + * create_selected_device_path() - create device path + * + * @file_info: pointer to the selected file information + * Return: + * device path or NULL. Caller must free the returned value + */ +static +struct efi_device_path *create_selected_device_path(struct eficonfig_select_file_info *file_info) +{ + char *p; + void *buf; + efi_uintn_t fp_size; + struct efi_device_path *dp; + struct efi_device_path_file_path *fp; + + fp_size = sizeof(struct efi_device_path) + + ((u16_strlen(file_info->current_path) + 1) * sizeof(u16)); + buf = calloc(1, fp_size + sizeof(END)); + if (!buf) + return NULL; + + fp = buf; + fp->dp.type = DEVICE_PATH_TYPE_MEDIA_DEVICE, + fp->dp.sub_type = DEVICE_PATH_SUB_TYPE_FILE_PATH, + fp->dp.length = (u16)fp_size; + u16_strcpy(fp->str, file_info->current_path); + + p = buf; + p += fp_size; + *((struct efi_device_path *)p) = END; + + dp = efi_dp_append(file_info->dp_volume, (struct efi_device_path *)buf); + free(buf); + + return dp; +} + +/** + * eficonfig_file_selected() - handler of file selection + * + * @data: pointer to the data of selected entry + * Return: status code + */ +static efi_status_t eficonfig_file_selected(void *data) +{ + u16 *tmp; + struct eficonfig_file_entry_data *info = data; + + if (!info) + return EFI_INVALID_PARAMETER; + + if (!strcmp(info->file_name, "..")) { + struct eficonfig_filepath_info *iter; + struct list_head *pos, *n; + int is_last; + char *filepath; + tmp = info->file_info->current_path; + + memset(info->file_info->current_path, 0, EFICONFIG_FILE_PATH_BUF_SIZE); + filepath = calloc(1, EFICONFIG_FILE_PATH_MAX); + if (!filepath) + return EFI_OUT_OF_RESOURCES; + + list_for_each_safe(pos, n, &info->file_info->filepath_list) { + iter = list_entry(pos, struct eficonfig_filepath_info, list); + + is_last = list_is_last(&iter->list, &info->file_info->filepath_list); + if (is_last) { + list_del(&iter->list); + free(iter->name); + free(iter); + break; + } + strlcat(filepath, iter->name, EFICONFIG_FILE_PATH_MAX); + } + utf8_utf16_strcpy(&tmp, filepath); + } else { + size_t new_len; + struct eficonfig_filepath_info *filepath_info; + + new_len = u16_strlen(info->file_info->current_path) + + strlen(info->file_name); + if (new_len >= EFICONFIG_FILE_PATH_MAX) { + eficonfig_print_msg("File path is too long!"); + return EFI_INVALID_PARAMETER; + } + tmp = &info->file_info->current_path[u16_strlen(info->file_info->current_path)]; + utf8_utf16_strcpy(&tmp, info->file_name); + + filepath_info = calloc(1, sizeof(struct eficonfig_filepath_info)); + if (!filepath_info) + return EFI_OUT_OF_RESOURCES; + + filepath_info->name = strdup(info->file_name); + if (!filepath_info->name) { + free(filepath_info); + return EFI_OUT_OF_RESOURCES; + } + list_add_tail(&filepath_info->list, &info->file_info->filepath_list); + + if (!info->is_directory) + info->file_info->file_selected = true; + } + + return EFI_SUCCESS; +} + +/** + * eficonfig_select_volume() - construct the volume selection menu + * + * @file_info: pointer to the file selection structure + * Return: status code + */ +static efi_status_t eficonfig_select_volume(struct eficonfig_select_file_info *file_info) +{ + u32 i; + efi_status_t ret; + efi_uintn_t count; + struct efimenu *efi_menu; + struct list_head *pos, *n; + struct efi_handler *handler; + struct eficonfig_entry *entry; + struct efi_device_path *device_path; + efi_handle_t *volume_handles = NULL; + struct efi_simple_file_system_protocol *v; + + ret = efi_locate_handle_buffer_int(BY_PROTOCOL, &efi_simple_file_system_protocol_guid, + NULL, &count, (efi_handle_t **)&volume_handles); + if (ret != EFI_SUCCESS) { + eficonfig_print_msg("No block device found!"); + return ret; + } + + efi_menu = calloc(1, sizeof(struct efimenu)); + if (!efi_menu) + return EFI_OUT_OF_RESOURCES; + + INIT_LIST_HEAD(&efi_menu->list); + for (i = 0; i < count; i++) { + char *devname; + struct efi_block_io *block_io; + struct eficonfig_volume_entry_data *info; + + if (efi_menu->count >= EFICONFIG_ENTRY_NUM_MAX - 1) + break; + + ret = efi_search_protocol(volume_handles[i], + &efi_simple_file_system_protocol_guid, &handler); + if (ret != EFI_SUCCESS) + continue; + ret = efi_protocol_open(handler, (void **)&v, efi_root, NULL, + EFI_OPEN_PROTOCOL_GET_PROTOCOL); + if (ret != EFI_SUCCESS) + continue; + + ret = efi_search_protocol(volume_handles[i], &efi_guid_device_path, &handler); + if (ret != EFI_SUCCESS) + continue; + ret = efi_protocol_open(handler, (void **)&device_path, + efi_root, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL); + if (ret != EFI_SUCCESS) + continue; + + ret = efi_search_protocol(volume_handles[i], &efi_block_io_guid, &handler); + if (ret != EFI_SUCCESS) + continue; + ret = efi_protocol_open(handler, (void **)&block_io, + efi_root, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL); + if (ret != EFI_SUCCESS) + continue; + + info = calloc(1, sizeof(struct eficonfig_volume_entry_data)); + if (!info) { + ret = EFI_OUT_OF_RESOURCES; + goto out; + } + + devname = calloc(1, BOOTMENU_DEVICE_NAME_MAX); + if (!devname) { + free(info); + ret = EFI_OUT_OF_RESOURCES; + goto out; + } + ret = efi_disk_get_device_name(volume_handles[i], devname, + BOOTMENU_DEVICE_NAME_MAX); + if (ret != EFI_SUCCESS) { + free(info); + goto out; + } + + info->v = v; + info->dp = device_path; + info->file_info = file_info; + ret = append_entry(efi_menu, devname, eficonfig_volume_selected, info); + if (ret != EFI_SUCCESS) { + free(info); + goto out; + } + } + + ret = append_quit_entry(efi_menu); + if (ret != EFI_SUCCESS) + goto out; + + ret = eficonfig_process_common(efi_menu, " ** Select Volume **"); +out: + efi_free_pool(volume_handles); + list_for_each_safe(pos, n, &efi_menu->list) { + entry = list_entry(pos, struct eficonfig_entry, list); + free(entry->data); + } + eficonfig_destroy(efi_menu); + + return ret; +} + +/** + * sort_file() - sort the file name in ascii order + * + * @data1: pointer to the file entry data + * @data2: pointer to the file entry data + * Return: -1 if the data1 file name is less than data2 file name, + * 0 if both file name match, + * 1 if the data1 file name is greater thant data2 file name. + */ +static int sort_file(const void *arg1, const void *arg2) +{ + const struct eficonfig_file_entry_data *data1, *data2; + + data1 = *((const struct eficonfig_file_entry_data **)arg1); + data2 = *((const struct eficonfig_file_entry_data **)arg2); + + return strcasecmp(data1->file_name, data2->file_name); +} + +/** + * eficonfig_create_file_entry() - construct the file menu entry + * + * @efi_menu: pointer to the efimenu structure + * @count: number of the directory and file + * @tmp_infos: pointer to the entry data array + * @f: pointer to the file handle + * @buf: pointer to the buffer to store the directory information + * @file_info: pointer to the file selection structure + * Return: status code + */ +static efi_status_t +eficonfig_create_file_entry(struct efimenu *efi_menu, u32 count, + struct eficonfig_file_entry_data **tmp_infos, + struct efi_file_handle *f, struct efi_file_info *buf, + struct eficonfig_select_file_info *file_info) +{ + char *name, *p; + efi_uintn_t len; + efi_status_t ret; + u32 i, entry_num = 0; + struct eficonfig_file_entry_data *info; + + efi_file_setpos_int(f, 0); + /* Read directory and construct menu structure */ + for (i = 0; i < count; i++) { + if (entry_num >= EFICONFIG_ENTRY_NUM_MAX - 1) + break; + + len = sizeof(struct efi_file_info) + EFICONFIG_FILE_PATH_BUF_SIZE; + ret = efi_file_read_int(f, &len, buf); + if (ret != EFI_SUCCESS || len == 0) + break; + + info = calloc(1, sizeof(struct eficonfig_file_entry_data)); + if (!info) { + ret = EFI_OUT_OF_RESOURCES; + goto out; + } + + /* append '\\' at the end of directory name */ + name = calloc(1, utf16_utf8_strlen(buf->file_name) + 2); + if (!name) { + ret = EFI_OUT_OF_RESOURCES; + free(info); + goto out; + } + p = name; + utf16_utf8_strcpy(&p, buf->file_name); + if (buf->attribute & EFI_FILE_DIRECTORY) { + /* filter out u'.' */ + if (!u16_strcmp(buf->file_name, u".")) { + free(info); + free(name); + continue; + } + name[u16_strlen(buf->file_name)] = '\\'; + info->is_directory = true; + } + + info->file_name = name; + info->file_info = file_info; + tmp_infos[entry_num++] = info; + } + + qsort(tmp_infos, entry_num, sizeof(*tmp_infos), + (int (*)(const void *, const void *))sort_file); + + for (i = 0; i < entry_num; i++) { + ret = append_entry(efi_menu, tmp_infos[i]->file_name, + eficonfig_file_selected, tmp_infos[i]); + if (ret != EFI_SUCCESS) + goto out; + } + +out: + return ret; +} + +/** + * eficonfig_select_file() - construct the file selection menu + * + * @file_info: pointer to the file selection structure + * @root: pointer to the file handle + * Return: status code + */ +static efi_status_t eficonfig_select_file(struct eficonfig_select_file_info *file_info, + struct efi_file_handle *root) +{ + u32 count = 0, i; + efi_uintn_t len; + efi_status_t ret; + struct efimenu *efi_menu; + struct efi_file_handle *f; + struct efi_file_info *buf; + struct eficonfig_file_entry_data **tmp_infos; + + buf = calloc(1, sizeof(struct efi_file_info) + EFICONFIG_FILE_PATH_BUF_SIZE); + if (!buf) + return EFI_OUT_OF_RESOURCES; + + while (!file_info->file_selected) { + efi_menu = calloc(1, sizeof(struct efimenu)); + if (!efi_menu) { + ret = EFI_OUT_OF_RESOURCES; + goto out; + } + INIT_LIST_HEAD(&efi_menu->list); + + ret = efi_file_open_int(root, &f, file_info->current_path, EFI_FILE_MODE_READ, 0); + if (ret != EFI_SUCCESS) { + eficonfig_print_msg("Reading volume failed!"); + free(efi_menu); + ret = EFI_ABORTED; + goto out; + } + + /* Count the number of directory entries */ + for (;;) { + len = sizeof(struct efi_file_info) + EFICONFIG_FILE_PATH_BUF_SIZE; + ret = efi_file_read_int(f, &len, buf); + if (ret != EFI_SUCCESS || len == 0) + break; + + count++; + } + + /* allocate array to sort the entry */ + tmp_infos = calloc(count, sizeof(*tmp_infos)); + if (!tmp_infos) { + ret = EFI_OUT_OF_RESOURCES; + goto err; + } + + ret = eficonfig_create_file_entry(efi_menu, count, tmp_infos, + f, buf, file_info); + if (ret != EFI_SUCCESS) + goto err; + + ret = append_quit_entry(efi_menu); + if (ret != EFI_SUCCESS) + goto err; + + ret = eficonfig_process_common(efi_menu, " ** Select File **"); +err: + efi_file_close_int(f); + eficonfig_destroy(efi_menu); + + if (tmp_infos) { + for (i = 0; i < count; i++) + free(tmp_infos[i]); + } + + free(tmp_infos); + + if (ret != EFI_SUCCESS) + break; + } + +out: + free(buf); + + return ret; +} + +/** + * handle_user_input() - handle user input + * + * @buf: pointer to the buffer + * @buf_size: size of the buffer + * @cursor_col: cursor column for user input + * @msg: pointer to the string to display + * Return: status code + */ +static efi_status_t handle_user_input(u16 *buf, int buf_size, + int cursor_col, char *msg) +{ + u16 *tmp; + efi_status_t ret; + + printf(ANSI_CLEAR_CONSOLE + ANSI_CURSOR_POSITION + "%s" + ANSI_CURSOR_POSITION + " Press ENTER to complete, ESC/CTRL+C to quit", + 0, 1, msg, 8, 1); + + /* tmp is used to accept user cancel */ + tmp = calloc(1, buf_size * sizeof(u16)); + if (!tmp) + return EFI_OUT_OF_RESOURCES; + + ret = efi_console_get_u16_string(cin, tmp, buf_size, NULL, 4, cursor_col); + if (ret == EFI_SUCCESS) + u16_strcpy(buf, tmp); + + free(tmp); + + /* to stay the parent menu */ + ret = (ret == EFI_ABORTED) ? EFI_NOT_READY : ret; + + return ret; +} + +/** + * eficonfig_boot_add_enter_description() - handle user input for description + * + * @data: pointer to the internal boot option structure + * Return: status code + */ +static efi_status_t eficonfig_boot_add_enter_description(void *data) +{ + struct eficonfig_boot_option *bo = data; + + return handle_user_input(bo->description, EFICONFIG_DESCRIPTION_MAX, 22, + "\n ** Edit Description **\n" + "\n" + " enter description: "); +} + +/** + * eficonfig_boot_add_optional_data() - handle user input for optional data + * + * @data: pointer to the internal boot option structure + * Return: status code + */ +static efi_status_t eficonfig_boot_add_optional_data(void *data) +{ + struct eficonfig_boot_option *bo = data; + + return handle_user_input(bo->optional_data, EFICONFIG_OPTIONAL_DATA_MAX, 24, + "\n ** Edit Optional Data **\n" + "\n" + " enter optional data:"); +} + +/** + * eficonfig_boot_edit_save() - handler to save the boot option + * + * @data: pointer to the internal boot option structure + * Return: status code + */ +static efi_status_t eficonfig_boot_edit_save(void *data) +{ + struct eficonfig_boot_option *bo = data; + + if (u16_strlen(bo->description) == 0) { + eficonfig_print_msg("Boot Description is empty!"); + bo->edit_completed = false; + return EFI_NOT_READY; + } + if (u16_strlen(bo->file_info.current_path) == 0) { + eficonfig_print_msg("File is not selected!"); + bo->edit_completed = false; + return EFI_NOT_READY; + } + + bo->edit_completed = true; + + return EFI_SUCCESS; +} + +/** + * eficonfig_process_select_file() - callback function for "Select File" entry + * + * @data: pointer to the data + * Return: status code + */ +efi_status_t eficonfig_process_select_file(void *data) +{ + return EFI_SUCCESS; +} + +/** + * eficonfig_process_clear_file_selection() - callback function for "Clear" entry + * + * @data: pointer to the data + * Return: status code + */ +efi_status_t eficonfig_process_clear_file_selection(void *data) +{ + struct eficonfig_select_file_info *file_info = data; + + /* clear the existing file information */ + file_info->current_volume = NULL; + file_info->current_path[0] = u'\0'; + file_info->dp_volume = NULL; + + return EFI_ABORTED; +} + +static struct eficonfig_item select_file_menu_items[] = { + {"Select File", eficonfig_process_select_file}, + {"Clear", eficonfig_process_clear_file_selection}, + {"Quit", eficonfig_process_quit}, +}; + + +/** + * eficonfig_display_select_file_option() - display select file option + * + * @file_info: pointer to the file information structure + * Return: status code + */ +efi_status_t eficonfig_display_select_file_option(struct eficonfig_select_file_info *file_info) +{ + efi_status_t ret; + struct efimenu *efi_menu; + + select_file_menu_items[1].data = file_info; + efi_menu = eficonfig_create_fixed_menu(select_file_menu_items, + ARRAY_SIZE(select_file_menu_items)); + if (!efi_menu) + return EFI_OUT_OF_RESOURCES; + + ret = eficonfig_process_common(efi_menu, " ** Update File **"); + if (ret != EFI_SUCCESS) /* User selects "Clear" or "Quit" */ + ret = EFI_NOT_READY; + + eficonfig_destroy(efi_menu); + + return ret; +} + +/** + * eficonfig_select_file_handler() - handle user file selection + * + * @data: pointer to the data + * Return: status code + */ +efi_status_t eficonfig_select_file_handler(void *data) +{ + size_t len; + efi_status_t ret; + struct list_head *pos, *n; + struct efi_file_handle *root; + struct eficonfig_filepath_info *item; + struct eficonfig_select_file_info *tmp = NULL; + struct eficonfig_select_file_info *file_info = data; + + ret = eficonfig_display_select_file_option(file_info); + if (ret != EFI_SUCCESS) + return ret; + + tmp = calloc(1, sizeof(struct eficonfig_select_file_info)); + if (!tmp) + return EFI_OUT_OF_RESOURCES; + + tmp->current_path = calloc(1, EFICONFIG_FILE_PATH_BUF_SIZE); + if (!tmp->current_path) { + free(tmp); + return EFI_OUT_OF_RESOURCES; + } + INIT_LIST_HEAD(&tmp->filepath_list); + + while (!tmp->file_selected) { + tmp->current_volume = NULL; + memset(tmp->current_path, 0, EFICONFIG_FILE_PATH_BUF_SIZE); + + ret = eficonfig_select_volume(tmp); + if (ret != EFI_SUCCESS) + goto out; + + if (!tmp->current_volume) + return EFI_INVALID_PARAMETER; + + ret = efi_open_volume_int(tmp->current_volume, &root); + if (ret != EFI_SUCCESS) + goto out; + + ret = eficonfig_select_file(tmp, root); + if (ret == EFI_ABORTED) + continue; + if (ret != EFI_SUCCESS) + goto out; + } + +out: + if (ret == EFI_SUCCESS) { + len = u16_strlen(tmp->current_path); + len = (len >= EFICONFIG_FILE_PATH_MAX) ? (EFICONFIG_FILE_PATH_MAX - 1) : len; + memcpy(file_info->current_path, tmp->current_path, len * sizeof(u16)); + file_info->current_path[len] = u'\0'; + file_info->current_volume = tmp->current_volume; + file_info->dp_volume = tmp->dp_volume; + } + + list_for_each_safe(pos, n, &tmp->filepath_list) { + item = list_entry(pos, struct eficonfig_filepath_info, list); + list_del(&item->list); + free(item->name); + free(item); + } + free(tmp->current_path); + free(tmp); + + /* to stay the parent menu */ + ret = (ret == EFI_ABORTED) ? EFI_NOT_READY : ret; + + return ret; +} + +/** + * eficonfig_get_unused_bootoption() - get unused "Boot####" index + * + * @buf: pointer to the buffer to store boot option variable name + * @buf_size: buffer size + * @index: pointer to store the index in the BootOrder variable + * Return: status code + */ +efi_status_t eficonfig_get_unused_bootoption(u16 *buf, efi_uintn_t buf_size, + unsigned int *index) +{ + u32 i; + efi_status_t ret; + efi_uintn_t size; + + if (buf_size < u16_strsize(u"Boot####")) + return EFI_BUFFER_TOO_SMALL; + + for (i = 0; i <= 0xFFFF; i++) { + size = 0; + efi_create_indexed_name(buf, buf_size, "Boot", i); + ret = efi_get_variable_int(buf, &efi_global_variable_guid, + NULL, &size, NULL, NULL); + if (ret == EFI_BUFFER_TOO_SMALL) + continue; + else + break; + } + + if (i > 0xFFFF) + return EFI_OUT_OF_RESOURCES; + + *index = i; + + return EFI_SUCCESS; +} + +/** + * eficonfig_set_boot_option() - set boot option + * + * @varname: pointer to variable name + * @dp: pointer to device path + * @label: pointer to label string + * @optional_data: pointer to optional data + * Return: status code + */ +static efi_status_t eficonfig_set_boot_option(u16 *varname, struct efi_device_path *dp, + efi_uintn_t dp_size, u16 *label, char *optional_data) +{ + void *p = NULL; + efi_status_t ret; + efi_uintn_t size; + struct efi_load_option lo; + + lo.file_path = dp; + lo.file_path_length = dp_size; + lo.attributes = LOAD_OPTION_ACTIVE; + lo.optional_data = optional_data; + lo.label = label; + + size = efi_serialize_load_option(&lo, (u8 **)&p); + if (!size) + return EFI_INVALID_PARAMETER; + + ret = efi_set_variable_int(varname, &efi_global_variable_guid, + EFI_VARIABLE_NON_VOLATILE | + EFI_VARIABLE_BOOTSERVICE_ACCESS | + EFI_VARIABLE_RUNTIME_ACCESS, + size, p, false); + free(p); + + return ret; +} + +/** + * eficonfig_append_bootorder() - append new boot option in BootOrder variable + * + * @index: "Boot####" index to append to BootOrder variable + * Return: status code + */ +efi_status_t eficonfig_append_bootorder(u16 index) +{ + u16 *bootorder; + efi_status_t ret; + u16 *new_bootorder = NULL; + efi_uintn_t last, size, new_size; + + /* append new boot option */ + bootorder = efi_get_var(u"BootOrder", &efi_global_variable_guid, &size); + last = size / sizeof(u16); + new_size = size + sizeof(u16); + new_bootorder = calloc(1, new_size); + if (!new_bootorder) { + ret = EFI_OUT_OF_RESOURCES; + goto out; + } + memcpy(new_bootorder, bootorder, size); + new_bootorder[last] = index; + + ret = efi_set_variable_int(u"BootOrder", &efi_global_variable_guid, + EFI_VARIABLE_NON_VOLATILE | + EFI_VARIABLE_BOOTSERVICE_ACCESS | + EFI_VARIABLE_RUNTIME_ACCESS, + new_size, new_bootorder, false); + if (ret != EFI_SUCCESS) + goto out; + +out: + free(bootorder); + free(new_bootorder); + + return ret; +} + +/** + * create_boot_option_entry() - create boot option entry + * + * @efi_menu: pointer to the efimenu structure + * @title: pointer to the entry title + * @val: pointer to boot option label + * @func: callback of each entry + * @data: pointer to the data to be passed to each entry callback + * Return: status code + */ +static efi_status_t create_boot_option_entry(struct efimenu *efi_menu, char *title, u16 *val, + eficonfig_entry_func func, void *data) +{ + u32 len; + char *p, *buf; + + len = strlen(title) + 1; + if (val) + len += utf16_utf8_strlen(val); + buf = calloc(1, len); + if (!buf) + return EFI_OUT_OF_RESOURCES; + + strcpy(buf, title); + if (val) { + p = buf + strlen(title); + utf16_utf8_strcpy(&p, val); + } + + return append_entry(efi_menu, buf, func, data); +} + +/** + * prepare_file_selection_entry() - prepare file selection entry + * + * @efi_menu: pointer to the efimenu structure + * @title: pointer to the title string + * @file_info: pointer to the file info + * Return: status code + */ +static efi_status_t prepare_file_selection_entry(struct efimenu *efi_menu, char *title, + struct eficonfig_select_file_info *file_info) +{ + u32 len; + efi_status_t ret; + u16 *file_name, *p; + efi_handle_t handle; + char devname[BOOTMENU_DEVICE_NAME_MAX] = {0}; + + /* get the device name only when the user already selected the file path */ + handle = efi_dp_find_obj(file_info->dp_volume, NULL, NULL); + if (handle) { + ret = efi_disk_get_device_name(handle, devname, BOOTMENU_DEVICE_NAME_MAX); + if (ret != EFI_SUCCESS) + return ret; + } + + /* append u'/' to devname, it is just for display purpose. */ + if (file_info->current_path[0] != u'\0' && file_info->current_path[0] != u'/') + strlcat(devname, "/", BOOTMENU_DEVICE_NAME_MAX); + + len = strlen(devname); + len += utf16_utf8_strlen(file_info->current_path) + 1; + file_name = calloc(1, len * sizeof(u16)); + if (!file_name) + return ret; + + p = file_name; + utf8_utf16_strcpy(&p, devname); + u16_strlcat(file_name, file_info->current_path, len); + ret = create_boot_option_entry(efi_menu, title, file_name, + eficonfig_select_file_handler, file_info); + free(file_name); + return ret; +} + +/** + * eficonfig_show_boot_option() - prepare menu entry for editing boot option + * + * Construct the structures to create edit boot option menu + * + * @bo: pointer to the boot option + * @header_str: pointer to the header string + * Return: status code + */ +static efi_status_t eficonfig_show_boot_option(struct eficonfig_boot_option *bo, + char *header_str) +{ + efi_status_t ret; + struct efimenu *efi_menu; + + efi_menu = calloc(1, sizeof(struct efimenu)); + if (!efi_menu) + return EFI_OUT_OF_RESOURCES; + + INIT_LIST_HEAD(&efi_menu->list); + + ret = create_boot_option_entry(efi_menu, "Description: ", bo->description, + eficonfig_boot_add_enter_description, bo); + if (ret != EFI_SUCCESS) + goto out; + + ret = prepare_file_selection_entry(efi_menu, "File: ", &bo->file_info); + if (ret != EFI_SUCCESS) + goto out; + + ret = prepare_file_selection_entry(efi_menu, "Initrd File: ", &bo->initrd_info); + if (ret != EFI_SUCCESS) + goto out; + + ret = create_boot_option_entry(efi_menu, "Optional Data: ", bo->optional_data, + eficonfig_boot_add_optional_data, bo); + if (ret != EFI_SUCCESS) + goto out; + + ret = create_boot_option_entry(efi_menu, "Save", NULL, + eficonfig_boot_edit_save, bo); + if (ret != EFI_SUCCESS) + goto out; + + ret = create_boot_option_entry(efi_menu, "Quit", NULL, + eficonfig_process_quit, NULL); + if (ret != EFI_SUCCESS) + goto out; + + ret = eficonfig_process_common(efi_menu, header_str); +out: + eficonfig_destroy(efi_menu); + + return ret; +} + +/** + * fill_file_info() - fill the file info from efi_device_path structure + * + * @dp: pointer to the device path + * @file_info: pointer to the file info structure + * @device_dp: pointer to the volume device path + */ +static void fill_file_info(struct efi_device_path *dp, + struct eficonfig_select_file_info *file_info, + struct efi_device_path *device_dp) +{ + u16 *file_str, *p; + struct efi_device_path *file_dp = NULL; + + efi_dp_split_file_path(dp, &device_dp, &file_dp); + file_info->dp_volume = device_dp; + + if (file_dp) { + file_str = efi_dp_str(file_dp); + /* + * efi_convert_device_path_to_text() automatically adds u'/' at the + * beginning of file name, remove u'/' before copying to current_path + */ + p = file_str; + if (p[0] == u'/') + p++; + + u16_strcpy(file_info->current_path, p); + efi_free_pool(file_dp); + efi_free_pool(file_str); + } +} + +/** + * eficonfig_edit_boot_option() - prepare boot option structure for editing + * + * Construct the boot option structure and copy the existing value + * + * @varname: pointer to the UEFI variable name + * @bo: pointer to the boot option + * @load_option: pointer to the load option + * @load_option_size: size of the load option + * @header_str: pointer to the header string + * Return : status code + */ +static efi_status_t eficonfig_edit_boot_option(u16 *varname, struct eficonfig_boot_option *bo, + void *load_option, efi_uintn_t load_option_size, + char *header_str) +{ + size_t len; + efi_status_t ret; + char *tmp = NULL, *p; + struct efi_load_option lo = {0}; + efi_uintn_t final_dp_size; + struct efi_device_path *dp = NULL; + efi_uintn_t size = load_option_size; + struct efi_device_path *final_dp = NULL; + struct efi_device_path *device_dp = NULL; + struct efi_device_path *initrd_dp = NULL; + struct efi_device_path *initrd_device_dp = NULL; + + const struct efi_initrd_dp id_dp = { + .vendor = { + { + DEVICE_PATH_TYPE_MEDIA_DEVICE, + DEVICE_PATH_SUB_TYPE_VENDOR_PATH, + sizeof(id_dp.vendor), + }, + EFI_INITRD_MEDIA_GUID, + }, + .end = { + DEVICE_PATH_TYPE_END, + DEVICE_PATH_SUB_TYPE_END, + sizeof(id_dp.end), + } + }; + + bo->file_info.current_path = calloc(1, EFICONFIG_FILE_PATH_BUF_SIZE); + if (!bo->file_info.current_path) { + ret = EFI_OUT_OF_RESOURCES; + goto out; + } + + bo->initrd_info.current_path = calloc(1, EFICONFIG_FILE_PATH_BUF_SIZE); + if (!bo->file_info.current_path) { + ret = EFI_OUT_OF_RESOURCES; + goto out; + } + + bo->description = calloc(1, EFICONFIG_DESCRIPTION_MAX * sizeof(u16)); + if (!bo->description) { + ret = EFI_OUT_OF_RESOURCES; + goto out; + } + + bo->optional_data = calloc(1, EFICONFIG_OPTIONAL_DATA_MAX * sizeof(u16)); + if (!bo->optional_data) { + ret = EFI_OUT_OF_RESOURCES; + goto out; + } + + /* copy the preset value */ + if (load_option) { + ret = efi_deserialize_load_option(&lo, load_option, &size); + if (ret != EFI_SUCCESS) + goto out; + + if (!lo.label || (lo.label && u16_strlen(lo.label) >= EFICONFIG_DESCRIPTION_MAX)) { + ret = EFI_INVALID_PARAMETER; + goto out; + } + u16_strcpy(bo->description, lo.label); + + /* EFI image file path is a first instance */ + if (lo.file_path) + fill_file_info(lo.file_path, &bo->file_info, device_dp); + + /* Initrd file path(optional) is placed at second instance. */ + initrd_dp = efi_dp_from_lo(&lo, &efi_lf2_initrd_guid); + if (initrd_dp) { + fill_file_info(initrd_dp, &bo->initrd_info, initrd_device_dp); + efi_free_pool(initrd_dp); + } + + if (size > 0) + memcpy(bo->optional_data, lo.optional_data, size); + } + + while (1) { + ret = eficonfig_show_boot_option(bo, header_str); + if (ret == EFI_SUCCESS && bo->edit_completed) + break; + if (ret == EFI_NOT_READY) + continue; + if (ret != EFI_SUCCESS) + goto out; + } + + if (bo->initrd_info.dp_volume) { + dp = create_selected_device_path(&bo->initrd_info); + if (!dp) { + ret = EFI_OUT_OF_RESOURCES; + goto out; + } + initrd_dp = efi_dp_append((const struct efi_device_path *)&id_dp, dp); + efi_free_pool(dp); + } + + dp = create_selected_device_path(&bo->file_info); + if (!dp) { + ret = EFI_OUT_OF_RESOURCES; + goto out; + } + final_dp_size = efi_dp_size(dp) + sizeof(END); + if (initrd_dp) { + final_dp = efi_dp_concat(dp, initrd_dp); + final_dp_size += efi_dp_size(initrd_dp) + sizeof(END); + } else { + final_dp = efi_dp_dup(dp); + } + efi_free_pool(dp); + + if (!final_dp) + goto out; + + if (utf16_utf8_strlen(bo->optional_data)) { + len = utf16_utf8_strlen(bo->optional_data) + 1; + tmp = calloc(1, len); + if (!tmp) + goto out; + p = tmp; + utf16_utf8_strncpy(&p, bo->optional_data, u16_strlen(bo->optional_data)); + } + + ret = eficonfig_set_boot_option(varname, final_dp, final_dp_size, bo->description, tmp); + if (ret != EFI_SUCCESS) + goto out; +out: + free(tmp); + free(bo->optional_data); + free(bo->description); + free(bo->file_info.current_path); + free(bo->initrd_info.current_path); + efi_free_pool(device_dp); + efi_free_pool(initrd_device_dp); + efi_free_pool(initrd_dp); + efi_free_pool(final_dp); + + return ret; +} + +/** + * eficonfig_process_add_boot_option() - handler to add boot option + * + * @data: pointer to the data for each entry + * Return: status code + */ +static efi_status_t eficonfig_process_add_boot_option(void *data) +{ + u16 varname[9]; + efi_status_t ret; + struct eficonfig_boot_option *bo = NULL; + + bo = calloc(1, sizeof(struct eficonfig_boot_option)); + if (!bo) + return EFI_OUT_OF_RESOURCES; + + ret = eficonfig_get_unused_bootoption(varname, sizeof(varname), &bo->boot_index); + if (ret != EFI_SUCCESS) + return ret; + + ret = eficonfig_edit_boot_option(varname, bo, NULL, 0, " ** Add Boot Option ** "); + if (ret != EFI_SUCCESS) + goto out; + + ret = eficonfig_append_bootorder((u16)bo->boot_index); + if (ret != EFI_SUCCESS) + goto out; + +out: + free(bo); + + /* to stay the parent menu */ + ret = (ret == EFI_ABORTED) ? EFI_SUCCESS : ret; + + return ret; +} + +/** + * eficonfig_init() - do required initialization for eficonfig command + * + * Return: status code + */ +static efi_status_t eficonfig_init(void) +{ + efi_status_t ret = EFI_SUCCESS; + static bool init; + struct efi_handler *handler; + + if (!init) { + ret = efi_search_protocol(efi_root, &efi_guid_text_input_protocol, &handler); + if (ret != EFI_SUCCESS) + return ret; + + ret = efi_protocol_open(handler, (void **)&cin, efi_root, NULL, + EFI_OPEN_PROTOCOL_GET_PROTOCOL); + if (ret != EFI_SUCCESS) + return ret; + } + + init = true; + + return ret; +} + +static const struct eficonfig_item maintenance_menu_items[] = { + {"Add Boot Option", eficonfig_process_add_boot_option}, + {"Quit", eficonfig_process_quit}, +}; + +/** + * do_eficonfig() - execute `eficonfig` command + * + * @cmdtp: table entry describing command + * @flag: bitmap indicating how the command was invoked + * @argc: number of arguments + * @argv: command line arguments + * Return: status code + */ +static int do_eficonfig(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) +{ + efi_status_t ret; + struct efimenu *efi_menu; + + if (argc > 1) + return CMD_RET_USAGE; + + ret = efi_init_obj_list(); + if (ret != EFI_SUCCESS) { + log_err("Error: Cannot initialize UEFI sub-system, r = %lu\n", + ret & ~EFI_ERROR_MASK); + + return CMD_RET_FAILURE; + } + + ret = eficonfig_init(); + if (ret != EFI_SUCCESS) + return CMD_RET_FAILURE; + + while (1) { + efi_menu = eficonfig_create_fixed_menu(maintenance_menu_items, + ARRAY_SIZE(maintenance_menu_items)); + if (!efi_menu) + return CMD_RET_FAILURE; + + ret = eficonfig_process_common(efi_menu, " ** UEFI Maintenance Menu **"); + eficonfig_destroy(efi_menu); + + if (ret == EFI_ABORTED) + break; + } + + return CMD_RET_SUCCESS; +} + +U_BOOT_CMD( + eficonfig, 1, 0, do_eficonfig, + "provide menu-driven UEFI variable maintenance interface", + "" +); diff --git a/include/efi_config.h b/include/efi_config.h new file mode 100644 index 0000000000..ea5bc4e1bf --- /dev/null +++ b/include/efi_config.h @@ -0,0 +1,96 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Menu-driven UEFI Variable maintenance + * + * Copyright (c) 2022 Masahisa Kojima, Linaro Limited + */ + +#ifndef _EFI_CONFIG_H +#define _EFI_CONFIG_H + +#include + +#define EFICONFIG_ENTRY_NUM_MAX 99 +#define EFICONFIG_FILE_PATH_MAX 512 +#define EFICONFIG_FILE_PATH_BUF_SIZE (EFICONFIG_FILE_PATH_MAX * sizeof(u16)) + +typedef efi_status_t (*eficonfig_entry_func)(void *data); + +/** + * struct eficonfig_entry - menu entry structure + * + * @num: menu entry index + * @title: title of entry + * @key: unique key + * @efi_menu: pointer to the menu structure + * @func: callback function to be called when this entry is selected + * @data: data to be passed to the callback function, caller must free() this pointer + * @list: list structure + */ +struct eficonfig_entry { + u32 num; + char *title; + char key[3]; + struct efimenu *efi_menu; + eficonfig_entry_func func; + void *data; + struct list_head list; +}; + +/** + * struct efimenu - efi menu structure + * + * @delay: delay for autoboot + * @active: active menu entry index + * @count: total count of menu entry + * @menu_header: menu header string + * @list: menu entry list structure + */ +struct efimenu { + int delay; + int active; + int count; + char *menu_header; + struct list_head list; +}; + +/** + * struct eficonfig_item - structure to construct eficonfig_entry + * + * @title: title of entry + * @func: callback function to be called when this entry is selected + * @data: data to be passed to the callback function + */ +struct eficonfig_item { + char *title; + eficonfig_entry_func func; + void *data; +}; + +/** + * struct eficonfig_select_file_info - structure to be used for file selection + * + * @current_volume: pointer to the efi_simple_file_system_protocol + * @dp_volume: pointer to device path of the selected device + * @current_path: pointer to the selected file path string + * @filepath_list: list_head structure for file path list + * @file_selectred: flag indicates file selecting status + */ +struct eficonfig_select_file_info { + struct efi_simple_file_system_protocol *current_volume; + struct efi_device_path *dp_volume; + u16 *current_path; + struct list_head filepath_list; + bool file_selected; +}; + +void eficonfig_print_msg(char *msg); +void eficonfig_destroy(struct efimenu *efi_menu); +efi_status_t eficonfig_process_quit(void *data); +efi_status_t eficonfig_process_common(struct efimenu *efi_menu, char *menu_header); +efi_status_t eficonfig_select_file_handler(void *data); +efi_status_t eficonfig_get_unused_bootoption(u16 *buf, + efi_uintn_t buf_size, u32 *index); +efi_status_t eficonfig_append_bootorder(u16 index); + +#endif diff --git a/include/efi_loader.h b/include/efi_loader.h index b0d6fff67c..4461f721e0 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -142,6 +142,11 @@ static inline efi_status_t efi_launch_capsules(void) EFI_GUID(0x63293792, 0xadf5, 0x9325, \ 0xb9, 0x9f, 0x4e, 0x0e, 0x45, 0x5c, 0x1b, 0x1e) +/* GUID for the auto generated boot menu entry */ +#define EFICONFIG_AUTO_GENERATED_ENTRY_GUID \ + EFI_GUID(0x38c1acc1, 0x9fc0, 0x41f0, \ + 0xb9, 0x01, 0xfa, 0x74, 0xd6, 0xd6, 0xe4, 0xde) + /* Use internal device tree when starting UEFI application */ #define EFI_FDT_USE_INTERNAL NULL @@ -226,6 +231,9 @@ const char *__efi_nesting_dec(void); #define EFI_CACHELINE_SIZE 128 #endif +/* max bootmenu title size for volume selection */ +#define BOOTMENU_DEVICE_NAME_MAX 16 + /* Key identifying current memory map */ extern efi_uintn_t efi_memory_map_key; @@ -249,6 +257,9 @@ extern const struct efi_hii_string_protocol efi_hii_string; uint16_t *efi_dp_str(struct efi_device_path *dp); +/* GUID for the auto generated boot menu entry */ +extern const efi_guid_t efi_guid_bootmenu_auto_generated; + /* GUID of the U-Boot root node */ extern const efi_guid_t efi_u_boot_guid; #ifdef CONFIG_SANDBOX @@ -314,6 +325,8 @@ extern const efi_guid_t efi_guid_firmware_management_protocol; extern const efi_guid_t efi_esrt_guid; /* GUID of the SMBIOS table */ extern const efi_guid_t smbios_guid; +/*GUID of console */ +extern const efi_guid_t efi_guid_text_input_protocol; extern char __efi_runtime_start[], __efi_runtime_stop[]; extern char __efi_runtime_rel_start[], __efi_runtime_rel_stop[]; @@ -1064,4 +1077,28 @@ efi_status_t efi_esrt_populate(void); efi_status_t efi_load_capsule_drivers(void); efi_status_t platform_get_eventlog(struct udevice *dev, u64 *addr, u32 *sz); + +efi_status_t efi_locate_handle_buffer_int(enum efi_locate_search_type search_type, + const efi_guid_t *protocol, void *search_key, + efi_uintn_t *no_handles, efi_handle_t **buffer); + +efi_status_t efi_open_volume_int(struct efi_simple_file_system_protocol *this, + struct efi_file_handle **root); +efi_status_t efi_file_open_int(struct efi_file_handle *this, + struct efi_file_handle **new_handle, + u16 *file_name, u64 open_mode, + u64 attributes); +efi_status_t efi_file_close_int(struct efi_file_handle *file); +efi_status_t efi_file_read_int(struct efi_file_handle *this, + efi_uintn_t *buffer_size, void *buffer); +efi_status_t efi_file_setpos_int(struct efi_file_handle *file, u64 pos); + +typedef efi_status_t (*efi_console_filter_func)(struct efi_input_key *key); +efi_status_t efi_console_get_u16_string + (struct efi_simple_text_input_protocol *cin, + u16 *buf, efi_uintn_t count, efi_console_filter_func filer_func, + int row, int col); + +efi_status_t efi_disk_get_device_name(const efi_handle_t handle, char *buf, int size); + #endif /* _EFI_LOADER_H */ diff --git a/lib/efi_loader/efi_bootmgr.c b/lib/efi_loader/efi_bootmgr.c index 234073ecb7..ede9116b3c 100644 --- a/lib/efi_loader/efi_bootmgr.c +++ b/lib/efi_loader/efi_bootmgr.c @@ -19,6 +19,9 @@ static const struct efi_boot_services *bs; static const struct efi_runtime_services *rs; +const efi_guid_t efi_guid_bootmenu_auto_generated = + EFICONFIG_AUTO_GENERATED_ENTRY_GUID; + /* * bootmgr implements the logic of trying to find a payload to boot * based on the BootOrder + BootXXXX variables, and then loading it. diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c index 4da64b5d29..1233418e77 100644 --- a/lib/efi_loader/efi_boottime.c +++ b/lib/efi_loader/efi_boottime.c @@ -2453,6 +2453,35 @@ static efi_status_t EFIAPI efi_protocols_per_handle( return EFI_EXIT(EFI_SUCCESS); } +efi_status_t efi_locate_handle_buffer_int(enum efi_locate_search_type search_type, + const efi_guid_t *protocol, void *search_key, + efi_uintn_t *no_handles, efi_handle_t **buffer) +{ + efi_status_t r; + efi_uintn_t buffer_size = 0; + + if (!no_handles || !buffer) { + r = EFI_INVALID_PARAMETER; + goto out; + } + *no_handles = 0; + *buffer = NULL; + r = efi_locate_handle(search_type, protocol, search_key, &buffer_size, + *buffer); + if (r != EFI_BUFFER_TOO_SMALL) + goto out; + r = efi_allocate_pool(EFI_BOOT_SERVICES_DATA, buffer_size, + (void **)buffer); + if (r != EFI_SUCCESS) + goto out; + r = efi_locate_handle(search_type, protocol, search_key, &buffer_size, + *buffer); + if (r == EFI_SUCCESS) + *no_handles = buffer_size / sizeof(efi_handle_t); +out: + return r; +} + /** * efi_locate_handle_buffer() - locate handles implementing a protocol * @search_type: selection criterion @@ -2474,30 +2503,13 @@ efi_status_t EFIAPI efi_locate_handle_buffer( efi_uintn_t *no_handles, efi_handle_t **buffer) { efi_status_t r; - efi_uintn_t buffer_size = 0; EFI_ENTRY("%d, %pUs, %p, %p, %p", search_type, protocol, search_key, no_handles, buffer); - if (!no_handles || !buffer) { - r = EFI_INVALID_PARAMETER; - goto out; - } - *no_handles = 0; - *buffer = NULL; - r = efi_locate_handle(search_type, protocol, search_key, &buffer_size, - *buffer); - if (r != EFI_BUFFER_TOO_SMALL) - goto out; - r = efi_allocate_pool(EFI_BOOT_SERVICES_DATA, buffer_size, - (void **)buffer); - if (r != EFI_SUCCESS) - goto out; - r = efi_locate_handle(search_type, protocol, search_key, &buffer_size, - *buffer); - if (r == EFI_SUCCESS) - *no_handles = buffer_size / sizeof(efi_handle_t); -out: + r = efi_locate_handle_buffer_int(search_type, protocol, search_key, + no_handles, buffer); + return EFI_EXIT(r); } diff --git a/lib/efi_loader/efi_console.c b/lib/efi_loader/efi_console.c index 3164fd484e..5be509f0d6 100644 --- a/lib/efi_loader/efi_console.c +++ b/lib/efi_loader/efi_console.c @@ -7,6 +7,7 @@ #define LOG_CATEGORY LOGC_EFI +#include #include #include #include @@ -1318,3 +1319,72 @@ out_of_memory: printf("ERROR: Out of memory\n"); return r; } + +/** + * efi_console_get_u16_string() - get user input string + * + * @cin: protocol interface to EFI_SIMPLE_TEXT_INPUT_PROTOCOL + * @buf: buffer to store user input string in UTF16 + * @count: number of u16 string including NULL terminator that buf has + * @filter_func: callback to filter user input + * @row: row number to locate user input form + * @col: column number to locate user input form + * Return: status code + */ +efi_status_t efi_console_get_u16_string(struct efi_simple_text_input_protocol *cin, + u16 *buf, efi_uintn_t count, + efi_console_filter_func filter_func, + int row, int col) +{ + efi_status_t ret; + efi_uintn_t len = 0; + struct efi_input_key key; + + printf(ANSI_CURSOR_POSITION + ANSI_CLEAR_LINE_TO_END + ANSI_CURSOR_SHOW, row, col); + + ret = EFI_CALL(cin->reset(cin, false)); + if (ret != EFI_SUCCESS) + return ret; + + for (;;) { + do { + ret = EFI_CALL(cin->read_key_stroke(cin, &key)); + mdelay(10); + } while (ret == EFI_NOT_READY); + + if (key.unicode_char == u'\b') { + if (len > 0) + buf[--len] = u'\0'; + + printf(ANSI_CURSOR_POSITION + "%ls" + ANSI_CLEAR_LINE_TO_END, row, col, buf); + continue; + } else if (key.unicode_char == u'\r') { + buf[len] = u'\0'; + return EFI_SUCCESS; + } else if (key.unicode_char == 0x3 || key.scan_code == 23) { + return EFI_ABORTED; + } else if (key.unicode_char < 0x20) { + /* ignore control codes other than Ctrl+C, '\r' and '\b' */ + continue; + } else if (key.scan_code != 0) { + /* only accept single ESC press for cancel */ + continue; + } + + if (filter_func) { + if (filter_func(&key) != EFI_SUCCESS) + continue; + } + + if (len >= (count - 1)) + continue; + + buf[len] = key.unicode_char; + len++; + printf(ANSI_CURSOR_POSITION "%ls", row, col, buf); + } +} diff --git a/lib/efi_loader/efi_disk.c b/lib/efi_loader/efi_disk.c index f269abf135..a34ca46a11 100644 --- a/lib/efi_loader/efi_disk.c +++ b/lib/efi_loader/efi_disk.c @@ -760,3 +760,53 @@ efi_status_t efi_disk_init(void) return EFI_SUCCESS; } + +/** + * efi_disk_get_device_name() - get U-Boot device name associated with EFI handle + * + * @handle: pointer to the EFI handle + * @buf: pointer to the buffer to store the string + * @size: size of buffer + * Return: status code + */ +efi_status_t efi_disk_get_device_name(const efi_handle_t handle, char *buf, int size) +{ + int count; + int diskid; + enum uclass_id id; + unsigned int part; + struct udevice *dev; + struct blk_desc *desc; + const char *if_typename; + bool is_partition = false; + struct disk_part *part_data; + + if (!handle || !buf || !size) + return EFI_INVALID_PARAMETER; + + dev = handle->dev; + id = device_get_uclass_id(dev); + if (id == UCLASS_BLK) { + desc = dev_get_uclass_plat(dev); + } else if (id == UCLASS_PARTITION) { + desc = dev_get_uclass_plat(dev_get_parent(dev)); + is_partition = true; + } else { + return EFI_INVALID_PARAMETER; + } + if_typename = blk_get_if_type_name(desc->if_type); + diskid = desc->devnum; + + if (is_partition) { + part_data = dev_get_uclass_plat(dev); + part = part_data->partnum; + count = snprintf(buf, size, "%s %d:%d", if_typename, diskid, part); + } else { + count = snprintf(buf, size, "%s %d", if_typename, diskid); + } + + if (count < 0 || (count + 1) > size) + return EFI_INVALID_PARAMETER; + + return EFI_SUCCESS; +} diff --git a/lib/efi_loader/efi_file.c b/lib/efi_loader/efi_file.c index 7a7077e6d0..c96a7f7ca3 100644 --- a/lib/efi_loader/efi_file.c +++ b/lib/efi_loader/efi_file.c @@ -246,10 +246,10 @@ error: return NULL; } -static efi_status_t efi_file_open_int(struct efi_file_handle *this, - struct efi_file_handle **new_handle, - u16 *file_name, u64 open_mode, - u64 attributes) +efi_status_t efi_file_open_int(struct efi_file_handle *this, + struct efi_file_handle **new_handle, + u16 *file_name, u64 open_mode, + u64 attributes) { struct file_handle *fh = to_fh(this); efi_status_t ret; @@ -369,11 +369,17 @@ static efi_status_t file_close(struct file_handle *fh) return EFI_SUCCESS; } -static efi_status_t EFIAPI efi_file_close(struct efi_file_handle *file) +efi_status_t efi_file_close_int(struct efi_file_handle *file) { struct file_handle *fh = to_fh(file); + + return file_close(fh); +} + +static efi_status_t EFIAPI efi_file_close(struct efi_file_handle *file) +{ EFI_ENTRY("%p", file); - return EFI_EXIT(file_close(fh)); + return EFI_EXIT(efi_file_close_int(file)); } static efi_status_t EFIAPI efi_file_delete(struct efi_file_handle *file) @@ -562,8 +568,8 @@ static efi_status_t dir_read(struct file_handle *fh, u64 *buffer_size, return EFI_SUCCESS; } -static efi_status_t efi_file_read_int(struct efi_file_handle *this, - efi_uintn_t *buffer_size, void *buffer) +efi_status_t efi_file_read_int(struct efi_file_handle *this, + efi_uintn_t *buffer_size, void *buffer) { struct file_handle *fh = to_fh(this); efi_status_t ret = EFI_SUCCESS; @@ -773,24 +779,11 @@ out: return EFI_EXIT(ret); } -/** - * efi_file_setpos() - set current position in file - * - * This function implements the SetPosition service of the EFI file protocol. - * See the UEFI spec for details. - * - * @file: file handle - * @pos: new file position - * Return: status code - */ -static efi_status_t EFIAPI efi_file_setpos(struct efi_file_handle *file, - u64 pos) +efi_status_t efi_file_setpos_int(struct efi_file_handle *file, u64 pos) { struct file_handle *fh = to_fh(file); efi_status_t ret = EFI_SUCCESS; - EFI_ENTRY("%p, %llu", file, pos); - if (fh->isdir) { if (pos != 0) { ret = EFI_UNSUPPORTED; @@ -812,6 +805,28 @@ static efi_status_t EFIAPI efi_file_setpos(struct efi_file_handle *file, fh->offset = pos; error: + return ret; +} + +/** + * efi_file_setpos() - set current position in file + * + * This function implements the SetPosition service of the EFI file protocol. + * See the UEFI spec for details. + * + * @file: file handle + * @pos: new file position + * Return: status code + */ +static efi_status_t EFIAPI efi_file_setpos(struct efi_file_handle *file, + u64 pos) +{ + efi_status_t ret = EFI_SUCCESS; + + EFI_ENTRY("%p, %llu", file, pos); + + ret = efi_file_setpos_int(file, pos); + return EFI_EXIT(ret); } @@ -1138,17 +1153,23 @@ struct efi_file_handle *efi_file_from_path(struct efi_device_path *fp) return f; } +efi_status_t efi_open_volume_int(struct efi_simple_file_system_protocol *this, + struct efi_file_handle **root) +{ + struct file_system *fs = to_fs(this); + + *root = file_open(fs, NULL, NULL, 0, 0); + + return EFI_SUCCESS; +} + static efi_status_t EFIAPI efi_open_volume(struct efi_simple_file_system_protocol *this, struct efi_file_handle **root) { - struct file_system *fs = to_fs(this); - EFI_ENTRY("%p, %p", this, root); - *root = file_open(fs, NULL, NULL, 0, 0); - - return EFI_EXIT(EFI_SUCCESS); + return EFI_EXIT(efi_open_volume_int(this, root)); } struct efi_simple_file_system_protocol * From e34158bc331712dc192e4ce6da86a8c80fe7367d Mon Sep 17 00:00:00 2001 From: Masahisa Kojima Date: Mon, 12 Sep 2022 17:33:51 +0900 Subject: [PATCH 124/374] eficonfig: add "Edit Boot Option" menu entry This commit adds the menu entry to edit the existing BOOT#### variable contents. User selects the item from the boot option list, then user can edit the description, file path and optional_data. Note that automatically generated boot option entry by bootmenu to support the removable media device is filtered out and user can not edit the automatically generated entry. Signed-off-by: Masahisa Kojima --- cmd/eficonfig.c | 281 +++++++++++++++++++++++++++++++++++++++++-- include/efi_config.h | 1 + 2 files changed, 274 insertions(+), 8 deletions(-) diff --git a/cmd/eficonfig.c b/cmd/eficonfig.c index 2d142c4c9b..bd1975895b 100644 --- a/cmd/eficonfig.c +++ b/cmd/eficonfig.c @@ -81,6 +81,17 @@ struct eficonfig_file_entry_data { char *file_name; }; +/** + * struct eficonfig_boot_selection_data - structure to be used to select the boot option entry + * + * @boot_index: index of the boot option + * @selected: pointer to store the selected index in the BootOrder variable + */ +struct eficonfig_boot_selection_data { + u16 boot_index; + int *selected; +}; + /** * eficonfig_print_msg() - print message * @@ -1209,34 +1220,58 @@ static efi_status_t prepare_file_selection_entry(struct efimenu *efi_menu, char { u32 len; efi_status_t ret; - u16 *file_name, *p; + u16 *file_name = NULL, *p; efi_handle_t handle; - char devname[BOOTMENU_DEVICE_NAME_MAX] = {0}; + char *devname; + + devname = calloc(1, EFICONFIG_VOLUME_PATH_MAX + 1); + if (!devname) + return EFI_OUT_OF_RESOURCES; /* get the device name only when the user already selected the file path */ handle = efi_dp_find_obj(file_info->dp_volume, NULL, NULL); if (handle) { - ret = efi_disk_get_device_name(handle, devname, BOOTMENU_DEVICE_NAME_MAX); + ret = efi_disk_get_device_name(handle, devname, EFICONFIG_VOLUME_PATH_MAX); if (ret != EFI_SUCCESS) - return ret; + goto out; + } + + /* + * If the preconfigured volume does not exist in the system, display the text + * converted volume device path instead of U-Boot friendly name(e.g. "usb 0:1"). + */ + if (!handle && file_info->dp_volume) { + u16 *dp_str; + char *q = devname; + + dp_str = efi_dp_str(file_info->dp_volume); + if (dp_str) + utf16_utf8_strncpy(&q, dp_str, EFICONFIG_VOLUME_PATH_MAX); + + efi_free_pool(dp_str); } /* append u'/' to devname, it is just for display purpose. */ if (file_info->current_path[0] != u'\0' && file_info->current_path[0] != u'/') - strlcat(devname, "/", BOOTMENU_DEVICE_NAME_MAX); + strlcat(devname, "/", EFICONFIG_VOLUME_PATH_MAX + 1); len = strlen(devname); len += utf16_utf8_strlen(file_info->current_path) + 1; file_name = calloc(1, len * sizeof(u16)); - if (!file_name) - return ret; + if (!file_name) { + ret = EFI_OUT_OF_RESOURCES; + goto out; + } p = file_name; utf8_utf16_strcpy(&p, devname); u16_strlcat(file_name, file_info->current_path, len); ret = create_boot_option_entry(efi_menu, title, file_name, eficonfig_select_file_handler, file_info); +out: + free(devname); free(file_name); + return ret; } @@ -1403,10 +1438,14 @@ static efi_status_t eficonfig_edit_boot_option(u16 *varname, struct eficonfig_bo if (ret != EFI_SUCCESS) goto out; - if (!lo.label || (lo.label && u16_strlen(lo.label) >= EFICONFIG_DESCRIPTION_MAX)) { + if (!lo.label) { ret = EFI_INVALID_PARAMETER; goto out; } + /* truncate the long label string */ + if (u16_strlen(lo.label) >= EFICONFIG_DESCRIPTION_MAX) + lo.label[EFICONFIG_DESCRIPTION_MAX - 1] = u'\0'; + u16_strcpy(bo->description, lo.label); /* EFI image file path is a first instance */ @@ -1524,6 +1563,231 @@ out: return ret; } +/** + * eficonfig_process_boot_selected() - handler to select boot option entry + * + * @data: pointer to the data for each entry + * Return: status code + */ +static efi_status_t eficonfig_process_boot_selected(void *data) +{ + struct eficonfig_boot_selection_data *info = data; + + if (info) + *info->selected = info->boot_index; + + return EFI_SUCCESS; +} + +/** + * search_bootorder() - search the boot option index in BootOrder + * + * @bootorder: pointer to the BootOrder variable + * @num: number of BootOrder entry + * @target: target boot option index to search + * @index: pointer to store the index of BootOrder variable + * Return: true if exists, false otherwise + */ +static bool search_bootorder(u16 *bootorder, efi_uintn_t num, u32 target, u32 *index) +{ + u32 i; + + for (i = 0; i < num; i++) { + if (target == bootorder[i]) { + if (index) + *index = i; + + return true; + } + } + + return false; +} + +/** + * eficonfig_add_boot_selection_entry() - add boot option menu entry + * + * @efi_menu: pointer to store the efimenu structure + * @boot_index: boot option index to be added + * @selected: pointer to store the selected boot option index + * Return: status code + */ +static efi_status_t eficonfig_add_boot_selection_entry(struct efimenu *efi_menu, + unsigned int boot_index, + unsigned int *selected) +{ + char *buf, *p; + efi_status_t ret; + efi_uintn_t size; + void *load_option; + struct efi_load_option lo; + u16 varname[] = u"Boot####"; + struct eficonfig_boot_selection_data *info; + + efi_create_indexed_name(varname, sizeof(varname), "Boot", boot_index); + load_option = efi_get_var(varname, &efi_global_variable_guid, &size); + if (!load_option) + return EFI_SUCCESS; + + ret = efi_deserialize_load_option(&lo, load_option, &size); + if (ret != EFI_SUCCESS) { + log_warning("Invalid load option for %ls\n", varname); + free(load_option); + return ret; + } + + if (size >= sizeof(efi_guid_t) && + !guidcmp(lo.optional_data, &efi_guid_bootmenu_auto_generated)) { + /* + * auto generated entry has GUID in optional_data, + * skip auto generated entry because it will be generated + * again even if it is edited or deleted. + */ + free(load_option); + return EFI_SUCCESS; + } + + info = calloc(1, sizeof(struct eficonfig_boot_selection_data)); + if (!info) { + free(load_option); + return EFI_OUT_OF_RESOURCES; + } + + buf = calloc(1, utf16_utf8_strlen(lo.label) + 1); + if (!buf) { + free(load_option); + free(info); + return EFI_OUT_OF_RESOURCES; + } + p = buf; + utf16_utf8_strcpy(&p, lo.label); + info->boot_index = boot_index; + info->selected = selected; + ret = append_entry(efi_menu, buf, eficonfig_process_boot_selected, info); + if (ret != EFI_SUCCESS) { + free(load_option); + free(info); + return ret; + } + free(load_option); + + return EFI_SUCCESS; +} + +/** + * eficonfig_show_boot_selection() - construct boot option menu entry + * + * @selected: pointer to store the selected boot option index + * Return: status code + */ +static efi_status_t eficonfig_show_boot_selection(unsigned int *selected) +{ + u32 i; + u16 *bootorder; + efi_status_t ret; + efi_uintn_t num, size; + struct efimenu *efi_menu; + struct list_head *pos, *n; + struct eficonfig_entry *entry; + + efi_menu = calloc(1, sizeof(struct efimenu)); + if (!efi_menu) + return EFI_OUT_OF_RESOURCES; + + bootorder = efi_get_var(u"BootOrder", &efi_global_variable_guid, &size); + + INIT_LIST_HEAD(&efi_menu->list); + num = size / sizeof(u16); + /* list the load option in the order of BootOrder variable */ + for (i = 0; i < num; i++) { + ret = eficonfig_add_boot_selection_entry(efi_menu, bootorder[i], selected); + if (ret != EFI_SUCCESS) + goto out; + + if (efi_menu->count >= EFICONFIG_ENTRY_NUM_MAX - 1) + break; + } + + /* list the remaining load option not included in the BootOrder */ + for (i = 0; i <= 0xFFFF; i++) { + /* If the index is included in the BootOrder, skip it */ + if (search_bootorder(bootorder, num, i, NULL)) + continue; + + ret = eficonfig_add_boot_selection_entry(efi_menu, i, selected); + if (ret != EFI_SUCCESS) + goto out; + + if (efi_menu->count >= EFICONFIG_ENTRY_NUM_MAX - 1) + break; + } + + ret = append_quit_entry(efi_menu); + if (ret != EFI_SUCCESS) + goto out; + + ret = eficonfig_process_common(efi_menu, " ** Select Boot Option **"); +out: + list_for_each_safe(pos, n, &efi_menu->list) { + entry = list_entry(pos, struct eficonfig_entry, list); + free(entry->data); + } + eficonfig_destroy(efi_menu); + + return ret; +} + +/** + * eficonfig_process_edit_boot_option() - handler to edit boot option + * + * @data: pointer to the data for each entry + * Return: status code + */ +static efi_status_t eficonfig_process_edit_boot_option(void *data) +{ + efi_status_t ret; + efi_uintn_t size; + struct eficonfig_boot_option *bo = NULL; + + while (1) { + unsigned int selected; + void *load_option; + u16 varname[] = u"Boot####"; + + ret = eficonfig_show_boot_selection(&selected); + if (ret != EFI_SUCCESS) + break; + + bo = calloc(1, sizeof(struct eficonfig_boot_option)); + if (!bo) { + ret = EFI_OUT_OF_RESOURCES; + goto out; + } + + bo->boot_index = selected; + efi_create_indexed_name(varname, sizeof(varname), "Boot", selected); + load_option = efi_get_var(varname, &efi_global_variable_guid, &size); + if (!load_option) { + free(bo); + ret = EFI_NOT_FOUND; + goto out; + } + + ret = eficonfig_edit_boot_option(varname, bo, load_option, size, + " ** Edit Boot Option ** "); + + free(load_option); + free(bo); + if (ret != EFI_SUCCESS && ret != EFI_ABORTED) + break; + } +out: + /* to stay the parent menu */ + ret = (ret == EFI_ABORTED) ? EFI_NOT_READY : ret; + + return ret; +} + /** * eficonfig_init() - do required initialization for eficonfig command * @@ -1553,6 +1817,7 @@ static efi_status_t eficonfig_init(void) static const struct eficonfig_item maintenance_menu_items[] = { {"Add Boot Option", eficonfig_process_add_boot_option}, + {"Edit Boot Option", eficonfig_process_edit_boot_option}, {"Quit", eficonfig_process_quit}, }; diff --git a/include/efi_config.h b/include/efi_config.h index ea5bc4e1bf..dddffe045e 100644 --- a/include/efi_config.h +++ b/include/efi_config.h @@ -11,6 +11,7 @@ #include #define EFICONFIG_ENTRY_NUM_MAX 99 +#define EFICONFIG_VOLUME_PATH_MAX 512 #define EFICONFIG_FILE_PATH_MAX 512 #define EFICONFIG_FILE_PATH_BUF_SIZE (EFICONFIG_FILE_PATH_MAX * sizeof(u16)) From 95fc669774ed15bf17217788865bfd6bda9a7a34 Mon Sep 17 00:00:00 2001 From: Masahisa Kojima Date: Mon, 12 Sep 2022 17:33:52 +0900 Subject: [PATCH 125/374] menu: add KEY_PLUS, KEY_MINUS and KEY_SPACE handling This is preparation to support menu-driven UEFI BootOrder variable updated by KEY_PLUS, KEY_MINUS and KEY_SPACE. Signed-off-by: Masahisa Kojima Reviewed-by: Heinrich Schuchardt Reviewed-by: Ilias Apalodimas --- common/menu.c | 9 +++++++++ include/menu.h | 3 +++ 2 files changed, 12 insertions(+) diff --git a/common/menu.c b/common/menu.c index 3e876b55b3..0d19601cf5 100644 --- a/common/menu.c +++ b/common/menu.c @@ -548,4 +548,13 @@ void bootmenu_loop(struct bootmenu_data *menu, /* ^C was pressed */ if (c == 0x3) *key = KEY_QUIT; + + if (c == '+') + *key = KEY_PLUS; + + if (c == '-') + *key = KEY_MINUS; + + if (c == ' ') + *key = KEY_SPACE; } diff --git a/include/menu.h b/include/menu.h index e74616cae8..702aacb170 100644 --- a/include/menu.h +++ b/include/menu.h @@ -48,6 +48,9 @@ enum bootmenu_key { KEY_DOWN, KEY_SELECT, KEY_QUIT, + KEY_PLUS, + KEY_MINUS, + KEY_SPACE, }; void bootmenu_autoboot_loop(struct bootmenu_data *menu, From bb8498aad676dbb7c4d29ceee6e8f8f4dfef9b57 Mon Sep 17 00:00:00 2001 From: Masahisa Kojima Date: Mon, 12 Sep 2022 17:33:53 +0900 Subject: [PATCH 126/374] eficonfig: add "Delete Boot Option" menu entry This commit adds the menu entry to delete the UEFI boot option. User moves the entry with UP/DOWN key, changes, then presses ENTER key to delete the selected boot option. Signed-off-by: Masahisa Kojima --- cmd/eficonfig.c | 71 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) diff --git a/cmd/eficonfig.c b/cmd/eficonfig.c index bd1975895b..5841a3ffe1 100644 --- a/cmd/eficonfig.c +++ b/cmd/eficonfig.c @@ -1788,6 +1788,76 @@ out: return ret; } +/** + * delete_boot_option() - delete selected boot option + * + * @boot_index: boot option index to delete + * Return: status code + */ +static efi_status_t delete_boot_option(u16 boot_index) +{ + u16 *bootorder; + u16 varname[9]; + efi_status_t ret; + unsigned int index; + efi_uintn_t num, size; + + efi_create_indexed_name(varname, sizeof(varname), + "Boot", boot_index); + ret = efi_set_variable_int(varname, &efi_global_variable_guid, + 0, 0, NULL, false); + if (ret != EFI_SUCCESS) { + log_err("delete boot option(%ls) failed\n", varname); + return ret; + } + + /* update BootOrder if necessary */ + bootorder = efi_get_var(u"BootOrder", &efi_global_variable_guid, &size); + if (!bootorder) + return EFI_SUCCESS; + + num = size / sizeof(u16); + if (!search_bootorder(bootorder, num, boot_index, &index)) + return EFI_SUCCESS; + + memmove(&bootorder[index], &bootorder[index + 1], + (num - index - 1) * sizeof(u16)); + size -= sizeof(u16); + ret = efi_set_variable_int(u"BootOrder", &efi_global_variable_guid, + EFI_VARIABLE_NON_VOLATILE | + EFI_VARIABLE_BOOTSERVICE_ACCESS | + EFI_VARIABLE_RUNTIME_ACCESS, + size, bootorder, false); + + return ret; +} + +/** + * eficonfig_process_delete_boot_option() - handler to delete boot option + * + * @data: pointer to the data for each entry + * Return: status code + */ +static efi_status_t eficonfig_process_delete_boot_option(void *data) +{ + efi_status_t ret; + unsigned int selected; + + while (1) { + ret = eficonfig_show_boot_selection(&selected); + if (ret == EFI_SUCCESS) + ret = delete_boot_option(selected); + + if (ret != EFI_SUCCESS) + break; + } + + /* to stay the parent menu */ + ret = (ret == EFI_ABORTED) ? EFI_NOT_READY : ret; + + return ret; +} + /** * eficonfig_init() - do required initialization for eficonfig command * @@ -1818,6 +1888,7 @@ static efi_status_t eficonfig_init(void) static const struct eficonfig_item maintenance_menu_items[] = { {"Add Boot Option", eficonfig_process_add_boot_option}, {"Edit Boot Option", eficonfig_process_edit_boot_option}, + {"Delete Boot Option", eficonfig_process_delete_boot_option}, {"Quit", eficonfig_process_quit}, }; From c416f1c0bcab87179661b367e469e51f35bd1841 Mon Sep 17 00:00:00 2001 From: Masahisa Kojima Date: Mon, 12 Sep 2022 17:33:54 +0900 Subject: [PATCH 127/374] bootmenu: add removable media entries UEFI specification requires booting from removal media using a architecture-specific default image name such as BOOTAA64.EFI. This commit adds the removable media entries into bootmenu, so that user can select the removable media and boot with default image. The bootmenu automatically enumerates the possible bootable media devices supporting EFI_SIMPLE_FILE_SYSTEM_PROTOCOL, add it as new UEFI boot option(BOOT####) and update BootOrder variable. This automatically generated UEFI boot option has the dedicated guid in the optional_data to distinguish it from the UEFI boot option user adds manually. This optional_data is removed when the efi bootmgr loads the selected UEFI boot option. This commit also provides the BOOT#### variable maintenance feature. Depending on the system hardware setup, some devices may not exist at a later system boot, so bootmenu checks the available device in each bootmenu invocation and automatically removes the BOOT#### variable corrensponding to the non-existent media device. Signed-off-by: Masahisa Kojima --- cmd/bootmenu.c | 22 +++- cmd/eficonfig.c | 208 +++++++++++++++++++++++++++++++++++ include/efi_config.h | 1 + include/efi_loader.h | 16 +++ lib/efi_loader/efi_bootmgr.c | 4 + 5 files changed, 245 insertions(+), 6 deletions(-) diff --git a/cmd/bootmenu.c b/cmd/bootmenu.c index 704d36debe..3340be1632 100644 --- a/cmd/bootmenu.c +++ b/cmd/bootmenu.c @@ -7,7 +7,7 @@ #include #include #include -#include +#include #include #include #include @@ -220,7 +220,7 @@ static int prepare_bootmenu_entry(struct bootmenu_data *menu, return 1; } -#if (CONFIG_IS_ENABLED(CMD_BOOTEFI_BOOTMGR)) +#if (CONFIG_IS_ENABLED(CMD_BOOTEFI_BOOTMGR)) && (CONFIG_IS_ENABLED(CMD_EFICONFIG)) /** * prepare_uefi_bootorder_entry() - generate the uefi bootmenu entries * @@ -340,11 +340,21 @@ static struct bootmenu_data *bootmenu_create(int delay) if (ret < 0) goto cleanup; -#if (CONFIG_IS_ENABLED(CMD_BOOTEFI_BOOTMGR)) +#if (CONFIG_IS_ENABLED(CMD_BOOTEFI_BOOTMGR)) && (CONFIG_IS_ENABLED(CMD_EFICONFIG)) if (i < MAX_COUNT - 1) { - ret = prepare_uefi_bootorder_entry(menu, &iter, &i); - if (ret < 0 && ret != -ENOENT) - goto cleanup; + efi_status_t efi_ret; + + /* + * UEFI specification requires booting from removal media using + * a architecture-specific default image name such as BOOTAA64.EFI. + */ + efi_ret = eficonfig_generate_media_device_boot_option(); + if (efi_ret != EFI_SUCCESS && efi_ret != EFI_NOT_FOUND) + goto cleanup; + + ret = prepare_uefi_bootorder_entry(menu, &iter, &i); + if (ret < 0 && ret != -ENOENT) + goto cleanup; } #endif diff --git a/cmd/eficonfig.c b/cmd/eficonfig.c index 5841a3ffe1..bbd6c3229e 100644 --- a/cmd/eficonfig.c +++ b/cmd/eficonfig.c @@ -1858,6 +1858,214 @@ static efi_status_t eficonfig_process_delete_boot_option(void *data) return ret; } +/** + * eficonfig_enumerate_boot_option() - enumerate the possible bootable media + * + * @opt: pointer to the media boot option structure + * @volume_handles: pointer to the efi handles + * @count: number of efi handle + * Return: status code + */ +efi_status_t eficonfig_enumerate_boot_option(struct eficonfig_media_boot_option *opt, + efi_handle_t *volume_handles, efi_status_t count) +{ + u32 i; + struct efi_handler *handler; + efi_status_t ret = EFI_SUCCESS; + + for (i = 0; i < count; i++) { + u16 *p; + u16 dev_name[BOOTMENU_DEVICE_NAME_MAX]; + char *optional_data; + struct efi_load_option lo; + char buf[BOOTMENU_DEVICE_NAME_MAX]; + struct efi_device_path *device_path; + + ret = efi_search_protocol(volume_handles[i], &efi_guid_device_path, &handler); + if (ret != EFI_SUCCESS) + continue; + ret = efi_protocol_open(handler, (void **)&device_path, + efi_root, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL); + if (ret != EFI_SUCCESS) + continue; + + ret = efi_disk_get_device_name(volume_handles[i], buf, BOOTMENU_DEVICE_NAME_MAX); + if (ret != EFI_SUCCESS) + continue; + + p = dev_name; + utf8_utf16_strncpy(&p, buf, strlen(buf)); + + lo.label = dev_name; + lo.attributes = LOAD_OPTION_ACTIVE; + lo.file_path = device_path; + lo.file_path_length = efi_dp_size(device_path) + sizeof(END); + /* + * Set the dedicated guid to optional_data, it is used to identify + * the boot option that automatically generated by the bootmenu. + * efi_serialize_load_option() expects optional_data is null-terminated + * utf8 string, so set the "1234567" string to allocate enough space + * to store guid, instead of realloc the load_option. + */ + lo.optional_data = "1234567"; + opt[i].size = efi_serialize_load_option(&lo, (u8 **)&opt[i].lo); + if (!opt[i].size) { + ret = EFI_OUT_OF_RESOURCES; + goto out; + } + /* set the guid */ + optional_data = (char *)opt[i].lo + (opt[i].size - u16_strsize(u"1234567")); + memcpy(optional_data, &efi_guid_bootmenu_auto_generated, sizeof(efi_guid_t)); + } + +out: + return ret; +} + +/** + * eficonfig_delete_invalid_boot_option() - delete non-existing boot option + * + * @opt: pointer to the media boot option structure + * @count: number of media boot option structure + * Return: status code + */ +efi_status_t eficonfig_delete_invalid_boot_option(struct eficonfig_media_boot_option *opt, + efi_status_t count) +{ + u32 i, j; + efi_uintn_t size; + efi_status_t ret; + void *load_option; + struct efi_load_option lo; + u16 varname[] = u"Boot####"; + + for (i = 0; i <= 0xFFFF; i++) { + efi_uintn_t tmp; + + efi_create_indexed_name(varname, sizeof(varname), "Boot", i); + load_option = efi_get_var(varname, &efi_global_variable_guid, &size); + if (!load_option) + continue; + + tmp = size; + ret = efi_deserialize_load_option(&lo, load_option, &size); + if (ret != EFI_SUCCESS) + goto next; + + if (size >= sizeof(efi_guid_bootmenu_auto_generated)) { + if (guidcmp(lo.optional_data, &efi_guid_bootmenu_auto_generated) == 0) { + for (j = 0; j < count; j++) { + if (opt[j].size == tmp && + memcmp(opt[j].lo, load_option, tmp) == 0) { + opt[j].exist = true; + break; + } + } + + if (j == count) { + ret = delete_boot_option(i); + if (ret != EFI_SUCCESS) { + free(load_option); + goto out; + } + } + } + } +next: + free(load_option); + } + +out: + return ret; +} + +/** + * eficonfig_generate_media_device_boot_option() - generate the media device boot option + * + * This function enumerates all devices supporting EFI_SIMPLE_FILE_SYSTEM_PROTOCOL + * and generate the bootmenu entries. + * This function also provide the BOOT#### variable maintenance for + * the media device entries. + * - Automatically create the BOOT#### variable for the newly detected device, + * this BOOT#### variable is distinguished by the special GUID + * stored in the EFI_LOAD_OPTION.optional_data + * - If the device is not attached to the system, the associated BOOT#### variable + * is automatically deleted. + * + * Return: status code + */ +efi_status_t eficonfig_generate_media_device_boot_option(void) +{ + u32 i; + efi_status_t ret; + efi_uintn_t count; + efi_handle_t *volume_handles = NULL; + struct eficonfig_media_boot_option *opt = NULL; + + ret = efi_locate_handle_buffer_int(BY_PROTOCOL, &efi_simple_file_system_protocol_guid, + NULL, &count, (efi_handle_t **)&volume_handles); + if (ret != EFI_SUCCESS) + return ret; + + opt = calloc(count, sizeof(struct eficonfig_media_boot_option)); + if (!opt) + goto out; + + /* enumerate all devices supporting EFI_SIMPLE_FILE_SYSTEM_PROTOCOL */ + ret = eficonfig_enumerate_boot_option(opt, volume_handles, count); + if (ret != EFI_SUCCESS) + goto out; + + /* + * System hardware configuration may vary depending on the user setup. + * The boot option is automatically added by the bootmenu. + * If the device is not attached to the system, the boot option needs + * to be deleted. + */ + ret = eficonfig_delete_invalid_boot_option(opt, count); + if (ret != EFI_SUCCESS) + goto out; + + /* add non-existent boot option */ + for (i = 0; i < count; i++) { + u32 boot_index; + u16 var_name[9]; + + if (!opt[i].exist) { + ret = eficonfig_get_unused_bootoption(var_name, sizeof(var_name), + &boot_index); + if (ret != EFI_SUCCESS) + goto out; + + ret = efi_set_variable_int(var_name, &efi_global_variable_guid, + EFI_VARIABLE_NON_VOLATILE | + EFI_VARIABLE_BOOTSERVICE_ACCESS | + EFI_VARIABLE_RUNTIME_ACCESS, + opt[i].size, opt[i].lo, false); + if (ret != EFI_SUCCESS) + goto out; + + ret = eficonfig_append_bootorder(boot_index); + if (ret != EFI_SUCCESS) { + efi_set_variable_int(var_name, &efi_global_variable_guid, + 0, 0, NULL, false); + goto out; + } + } + } + +out: + if (opt) { + for (i = 0; i < count; i++) + free(opt[i].lo); + } + free(opt); + efi_free_pool(volume_handles); + + return ret; +} + + /** * eficonfig_init() - do required initialization for eficonfig command * diff --git a/include/efi_config.h b/include/efi_config.h index dddffe045e..098cac2115 100644 --- a/include/efi_config.h +++ b/include/efi_config.h @@ -93,5 +93,6 @@ efi_status_t eficonfig_select_file_handler(void *data); efi_status_t eficonfig_get_unused_bootoption(u16 *buf, efi_uintn_t buf_size, u32 *index); efi_status_t eficonfig_append_bootorder(u16 index); +efi_status_t eficonfig_generate_media_device_boot_option(void); #endif diff --git a/include/efi_loader.h b/include/efi_loader.h index 4461f721e0..6b63ae8dde 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -953,6 +953,22 @@ struct efi_signature_store { struct x509_certificate; struct pkcs7_message; +/** + * struct eficonfig_media_boot_option - boot option for (removable) media device + * + * This structure is used to enumerate possible boot option + * + * @lo: Serialized load option data + * @size: Size of serialized load option data + * @exist: Flag to indicate the load option already exists + * in Non-volatile load option + */ +struct eficonfig_media_boot_option { + void *lo; + efi_uintn_t size; + bool exist; +}; + bool efi_hash_regions(struct image_region *regs, int count, void **hash, const char *hash_algo, int *len); bool efi_signature_lookup_digest(struct efi_image_regions *regs, diff --git a/lib/efi_loader/efi_bootmgr.c b/lib/efi_loader/efi_bootmgr.c index ede9116b3c..4b24b41047 100644 --- a/lib/efi_loader/efi_bootmgr.c +++ b/lib/efi_loader/efi_bootmgr.c @@ -246,6 +246,10 @@ static efi_status_t try_load_entry(u16 n, efi_handle_t *handle, } /* Set load options */ + if (size >= sizeof(efi_guid_t) && + !guidcmp(lo.optional_data, &efi_guid_bootmenu_auto_generated)) + size = 0; + if (size) { *load_options = malloc(size); if (!*load_options) { From b5135a1e5b9ef80b0f49651f7b983d2b206aa9ea Mon Sep 17 00:00:00 2001 From: Masahisa Kojima Date: Mon, 12 Sep 2022 17:33:55 +0900 Subject: [PATCH 128/374] eficonfig: scan media device in eficonfig startup In eficonfig startup, scan media devices and update the UEFI boot option. Signed-off-by: Masahisa Kojima --- cmd/eficonfig.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/cmd/eficonfig.c b/cmd/eficonfig.c index bbd6c3229e..99c83d1adf 100644 --- a/cmd/eficonfig.c +++ b/cmd/eficonfig.c @@ -2129,6 +2129,10 @@ static int do_eficonfig(struct cmd_tbl *cmdtp, int flag, int argc, char *const a if (ret != EFI_SUCCESS) return CMD_RET_FAILURE; + ret = eficonfig_generate_media_device_boot_option(); + if (ret != EFI_SUCCESS && ret != EFI_NOT_FOUND) + return ret; + while (1) { efi_menu = eficonfig_create_fixed_menu(maintenance_menu_items, ARRAY_SIZE(maintenance_menu_items)); From e5948ee30143d523b7a021f10f3ae88e7fdd4478 Mon Sep 17 00:00:00 2001 From: Masahisa Kojima Date: Mon, 12 Sep 2022 17:33:56 +0900 Subject: [PATCH 129/374] eficonfig: add "Change Boot Order" menu entry This commit adds the menu entry to update UEFI BootOrder variable. User moves the entry with UP/DOWN key, changes the order with PLUS/MINUS key, press SPACE to activate or deactivate the entry, then finalizes the order by ENTER key. If the entry is activated, the boot index is added into the BootOrder variable in the order of the list. The U-Boot menu framework is well designed for static menu, this commit implements the own menu display and key handling for dynamically change the order of menu entry. Signed-off-by: Masahisa Kojima --- cmd/eficonfig.c | 348 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 347 insertions(+), 1 deletion(-) diff --git a/cmd/eficonfig.c b/cmd/eficonfig.c index 99c83d1adf..2595dd9563 100644 --- a/cmd/eficonfig.c +++ b/cmd/eficonfig.c @@ -92,6 +92,23 @@ struct eficonfig_boot_selection_data { int *selected; }; +/** + * struct eficonfig_boot_order - structure to be used to update BootOrder variable + * + * @num: index in the menu entry + * @description: pointer to the description string + * @boot_index: boot option index + * @active: flag to include the boot option into BootOrder variable + * @list: list structure + */ +struct eficonfig_boot_order { + u32 num; + u16 *description; + u32 boot_index; + bool active; + struct list_head list; +}; + /** * eficonfig_print_msg() - print message * @@ -1788,6 +1805,335 @@ out: return ret; } +/** + * eficonfig_display_change_boot_order() - display the BootOrder list + * + * @efi_menu: pointer to the efimenu structure + * Return: status code + */ +static void eficonfig_display_change_boot_order(struct efimenu *efi_menu) +{ + bool reverse; + struct list_head *pos, *n; + struct eficonfig_boot_order *entry; + + printf(ANSI_CLEAR_CONSOLE ANSI_CURSOR_POSITION + "\n ** Change Boot Order **\n" + ANSI_CURSOR_POSITION + " Press UP/DOWN to move, +/- to change order" + ANSI_CURSOR_POSITION + " Press SPACE to activate or deactivate the entry" + ANSI_CURSOR_POSITION + " Select [Save] to complete, ESC/CTRL+C to quit" + ANSI_CURSOR_POSITION ANSI_CLEAR_LINE, + 1, 1, efi_menu->count + 5, 1, efi_menu->count + 6, 1, + efi_menu->count + 7, 1, efi_menu->count + 8, 1); + + /* draw boot option list */ + list_for_each_safe(pos, n, &efi_menu->list) { + entry = list_entry(pos, struct eficonfig_boot_order, list); + reverse = (entry->num == efi_menu->active); + + printf(ANSI_CURSOR_POSITION, entry->num + 4, 7); + + if (reverse) + puts(ANSI_COLOR_REVERSE); + + if (entry->num < efi_menu->count - 2) { + if (entry->active) + printf("[*] "); + else + printf("[ ] "); + } + + printf("%ls", entry->description); + + if (reverse) + puts(ANSI_COLOR_RESET); + } +} + +/** + * eficonfig_choice_change_boot_order() - handle the BootOrder update + * + * @efi_menu: pointer to the efimenu structure + * Return: status code + */ +static efi_status_t eficonfig_choice_change_boot_order(struct efimenu *efi_menu) +{ + int esc = 0; + struct list_head *pos, *n; + struct eficonfig_boot_order *tmp; + enum bootmenu_key key = KEY_NONE; + struct eficonfig_boot_order *entry; + + while (1) { + bootmenu_loop(NULL, &key, &esc); + + switch (key) { + case KEY_PLUS: + if (efi_menu->active > 0) { + list_for_each_safe(pos, n, &efi_menu->list) { + entry = list_entry(pos, struct eficonfig_boot_order, list); + if (entry->num == efi_menu->active) + break; + } + tmp = list_entry(pos->prev, struct eficonfig_boot_order, list); + entry->num--; + tmp->num++; + list_del(&tmp->list); + list_add(&tmp->list, &entry->list); + } + fallthrough; + case KEY_UP: + if (efi_menu->active > 0) + --efi_menu->active; + return EFI_NOT_READY; + case KEY_MINUS: + if (efi_menu->active < efi_menu->count - 3) { + list_for_each_safe(pos, n, &efi_menu->list) { + entry = list_entry(pos, struct eficonfig_boot_order, list); + if (entry->num == efi_menu->active) + break; + } + tmp = list_entry(pos->next, struct eficonfig_boot_order, list); + entry->num++; + tmp->num--; + list_del(&entry->list); + list_add(&entry->list, &tmp->list); + + ++efi_menu->active; + } + return EFI_NOT_READY; + case KEY_DOWN: + if (efi_menu->active < efi_menu->count - 1) + ++efi_menu->active; + return EFI_NOT_READY; + case KEY_SELECT: + /* "Save" */ + if (efi_menu->active == efi_menu->count - 2) + return EFI_SUCCESS; + + /* "Quit" */ + if (efi_menu->active == efi_menu->count - 1) + return EFI_ABORTED; + + break; + case KEY_SPACE: + if (efi_menu->active < efi_menu->count - 2) { + list_for_each_safe(pos, n, &efi_menu->list) { + entry = list_entry(pos, struct eficonfig_boot_order, list); + if (entry->num == efi_menu->active) { + entry->active = entry->active ? false : true; + return EFI_NOT_READY; + } + } + } + break; + case KEY_QUIT: + return EFI_ABORTED; + default: + /* Pressed key is not valid, no need to regenerate the menu */ + break; + } + } +} + +/** + * eficonfig_add_change_boot_order_entry() - add boot order entry + * + * @efi_menu: pointer to the efimenu structure + * @boot_index: boot option index to be added + * @active: flag to include the boot option into BootOrder + * Return: status code + */ +static efi_status_t eficonfig_add_change_boot_order_entry(struct efimenu *efi_menu, + u32 boot_index, bool active) +{ + efi_status_t ret; + efi_uintn_t size; + void *load_option; + struct efi_load_option lo; + u16 varname[] = u"Boot####"; + struct eficonfig_boot_order *entry; + + efi_create_indexed_name(varname, sizeof(varname), "Boot", boot_index); + load_option = efi_get_var(varname, &efi_global_variable_guid, &size); + if (!load_option) + return EFI_SUCCESS; + + ret = efi_deserialize_load_option(&lo, load_option, &size); + if (ret != EFI_SUCCESS) { + free(load_option); + return ret; + } + + entry = calloc(1, sizeof(struct eficonfig_boot_order)); + if (!entry) { + free(load_option); + return EFI_OUT_OF_RESOURCES; + } + + entry->description = u16_strdup(lo.label); + if (!entry->description) { + free(load_option); + free(entry); + return EFI_OUT_OF_RESOURCES; + } + entry->num = efi_menu->count++; + entry->boot_index = boot_index; + entry->active = active; + list_add_tail(&entry->list, &efi_menu->list); + + free(load_option); + + return EFI_SUCCESS; +} + +/** + * eficonfig_create_change_boot_order_entry() - create boot order entry + * + * @efi_menu: pointer to the efimenu structure + * @bootorder: pointer to the BootOrder variable + * @num: number of BootOrder entry + * Return: status code + */ +static efi_status_t eficonfig_create_change_boot_order_entry(struct efimenu *efi_menu, + u16 *bootorder, efi_uintn_t num) +{ + u32 i; + efi_status_t ret; + struct eficonfig_boot_order *entry; + + /* list the load option in the order of BootOrder variable */ + for (i = 0; i < num; i++) { + if (efi_menu->count >= EFICONFIG_ENTRY_NUM_MAX - 2) + break; + + ret = eficonfig_add_change_boot_order_entry(efi_menu, bootorder[i], true); + if (ret != EFI_SUCCESS) + goto out; + } + + /* list the remaining load option not included in the BootOrder */ + for (i = 0; i < 0xFFFF; i++) { + if (efi_menu->count >= EFICONFIG_ENTRY_NUM_MAX - 2) + break; + + /* If the index is included in the BootOrder, skip it */ + if (search_bootorder(bootorder, num, i, NULL)) + continue; + + ret = eficonfig_add_change_boot_order_entry(efi_menu, i, false); + if (ret != EFI_SUCCESS) + goto out; + } + + /* add "Save" and "Quit" entries */ + entry = calloc(1, sizeof(struct eficonfig_boot_order)); + if (!entry) + goto out; + + entry->num = efi_menu->count++; + entry->description = u16_strdup(u"Save"); + list_add_tail(&entry->list, &efi_menu->list); + + entry = calloc(1, sizeof(struct eficonfig_boot_order)); + if (!entry) + goto out; + + entry->num = efi_menu->count++; + entry->description = u16_strdup(u"Quit"); + list_add_tail(&entry->list, &efi_menu->list); + + efi_menu->active = 0; + + return EFI_SUCCESS; +out: + return EFI_OUT_OF_RESOURCES; +} + +/** + * eficonfig_process_change_boot_order() - handler to change boot order + * + * @data: pointer to the data for each entry + * Return: status code + */ +static efi_status_t eficonfig_process_change_boot_order(void *data) +{ + u32 count; + u16 *bootorder; + efi_status_t ret; + efi_uintn_t num, size; + struct list_head *pos, *n; + struct eficonfig_boot_order *entry; + struct efimenu *efi_menu; + + efi_menu = calloc(1, sizeof(struct efimenu)); + if (!efi_menu) + return EFI_OUT_OF_RESOURCES; + + bootorder = efi_get_var(u"BootOrder", &efi_global_variable_guid, &size); + + INIT_LIST_HEAD(&efi_menu->list); + num = size / sizeof(u16); + ret = eficonfig_create_change_boot_order_entry(efi_menu, bootorder, num); + if (ret != EFI_SUCCESS) + goto out; + + while (1) { + eficonfig_display_change_boot_order(efi_menu); + + ret = eficonfig_choice_change_boot_order(efi_menu); + if (ret == EFI_SUCCESS) { + u16 *new_bootorder; + + new_bootorder = calloc(1, (efi_menu->count - 2) * sizeof(u16)); + if (!new_bootorder) { + ret = EFI_OUT_OF_RESOURCES; + goto out; + } + + /* create new BootOrder */ + count = 0; + list_for_each_safe(pos, n, &efi_menu->list) { + entry = list_entry(pos, struct eficonfig_boot_order, list); + if (entry->active) + new_bootorder[count++] = entry->boot_index; + } + + size = count * sizeof(u16); + ret = efi_set_variable_int(u"BootOrder", &efi_global_variable_guid, + EFI_VARIABLE_NON_VOLATILE | + EFI_VARIABLE_BOOTSERVICE_ACCESS | + EFI_VARIABLE_RUNTIME_ACCESS, + size, new_bootorder, false); + + free(new_bootorder); + goto out; + } else if (ret == EFI_NOT_READY) { + continue; + } else { + goto out; + } + } +out: + list_for_each_safe(pos, n, &efi_menu->list) { + entry = list_entry(pos, struct eficonfig_boot_order, list); + list_del(&entry->list); + free(entry->description); + free(entry); + } + + free(bootorder); + free(efi_menu); + + /* to stay the parent menu */ + ret = (ret == EFI_ABORTED) ? EFI_NOT_READY : ret; + + return ret; +} + /** * delete_boot_option() - delete selected boot option * @@ -2065,7 +2411,6 @@ out: return ret; } - /** * eficonfig_init() - do required initialization for eficonfig command * @@ -2096,6 +2441,7 @@ static efi_status_t eficonfig_init(void) static const struct eficonfig_item maintenance_menu_items[] = { {"Add Boot Option", eficonfig_process_add_boot_option}, {"Edit Boot Option", eficonfig_process_edit_boot_option}, + {"Change Boot Order", eficonfig_process_change_boot_order}, {"Delete Boot Option", eficonfig_process_delete_boot_option}, {"Quit", eficonfig_process_quit}, }; From f076c994bfec77c9a784d15f0c6956e0132d7f90 Mon Sep 17 00:00:00 2001 From: Masahisa Kojima Date: Mon, 12 Sep 2022 17:33:57 +0900 Subject: [PATCH 130/374] doc:bootmenu: add description for UEFI boot support The bootmenu enumerates the UEFI boot options for boot device selection. This commit adds the description how the UEFI boot work in bootmenu. This commit also adds "Synopsis", "Description" and "Configuration" sections to follow the U-Boot command documentation format. Signed-off-by: Masahisa Kojima Reviewed-by: Ilias Apalodimas --- doc/usage/cmd/bootmenu.rst | 74 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) diff --git a/doc/usage/cmd/bootmenu.rst b/doc/usage/cmd/bootmenu.rst index 9430f8c9aa..cb3c8d2f93 100644 --- a/doc/usage/cmd/bootmenu.rst +++ b/doc/usage/cmd/bootmenu.rst @@ -4,6 +4,15 @@ bootmenu command ================ +Synopsis +-------- +:: + + bootmenu [delay] + +Description +----------- + The "bootmenu" command uses U-Boot menu interfaces and provides a simple mechanism for creating menus with different boot items. The cursor keys "Up" and "Down" are used for navigation through @@ -79,6 +88,55 @@ The above example will be rendered as below:: The selected menu entry will be highlighted - it will have inverted background and text colors. +UEFI boot variable enumeration +'''''''''''''''''''''''''''''' +If enabled, the bootmenu command will automatically generate and add +UEFI-related boot menu entries for the following items. + + * possible bootable media with default file names + * user-defined UEFI boot options + +The bootmenu automatically enumerates the possible bootable +media devices supporting EFI_SIMPLE_FILE_SYSTEM_PROTOCOL. +This auto generated entry is named as " :" format. +(e.g. "usb 0:1") + +The bootmenu displays the UEFI-related menu entries in order of "BootOrder". +When the user selects the UEFI boot menu entry, the bootmenu sets +the selected boot variable index to "BootNext" without non-volatile attribute, +then call the uefi boot manager with the command "bootefi bootmgr". + +Example bootmenu is as below:: + + *** U-Boot Boot Menu *** + + mmc 0:1 + mmc 0:2 + debian + nvme 0:1 + ubuntu + nvme 0:2 + usb 0:2 + U-Boot console + +Default behavior when user exits from the bootmenu +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +User can exit from bootmenu by selecting the last entry +"U-Boot console"/"Quit" or ESC/CTRL+C key. + +When the CONFIG_BOOTMENU_DISABLE_UBOOT_CONSOLE is disabled, +user exits from the bootmenu and returns to the U-Boot console. + +When the CONFIG_BOOTMENU_DISABLE_UBOOT_CONSOLE is enabled, user can not +enter the U-Boot console. When the user exits from the bootmenu, +the bootmenu invokes the following default behavior. + + * if CONFIG_CMD_BOOTEFI_BOOTMGR is enabled, execute "bootefi bootmgr" command + * "bootefi bootmgr" fails or is not enabled, then execute "run bootcmd" command. + +Configuration +------------- + The "bootmenu" command is enabled by:: CONFIG_CMD_BOOTMENU=y @@ -88,3 +146,19 @@ To run the bootmenu at startup add these additional settings:: CONFIG_AUTOBOOT_KEYED=y CONFIG_BOOTDELAY=30 CONFIG_AUTOBOOT_MENU_SHOW=y + +UEFI boot variable enumeration is enabled by:: + + CONFIG_CMD_BOOTEFI_BOOTMGR=y + +To improve the product security, entering U-Boot console from bootmenu +can be disabled by:: + + CONFIG_BOOTMENU_DISABLE_UBOOT_CONSOLE=y + +To scan the discoverable devices connected to the buses such as +USB and PCIe prior to bootmenu showing up, CONFIG_PREBOOT can be +used to run the command before showing the bootmenu, i.e.:: + + CONFIG_USE_PREBOOT=y + CONFIG_PREBOOT="pci enum; usb start; scsi scan; nvme scan; virtio scan" From 1b2c589eb7deb4d79fa37bc3207ca597251d5d1c Mon Sep 17 00:00:00 2001 From: Masahisa Kojima Date: Mon, 12 Sep 2022 17:33:58 +0900 Subject: [PATCH 131/374] doc:eficonfig: add documentation for eficonfig command Add documentation for eficonfig command. Signed-off-by: Masahisa Kojima Reviewed-by: Ilias Apalodimas --- doc/usage/cmd/eficonfig.rst | 71 +++++++++++++++++++++++++++++++++++++ doc/usage/index.rst | 1 + 2 files changed, 72 insertions(+) create mode 100644 doc/usage/cmd/eficonfig.rst diff --git a/doc/usage/cmd/eficonfig.rst b/doc/usage/cmd/eficonfig.rst new file mode 100644 index 0000000000..340ebc80db --- /dev/null +++ b/doc/usage/cmd/eficonfig.rst @@ -0,0 +1,71 @@ +.. SPDX-License-Identifier: GPL-2.0+ +.. (C) Copyright 2022, Masahisa Kojima + +eficonfig command +================= + +Synopsis +-------- +:: + + eficonfig + +Description +----------- + +The "eficonfig" command uses U-Boot menu interface and provides +a menu-driven UEFI variable maintenance feature. +The "eficonfig" has the following menu entries. + +Add Boot Option + Add new UEFI Boot Option. + User can edit description, file path, and optional_data. + +Edit Boot Option + Edit the existing UEFI Boot Option + User can edit description, file path, and optional_data. + +Change Boot Order + Change the order of UEFI BootOrder variable. + +Delete Boot Option + Delete the UEFI Boot Option + +Configuration +------------- + +The "eficonfig" command is enabled by:: + + CONFIG_CMD_EFICONFIG=y + +If CONFIG_BOOTMENU_DISABLE_UBOOT_CONSOLE is enabled, user can not enter +U-Boot console. In this case, bootmenu can be used to invoke "eficonfig":: + + CONFIG_USE_PREBOOT=y + CONFIG_PREBOOT="setenv bootmenu_0 UEFI Maintenance Menu=eficonfig" + +How to boot the system with newly added UEFI Boot Option +'''''''''''''''''''''''''''''''''''''''''''''''''''''''' + +"eficonfig" command is responsible for configuring the UEFI variables, +not directly handle the system boot. +The new Boot Option added by "eficonfig" is appended at the last entry +of UEFI BootOrder variable, user may want to change the boot order +through "Change Boot Order". +If the bootmenu is enabled, CONFIG_BOOTMENU_DISABLE_UBOOT_CONSOLE is enabled, +and "eficonfig" is configured as preboot command, the newly added Boot Options +are enumerated in the bootmenu when user exits from the eficonfig menu. +User may select the entry in the bootmenu to boot the system, or follow +the U-Boot configuration the system already has. + +Auto boot with the UEFI Boot Option +''''''''''''''''''''''''''''''''''' + +To do auto boot according to the UEFI BootOrder variable, +add "bootefi bootmgr" entry as a default or first bootmenu entry:: + + CONFIG_PREBOOT="setenv bootmenu_0 UEFI Boot Manager=bootefi bootmgr; setenv bootmenu_1 UEFI Maintenance Menu=eficonfig" + +See also +-------- +* :doc:`bootmenu` provides a simple mechanism for creating menus with different boot items diff --git a/doc/usage/index.rst b/doc/usage/index.rst index 5170fa8b4a..b36305c1ff 100644 --- a/doc/usage/index.rst +++ b/doc/usage/index.rst @@ -35,6 +35,7 @@ Shell commands cmd/conitrace cmd/dm cmd/echo + cmd/eficonfig cmd/env cmd/event cmd/exception From da4fb707ca095c223b67637e2525df4866e51c62 Mon Sep 17 00:00:00 2001 From: Masahisa Kojima Date: Mon, 12 Sep 2022 17:33:59 +0900 Subject: [PATCH 132/374] test: unit test for eficonfig Provide a unit test for the eficonfig command. Signed-off-by: Masahisa Kojima Acked-by: Ilias Apalodimas --- configs/sandbox_defconfig | 1 + test/py/tests/test_eficonfig/conftest.py | 40 ++ .../py/tests/test_eficonfig/test_eficonfig.py | 354 ++++++++++++++++++ 3 files changed, 395 insertions(+) create mode 100644 test/py/tests/test_eficonfig/conftest.py create mode 100644 test/py/tests/test_eficonfig/test_eficonfig.py diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig index e6a1718571..830b149251 100644 --- a/configs/sandbox_defconfig +++ b/configs/sandbox_defconfig @@ -93,6 +93,7 @@ CONFIG_CMD_LINK_LOCAL=y CONFIG_CMD_ETHSW=y CONFIG_CMD_BMP=y CONFIG_CMD_BOOTCOUNT=y +CONFIG_CMD_EFICONFIG=y CONFIG_CMD_EFIDEBUG=y CONFIG_CMD_RTC=y CONFIG_CMD_TIME=y diff --git a/test/py/tests/test_eficonfig/conftest.py b/test/py/tests/test_eficonfig/conftest.py new file mode 100644 index 0000000000..f289df0362 --- /dev/null +++ b/test/py/tests/test_eficonfig/conftest.py @@ -0,0 +1,40 @@ +# SPDX-License-Identifier: GPL-2.0+ + +"""Fixture for UEFI eficonfig test +""" + +import os +import shutil +from subprocess import check_call +import pytest + +@pytest.fixture(scope='session') +def efi_eficonfig_data(u_boot_config): + """Set up a file system to be used in UEFI "eficonfig" command + tests + + Args: + u_boot_config -- U-boot configuration. + + Return: + A path to disk image to be used for testing + """ + mnt_point = u_boot_config.persistent_data_dir + '/test_efi_eficonfig' + image_path = u_boot_config.persistent_data_dir + '/efi_eficonfig.img' + + shutil.rmtree(mnt_point, ignore_errors=True) + os.mkdir(mnt_point, mode = 0o755) + + with open(mnt_point + '/initrd-1.img', 'w', encoding = 'ascii') as file: + file.write("initrd 1") + + with open(mnt_point + '/initrd-2.img', 'w', encoding = 'ascii') as file: + file.write("initrd 2") + + shutil.copyfile(u_boot_config.build_dir + '/lib/efi_loader/initrddump.efi', + mnt_point + '/initrddump.efi') + + check_call(f'virt-make-fs --partition=gpt --size=+1M --type=vfat {mnt_point} {image_path}', + shell=True) + + return image_path diff --git a/test/py/tests/test_eficonfig/test_eficonfig.py b/test/py/tests/test_eficonfig/test_eficonfig.py new file mode 100644 index 0000000000..99606d9c4b --- /dev/null +++ b/test/py/tests/test_eficonfig/test_eficonfig.py @@ -0,0 +1,354 @@ +# SPDX-License-Identifier: GPL-2.0+ +""" Unit test for UEFI menu-driven configuration +""" + +import pytest +import time + +@pytest.mark.boardspec('sandbox') +@pytest.mark.buildconfigspec('cmd_eficonfig') +@pytest.mark.buildconfigspec('cmd_bootefi_bootmgr') +def test_efi_eficonfig(u_boot_console, efi_eficonfig_data): + + def send_user_input_and_wait(user_str, expect_str): + time.sleep(0.1) # TODO: does not work correctly without sleep + u_boot_console.run_command(cmd=user_str, wait_for_prompt=False, + wait_for_echo=True, send_nl=False) + u_boot_console.run_command(cmd='\x0d', wait_for_prompt=False, + wait_for_echo=False, send_nl=False) + if expect_str is not None: + for i in expect_str: + u_boot_console.p.expect([i]) + + def press_up_down_enter_and_wait(up_count, down_count, enter, expect_str): + # press UP key + for i in range(up_count): + u_boot_console.run_command(cmd='\x1b\x5b\x41', wait_for_prompt=False, + wait_for_echo=False, send_nl=False) + # press DOWN key + for i in range(down_count): + u_boot_console.run_command(cmd='\x1b\x5b\x42', wait_for_prompt=False, + wait_for_echo=False, send_nl=False) + # press ENTER if requested + if enter: + u_boot_console.run_command(cmd='\x0d', wait_for_prompt=False, + wait_for_echo=False, send_nl=False) + # wait expected output + if expect_str is not None: + for i in expect_str: + u_boot_console.p.expect([i]) + + def press_escape_key(wait_prompt): + u_boot_console.run_command(cmd='\x1b', wait_for_prompt=wait_prompt, wait_for_echo=False, send_nl=False) + + def press_enter_key(wait_prompt): + u_boot_console.run_command(cmd='\x0d', wait_for_prompt=wait_prompt, + wait_for_echo=False, send_nl=False) + + def check_current_is_maintenance_menu(): + for i in ('UEFI Maintenance Menu', 'Add Boot Option', 'Edit Boot Option', + 'Change Boot Order', 'Delete Boot Option', 'Quit'): + u_boot_console.p.expect([i]) + + """ Unit test for "eficonfig" command + The menu-driven interface is used to set up UEFI load options. + The bootefi bootmgr loads initrddump.efi as a payload. + The crc32 of the loaded initrd.img is checked + + Args: + u_boot_console -- U-Boot console + efi__data -- Path to the disk image used for testing. + Test disk image has following files. + initrd-1.img + initrd-2.img + initrddump.efi + + """ + + # Restart the system to clean the previous state + u_boot_console.restart_uboot() + + with u_boot_console.temporary_timeout(500): + # + # Test Case 1: Check the menu is displayed + # + u_boot_console.run_command('eficonfig', wait_for_prompt=False) + for i in ('UEFI Maintenance Menu', 'Add Boot Option', 'Edit Boot Option', + 'Change Boot Order', 'Delete Boot Option', 'Quit'): + u_boot_console.p.expect([i]) + # Select "Add Boot Option" + press_enter_key(False) + for i in ('Add Boot Option', 'Description:', 'File', 'Initrd File', 'Optional Data', + 'Save', 'Quit'): + u_boot_console.p.expect([i]) + press_escape_key(False) + check_current_is_maintenance_menu() + # return to U-Boot console + press_escape_key(True) + + # + # Test Case 2: check auto generated media device entry + # + + # bind the test disk image for succeeding tests + u_boot_console.run_command(cmd = f'host bind 0 {efi_eficonfig_data}') + + u_boot_console.run_command('eficonfig', wait_for_prompt=False) + + # Change the Boot Order + press_up_down_enter_and_wait(0, 2, True, 'Quit') + for i in ('host 0:1', 'Save', 'Quit'): + u_boot_console.p.expect([i]) + # disable auto generated boot option for succeeding test + u_boot_console.run_command(cmd=' ', wait_for_prompt=False, + wait_for_echo=False, send_nl=False) + # Save the BootOrder + press_up_down_enter_and_wait(0, 1, True, None) + check_current_is_maintenance_menu() + + # + # Test Case 3: Add first Boot Option and load it + # + + # Select 'Add Boot Option' + press_up_down_enter_and_wait(0, 0, True, 'Quit') + + # Press the enter key to select 'Description:' entry, then enter Description + press_up_down_enter_and_wait(0, 0, True, 'enter description:') + # Send Description user input, press ENTER key to complete + send_user_input_and_wait('test 1', 'Quit') + + # Set EFI image(initrddump.efi) + press_up_down_enter_and_wait(0, 1, True, 'Quit') + press_up_down_enter_and_wait(0, 0, True, 'host 0:1') + # Select 'host 0:1' + press_up_down_enter_and_wait(0, 0, True, 'Quit') + # Press down key to select "initrddump.efi" entry followed by the enter key + press_up_down_enter_and_wait(0, 2, True, 'Quit') + + # Set Initrd file(initrd-1.img) + press_up_down_enter_and_wait(0, 2, True, 'Quit') + press_up_down_enter_and_wait(0, 0, True, 'host 0:1') + # Select 'host 0:1' + press_up_down_enter_and_wait(0, 0, True, 'Quit') + # Press down key to select "initrd-1.img" entry followed by the enter key + press_up_down_enter_and_wait(0, 0, True, 'Quit') + + # Set optional_data + press_up_down_enter_and_wait(0, 3, True, 'Optional Data:') + # Send Description user input, press ENTER key to complete + send_user_input_and_wait('nocolor', None) + for i in ('Description: test 1', 'File: host 0:1/initrddump.efi', + 'Initrd File: host 0:1/initrd-1.img', 'Optional Data: nocolor', 'Save', 'Quit'): + u_boot_console.p.expect([i]) + + # Save the Boot Option + press_up_down_enter_and_wait(0, 4, True, None) + check_current_is_maintenance_menu() + + # Check the newly added Boot Option is handled correctly + # Return to U-Boot console + press_escape_key(True) + u_boot_console.run_command(cmd = 'bootefi bootmgr') + response = u_boot_console.run_command(cmd = 'load', wait_for_echo=False) + assert 'crc32: 0x181464af' in response + u_boot_console.run_command(cmd = 'exit', wait_for_echo=False) + + # + # Test Case 4: Add second Boot Option and load it + # + u_boot_console.run_command('eficonfig', wait_for_prompt=False) + + # Select 'Add Boot Option' + press_up_down_enter_and_wait(0, 0, True, 'Quit') + + # Press the enter key to select 'Description:' entry, then enter Description + press_up_down_enter_and_wait(0, 0, True, 'enter description:') + # Send Description user input, press ENTER key to complete + send_user_input_and_wait('test 2', 'Quit') + + # Set EFI image(initrddump.efi) + press_up_down_enter_and_wait(0, 1, True, 'Quit') + press_up_down_enter_and_wait(0, 0, True, 'host 0:1') + # Select 'host 0:1' + press_up_down_enter_and_wait(0, 0, True, 'Quit') + # Press down key to select "initrddump.efi" entry followed by the enter key + press_up_down_enter_and_wait(0, 2, True, 'Quit') + + # Set Initrd file(initrd-2.img) + press_up_down_enter_and_wait(0, 2, True, 'Quit') + press_up_down_enter_and_wait(0, 0, True, 'host 0:1') + # Select 'host 0:1' + press_up_down_enter_and_wait(0, 0, True, 'Quit') + # Press down key to select "initrd-2.img" entry followed by the enter key + press_up_down_enter_and_wait(0, 1, True, 'Quit') + + # Set optional_data + press_up_down_enter_and_wait(0, 3, True, 'Optional Data:') + # Send Description user input, press ENTER key to complete + send_user_input_and_wait('nocolor', None) + for i in ('Description: test 2', 'File: host 0:1/initrddump.efi', + 'Initrd File: host 0:1/initrd-2.img', 'Optional Data: nocolor', 'Save', 'Quit'): + u_boot_console.p.expect([i]) + + # Save the Boot Option + press_up_down_enter_and_wait(0, 4, True, 'Quit') + + # Change the Boot Order + press_up_down_enter_and_wait(0, 2, True, 'Quit') + press_up_down_enter_and_wait(0, 1, False, 'Quit') + # move 'test 1' to the second entry + u_boot_console.run_command(cmd='+', wait_for_prompt=False, + wait_for_echo=False, send_nl=False) + for i in ('test 2', 'test 1', 'host 0:1', 'Save', 'Quit'): + u_boot_console.p.expect([i]) + # Save the BootOrder + press_up_down_enter_and_wait(0, 3, True, None) + check_current_is_maintenance_menu() + + # Check the newly added Boot Option is handled correctly + # Return to U-Boot console + press_escape_key(True) + u_boot_console.run_command(cmd = 'bootefi bootmgr') + response = u_boot_console.run_command(cmd = 'load', wait_for_echo=False) + assert 'crc32: 0x811d3515' in response + u_boot_console.run_command(cmd = 'exit', wait_for_echo=False) + + # + # Test Case 5: Change BootOrder and load it + # + u_boot_console.run_command('eficonfig', wait_for_prompt=False) + + # Change the Boot Order + press_up_down_enter_and_wait(0, 2, True, None) + # Check the curren BootOrder + for i in ('test 2', 'test 1', 'host 0:1', 'Save', 'Quit'): + u_boot_console.p.expect([i]) + # move 'test 2' to the second entry + u_boot_console.run_command(cmd='-', wait_for_prompt=False, + wait_for_echo=False, send_nl=False) + for i in ('test 1', 'test 2', 'host 0:1', 'Save', 'Quit'): + u_boot_console.p.expect([i]) + # Save the BootOrder + press_up_down_enter_and_wait(0, 2, True, None) + check_current_is_maintenance_menu() + + # Return to U-Boot console + press_escape_key(True) + u_boot_console.run_command(cmd = 'bootefi bootmgr') + response = u_boot_console.run_command(cmd = 'load', wait_for_echo=False) + assert 'crc32: 0x181464af' in response + u_boot_console.run_command(cmd = 'exit', wait_for_echo=False) + + # + # Test Case 6: Delete Boot Option(label:test 2) + # + u_boot_console.run_command('eficonfig', wait_for_prompt=False) + + # Select 'Delete Boot Option' + press_up_down_enter_and_wait(0, 3, True, None) + # Check the current BootOrder + for i in ('test 1', 'test 2', 'Quit'): + u_boot_console.p.expect([i]) + + # Delete 'test 2' + press_up_down_enter_and_wait(0, 1, True, None) + for i in ('test 1', 'Quit'): + u_boot_console.p.expect([i]) + press_escape_key(False) + check_current_is_maintenance_menu() + # Return to U-Boot console + press_escape_key(True) + + # + # Test Case 7: Edit Boot Option + # + u_boot_console.run_command('eficonfig', wait_for_prompt=False) + # Select 'Edit Boot Option' + press_up_down_enter_and_wait(0, 1, True, None) + # Check the curren BootOrder + for i in ('test 1', 'Quit'): + u_boot_console.p.expect([i]) + press_up_down_enter_and_wait(0, 0, True, None) + for i in ('Description: test 1', 'File: host 0:1/initrddump.efi', + 'Initrd File: host 0:1/initrd-1.img', 'Optional Data: nocolor', 'Save', 'Quit'): + u_boot_console.p.expect([i]) + + # Press the enter key to select 'Description:' entry, then enter Description + press_up_down_enter_and_wait(0, 0, True, 'enter description:') + # Send Description user input, press ENTER key to complete + send_user_input_and_wait('test 3', 'Quit') + + # Set EFI image(initrddump.efi) + press_up_down_enter_and_wait(0, 1, True, 'Quit') + press_up_down_enter_and_wait(0, 0, True, 'host 0:1') + # Select 'host 0:1' + press_up_down_enter_and_wait(0, 0, True, 'Quit') + # Press down key to select "initrddump.efi" entry followed by the enter key + press_up_down_enter_and_wait(0, 2, True, 'Quit') + + # Set Initrd file(initrd-2.img) + press_up_down_enter_and_wait(0, 2, True, 'Quit') + press_up_down_enter_and_wait(0, 0, True, 'host 0:1') + # Select 'host 0:1' + press_up_down_enter_and_wait(0, 0, True, 'Quit') + # Press down key to select "initrd-1.img" entry followed by the enter key + press_up_down_enter_and_wait(0, 1, True, 'Quit') + + # Set optional_data + press_up_down_enter_and_wait(0, 3, True, 'Optional Data:') + # Send Description user input, press ENTER key to complete + send_user_input_and_wait('', None) + for i in ('Description: test 3', 'File: host 0:1/initrddump.efi', + 'Initrd File: host 0:1/initrd-2.img', 'Optional Data:', 'Save', 'Quit'): + u_boot_console.p.expect([i]) + + # Save the Boot Option + press_up_down_enter_and_wait(0, 4, True, 'Quit') + press_escape_key(False) + check_current_is_maintenance_menu() + + # Check the updated Boot Option is handled correctly + # Return to U-Boot console + press_escape_key(True) + u_boot_console.run_command(cmd = 'bootefi bootmgr') + response = u_boot_console.run_command(cmd = 'load', wait_for_echo=False) + assert 'crc32: 0x811d3515' in response + u_boot_console.run_command(cmd = 'exit', wait_for_echo=False) + + # + # Test Case 8: Delete Boot Option(label:test 3) + # + u_boot_console.run_command('eficonfig', wait_for_prompt=False) + + # Select 'Delete Boot Option' + press_up_down_enter_and_wait(0, 3, True, None) + # Check the curren BootOrder + for i in ('test 3', 'Quit'): + u_boot_console.p.expect([i]) + + # Delete 'test 3' + press_up_down_enter_and_wait(0, 0, True, 'Quit') + press_escape_key(False) + check_current_is_maintenance_menu() + # Return to U-Boot console + press_escape_key(True) + + # remove the host device + u_boot_console.run_command(cmd = f'host bind -r 0') + + # + # Test Case 9: No block device found + # + u_boot_console.run_command('eficonfig', wait_for_prompt=False) + + # Select 'Add Boot Option' + press_up_down_enter_and_wait(0, 0, True, 'Quit') + + # Set EFI image + press_up_down_enter_and_wait(0, 1, True, 'Quit') + press_up_down_enter_and_wait(0, 0, True, 'No block device found!') + press_escape_key(False) + check_current_is_maintenance_menu() + # Return to U-Boot console + press_escape_key(True) From 1ce8e10f3b4bd23dfdd7dad076b56ba36fa6416d Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 28 Aug 2022 12:32:46 -0600 Subject: [PATCH 133/374] image: Fix up ANDROID_BOOT_IMAGE ramdisk code Convert this to an if(), fix the cast from an address to a pointer and make sure that any error is returned correctly. Signed-off-by: Simon Glass --- boot/image-board.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/boot/image-board.c b/boot/image-board.c index 4e4d1c157d..14b595977e 100644 --- a/boot/image-board.c +++ b/boot/image-board.c @@ -421,12 +421,19 @@ static int select_ramdisk(bootm_headers_t *images, const char *select, u8 arch, images->fit_noffset_rd = rd_noffset; break; #endif -#ifdef CONFIG_ANDROID_BOOT_IMAGE case IMAGE_FORMAT_ANDROID: - android_image_get_ramdisk((void *)images->os.start, - rd_datap, rd_lenp); - break; -#endif + if (IS_ENABLED(CONFIG_ANDROID_BOOT_IMAGE)) { + void *ptr = map_sysmem(images->os.start, 0); + int ret; + + ret = android_image_get_ramdisk(ptr, rd_datap, + rd_lenp); + unmap_sysmem(ptr); + if (ret) + return ret; + break; + } + fallthrough; default: if (IS_ENABLED(CONFIG_SUPPORT_RAW_INITRD)) { char *end = NULL; From 4f2d94129d92c5efd753b486a7c95beb10b53d50 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 28 Aug 2022 12:32:47 -0600 Subject: [PATCH 134/374] image: Track when ramdisk processing is completed The current switch default is tricky since it relies on #ifdefs to work. Use a bool instead. Also fix the comment on @select, since it has a dual purpose. Signed-off-by: Simon Glass --- boot/image-board.c | 34 +++++++++++++++++++++------------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/boot/image-board.c b/boot/image-board.c index 14b595977e..2d5e5b6e6f 100644 --- a/boot/image-board.c +++ b/boot/image-board.c @@ -314,7 +314,7 @@ int genimg_has_config(bootm_headers_t *images) * select_ramdisk() - Select and locate the ramdisk to use * * @images: pointer to the bootm images structure - * @select: name of ramdisk to select, or NULL for any + * @select: name of ramdisk to select, or hex address, NULL for any * @arch: expected ramdisk architecture * @rd_datap: pointer to a ulong variable, will hold ramdisk pointer * @rd_lenp: pointer to a ulong variable, will hold ramdisk length @@ -324,6 +324,7 @@ int genimg_has_config(bootm_headers_t *images) static int select_ramdisk(bootm_headers_t *images, const char *select, u8 arch, ulong *rd_datap, ulong *rd_lenp) { + bool done = false; ulong rd_addr; char *buf; @@ -401,6 +402,7 @@ static int select_ramdisk(bootm_headers_t *images, const char *select, u8 arch, *rd_datap = image_get_data(rd_hdr); *rd_lenp = image_get_data_size(rd_hdr); + done = true; break; } #endif @@ -419,6 +421,7 @@ static int select_ramdisk(bootm_headers_t *images, const char *select, u8 arch, images->fit_hdr_rd = map_sysmem(rd_addr, 0); images->fit_uname_rd = fit_uname_ramdisk; images->fit_noffset_rd = rd_noffset; + done = true; break; #endif case IMAGE_FORMAT_ANDROID: @@ -431,24 +434,29 @@ static int select_ramdisk(bootm_headers_t *images, const char *select, u8 arch, unmap_sysmem(ptr); if (ret) return ret; - break; + done = true; } - fallthrough; - default: - if (IS_ENABLED(CONFIG_SUPPORT_RAW_INITRD)) { - char *end = NULL; + break; + } - if (select) - end = strchr(select, ':'); - if (end) { - *rd_lenp = hextoul(++end, NULL); - *rd_datap = rd_addr; - break; - } + if (!done) { + if (IS_ENABLED(CONFIG_SUPPORT_RAW_INITRD)) { + char *end = NULL; + + if (select) + end = strchr(select, ':'); + if (end) { + *rd_lenp = hextoul(++end, NULL); + *rd_datap = rd_addr; + done = true; } + } + + if (!done) { puts("Wrong Ramdisk Image Format\n"); return -EINVAL; } + } return 0; } From 0f81af4897e5875faf3c3d676f8140556b7efc36 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 28 Aug 2022 12:32:48 -0600 Subject: [PATCH 135/374] image: Drop #ifdefs for LEGACY_IMAGE_FORMAT Use if() instead of the #ifdef in select_ramdisk(). Signed-off-by: Simon Glass --- boot/image-board.c | 31 ++++++++++++++----------------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/boot/image-board.c b/boot/image-board.c index 2d5e5b6e6f..a80ad08b15 100644 --- a/boot/image-board.c +++ b/boot/image-board.c @@ -24,7 +24,6 @@ DECLARE_GLOBAL_DATA_PTR; -#if CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT) /** * image_get_ramdisk - get and verify ramdisk image * @rd_addr: ramdisk image start address @@ -83,7 +82,6 @@ static const image_header_t *image_get_ramdisk(ulong rd_addr, u8 arch, return rd_hdr; } -#endif /*****************************************************************************/ /* Shared dual-format routines */ @@ -386,26 +384,25 @@ static int select_ramdisk(bootm_headers_t *images, const char *select, u8 arch, */ buf = map_sysmem(rd_addr, 0); switch (genimg_get_format(buf)) { -#if CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT) - case IMAGE_FORMAT_LEGACY: { - const image_header_t *rd_hdr; + case IMAGE_FORMAT_LEGACY: + if (CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT)) { + const image_header_t *rd_hdr; - printf("## Loading init Ramdisk from Legacy Image at %08lx ...\n", - rd_addr); + printf("## Loading init Ramdisk from Legacy Image at %08lx ...\n", + rd_addr); - bootstage_mark(BOOTSTAGE_ID_CHECK_RAMDISK); - rd_hdr = image_get_ramdisk(rd_addr, arch, - images->verify); + bootstage_mark(BOOTSTAGE_ID_CHECK_RAMDISK); + rd_hdr = image_get_ramdisk(rd_addr, arch, + images->verify); - if (!rd_hdr) - return -ENOENT; + if (!rd_hdr) + return -ENOENT; - *rd_datap = image_get_data(rd_hdr); - *rd_lenp = image_get_data_size(rd_hdr); - done = true; + *rd_datap = image_get_data(rd_hdr); + *rd_lenp = image_get_data_size(rd_hdr); + done = true; + } break; - } -#endif #if CONFIG_IS_ENABLED(FIT) case IMAGE_FORMAT_FIT: rd_noffset = fit_image_load(images, From f7659f69f70743dbd772b1dea24f346a63757eb8 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 28 Aug 2022 12:32:49 -0600 Subject: [PATCH 136/374] image: Drop one #ifdef for FIT Drop the #ifdef from near the end of select_ramdisk(). Move some variables to the top of the function to make this work. Signed-off-by: Simon Glass --- boot/image-board.c | 37 +++++++++++++++++++------------------ 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/boot/image-board.c b/boot/image-board.c index a80ad08b15..07b7e467cc 100644 --- a/boot/image-board.c +++ b/boot/image-board.c @@ -322,14 +322,16 @@ int genimg_has_config(bootm_headers_t *images) static int select_ramdisk(bootm_headers_t *images, const char *select, u8 arch, ulong *rd_datap, ulong *rd_lenp) { + const char *fit_uname_config; + const char *fit_uname_ramdisk; bool done = false; + int rd_noffset; ulong rd_addr; char *buf; #if CONFIG_IS_ENABLED(FIT) - const char *fit_uname_config = images->fit_uname_cfg; - const char *fit_uname_ramdisk = NULL; - int rd_noffset; + fit_uname_config = images->fit_uname_cfg; + fit_uname_ramdisk = NULL; if (select) { ulong default_addr; @@ -403,24 +405,23 @@ static int select_ramdisk(bootm_headers_t *images, const char *select, u8 arch, done = true; } break; -#if CONFIG_IS_ENABLED(FIT) case IMAGE_FORMAT_FIT: - rd_noffset = fit_image_load(images, - rd_addr, &fit_uname_ramdisk, - &fit_uname_config, arch, - IH_TYPE_RAMDISK, - BOOTSTAGE_ID_FIT_RD_START, - FIT_LOAD_OPTIONAL_NON_ZERO, - rd_datap, rd_lenp); - if (rd_noffset < 0) - return rd_noffset; + if (CONFIG_IS_ENABLED(FIT)) { + rd_noffset = fit_image_load(images, rd_addr, + &fit_uname_ramdisk, &fit_uname_config, + arch, IH_TYPE_RAMDISK, + BOOTSTAGE_ID_FIT_RD_START, + FIT_LOAD_OPTIONAL_NON_ZERO, + rd_datap, rd_lenp); + if (rd_noffset < 0) + return rd_noffset; - images->fit_hdr_rd = map_sysmem(rd_addr, 0); - images->fit_uname_rd = fit_uname_ramdisk; - images->fit_noffset_rd = rd_noffset; - done = true; + images->fit_hdr_rd = map_sysmem(rd_addr, 0); + images->fit_uname_rd = fit_uname_ramdisk; + images->fit_noffset_rd = rd_noffset; + done = true; + } break; -#endif case IMAGE_FORMAT_ANDROID: if (IS_ENABLED(CONFIG_ANDROID_BOOT_IMAGE)) { void *ptr = map_sysmem(images->os.start, 0); From 1a68c039c500a97f46bd0ae180df01a42636fde8 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 28 Aug 2022 12:32:50 -0600 Subject: [PATCH 137/374] image: Drop another #ifdef for FIT Drop the prenultimate one of these from select_ramdisk(). Signed-off-by: Simon Glass --- boot/image-board.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/boot/image-board.c b/boot/image-board.c index 07b7e467cc..8858a2fe12 100644 --- a/boot/image-board.c +++ b/boot/image-board.c @@ -363,7 +363,9 @@ static int select_ramdisk(bootm_headers_t *images, const char *select, u8 arch, rd_addr); } #if CONFIG_IS_ENABLED(FIT) - } else { + } +#endif + if (CONFIG_IS_ENABLED(FIT) && !select) { /* use FIT configuration provided in first bootm * command argument. If the property is not defined, * quit silently (with -ENOPKG) @@ -377,7 +379,6 @@ static int select_ramdisk(bootm_headers_t *images, const char *select, u8 arch, else if (rd_noffset < 0) return rd_noffset; } -#endif /* * Check if there is an initrd image at the From ca78883fdcc67907780ae04188799abb9348bf37 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 28 Aug 2022 12:32:51 -0600 Subject: [PATCH 138/374] image: Drop remaining FIT #ifdef Drop the last one of these, by using a done_select variable to control whether to fall back to using 'select' as a hex value. Note that the indentation is not adjusted, to make this easier to review. Signed-off-by: Simon Glass --- boot/image-board.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/boot/image-board.c b/boot/image-board.c index 8858a2fe12..7c0948b592 100644 --- a/boot/image-board.c +++ b/boot/image-board.c @@ -324,12 +324,13 @@ static int select_ramdisk(bootm_headers_t *images, const char *select, u8 arch, { const char *fit_uname_config; const char *fit_uname_ramdisk; + bool done_select = !select; bool done = false; int rd_noffset; ulong rd_addr; char *buf; -#if CONFIG_IS_ENABLED(FIT) + if (CONFIG_IS_ENABLED(FIT)) { fit_uname_config = images->fit_uname_cfg; fit_uname_ramdisk = NULL; @@ -350,21 +351,21 @@ static int select_ramdisk(bootm_headers_t *images, const char *select, u8 arch, &rd_addr, &fit_uname_config)) { debug("* ramdisk: config '%s' from image at 0x%08lx\n", fit_uname_config, rd_addr); + done_select = true; } else if (fit_parse_subimage(select, default_addr, &rd_addr, &fit_uname_ramdisk)) { debug("* ramdisk: subimage '%s' from image at 0x%08lx\n", fit_uname_ramdisk, rd_addr); - } else -#endif - { + done_select = true; + } + } + } + if (!done_select) { rd_addr = hextoul(select, NULL); debug("* ramdisk: cmdline image address = 0x%08lx\n", rd_addr); - } -#if CONFIG_IS_ENABLED(FIT) - } -#endif + } if (CONFIG_IS_ENABLED(FIT) && !select) { /* use FIT configuration provided in first bootm * command argument. If the property is not defined, From 20f5d83fb1507514d60942cf6ca9a53c7448b803 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 28 Aug 2022 12:32:52 -0600 Subject: [PATCH 139/374] image: Correct indentation in select_ramdisk() Finish off the refactoring by correcting the indent levels. Note that this does not include any functional changes. Signed-off-by: Simon Glass --- boot/image-board.c | 138 ++++++++++++++++++++++----------------------- 1 file changed, 68 insertions(+), 70 deletions(-) diff --git a/boot/image-board.c b/boot/image-board.c index 7c0948b592..7a17ffb7f7 100644 --- a/boot/image-board.c +++ b/boot/image-board.c @@ -347,8 +347,8 @@ static int select_ramdisk(bootm_headers_t *images, const char *select, u8 arch, else default_addr = image_load_addr; - if (fit_parse_conf(select, default_addr, - &rd_addr, &fit_uname_config)) { + if (fit_parse_conf(select, default_addr, &rd_addr, + &fit_uname_config)) { debug("* ramdisk: config '%s' from image at 0x%08lx\n", fit_uname_config, rd_addr); done_select = true; @@ -362,82 +362,80 @@ static int select_ramdisk(bootm_headers_t *images, const char *select, u8 arch, } } if (!done_select) { - rd_addr = hextoul(select, NULL); - debug("* ramdisk: cmdline image address = 0x%08lx\n", - rd_addr); + rd_addr = hextoul(select, NULL); + debug("* ramdisk: cmdline image address = 0x%08lx\n", rd_addr); } - if (CONFIG_IS_ENABLED(FIT) && !select) { - /* use FIT configuration provided in first bootm - * command argument. If the property is not defined, - * quit silently (with -ENOPKG) - */ - rd_addr = map_to_sysmem(images->fit_hdr_os); - rd_noffset = fit_get_node_from_config(images, - FIT_RAMDISK_PROP, - rd_addr); - if (rd_noffset == -ENOENT) - return -ENOPKG; - else if (rd_noffset < 0) - return rd_noffset; - } - - /* - * Check if there is an initrd image at the - * address provided in the second bootm argument - * check image type, for FIT images get FIT node. + if (CONFIG_IS_ENABLED(FIT) && !select) { + /* use FIT configuration provided in first bootm + * command argument. If the property is not defined, + * quit silently (with -ENOPKG) */ - buf = map_sysmem(rd_addr, 0); - switch (genimg_get_format(buf)) { - case IMAGE_FORMAT_LEGACY: - if (CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT)) { - const image_header_t *rd_hdr; + rd_addr = map_to_sysmem(images->fit_hdr_os); + rd_noffset = fit_get_node_from_config(images, FIT_RAMDISK_PROP, + rd_addr); + if (rd_noffset == -ENOENT) + return -ENOPKG; + else if (rd_noffset < 0) + return rd_noffset; + } - printf("## Loading init Ramdisk from Legacy Image at %08lx ...\n", - rd_addr); + /* + * Check if there is an initrd image at the + * address provided in the second bootm argument + * check image type, for FIT images get FIT node. + */ + buf = map_sysmem(rd_addr, 0); + switch (genimg_get_format(buf)) { + case IMAGE_FORMAT_LEGACY: + if (CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT)) { + const image_header_t *rd_hdr; - bootstage_mark(BOOTSTAGE_ID_CHECK_RAMDISK); - rd_hdr = image_get_ramdisk(rd_addr, arch, - images->verify); + printf("## Loading init Ramdisk from Legacy Image at %08lx ...\n", + rd_addr); - if (!rd_hdr) - return -ENOENT; + bootstage_mark(BOOTSTAGE_ID_CHECK_RAMDISK); + rd_hdr = image_get_ramdisk(rd_addr, arch, + images->verify); - *rd_datap = image_get_data(rd_hdr); - *rd_lenp = image_get_data_size(rd_hdr); - done = true; - } - break; - case IMAGE_FORMAT_FIT: - if (CONFIG_IS_ENABLED(FIT)) { - rd_noffset = fit_image_load(images, rd_addr, - &fit_uname_ramdisk, &fit_uname_config, - arch, IH_TYPE_RAMDISK, - BOOTSTAGE_ID_FIT_RD_START, - FIT_LOAD_OPTIONAL_NON_ZERO, - rd_datap, rd_lenp); - if (rd_noffset < 0) - return rd_noffset; + if (!rd_hdr) + return -ENOENT; - images->fit_hdr_rd = map_sysmem(rd_addr, 0); - images->fit_uname_rd = fit_uname_ramdisk; - images->fit_noffset_rd = rd_noffset; - done = true; - } - break; - case IMAGE_FORMAT_ANDROID: - if (IS_ENABLED(CONFIG_ANDROID_BOOT_IMAGE)) { - void *ptr = map_sysmem(images->os.start, 0); - int ret; - - ret = android_image_get_ramdisk(ptr, rd_datap, - rd_lenp); - unmap_sysmem(ptr); - if (ret) - return ret; - done = true; - } - break; + *rd_datap = image_get_data(rd_hdr); + *rd_lenp = image_get_data_size(rd_hdr); + done = true; } + break; + case IMAGE_FORMAT_FIT: + if (CONFIG_IS_ENABLED(FIT)) { + rd_noffset = fit_image_load(images, rd_addr, + &fit_uname_ramdisk, + &fit_uname_config, + arch, IH_TYPE_RAMDISK, + BOOTSTAGE_ID_FIT_RD_START, + FIT_LOAD_OPTIONAL_NON_ZERO, + rd_datap, rd_lenp); + if (rd_noffset < 0) + return rd_noffset; + + images->fit_hdr_rd = map_sysmem(rd_addr, 0); + images->fit_uname_rd = fit_uname_ramdisk; + images->fit_noffset_rd = rd_noffset; + done = true; + } + break; + case IMAGE_FORMAT_ANDROID: + if (IS_ENABLED(CONFIG_ANDROID_BOOT_IMAGE)) { + void *ptr = map_sysmem(images->os.start, 0); + int ret; + + ret = android_image_get_ramdisk(ptr, rd_datap, rd_lenp); + unmap_sysmem(ptr); + if (ret) + return ret; + done = true; + } + break; + } if (!done) { if (IS_ENABLED(CONFIG_SUPPORT_RAW_INITRD)) { From 9c2e9128f34d8a23eb567da07842fad041bfc57b Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 28 Aug 2022 12:32:53 -0600 Subject: [PATCH 140/374] image: Drop some other #ifdefs in image-board.c Remove all but a few that are difficult, relying on legacy CONFIG options or optional global_data fields. Drop the duplicate function name in the comment for boot_get_cmdline(). Signed-off-by: Simon Glass --- boot/image-board.c | 67 +++++++++++++++++++++++++--------------------- include/image.h | 6 +++++ 2 files changed, 42 insertions(+), 31 deletions(-) diff --git a/boot/image-board.c b/boot/image-board.c index 7a17ffb7f7..1be0a359ab 100644 --- a/boot/image-board.c +++ b/boot/image-board.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -172,29 +173,29 @@ void memmove_wd(void *to, void *from, size_t len, ulong chunksz) if (to == from) return; -#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG) - if (to > from) { - from += len; - to += len; - } - while (len > 0) { - size_t tail = (len > chunksz) ? chunksz : len; - - WATCHDOG_RESET(); + if (IS_ENABLED(CONFIG_HW_WATCHDOG) || IS_ENABLED(CONFIG_WATCHDOG)) { if (to > from) { - to -= tail; - from -= tail; + from += len; + to += len; } - memmove(to, from, tail); - if (to < from) { - to += tail; - from += tail; + while (len > 0) { + size_t tail = (len > chunksz) ? chunksz : len; + + WATCHDOG_RESET(); + if (to > from) { + to -= tail; + from -= tail; + } + memmove(to, from, tail); + if (to < from) { + to += tail; + from += tail; + } + len -= tail; } - len -= tail; + } else { + memmove(to, from, len); } -#else /* !(CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG) */ - memmove(to, from, len); -#endif /* CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG */ } /** @@ -551,7 +552,6 @@ int boot_get_ramdisk(int argc, char *const argv[], bootm_headers_t *images, return 0; } -#if defined(CONFIG_LMB) /** * boot_ramdisk_high - relocate init ramdisk * @lmb: pointer to lmb handle, will be used for memory mgmt @@ -645,7 +645,6 @@ int boot_ramdisk_high(struct lmb *lmb, ulong rd_data, ulong rd_len, error: return -1; } -#endif int boot_get_setup(bootm_headers_t *images, u8 arch, ulong *setup_start, ulong *setup_len) @@ -839,15 +838,13 @@ int boot_get_loadable(int argc, char *const argv[], bootm_headers_t *images, return 0; } -#if defined(CONFIG_LMB) -#ifdef CONFIG_SYS_BOOT_GET_CMDLINE /** * boot_get_cmdline - allocate and initialize kernel cmdline * @lmb: pointer to lmb handle, will be used for memory mgmt * @cmd_start: pointer to a ulong variable, will hold cmdline start * @cmd_end: pointer to a ulong variable, will hold cmdline end * - * boot_get_cmdline() allocates space for kernel command line below + * This allocates space for kernel command line below * BOOTMAPSZ + env_get_bootm_low() address. If "bootargs" U-Boot environment * variable is present its contents is copied to allocated kernel * command line. @@ -858,10 +855,19 @@ int boot_get_loadable(int argc, char *const argv[], bootm_headers_t *images, */ int boot_get_cmdline(struct lmb *lmb, ulong *cmd_start, ulong *cmd_end) { + int barg; char *cmdline; char *s; - cmdline = (char *)(ulong)lmb_alloc_base(lmb, CONFIG_SYS_BARGSIZE, 0xf, + /* + * Help the compiler detect that this function is only called when + * CONFIG_SYS_BOOT_GET_CMDLINE is enabled + */ + if (!IS_ENABLED(CONFIG_SYS_BOOT_GET_CMDLINE)) + return 0; + + barg = IF_ENABLED_INT(CONFIG_SYS_BOOT_GET_CMDLINE, CONFIG_SYS_BARGSIZE); + cmdline = (char *)(ulong)lmb_alloc_base(lmb, barg, 0xf, env_get_bootm_mapsize() + env_get_bootm_low()); if (!cmdline) return -1; @@ -907,22 +913,22 @@ int boot_get_kbd(struct lmb *lmb, struct bd_info **kbd) debug("## kernel board info at 0x%08lx\n", (ulong)*kbd); -#if defined(DEBUG) - if (IS_ENABLED(CONFIG_CMD_BDI)) + if (_DEBUG && IS_ENABLED(CONFIG_CMD_BDI)) do_bdinfo(NULL, 0, 0, NULL); -#endif return 0; } -#endif int image_setup_linux(bootm_headers_t *images) { ulong of_size = images->ft_len; char **of_flat_tree = &images->ft_addr; - struct lmb *lmb = &images->lmb; + struct lmb *lmb = images_lmb(images); int ret; + /* This function cannot be called without lmb support */ + if (!CONFIG_IS_ENABLED(LMB)) + return -EFAULT; if (CONFIG_IS_ENABLED(OF_LIBFDT)) boot_fdt_add_mem_rsv_regions(lmb, *of_flat_tree); @@ -949,7 +955,6 @@ int image_setup_linux(bootm_headers_t *images) return 0; } -#endif void genimg_print_size(uint32_t size) { diff --git a/include/image.h b/include/image.h index e4c6a50b88..a148073113 100644 --- a/include/image.h +++ b/include/image.h @@ -360,6 +360,12 @@ typedef struct bootm_headers { #endif } bootm_headers_t; +#ifdef CONFIG_LMB +#define images_lmb(_images) (&(_images)->lmb) +#else +#define images_lmb(_images) NULL +#endif + extern bootm_headers_t images; /* From 7a0d88076b9cd8ccc88d41383f92ac2494d4168e Mon Sep 17 00:00:00 2001 From: Nathan Barrett-Morrison Date: Wed, 2 Feb 2022 15:05:18 -0500 Subject: [PATCH 141/374] Add in the ability to load and boot an uncompressed kernel image during the Falcon Mode boot sequence. This is required for architectures which do not support compressed kernel images (i.e. ARM64). This is only used while not booting via FIT image. Signed-off-by: Nathan Barrett-Morrison Cc: Tom Rini Reviewed-by: Tom Rini --- arch/arm/lib/Makefile | 5 ++++- common/spl/spl.c | 21 +++++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile index d137b4bf0f..62cf80f373 100644 --- a/arch/arm/lib/Makefile +++ b/arch/arm/lib/Makefile @@ -35,7 +35,10 @@ obj-$(CONFIG_CMD_BOOTM) += bootm.o obj-$(CONFIG_CMD_BOOTZ) += bootm.o zimage.o else obj-$(CONFIG_$(SPL_TPL_)FRAMEWORK) += spl.o -obj-$(CONFIG_SPL_FRAMEWORK) += zimage.o +ifdef CONFIG_SPL_FRAMEWORK +obj-$(CONFIG_CMD_BOOTI) += image.o +obj-$(CONFIG_CMD_BOOTZ) += zimage.o +endif obj-$(CONFIG_OF_LIBFDT) += bootm-fdt.o endif ifdef CONFIG_ARM64 diff --git a/common/spl/spl.c b/common/spl/spl.c index 29e0898f03..828f72f30b 100644 --- a/common/spl/spl.c +++ b/common/spl/spl.c @@ -116,6 +116,11 @@ int __weak bootz_setup(ulong image, ulong *start, ulong *end) { return 1; } + +int __weak booti_setup(ulong image, ulong *relocated_addr, ulong *size, bool force_reloc) +{ + return 1; +} #endif /* Weak default function for arch/board-specific fixups to the spl_image_info */ @@ -391,6 +396,21 @@ int spl_parse_image_header(struct spl_image_info *spl_image, #endif #if CONFIG_IS_ENABLED(OS_BOOT) +#if defined(CMD_BOOTI) + ulong start, size; + + if (!booti_setup((ulong)header, &start, &size, 0)) { + spl_image->name = "Linux"; + spl_image->os = IH_OS_LINUX; + spl_image->load_addr = start; + spl_image->entry_point = start; + spl_image->size = size; + debug(SPL_TPL_PROMPT + "payload Image, load addr: 0x%lx size: %d\n", + spl_image->load_addr, spl_image->size); + return 0; + } +#elif defined(CMD_BOOTZ) ulong start, end; if (!bootz_setup((ulong)header, &start, &end)) { @@ -404,6 +424,7 @@ int spl_parse_image_header(struct spl_image_info *spl_image, spl_image->load_addr, spl_image->size); return 0; } +#endif #endif if (!spl_parse_board_header(spl_image, bootdev, (const void *)header, sizeof(*header))) From b471bdc47b2acabe0b5fcb0fb40a0b1c0602d3b3 Mon Sep 17 00:00:00 2001 From: Stefan Herbrechtsmeier Date: Tue, 14 Jun 2022 15:21:30 +0200 Subject: [PATCH 142/374] dm: core: Add functions to read 8/16-bit integers Add functions to read 8/16-bit integers like the existing functions for 32/64-bit to simplify read of 8/16-bit integers from device tree properties. Signed-off-by: Stefan Herbrechtsmeier Reviewed-by: Marek Vasut Reviewed-by: Simon Glass Reviewed-by: Simon Glass --- arch/sandbox/dts/test.dts | 2 ++ drivers/core/of_access.c | 38 +++++++++++++++++++++++ drivers/core/ofnode.c | 62 +++++++++++++++++++++++++++++++++++++ drivers/core/read.c | 21 +++++++++++++ include/dm/of_access.h | 32 +++++++++++++++++++ include/dm/ofnode.h | 40 ++++++++++++++++++++++++ include/dm/read.h | 65 +++++++++++++++++++++++++++++++++++++++ test/dm/test-fdt.c | 19 ++++++++++++ 8 files changed, 279 insertions(+) diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts index 2761588f0d..c7fffa2da2 100644 --- a/arch/sandbox/dts/test.dts +++ b/arch/sandbox/dts/test.dts @@ -233,6 +233,8 @@ test5-gpios = <&gpio_a 19>; bool-value; + int8-value = /bits/ 8 <0x12>; + int16-value = /bits/ 16 <0x1234>; int-value = <1234>; uint-value = <(-1234)>; int64-value = /bits/ 64 <0x1111222233334444>; diff --git a/drivers/core/of_access.c b/drivers/core/of_access.c index a52f5a6b18..df007e642b 100644 --- a/drivers/core/of_access.c +++ b/drivers/core/of_access.c @@ -488,6 +488,44 @@ static void *of_find_property_value_of_size(const struct device_node *np, return prop->value; } +int of_read_u8(const struct device_node *np, const char *propname, u8 *outp) +{ + const u8 *val; + + debug("%s: %s: ", __func__, propname); + if (!np) + return -EINVAL; + val = of_find_property_value_of_size(np, propname, sizeof(*outp)); + if (IS_ERR(val)) { + debug("(not found)\n"); + return PTR_ERR(val); + } + + *outp = *val; + debug("%#x (%d)\n", *outp, *outp); + + return 0; +} + +int of_read_u16(const struct device_node *np, const char *propname, u16 *outp) +{ + const __be16 *val; + + debug("%s: %s: ", __func__, propname); + if (!np) + return -EINVAL; + val = of_find_property_value_of_size(np, propname, sizeof(*outp)); + if (IS_ERR(val)) { + debug("(not found)\n"); + return PTR_ERR(val); + } + + *outp = be16_to_cpup(val); + debug("%#x (%d)\n", *outp, *outp); + + return 0; +} + int of_read_u32(const struct device_node *np, const char *propname, u32 *outp) { return of_read_u32_index(np, propname, 0, outp); diff --git a/drivers/core/ofnode.c b/drivers/core/ofnode.c index 45ea84e9fb..42f3c09a51 100644 --- a/drivers/core/ofnode.c +++ b/drivers/core/ofnode.c @@ -31,6 +31,68 @@ bool ofnode_name_eq(ofnode node, const char *name) return (strlen(name) == len) && !strncmp(node_name, name, len); } +int ofnode_read_u8(ofnode node, const char *propname, u8 *outp) +{ + const u8 *cell; + int len; + + assert(ofnode_valid(node)); + debug("%s: %s: ", __func__, propname); + + if (ofnode_is_np(node)) + return of_read_u8(ofnode_to_np(node), propname, outp); + + cell = fdt_getprop(gd->fdt_blob, ofnode_to_offset(node), propname, + &len); + if (!cell || len < sizeof(*cell)) { + debug("(not found)\n"); + return -EINVAL; + } + *outp = *cell; + debug("%#x (%d)\n", *outp, *outp); + + return 0; +} + +u8 ofnode_read_u8_default(ofnode node, const char *propname, u8 def) +{ + assert(ofnode_valid(node)); + ofnode_read_u8(node, propname, &def); + + return def; +} + +int ofnode_read_u16(ofnode node, const char *propname, u16 *outp) +{ + const fdt16_t *cell; + int len; + + assert(ofnode_valid(node)); + debug("%s: %s: ", __func__, propname); + + if (ofnode_is_np(node)) + return of_read_u16(ofnode_to_np(node), propname, outp); + + cell = fdt_getprop(gd->fdt_blob, ofnode_to_offset(node), propname, + &len); + if (!cell || len < sizeof(*cell)) { + debug("(not found)\n"); + return -EINVAL; + } + *outp = be16_to_cpup(cell); + debug("%#x (%d)\n", *outp, *outp); + + return 0; +} + +u16 ofnode_read_u16_default(ofnode node, const char *propname, u16 def) +{ + assert(ofnode_valid(node)); + ofnode_read_u16(node, propname, &def); + + return def; +} + int ofnode_read_u32(ofnode node, const char *propname, u32 *outp) { return ofnode_read_u32_index(node, propname, 0, outp); diff --git a/drivers/core/read.c b/drivers/core/read.c index c73508d276..07ab8ab41c 100644 --- a/drivers/core/read.c +++ b/drivers/core/read.c @@ -13,6 +13,27 @@ #include #include +int dev_read_u8(const struct udevice *dev, const char *propname, u8 *outp) +{ + return ofnode_read_u8(dev_ofnode(dev), propname, outp); +} + +u8 dev_read_u8_default(const struct udevice *dev, const char *propname, u8 def) +{ + return ofnode_read_u8_default(dev_ofnode(dev), propname, def); +} + +int dev_read_u16(const struct udevice *dev, const char *propname, u16 *outp) +{ + return ofnode_read_u16(dev_ofnode(dev), propname, outp); +} + +u16 dev_read_u16_default(const struct udevice *dev, const char *propname, + u16 def) +{ + return ofnode_read_u16_default(dev_ofnode(dev), propname, def); +} + int dev_read_u32(const struct udevice *dev, const char *propname, u32 *outp) { return ofnode_read_u32(dev_ofnode(dev), propname, outp); diff --git a/include/dm/of_access.h b/include/dm/of_access.h index 5b7821d0a1..83f34f0d2a 100644 --- a/include/dm/of_access.h +++ b/include/dm/of_access.h @@ -264,6 +264,38 @@ struct device_node *of_find_node_by_prop_value(struct device_node *from, */ struct device_node *of_find_node_by_phandle(phandle handle); +/** + * of_read_u8() - Find and read a 8-bit integer from a property + * + * Search for a property in a device node and read a 8-bit value from + * it. + * + * @np: device node from which the property value is to be read. + * @propname: name of the property to be searched. + * @outp: pointer to return value, modified only if return value is 0. + * + * Return: 0 on success, -EINVAL if the property does not exist, + * -ENODATA if property does not have a value, and -EOVERFLOW if the + * property data isn't large enough. + */ +int of_read_u8(const struct device_node *np, const char *propname, u8 *outp); + +/** + * of_read_u16() - Find and read a 16-bit integer from a property + * + * Search for a property in a device node and read a 16-bit value from + * it. + * + * @np: device node from which the property value is to be read. + * @propname: name of the property to be searched. + * @outp: pointer to return value, modified only if return value is 0. + * + * Return: 0 on success, -EINVAL if the property does not exist, + * -ENODATA if property does not have a value, and -EOVERFLOW if the + * property data isn't large enough. + */ +int of_read_u16(const struct device_node *np, const char *propname, u16 *outp); + /** * of_read_u32() - Find and read a 32-bit integer from a property * diff --git a/include/dm/ofnode.h b/include/dm/ofnode.h index 7ce1e4c6d9..f6085231bb 100644 --- a/include/dm/ofnode.h +++ b/include/dm/ofnode.h @@ -221,6 +221,46 @@ static inline oftree oftree_default(void) */ bool ofnode_name_eq(ofnode node, const char *name); +/** + * ofnode_read_u8() - Read a 8-bit integer from a property + * + * @node: valid node reference to read property from + * @propname: name of the property to read from + * @outp: place to put value (if found) + * Return: 0 if OK, -ve on error + */ +int ofnode_read_u8(ofnode node, const char *propname, u8 *outp); + +/** + * ofnode_read_u8_default() - Read a 8-bit integer from a property + * + * @node: valid node reference to read property from + * @propname: name of the property to read from + * @def: default value to return if the property has no value + * Return: property value, or @def if not found + */ +u8 ofnode_read_u8_default(ofnode node, const char *propname, u8 def); + +/** + * ofnode_read_u16() - Read a 16-bit integer from a property + * + * @node: valid node reference to read property from + * @propname: name of the property to read from + * @outp: place to put value (if found) + * Return: 0 if OK, -ve on error + */ +int ofnode_read_u16(ofnode node, const char *propname, u16 *outp); + +/** + * ofnode_read_u16_default() - Read a 16-bit integer from a property + * + * @node: valid node reference to read property from + * @propname: name of the property to read from + * @def: default value to return if the property has no value + * Return: property value, or @def if not found + */ +u16 ofnode_read_u16_default(ofnode node, const char *propname, u16 def); + /** * ofnode_read_u32() - Read a 32-bit integer from a property * diff --git a/include/dm/read.h b/include/dm/read.h index 1b54b69acf..122b9cd15b 100644 --- a/include/dm/read.h +++ b/include/dm/read.h @@ -31,6 +31,47 @@ static inline const struct device_node *dev_np(const struct udevice *dev) #endif #if !defined(CONFIG_DM_DEV_READ_INLINE) || CONFIG_IS_ENABLED(OF_PLATDATA) +/** + * dev_read_u8() - read a 8-bit integer from a device's DT property + * + * @dev: device to read DT property from + * @propname: name of the property to read from + * @outp: place to put value (if found) + * Return: 0 if OK, -ve on error + */ +int dev_read_u8(const struct udevice *dev, const char *propname, u8 *outp); + +/** + * dev_read_u8_default() - read a 8-bit integer from a device's DT property + * + * @dev: device to read DT property from + * @propname: name of the property to read from + * @def: default value to return if the property has no value + * Return: property value, or @def if not found + */ +u8 dev_read_u8_default(const struct udevice *dev, const char *propname, u8 def); + +/** + * dev_read_u16() - read a 16-bit integer from a device's DT property + * + * @dev: device to read DT property from + * @propname: name of the property to read from + * @outp: place to put value (if found) + * Return: 0 if OK, -ve on error + */ +int dev_read_u16(const struct udevice *dev, const char *propname, u16 *outp); + +/** + * dev_read_u16_default() - read a 16-bit integer from a device's DT property + * + * @dev: device to read DT property from + * @propname: name of the property to read from + * @def: default value to return if the property has no value + * Return: property value, or @def if not found + */ +u16 dev_read_u16_default(const struct udevice *dev, const char *propname, + u16 def); + /** * dev_read_u32() - read a 32-bit integer from a device's DT property * @@ -772,6 +813,30 @@ phy_interface_t dev_read_phy_mode(const struct udevice *dev); #else /* CONFIG_DM_DEV_READ_INLINE is enabled */ #include +static inline int dev_read_u8(const struct udevice *dev, + const char *propname, u8 *outp) +{ + return ofnode_read_u8(dev_ofnode(dev), propname, outp); +} + +static inline int dev_read_u8_default(const struct udevice *dev, + const char *propname, u8 def) +{ + return ofnode_read_u8_default(dev_ofnode(dev), propname, def); +} + +static inline int dev_read_u16(const struct udevice *dev, + const char *propname, u16 *outp) +{ + return ofnode_read_u16(dev_ofnode(dev), propname, outp); +} + +static inline int dev_read_u16_default(const struct udevice *dev, + const char *propname, u16 def) +{ + return ofnode_read_u16_default(dev_ofnode(dev), propname, def); +} + static inline int dev_read_u32(const struct udevice *dev, const char *propname, u32 *outp) { diff --git a/test/dm/test-fdt.c b/test/dm/test-fdt.c index 6118ad42ca..012f2f455f 100644 --- a/test/dm/test-fdt.c +++ b/test/dm/test-fdt.c @@ -815,6 +815,8 @@ DM_TEST(dm_test_first_child, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); static int dm_test_read_int(struct unit_test_state *uts) { struct udevice *dev; + u8 val8; + u16 val16; u32 val32; s32 sval; uint val; @@ -822,6 +824,23 @@ static int dm_test_read_int(struct unit_test_state *uts) ut_assertok(uclass_first_device_err(UCLASS_TEST_FDT, &dev)); ut_asserteq_str("a-test", dev->name); + + ut_assertok(dev_read_u8(dev, "int8-value", &val8)); + ut_asserteq(0x12, val8); + + ut_asserteq(-EINVAL, dev_read_u8(dev, "missing", &val8)); + ut_asserteq(6, dev_read_u8_default(dev, "missing", 6)); + + ut_asserteq(0x12, dev_read_u8_default(dev, "int8-value", 6)); + + ut_assertok(dev_read_u16(dev, "int16-value", &val16)); + ut_asserteq(0x1234, val16); + + ut_asserteq(-EINVAL, dev_read_u16(dev, "missing", &val16)); + ut_asserteq(6, dev_read_u16_default(dev, "missing", 6)); + + ut_asserteq(0x1234, dev_read_u16_default(dev, "int16-value", 6)); + ut_assertok(dev_read_u32(dev, "int-value", &val32)); ut_asserteq(1234, val32); From c0facda1976f7990ad9edbaecb6802369867c1d6 Mon Sep 17 00:00:00 2001 From: Stefan Herbrechtsmeier Date: Tue, 14 Jun 2022 15:21:31 +0200 Subject: [PATCH 143/374] misc: usb251xb: Support 8/16 bit device tree values The device tree binding [1] specify the vendor-id, product-id, device-id and language-id as 16 bit values and the linux driver reads the boost-up value as 8 bit value. [1] https://www.kernel.org/doc/Documentation/devicetree/bindings/usb/usb251xb.txt Signed-off-by: Stefan Herbrechtsmeier Reviewed-by: Marek Vasut --- drivers/misc/usb251xb.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/misc/usb251xb.c b/drivers/misc/usb251xb.c index 077edc2504..a78ad1843a 100644 --- a/drivers/misc/usb251xb.c +++ b/drivers/misc/usb251xb.c @@ -400,14 +400,14 @@ static int usb251xb_of_to_plat(struct udevice *dev) } } - if (dev_read_u32(dev, "vendor-id", &hub->vendor_id)) - hub->vendor_id = USB251XB_DEF_VENDOR_ID; + hub->vendor_id = dev_read_u16_default(dev, "vendor-id", + USB251XB_DEF_VENDOR_ID); - if (dev_read_u32(dev, "product-id", &hub->product_id)) - hub->product_id = data->product_id; + hub->product_id = dev_read_u16_default(dev, "product-id", + data->product_id); - if (dev_read_u32(dev, "device-id", &hub->device_id)) - hub->device_id = USB251XB_DEF_DEVICE_ID; + hub->device_id = dev_read_u16_default(dev, "device-id", + USB251XB_DEF_DEVICE_ID); hub->conf_data1 = USB251XB_DEF_CONFIG_DATA_1; if (dev_read_bool(dev, "self-powered")) { @@ -513,11 +513,11 @@ static int usb251xb_of_to_plat(struct udevice *dev) if (!dev_read_u32(dev, "power-on-time-ms", &property_u32)) hub->power_on_time = min_t(u8, property_u32 / 2, 255); - if (dev_read_u32(dev, "language-id", &hub->lang_id)) - hub->lang_id = USB251XB_DEF_LANGUAGE_ID; + hub->lang_id = dev_read_u16_default(dev, "language-id", + USB251XB_DEF_LANGUAGE_ID); - if (!dev_read_u32(dev, "boost-up", &hub->boost_up)) - hub->boost_up = USB251XB_DEF_BOOST_UP; + hub->boost_up = dev_read_u8_default(dev, "boost-up", + USB251XB_DEF_BOOST_UP); cproperty_char = dev_read_string(dev, "manufacturer"); strlcpy(str, cproperty_char ? : USB251XB_DEF_MANUFACTURER_STRING, From 77253c50ab5910bf72e1e868c86940c5a2bc7bb9 Mon Sep 17 00:00:00 2001 From: Stefan Herbrechtsmeier Date: Tue, 14 Jun 2022 16:12:00 +0200 Subject: [PATCH 144/374] spl: fit: Allocate buffers aligned to cache line size Allocate memory for buffers at a cache-line boundary to avoid misaligned buffer address for subsequent reads. This avoids an additional sector-based memory copy in the fat file system driver: FAT: Misaligned buffer address (...) Signed-off-by: Stefan Herbrechtsmeier --- common/spl/spl_fit.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/common/spl/spl_fit.c b/common/spl/spl_fit.c index a35be52965..c1ed31e367 100644 --- a/common/spl/spl_fit.c +++ b/common/spl/spl_fit.c @@ -10,7 +10,7 @@ #include #include #include -#include +#include #include #include #include @@ -429,7 +429,9 @@ static int spl_fit_append_fdt(struct spl_image_info *spl_image, * depending on how the overlay is stored, so * don't fail yet if the allocation failed. */ - tmpbuffer = malloc(CONFIG_SPL_LOAD_FIT_APPLY_OVERLAY_BUF_SZ); + size_t size = CONFIG_SPL_LOAD_FIT_APPLY_OVERLAY_BUF_SZ; + + tmpbuffer = malloc_cache_aligned(size); if (!tmpbuffer) debug("%s: unable to allocate space for overlays\n", __func__); @@ -537,7 +539,7 @@ static void *spl_get_fit_load_buffer(size_t size) { void *buf; - buf = malloc(size); + buf = malloc_cache_aligned(size); if (!buf) { pr_err("Could not get FIT buffer of %lu bytes\n", (ulong)size); pr_err("\tcheck CONFIG_SYS_SPL_MALLOC_SIZE\n"); From fd0d7a6c88fe0ae16dda95eba52c598b9fa9db2a Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Tue, 26 Jul 2022 16:21:41 +0200 Subject: [PATCH 145/374] drivers: tee: optee: remove unused probe local variable Removes local variable child in optee_probe() that is not used. Cc: Patrick Delaunay Reviewed-by: Patrick Delaunay Signed-off-by: Etienne Carriere --- drivers/tee/optee/core.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/tee/optee/core.c b/drivers/tee/optee/core.c index a89d62aaf0..c1f5fc4c7a 100644 --- a/drivers/tee/optee/core.c +++ b/drivers/tee/optee/core.c @@ -642,7 +642,6 @@ static int optee_probe(struct udevice *dev) { struct optee_pdata *pdata = dev_get_plat(dev); u32 sec_caps; - struct udevice *child; int ret; if (!is_optee_api(pdata->invoke_fn)) { @@ -673,7 +672,7 @@ static int optee_probe(struct udevice *dev) * only bind the drivers associated to the supported OP-TEE TA */ if (IS_ENABLED(CONFIG_RNG_OPTEE)) { - ret = device_bind_driver(dev, "optee-rng", "optee-rng", &child); + ret = device_bind_driver(dev, "optee-rng", "optee-rng", NULL); if (ret) return ret; } From 94ccfb78a4d61cac7cbc78f23751ec1db949d29e Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Tue, 26 Jul 2022 16:21:42 +0200 Subject: [PATCH 146/374] drivers: tee: optee: discover OP-TEE services This change defines resources for OP-TEE service drivers to register themselves for being bound to when OP-TEE firmware reports the related service is supported. OP-TEE services are discovered during optee driver probe sequence which mandates optee driver is always probe once bound. Discovery of optee services and binding to related U-Boot drivers is embedded upon configuration switch CONFIG_OPTEE_SERVICE_DISCOVERY. Cc: Jens Wiklander Cc: Patrick Delaunay Signed-off-by: Etienne Carriere Reviewed-by: Patrick Delaunay --- drivers/tee/optee/Kconfig | 8 ++ drivers/tee/optee/core.c | 171 ++++++++++++++++++++++++++++++++++-- include/tee/optee_service.h | 34 +++++++ 3 files changed, 208 insertions(+), 5 deletions(-) create mode 100644 include/tee/optee_service.h diff --git a/drivers/tee/optee/Kconfig b/drivers/tee/optee/Kconfig index d03028070b..9dc65b0501 100644 --- a/drivers/tee/optee/Kconfig +++ b/drivers/tee/optee/Kconfig @@ -37,6 +37,14 @@ config OPTEE_TA_SCP03 help Enables support for controlling (enabling, provisioning) the Secure Channel Protocol 03 operation in the OP-TEE SCP03 TA. + +config OPTEE_SERVICE_DISCOVERY + bool "OP-TEE service discovery" + default y + help + This implements automated driver binding of OP-TEE service drivers by + requesting OP-TEE firmware to enumerate its hosted services. + endmenu endif diff --git a/drivers/tee/optee/core.c b/drivers/tee/optee/core.c index c1f5fc4c7a..9240277579 100644 --- a/drivers/tee/optee/core.c +++ b/drivers/tee/optee/core.c @@ -14,6 +14,7 @@ #include #include #include +#include #include "optee_smc.h" #include "optee_msg.h" @@ -22,6 +23,25 @@ #define PAGELIST_ENTRIES_PER_PAGE \ ((OPTEE_MSG_NONCONTIG_PAGE_SIZE / sizeof(u64)) - 1) +/* + * PTA_DEVICE_ENUM interface exposed by OP-TEE to discover enumerated services + */ +#define PTA_DEVICE_ENUM { 0x7011a688, 0xddde, 0x4053, \ + { 0xa5, 0xa9, 0x7b, 0x3c, 0x4d, 0xdf, 0x13, 0xb8 } } +/* + * PTA_CMD_GET_DEVICES - List services without supplicant dependencies + * + * [out] memref[0]: List of the UUIDs of service enumerated by OP-TEE + */ +#define PTA_CMD_GET_DEVICES 0x0 + +/* + * PTA_CMD_GET_DEVICES_SUPP - List services depending on tee supplicant + * + * [out] memref[0]: List of the UUIDs of service enumerated by OP-TEE + */ +#define PTA_CMD_GET_DEVICES_SUPP 0x1 + typedef void (optee_invoke_fn)(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, @@ -42,6 +62,134 @@ struct rpc_param { u32 a7; }; +static struct optee_service *find_service_driver(const struct tee_optee_ta_uuid *uuid) +{ + struct optee_service *service; + u8 loc_uuid[TEE_UUID_LEN]; + size_t service_cnt, idx; + + service_cnt = ll_entry_count(struct optee_service, optee_service); + service = ll_entry_start(struct optee_service, optee_service); + + for (idx = 0; idx < service_cnt; idx++, service++) { + tee_optee_ta_uuid_to_octets(loc_uuid, &service->uuid); + if (!memcmp(uuid, loc_uuid, sizeof(uuid))) + return service; + } + + return NULL; +} + +static int bind_service_list(struct udevice *dev, struct tee_shm *service_list, size_t count) +{ + const struct tee_optee_ta_uuid *service_uuid = (const void *)service_list->addr; + struct optee_service *service; + size_t idx; + int ret; + + for (idx = 0; idx < count; idx++) { + service = find_service_driver(service_uuid + idx); + if (!service) + continue; + + ret = device_bind_driver(dev, service->driver_name, service->driver_name, NULL); + if (ret) { + dev_warn(dev, "%s was not bound: %d, ignored\n", service->driver_name, ret); + continue; + } + } + + return 0; +} + +static int __enum_services(struct udevice *dev, struct tee_shm *shm, size_t *shm_size, u32 tee_sess) +{ + struct tee_invoke_arg arg = { }; + struct tee_param param = { }; + int ret = 0; + + arg.func = PTA_CMD_GET_DEVICES; + arg.session = tee_sess; + + /* Fill invoke cmd params */ + param.attr = TEE_PARAM_ATTR_TYPE_MEMREF_OUTPUT; + param.u.memref.shm = shm; + param.u.memref.size = *shm_size; + + ret = tee_invoke_func(dev, &arg, 1, ¶m); + if (ret || (arg.ret && arg.ret != TEE_ERROR_SHORT_BUFFER)) { + dev_err(dev, "PTA_CMD_GET_DEVICES invoke function err: 0x%x\n", arg.ret); + return -EINVAL; + } + + *shm_size = param.u.memref.size; + + return 0; +} + +static int enum_services(struct udevice *dev, struct tee_shm **shm, size_t *count, u32 tee_sess) +{ + size_t shm_size = 0; + int ret; + + ret = __enum_services(dev, NULL, &shm_size, tee_sess); + if (ret) + return ret; + + ret = tee_shm_alloc(dev, shm_size, 0, shm); + if (ret) { + dev_err(dev, "Failed to allocated shared memory: %d\n", ret); + return ret; + } + + ret = __enum_services(dev, *shm, &shm_size, tee_sess); + if (!ret) + *count = shm_size / sizeof(struct tee_optee_ta_uuid); + + return ret; +} + +static int open_enum_session(struct udevice *dev, u32 *tee_sess) +{ + const struct tee_optee_ta_uuid pta_uuid = PTA_DEVICE_ENUM; + struct tee_open_session_arg arg = { }; + int ret; + + tee_optee_ta_uuid_to_octets(arg.uuid, &pta_uuid); + + ret = tee_open_session(dev, &arg, 0, NULL); + if (ret || arg.ret) { + if (!ret) + ret = -EIO; + return ret; + } + + *tee_sess = arg.session; + + return 0; +} + +static int bind_service_drivers(struct udevice *dev) +{ + struct tee_shm *service_list = NULL; + size_t service_count; + u32 tee_sess; + int ret; + + ret = open_enum_session(dev, &tee_sess); + if (ret) + return ret; + + ret = enum_services(dev, &service_list, &service_count, tee_sess); + if (!ret) + ret = bind_service_list(dev, service_list, service_count); + + tee_shm_free(service_list); + tee_close_session(dev, tee_sess); + + return ret; +} + /** * reg_pair_to_ptr() - Make a pointer of 2 32-bit values * @reg0: High bits of the pointer @@ -638,6 +786,14 @@ static int optee_of_to_plat(struct udevice *dev) return 0; } +static int optee_bind(struct udevice *dev) +{ + if (IS_ENABLED(CONFIG_OPTEE_SERVICE_DISCOVERY)) + dev_or_flags(dev, DM_FLAG_PROBE_AFTER_BIND); + + return 0; +} + static int optee_probe(struct udevice *dev) { struct optee_pdata *pdata = dev_get_plat(dev); @@ -667,11 +823,15 @@ static int optee_probe(struct udevice *dev) return -ENOENT; } - /* - * in U-Boot, the discovery of TA on the TEE bus is not supported: - * only bind the drivers associated to the supported OP-TEE TA - */ - if (IS_ENABLED(CONFIG_RNG_OPTEE)) { + if (IS_ENABLED(CONFIG_OPTEE_SERVICE_DISCOVERY)) { + ret = bind_service_drivers(dev); + if (ret) + return ret; + } else if (IS_ENABLED(CONFIG_RNG_OPTEE)) { + /* + * Discovery of TAs on the TEE bus is not supported in U-Boot: + * only bind the drivers associated to the supported OP-TEE TA + */ ret = device_bind_driver(dev, "optee-rng", "optee-rng", NULL); if (ret) return ret; @@ -691,6 +851,7 @@ U_BOOT_DRIVER(optee) = { .of_match = optee_match, .of_to_plat = optee_of_to_plat, .probe = optee_probe, + .bind = optee_bind, .ops = &optee_ops, .plat_auto = sizeof(struct optee_pdata), .priv_auto = sizeof(struct optee_private), diff --git a/include/tee/optee_service.h b/include/tee/optee_service.h new file mode 100644 index 0000000000..fca468af7c --- /dev/null +++ b/include/tee/optee_service.h @@ -0,0 +1,34 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ +/* + * (C) Copyright 2022 Linaro Limited + */ + +#ifndef _OPTEE_SERVICE_H +#define _OPTEE_SERVICE_H + +/* + * struct optee_service - Discoverable OP-TEE service + * + * @driver_name - Name of the related driver + * @uuid - UUID of the OP-TEE service related to the driver + * + * Use macro OPTEE_SERVICE_DRIVER() to register a driver related to an + * OP-TEE service discovered when driver asks OP-TEE services enumaration. + */ +struct optee_service { + const char *driver_name; + const struct tee_optee_ta_uuid uuid; +}; + +#ifdef CONFIG_OPTEE_SERVICE_DISCOVERY +#define OPTEE_SERVICE_DRIVER(__name, __uuid, __drv_name) \ + ll_entry_declare(struct optee_service, __name, optee_service) = { \ + .uuid = __uuid, \ + .driver_name = __drv_name, \ + } +#else +#define OPTEE_SERVICE_DRIVER(__name, __uuid, __drv_name) \ + static int __name##__COUNTER__ __always_unused +#endif + +#endif /* _OPTEE_SERVICE_H */ From 57fb86a97d75dbf9898bce50813cf63106da08ac Mon Sep 17 00:00:00 2001 From: Etienne Carriere Date: Tue, 26 Jul 2022 16:21:43 +0200 Subject: [PATCH 147/374] drivers: rng: optee_rng: register to CONFIG_OPTEE_SERVICE_DISCOVERY Changes optee_rng driver to register itself has a OP-TEE service so that a device is bound for the driver when OP-TEE enumerates the PTA RNG service. Cc: Sughosh Ganu Cc: Patrick Delaunay Signed-off-by: Etienne Carriere Reviewed-by: Patrick Delaunay --- drivers/rng/Kconfig | 1 + drivers/rng/optee_rng.c | 7 ++++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/rng/Kconfig b/drivers/rng/Kconfig index 16143681da..5dcf68176a 100644 --- a/drivers/rng/Kconfig +++ b/drivers/rng/Kconfig @@ -41,6 +41,7 @@ config RNG_NPCM config RNG_OPTEE bool "OP-TEE based Random Number Generator support" depends on DM_RNG && OPTEE + default y if OPTEE_SERVICE_DISCOVERY help This driver provides support for the OP-TEE based Random Number Generator on ARM SoCs where hardware entropy sources are not diff --git a/drivers/rng/optee_rng.c b/drivers/rng/optee_rng.c index aa8ce864d3..410dfc053f 100644 --- a/drivers/rng/optee_rng.c +++ b/drivers/rng/optee_rng.c @@ -11,6 +11,9 @@ #include #include #include +#include + +#define DRIVER_NAME "optee-rng" #define TEE_ERROR_HEALTH_TEST_FAIL 0x00000001 @@ -35,6 +38,8 @@ #define TA_HWRNG_UUID { 0xab7a617c, 0xb8e7, 0x4d8f, \ { 0x83, 0x01, 0xd0, 0x9b, 0x61, 0x03, 0x6b, 0x64 } } +OPTEE_SERVICE_DRIVER(optee_rng, TA_HWRNG_UUID, DRIVER_NAME); + /** open_session_ta_hwrng() - Open session with hwrng Trusted App * * @dev: device @@ -177,7 +182,7 @@ static const struct dm_rng_ops optee_rng_ops = { }; U_BOOT_DRIVER(optee_rng) = { - .name = "optee-rng", + .name = DRIVER_NAME, .id = UCLASS_RNG, .ops = &optee_rng_ops, .probe = optee_rng_probe, From 56ce22c0cd5a9cea09044f62d5f641f38e41f909 Mon Sep 17 00:00:00 2001 From: Sean Anderson Date: Tue, 23 Aug 2022 15:10:39 -0400 Subject: [PATCH 148/374] post: memory: Fix format strings This fixes numerous cases of format strings not matching their arguments. Also keep the format strings on one line for easier grepping. Signed-off-by: Sean Anderson Reviewed-by: Simon Glass --- post/drivers/memory.c | 30 ++++++++++++------------------ 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/post/drivers/memory.c b/post/drivers/memory.c index 281989da6f..4fb9355d60 100644 --- a/post/drivers/memory.c +++ b/post/drivers/memory.c @@ -228,9 +228,8 @@ static int memory_post_dataline(unsigned long long * pmem) hi = (temp64>>32) & 0xffffffff; lo = temp64 & 0xffffffff; - post_log("Memory (data line) error at %08x, " - "wrote %08x%08x, read %08x%08x !\n", - pmem, pathi, patlo, hi, lo); + post_log("Memory (data line) error at %p, wrote %08x%08x, read %08x%08x !\n", + pmem, pathi, patlo, hi, lo); ret = -1; } } @@ -259,9 +258,8 @@ static int memory_post_addrline(ulong *testaddr, ulong *base, ulong size) } #endif if(readback == *testaddr) { - post_log("Memory (address line) error at %08x<->%08x, " - "XOR value %08x !\n", - testaddr, target, xor); + post_log("Memory (address line) error at %p<->%p, XOR value %08lx !\n", + testaddr, target, xor); ret = -1; } } @@ -287,9 +285,8 @@ static int memory_post_test1(unsigned long start, for (i = 0; i < size / sizeof (ulong) && !ret; i++) { readback = mem[i]; if (readback != val) { - post_log("Memory error at %08x, " - "wrote %08x, read %08x !\n", - mem + i, val, readback); + post_log("Memory error at %p, wrote %08lx, read %08lx !\n", + mem + i, val, readback); ret = -1; break; @@ -317,9 +314,8 @@ static int memory_post_test2(unsigned long start, unsigned long size) for (i = 0; i < size / sizeof (ulong) && !ret; i++) { readback = mem[i]; if (readback != (1 << (i % 32))) { - post_log("Memory error at %08x, " - "wrote %08x, read %08x !\n", - mem + i, 1 << (i % 32), readback); + post_log("Memory error at %p, wrote %08lx, read %08lx !\n", + mem + i, 1UL << (i % 32), readback); ret = -1; break; @@ -347,9 +343,8 @@ static int memory_post_test3(unsigned long start, unsigned long size) for (i = 0; i < size / sizeof (ulong) && !ret; i++) { readback = mem[i]; if (readback != i) { - post_log("Memory error at %08x, " - "wrote %08x, read %08x !\n", - mem + i, i, readback); + post_log("Memory error at %p, wrote %08lx, read %08lx !\n", + mem + i, i, readback); ret = -1; break; @@ -377,9 +372,8 @@ static int memory_post_test4(unsigned long start, unsigned long size) for (i = 0; i < size / sizeof (ulong) && !ret; i++) { readback = mem[i]; if (readback != ~i) { - post_log("Memory error at %08x, " - "wrote %08x, read %08x !\n", - mem + i, ~i, readback); + post_log("Memory error at %p, wrote %08lx, read %08lx !\n", + mem + i, ~i, readback); ret = -1; break; From 1b3e68203cab4dfdd90d0934ec08762be723f3b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Sat, 27 Aug 2022 16:37:55 +0200 Subject: [PATCH 149/374] xyz-modem: Allow to configure initial timeout for loadx and loady MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Now when loadx and loady commands could be aborted / cancelled by CTRL+C, allow to configure timeout for initial x/y-modem packet via env variable $loadxy_timeout and by default use value from new compile-time config option CONFIG_CMD_LOADXY_TIMEOUT. Value is in seconds and zero value means infinite timeout. Default value is 90s which is the value used before this change for loadx command. Other load commands loadb and loads already waits infinitely. Same behavior for loadx and loady commands can be achieved by setting $loadxy_timeout or CONFIG_CMD_LOADXY_TIMEOUT to 0. Signed-off-by: Pali Rohár --- cmd/Kconfig | 7 +++++++ common/xyzModem.c | 40 ++++++++++++++++++++++++++++++++++++++-- 2 files changed, 45 insertions(+), 2 deletions(-) diff --git a/cmd/Kconfig b/cmd/Kconfig index 37bc64dcfb..08821b0bd4 100644 --- a/cmd/Kconfig +++ b/cmd/Kconfig @@ -1194,6 +1194,13 @@ config CMD_LOADS help Load an S-Record file over serial line +config CMD_LOADXY_TIMEOUT + int "loadxy_timeout" + range 0 2000 + default 90 + help + Initial timeout for loadx and loady commands. Zero means infinity. + config CMD_LSBLK depends on BLK bool "lsblk - list block drivers and devices" diff --git a/common/xyzModem.c b/common/xyzModem.c index ece25acb18..a68d392902 100644 --- a/common/xyzModem.c +++ b/common/xyzModem.c @@ -26,6 +26,7 @@ #include #include #include +#include /* Assumption - run xyzModem protocol over the console port */ @@ -50,6 +51,8 @@ static struct int len, mode, total_retries; int total_SOH, total_STX, total_CAN; bool crc_mode, at_eof, tx_ack; + bool first_xmodem_packet; + ulong initial_time, timeout; unsigned long file_length, read_length; } xyz; @@ -409,6 +412,19 @@ xyzModem_get_hdr (void) return 0; } +static +ulong +xyzModem_get_initial_timeout (void) +{ + /* timeout is in seconds, non-positive timeout value is infinity */ +#if CONFIG_IS_ENABLED(ENV_SUPPORT) + const char *timeout_str = env_get("loadxy_timeout"); + if (timeout_str) + return 1000 * simple_strtol(timeout_str, NULL, 10); +#endif + return 1000 * CONFIG_CMD_LOADXY_TIMEOUT; +} + int xyzModem_stream_open (connection_info_t * info, int *err) { @@ -439,18 +455,28 @@ xyzModem_stream_open (connection_info_t * info, int *err) xyz.total_CAN = 0; xyz.read_length = 0; xyz.file_length = 0; + xyz.first_xmodem_packet = false; + xyz.initial_time = get_timer(0); + xyz.timeout = xyzModem_get_initial_timeout(); CYGACC_COMM_IF_PUTC (*xyz.__chan, (xyz.crc_mode ? 'C' : NAK)); if (xyz.mode == xyzModem_xmodem) { /* X-modem doesn't have an information header - exit here */ + xyz.first_xmodem_packet = true; xyz.next_blk = 1; return 0; } - while (retries-- > 0) + while (!(xyz.timeout && get_timer(xyz.initial_time) > xyz.timeout)) { + if (--retries <= 0) + { + retries = xyzModem_MAX_RETRIES; + crc_retries = xyzModem_MAX_RETRIES_WITH_CRC; + xyz.crc_mode = true; + } stat = xyzModem_get_hdr (); if (stat == 0) { @@ -503,9 +529,19 @@ xyzModem_stream_read (char *buf, int size, int *err) retries = xyzModem_MAX_RETRIES; while (retries-- > 0) { + if (xyz.first_xmodem_packet && xyz.timeout && + get_timer(xyz.initial_time) > xyz.timeout) + { + *err = xyzModem_timeout; + xyz.len = -1; + return total; + } + stat = xyzModem_get_hdr (); if (stat == 0) { + if (xyz.mode == xyzModem_xmodem && xyz.first_xmodem_packet) + xyz.first_xmodem_packet = false; if (xyz.blk == xyz.next_blk) { xyz.tx_ack = true; @@ -583,7 +619,7 @@ xyzModem_stream_read (char *buf, int size, int *err) xyz.total_retries++; ZM_DEBUG (zm_dprintf ("NAK (%d)\n", __LINE__)); } - if (stat < 0) + if (stat < 0 && (!xyz.first_xmodem_packet || stat != xyzModem_timeout)) { *err = stat; xyz.len = -1; From 9895bda2ed09fe6b38f553022c263d5aa975cf99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Mon, 29 Aug 2022 17:36:23 +0200 Subject: [PATCH 150/374] doc: cmd: loady: Document new configuration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Pali Rohár --- doc/usage/cmd/loady.rst | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/doc/usage/cmd/loady.rst b/doc/usage/cmd/loady.rst index 2819cc72ae..718af6e128 100644 --- a/doc/usage/cmd/loady.rst +++ b/doc/usage/cmd/loady.rst @@ -61,6 +61,13 @@ Configuration The command is only available if CONFIG_CMD_LOADB=y. +Initial timeout in seconds while waiting for transfer is configured by +config option CMD_LOADXY_TIMEOUT or by env variable $loadxy_timeout. +Setting it to 0 means infinite timeout. + +Transfer can be cancelled by pressing 3 times after two seconds +of inactivity on terminal. + Return value ------------ From 4ca8d95ce1e71995052e81f1854a23803ca48b73 Mon Sep 17 00:00:00 2001 From: Alexander Sowarka Date: Sun, 28 Aug 2022 21:30:20 +0200 Subject: [PATCH 151/374] nvme: Fix multipage prp-list The nvme driver falsely assumed that the last entry on a page of the prp-list always points to the next page of the prp-list. This potentially can lead to the illegal creation of pages on the prp-list with only a single entry. This change now ensures that splitting the prp-list into multiple pages, behaves now as required by the NVME-Spec. Related to this, also the size of the memory allocation is adjusted accordingly. Signed-off-by: Alexander Sowarka --- drivers/nvme/nvme.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/nvme/nvme.c b/drivers/nvme/nvme.c index a305305885..31cf700633 100644 --- a/drivers/nvme/nvme.c +++ b/drivers/nvme/nvme.c @@ -72,7 +72,7 @@ static int nvme_setup_prps(struct nvme_dev *dev, u64 *prp2, } nprps = DIV_ROUND_UP(length, page_size); - num_pages = DIV_ROUND_UP(nprps, prps_per_page); + num_pages = DIV_ROUND_UP(nprps - 1, prps_per_page - 1); if (nprps > dev->prp_entry_num) { free(dev->prp_pool); @@ -85,13 +85,13 @@ static int nvme_setup_prps(struct nvme_dev *dev, u64 *prp2, printf("Error: malloc prp_pool fail\n"); return -ENOMEM; } - dev->prp_entry_num = prps_per_page * num_pages; + dev->prp_entry_num = num_pages * (prps_per_page - 1) + 1; } prp_pool = dev->prp_pool; i = 0; while (nprps) { - if (i == ((page_size >> 3) - 1)) { + if ((i == (prps_per_page - 1)) && nprps > 1) { *(prp_pool + i) = cpu_to_le64((ulong)prp_pool + page_size); i = 0; @@ -104,7 +104,7 @@ static int nvme_setup_prps(struct nvme_dev *dev, u64 *prp2, *prp2 = (ulong)dev->prp_pool; flush_dcache_range((ulong)dev->prp_pool, (ulong)dev->prp_pool + - dev->prp_entry_num * sizeof(u64)); + num_pages * page_size); return 0; } From 04dd7c8e5624ee971004a6b310c2e7d958a0018c Mon Sep 17 00:00:00 2001 From: Xiang W Date: Mon, 29 Aug 2022 07:53:15 +0800 Subject: [PATCH 152/374] virtio: pci: fix bug of virtio_pci_map_capability The bar of the structure virtio_pci_cap is the index, and each base address occupies 4 bytes, so it needs to be multiplied by 4. This patch fixes a bug reported by Felix Yan https://lists.denx.de/pipermail/u-boot/2022-August/492779.html Signed-off-by: Xiang W Tested-by: Felix Yan --- drivers/virtio/virtio_pci_modern.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/virtio/virtio_pci_modern.c b/drivers/virtio/virtio_pci_modern.c index 880a12cc28..cfde4007f5 100644 --- a/drivers/virtio/virtio_pci_modern.c +++ b/drivers/virtio/virtio_pci_modern.c @@ -466,7 +466,7 @@ static void __iomem *virtio_pci_map_capability(struct udevice *udev, unsigned long mask = PCI_REGION_TYPE | PCI_REGION_SYS_MEMORY | PCI_REGION_RO; unsigned long flags = PCI_REGION_MEM; - u8 *p = dm_pci_map_bar(udev, PCI_BASE_ADDRESS_0 + cap->bar, cap->offset, + u8 *p = dm_pci_map_bar(udev, PCI_BASE_ADDRESS_0 + 4 * cap->bar, cap->offset, cap->length, mask, flags); return (void __iomem *)p; From d7124f0ba42263e6a24a829ca523861650bfec65 Mon Sep 17 00:00:00 2001 From: Patrice Chotard Date: Tue, 30 Aug 2022 14:09:11 +0200 Subject: [PATCH 153/374] gpio: Allow to print pin's label even for pin with GPIOF_FUNC function Currently, if pin's function is GPIOF_FUNC, only "func" if displayed without any other information. It would be interesting, if information is available, to indicate which pinmuxing's name is used. For example, for STM32 SoC's based platform, "gpio status" command output : before Bank GPIOZ: GPIOZ0: unused : 0 [ ] GPIOZ1: unused : 0 [ ] GPIOZ2: unused : 0 [ ] GPIOZ3: unused : 0 [ ] GPIOZ4: func GPIOZ5: func GPIOZ6: unused : 0 [ ] GPIOZ7: unused : 0 [ ] GPIOZ8: unknown GPIOZ9: unknown GPIOZ10: unknown GPIOZ11: unknown GPIOZ12: unknown GPIOZ13: unknown GPIOZ14: unknown GPIOZ15: unknown After Bank GPIOZ: GPIOZ0: unused : 0 [ ] GPIOZ1: unused : 0 [ ] GPIOZ2: unused : 0 [ ] GPIOZ3: unused : 0 [ ] GPIOZ4: func i2c4-0 GPIOZ5: func i2c4-0 GPIOZ6: unused : 0 [ ] GPIOZ7: unused : 0 [ ] GPIOZ8: unknown GPIOZ9: unknown GPIOZ10: unknown GPIOZ11: unknown GPIOZ12: unknown GPIOZ13: unknown GPIOZ14: unknown GPIOZ15: unknown Signed-off-by: Patrice Chotard Reviewed-by: Simon Glass Reviewed-by: Patrick Delaunay --- drivers/gpio/gpio-uclass.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/drivers/gpio/gpio-uclass.c b/drivers/gpio/gpio-uclass.c index 0ed32b7217..d60e46159a 100644 --- a/drivers/gpio/gpio-uclass.c +++ b/drivers/gpio/gpio-uclass.c @@ -884,26 +884,31 @@ int gpio_get_status(struct udevice *dev, int offset, char *buf, int buffsize) const struct dm_gpio_ops *ops = gpio_get_ops(dev); struct gpio_dev_priv *priv; char *str = buf; + const char *label; int func; int ret; int len; + bool used; BUILD_BUG_ON(GPIOF_COUNT != ARRAY_SIZE(gpio_function)); *buf = 0; priv = dev_get_uclass_priv(dev); - ret = gpio_get_raw_function(dev, offset, NULL); + ret = gpio_get_raw_function(dev, offset, &label); if (ret < 0) return ret; func = ret; len = snprintf(str, buffsize, "%s%d: %s", priv->bank_name ? priv->bank_name : "", offset, gpio_function[func]); - if (func == GPIOF_INPUT || func == GPIOF_OUTPUT || - func == GPIOF_UNUSED) { - const char *label; - bool used; + switch (func) { + case GPIOF_FUNC: + snprintf(str + len, buffsize - len, " %s", label ? label : ""); + break; + case GPIOF_INPUT: + case GPIOF_OUTPUT: + case GPIOF_UNUSED: ret = ops->get_value(dev, offset); if (ret < 0) return ret; @@ -913,6 +918,7 @@ int gpio_get_status(struct udevice *dev, int offset, char *buf, int buffsize) used ? 'x' : ' ', used ? " " : "", label ? label : ""); + break; } return 0; From a32920897a205c53717d864ae6c44fb6703094c9 Mon Sep 17 00:00:00 2001 From: Patrice Chotard Date: Tue, 30 Aug 2022 14:09:12 +0200 Subject: [PATCH 154/374] gpio: Fix pin's status display for pin with GPIOF_UNUSED function Even pin with GPIOF_UNUSED function can have a label. The criteria to add or not a space character is linked to label not to the used/unused status. Signed-off-by: Patrice Chotard Reviewed-by: Simon Glass Reviewed-by: Patrick Delaunay --- drivers/gpio/gpio-uclass.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpio/gpio-uclass.c b/drivers/gpio/gpio-uclass.c index d60e46159a..a00880e446 100644 --- a/drivers/gpio/gpio-uclass.c +++ b/drivers/gpio/gpio-uclass.c @@ -916,7 +916,7 @@ int gpio_get_status(struct udevice *dev, int offset, char *buf, int buffsize) snprintf(str + len, buffsize - len, ": %d [%c]%s%s", ret, used ? 'x' : ' ', - used ? " " : "", + label ? " " : "", label ? label : ""); break; } From 2c38f7c31806c5724a2f9c58a47cf76979fd6f0a Mon Sep 17 00:00:00 2001 From: Patrice Chotard Date: Tue, 30 Aug 2022 14:09:13 +0200 Subject: [PATCH 155/374] pinctrl: pinctrl_stm32: Populate uc_priv->name[] with pinmux node's name Populate uc_priv->name[] with pinmux node's name in order to indicate the pinmuxing's name in case GPIO is configured in alternate. For example, for STM32 SoC's based platform, "gpio status" command output : before Bank GPIOZ: GPIOZ0: unused : 0 [ ] GPIOZ1: unused : 0 [ ] GPIOZ2: unused : 0 [ ] GPIOZ3: unused : 0 [ ] GPIOZ4: func GPIOZ5: func GPIOZ6: unused : 0 [ ] GPIOZ7: unused : 0 [ ] GPIOZ8: unknown GPIOZ9: unknown GPIOZ10: unknown GPIOZ11: unknown GPIOZ12: unknown GPIOZ13: unknown GPIOZ14: unknown GPIOZ15: unknown After Bank GPIOZ: GPIOZ0: unused : 0 [ ] GPIOZ1: unused : 0 [ ] GPIOZ2: unused : 0 [ ] GPIOZ3: unused : 0 [ ] GPIOZ4: func i2c4-0 GPIOZ5: func i2c4-0 GPIOZ6: unused : 0 [ ] GPIOZ7: unused : 0 [ ] GPIOZ8: unknown GPIOZ9: unknown GPIOZ10: unknown GPIOZ11: unknown GPIOZ12: unknown GPIOZ13: unknown GPIOZ14: unknown GPIOZ15: unknown Signed-off-by: Patrice Chotard Reviewed-by: Patrick Delaunay --- drivers/pinctrl/pinctrl_stm32.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/pinctrl/pinctrl_stm32.c b/drivers/pinctrl/pinctrl_stm32.c index 990cd19286..b755fa42b4 100644 --- a/drivers/pinctrl/pinctrl_stm32.c +++ b/drivers/pinctrl/pinctrl_stm32.c @@ -257,10 +257,12 @@ static int stm32_pinctrl_probe(struct udevice *dev) return 0; } -static int stm32_gpio_config(struct gpio_desc *desc, +static int stm32_gpio_config(ofnode node, + struct gpio_desc *desc, const struct stm32_gpio_ctl *ctl) { struct stm32_gpio_priv *priv = dev_get_priv(desc->dev); + struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(desc->dev); struct stm32_gpio_regs *regs = priv->regs; struct stm32_pinctrl_priv *ctrl_priv; int ret; @@ -291,6 +293,8 @@ static int stm32_gpio_config(struct gpio_desc *desc, index = desc->offset; clrsetbits_le32(®s->otyper, OTYPE_MSK << index, ctl->otype << index); + uc_priv->name[desc->offset] = strdup(ofnode_get_name(node)); + hwspinlock_unlock(&ctrl_priv->hws); return 0; @@ -385,7 +389,7 @@ static int stm32_pinctrl_config(ofnode node) if (rv) return rv; desc.offset = gpio_dsc.pin; - rv = stm32_gpio_config(&desc, &gpio_ctl); + rv = stm32_gpio_config(node, &desc, &gpio_ctl); log_debug("rv = %d\n\n", rv); if (rv) return rv; From f6f681642f0d730887bfe944b029cb6f76a35fb6 Mon Sep 17 00:00:00 2001 From: Patrice Chotard Date: Tue, 30 Aug 2022 14:09:14 +0200 Subject: [PATCH 156/374] gpio: sandbox: Add GPIOD_IS_AF for gpio configured in alternate function This allows to test if a pin's label if displayed using gpio_get_status() when this pin is configured in alternate function. Signed-off-by: Patrice Chotard Reviewed-by: Simon Glass Reviewed-by: Patrick Delaunay --- drivers/gpio/sandbox.c | 5 +++++ include/asm-generic/gpio.h | 1 + include/dt-bindings/gpio/sandbox-gpio.h | 3 +++ test/dm/gpio.c | 30 +++++++++++++++++++++++++ 4 files changed, 39 insertions(+) diff --git a/drivers/gpio/sandbox.c b/drivers/gpio/sandbox.c index 106b2a7b27..305f9a6ff6 100644 --- a/drivers/gpio/sandbox.c +++ b/drivers/gpio/sandbox.c @@ -196,6 +196,8 @@ static int sb_gpio_get_function(struct udevice *dev, unsigned offset) return GPIOF_OUTPUT; if (get_gpio_flag(dev, offset, GPIOD_IS_IN)) return GPIOF_INPUT; + if (get_gpio_flag(dev, offset, GPIOD_IS_AF)) + return GPIOF_FUNC; return GPIOF_INPUT; /*GPIO is not configurated */ } @@ -219,6 +221,9 @@ static int sb_gpio_xlate(struct udevice *dev, struct gpio_desc *desc, if (args->args[1] & GPIO_OUT_ACTIVE) desc->flags |= GPIOD_IS_OUT_ACTIVE; + if (args->args[1] & GPIO_AF) + desc->flags |= GPIOD_IS_AF; + return 0; } diff --git a/include/asm-generic/gpio.h b/include/asm-generic/gpio.h index 81f63f06f1..0fcf70983f 100644 --- a/include/asm-generic/gpio.h +++ b/include/asm-generic/gpio.h @@ -127,6 +127,7 @@ struct gpio_desc { #define GPIOD_OPEN_SOURCE BIT(6) /* GPIO is open source type */ #define GPIOD_PULL_UP BIT(7) /* GPIO has pull-up enabled */ #define GPIOD_PULL_DOWN BIT(8) /* GPIO has pull-down enabled */ +#define GPIOD_IS_AF BIT(9) /* GPIO is an alternate function */ /* Flags for updating the above */ #define GPIOD_MASK_DIR (GPIOD_IS_OUT | GPIOD_IS_IN | \ diff --git a/include/dt-bindings/gpio/sandbox-gpio.h b/include/dt-bindings/gpio/sandbox-gpio.h index e4bfdb3ce1..05f9836583 100644 --- a/include/dt-bindings/gpio/sandbox-gpio.h +++ b/include/dt-bindings/gpio/sandbox-gpio.h @@ -21,4 +21,7 @@ /* Bit 18 express GPIO output is active */ #define GPIO_OUT_ACTIVE 0x40000 +/* Bit 19 express GPIO set as alternate function */ +#define GPIO_AF 0x80000 + #endif diff --git a/test/dm/gpio.c b/test/dm/gpio.c index 33ae98701f..a8c35d4370 100644 --- a/test/dm/gpio.c +++ b/test/dm/gpio.c @@ -778,3 +778,33 @@ static int dm_test_gpio_get_values_as_int_base3(struct unit_test_state *uts) } DM_TEST(dm_test_gpio_get_values_as_int_base3, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); + +/* Check that gpio_get_status return the label of a GPIO configured as GPIOD_AF */ +static int dm_test_gpio_function(struct unit_test_state *uts) +{ + struct gpio_desc desc; + struct udevice *dev; + ulong flags; + unsigned int offset, gpio; + char buf[80]; + + ut_assertok(uclass_get_device(UCLASS_TEST_FDT, 0, &dev)); + ut_asserteq_str("a-test", dev->name); + + /* request gpio_b 5 */ + ut_assertok(gpio_request_by_name(dev, "test-gpios", 2, &desc, 0)); + /* update gpio_b 5 function to GPIO_AF */ + ut_assertok(dm_gpio_clrset_flags(&desc, GPIOD_IS_AF, GPIOD_IS_AF)); + ut_assertok(dm_gpio_get_flags(&desc, &flags)); + ut_asserteq(GPIOD_IS_AF, flags); + /* check using gpio_get_status that label is displayed for a pin with GPIO_AF function */ + ut_assertok(gpio_lookup_name("b5", &dev, &offset, &gpio)); + ut_assertok(gpio_get_status(dev, offset, buf, sizeof(buf))); + ut_asserteq_str("b5: func a-test.test-gpios2", buf); + + ut_assertok(dm_gpio_free(dev, &desc)); + + return 0; +} +DM_TEST(dm_test_gpio_function, + UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); From 069f0d7506f6e256f9e2ade82e315ef976dfb9ba Mon Sep 17 00:00:00 2001 From: Sean Anderson Date: Tue, 30 Aug 2022 16:40:37 -0400 Subject: [PATCH 157/374] cli: Reduce size of readline buffers in SPL Normally, readline is not used int SPL. However, it may be useful to enable the Freescale DDR interactive mode in SPL, while U-Boot is still executing from SRAM. The default settings for readline result in a large buffer being allocated. Reduce the size of the maximum input line, and the number of lines of scrollback when building for SPL. Signed-off-by: Sean Anderson Reviewed-by: Simon Glass --- common/cli_readline.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/common/cli_readline.c b/common/cli_readline.c index e86ee73faf..f883b7ffac 100644 --- a/common/cli_readline.c +++ b/common/cli_readline.c @@ -72,8 +72,13 @@ static char *delete_char (char *buffer, char *p, int *colp, int *np, int plen) #define getcmd_getch() getchar() #define getcmd_cbeep() getcmd_putch('\a') +#ifdef CONFIG_SPL_BUILD +#define HIST_MAX 3 +#define HIST_SIZE 32 +#else #define HIST_MAX 20 #define HIST_SIZE CONFIG_SYS_CBSIZE +#endif static int hist_max; static int hist_add_idx; From 0cd933bb4bd74084d942c42098ebf9e07d9e0f63 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Wed, 31 Aug 2022 21:13:40 +0200 Subject: [PATCH 158/374] lib: rsa: fix padding_pss_verify MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Check the that the hash length is shorter than the message length. This avoids: ./tools/../lib/rsa/rsa-verify.c:275:11: warning: ‘*db’ may be used uninitialized [-Wmaybe-uninitialized] 275 | db[0] &= 0xff >> leftmost_bits; Fixes: 061daa0b61f0 ("rsa: add support of padding pss") Signed-off-by: Heinrich Schuchardt Reviewed-by: Simon Glass --- lib/rsa/rsa-verify.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/rsa/rsa-verify.c b/lib/rsa/rsa-verify.c index 1d95cfbdee..9605c37639 100644 --- a/lib/rsa/rsa-verify.c +++ b/lib/rsa/rsa-verify.c @@ -215,6 +215,8 @@ out: * @msg_len: Message length * @hash: Pointer to the expected hash * @hash_len: Length of the hash + * + * Return: 0 if padding is correct, non-zero otherwise */ int padding_pss_verify(struct image_sign_info *info, const uint8_t *msg, int msg_len, @@ -234,6 +236,9 @@ int padding_pss_verify(struct image_sign_info *info, uint8_t leftmost_mask; struct checksum_algo *checksum = info->checksum; + if (db_len <= 0) + return -EINVAL; + /* first, allocate everything */ db_mask = malloc(db_len); db = malloc(db_len); From 6dfc1f4c5139c9310ae36e0b12a9d2aa4984cd66 Mon Sep 17 00:00:00 2001 From: Bernhard Messerklinger Date: Thu, 25 Aug 2022 08:54:00 +0200 Subject: [PATCH 159/374] brppt1: Remove unused board variants The SPI and NAND board variants never went into production. Drop those board variants. Signed-off-by: Bernhard Messerklinger Reviewed-by: Wolfgang Wallner --- arch/arm/dts/Makefile | 2 - arch/arm/dts/am335x-brppt1-nand.dts | 374 --------------------------- arch/arm/dts/am335x-brppt1-spi.dts | 377 ---------------------------- board/BuR/brppt1/board.c | 4 +- board/BuR/brppt1/mux.c | 39 +-- configs/brppt1_nand_defconfig | 122 --------- configs/brppt1_spi_defconfig | 130 ---------- include/configs/brppt1.h | 64 +---- 8 files changed, 7 insertions(+), 1105 deletions(-) delete mode 100644 arch/arm/dts/am335x-brppt1-nand.dts delete mode 100644 arch/arm/dts/am335x-brppt1-spi.dts delete mode 100644 configs/brppt1_nand_defconfig delete mode 100644 configs/brppt1_spi_defconfig diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index 7330121dba..5bff2e65b7 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -388,8 +388,6 @@ dtb-$(CONFIG_AM33XX) += \ am335x-boneblack-wireless.dtb \ am335x-boneblue.dtb \ am335x-brppt1-mmc.dtb \ - am335x-brppt1-nand.dtb \ - am335x-brppt1-spi.dtb \ am335x-brxre1.dtb \ am335x-brsmarc1.dtb \ am335x-draco.dtb \ diff --git a/arch/arm/dts/am335x-brppt1-nand.dts b/arch/arm/dts/am335x-brppt1-nand.dts deleted file mode 100644 index 67c609739f..0000000000 --- a/arch/arm/dts/am335x-brppt1-nand.dts +++ /dev/null @@ -1,374 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Copyright (C) 2018 B&R Industrial Automation GmbH - * http://www.br-automation.com - * - */ -/dts-v1/; - -#include "am33xx.dtsi" - -/ { - model = "BRPPT1 (NAND) Panel"; - compatible = "ti,am33xx"; - - fset: factory-settings { - bl-version = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456890"; - version = <0x0100>; - order-no = "6PPT30 (NAND)"; - hw-revision = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456890"; - serial-no = "0"; - device-id = <0x0>; - parent-id = <0x0>; - hw-variant = <0x1>; - }; - - aliases { - ds1bkl0 = &pwmbacklight; - ds1bkl1 = &tps_bl; - ds1timing = &timing0; - ds1ctrl = &lcdc; - gpmc = &gpmc; - mmc = &mmc2; - fset = &fset; - }; - - chosen { - bootargs = "console=ttyO0,115200 earlyprintk"; - stdout-path = &uart0; - }; - - memory { - device_type = "memory"; - reg = <0x80000000 0x10000000>; /* 256 MB */ - }; - - panel { - status = "disabled"; - - compatible = "ti,tilcdc,panel"; - enable-gpios = <&gpio0 6 GPIO_ACTIVE_LOW>; - - backlight = <&pwmbacklight>; - bkl-pwm = <&pwmbacklight>; - bkl-tps = <&tps_bl>; - - panel-info { - ac-bias = <255>; - ac-bias-intrpt = <0>; - dma-burst-sz = <16>; - bpp = <32>; - fdd = <0x80>; - sync-edge = <0>; - sync-ctrl = <1>; - raster-order = <0>; - fifo-th = <0>; - }; - - display-timings { - native-mode = <&timing0>; - timing0: lcd { - clock-frequency = <32000000>; - hactive = <800>; - vactive = <480>; - hfront-porch = <2>; - hback-porch = <192>; - hsync-len = <1>; - vfront-porch = <20>; - vback-porch = <2>; - vsync-len = <1>; - hsync-active = <1>; - vsync-active = <1>; - pupdelay = <10>; - pondelay = <10>; - }; - }; - }; - - vmmcsd_fixed: fixedregulator@0 { - compatible = "regulator-fixed"; - regulator-name = "vmmcsd_fixed"; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; - }; - - pwm0: omap-pwm@timer5 { - compatible = "ti,omap-dmtimer-pwm"; - ti,timers = <&timer5>; - #pwm-cells = <3>; - }; - - pwm1: omap-pwm@timer6 { - compatible = "ti,omap-dmtimer-pwm"; - ti,timers = <&timer6>; - #pwm-cells = <3>; - }; - - beeper: pwm-beep { - compatible = "pwm-beeper"; - pwms = <&pwm0 0 0 0>; - }; - - pwmbacklight: pwm-bkl { - compatible = "pwm-backlight"; - pwms = <&pwm1 0 5000000 0>; - - default-brightness-level = <255>; - brightness-levels = <0 16 32 64 128 170 202 234 255>; - - power-supply = <&vmmcsd_fixed>; - enable-gpios = <&gpio0 7 GPIO_ACTIVE_HIGH>; - }; -}; - -&uart0 { /* console uart */ - u-boot,dm-spl; - status = "okay"; -}; - -&uart1 { - status = "okay"; -}; - -&i2c0 { - u-boot,dm-spl; - status = "okay"; - clock-frequency = <400000>; - - tps: tps@24 { /* PMIC controller */ - u-boot,dm-spl; - reg = <0x24>; - compatible = "ti,tps65217"; - - tps_bl: backlight { - compatible = "ti,tps65217-bl"; - isel = <1>; /* 1 - ISET1, 2 ISET2 */ - fdim = <1000>; /* TPS65217_BL_FDIM_1kHZ */ - default-brightness = <50>; - }; - }; -}; - -&i2c2 { - status = "okay"; - clock-frequency = <100000>; -}; - -&edma { - status = "okay"; -}; - -&cppi41dma { - status = "okay"; -}; - -&usb { - status = "okay"; -}; - -&usb_ctrl_mod { - status = "okay"; -}; - -&usb0_phy { - status = "okay"; -}; - -&usb1_phy { - status = "okay"; -}; - -&usb0 { - status = "okay"; - dr_mode = "host"; -}; - -&usb1 { - status = "okay"; - dr_mode = "host"; -}; - -&davinci_mdio { - status = "okay"; - - phy0: ethernet-phy@0 { - reg = <1>; - }; - - phy1: ethernet-phy@1 { - reg = <2>; - }; -}; - -&mac { - dual_emac; - status = "okay"; -}; - -&cpsw_emac0 { - phy-handle = <&phy0>; - dual_emac_res_vlan = <1>; - phy-mode = "mii"; -}; - -&cpsw_emac1 { - phy-handle = <&phy1>; - dual_emac_res_vlan = <2>; - phy-mode = "mii"; -}; - -&mmc2 { - vmmc-supply = <&vmmcsd_fixed>; - bus-width = <0x4>; - ti,non-removable; - ti,needs-special-hs-handling; - ti,vcc-aux-disable-is-sleep; - status = "disabled"; -}; - -&l4_per { - - segment@300000 { - - target-module@e000 { - u-boot,dm-pre-reloc; - - lcdc: lcdc@0 { - u-boot,dm-pre-reloc; - status = "disabled"; - }; - }; - }; -}; - -&elm { - status = "okay"; -}; - -&sham { - status = "okay"; -}; - -&aes { - status = "okay"; -}; - -&gpio0 { - u-boot,dm-spl; - ti,no-reset-on-init; -}; - -&gpio1 { - u-boot,dm-spl; - ti,no-reset-on-init; -}; - -&gpio2 { - u-boot,dm-spl; - ti,no-reset-on-init; -}; - -&gpio3 { - u-boot,dm-spl; - ti,no-reset-on-init; -}; - -&wdt2 { - ti,no-reset-on-init; - ti,no-idle-on-init; -}; - -&tscadc { - status = "okay"; - tsc { - ti,wires = <4>; - ti,x-plate-resistance = <200>; - ti,zx-cutoff-ratio = <40>; - ti,min_deviation = <60>; - ti,max_deviation = <600>; - ti,coordinate-readouts = <5>; - ti,wire-config = <0x00 0x11 0x22 0x33>; - - bnr-buttons { - Home-Button {}; - }; - }; - - adc { - ti,adc-channels = <5 6 7>; - }; -}; - -&gpmc { - u-boot,dm-spl; - status = "okay"; - pinctrl-names = "default"; - ranges = <0 0 0x08000000 0x10000000>; /* CS0: NAND */ - nand@0,0 { - compatible = "ti,omap2-nand"; - reg = <0 0 4>; /* CS0, offset 0, IO size 4 */ - interrupt-parent = <&gpmc>; - rb-gpios = <&gpmc 1 GPIO_ACTIVE_HIGH>; /* gpmc_wait1 */ - ti,nand-ecc-opt = "bch8"; - ti,elm-id = <&elm>; - nand-bus-width = <8>; - gpmc,device-width = <1>; - gpmc,sync-clk-ps = <0>; - gpmc,cs-on-ns = <0>; - gpmc,cs-rd-off-ns = <44>; - gpmc,cs-wr-off-ns = <44>; - gpmc,adv-on-ns = <6>; - gpmc,adv-rd-off-ns = <34>; - gpmc,adv-wr-off-ns = <44>; - gpmc,we-on-ns = <0>; - gpmc,we-off-ns = <40>; - gpmc,oe-on-ns = <0>; - gpmc,oe-off-ns = <54>; - gpmc,access-ns = <64>; - gpmc,rd-cycle-ns = <82>; - gpmc,wr-cycle-ns = <82>; - gpmc,wait-on-read = "true"; - gpmc,wait-on-write = "true"; - gpmc,bus-turnaround-ns = <0>; - gpmc,cycle2cycle-delay-ns = <0>; - gpmc,clk-activation-ns = <0>; - gpmc,wait-monitoring-ns = <0>; - gpmc,wr-access-ns = <40>; - gpmc,wr-data-mux-bus-ns = <0>; - gpmc,wait-pin = <1>; - #address-cells = <1>; - #size-cells = <1>; - partition@0 { - label = "NAND.MLO"; - reg = <0x00000000 0x000020000>; - }; - partition@1 { - label = "NAND.cfgscr"; - reg = <0x00020000 0x00020000>; - }; - partition@2 { - label = "NAND.dtb"; - reg = <0x00040000 0x00020000>; - }; - partition@3 { - label = "NAND.u-boot-env"; - reg = <0x00060000 0x00020000>; - }; - partition@4 { - label = "NAND.u-boot"; - reg = <0x00080000 0x00080000>; - }; - partition@5 { - label = "NAND.kernel"; - reg = <0x00100000 0x00400000>; - }; - partition@6 { - label = "NAND.rootfs"; - reg = <0x00500000 0x08000000>; - }; - partition@7 { - label = "NAND.user"; - reg = <0x08500000 0x17b00000>; - }; - }; -}; diff --git a/arch/arm/dts/am335x-brppt1-spi.dts b/arch/arm/dts/am335x-brppt1-spi.dts deleted file mode 100644 index ce3dce204d..0000000000 --- a/arch/arm/dts/am335x-brppt1-spi.dts +++ /dev/null @@ -1,377 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Copyright (C) 2018 B&R Industrial Automation GmbH - * http://www.br-automation.com - * - */ -/dts-v1/; - -#include "am33xx.dtsi" - -/ { - model = "BRPPT1 (MMC) Panel"; - compatible = "ti,am33xx"; - - fset: factory-settings { - bl-version = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456890"; - version = <0x0100>; - order-no = "6PPT30 (SPI)"; - hw-revision = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456890"; - serial-no = "0"; - device-id = <0x0>; - parent-id = <0x0>; - hw-variant = <0x1>; - }; - - aliases { - ds1bkl0 = &pwmbacklight; - ds1bkl1 = &tps_bl; - ds1timing = &timing0; - ds1ctrl = &lcdc; - gpmc = &gpmc; - mmc = &mmc2; - spi0 = &spi0; - fset = &fset; - }; - - chosen { - bootargs = "console=ttyO0,115200 earlyprintk"; - stdout-path = &uart0; - }; - - memory { - device_type = "memory"; - reg = <0x80000000 0x10000000>; /* 256 MB */ - }; - - panel { - status = "disabled"; - - compatible = "ti,tilcdc,panel"; - enable-gpios = <&gpio0 6 GPIO_ACTIVE_LOW>; - - backlight = <&pwmbacklight>; - bkl-pwm = <&pwmbacklight>; - bkl-tps = <&tps_bl>; - - panel-info { - ac-bias = <255>; - ac-bias-intrpt = <0>; - dma-burst-sz = <16>; - bpp = <32>; - fdd = <0x80>; - sync-edge = <0>; - sync-ctrl = <1>; - raster-order = <0>; - fifo-th = <0>; - }; - - display-timings { - native-mode = <&timing0>; - timing0: lcd { - clock-frequency = <32000000>; - hactive = <800>; - vactive = <480>; - hfront-porch = <2>; - hback-porch = <192>; - hsync-len = <1>; - vfront-porch = <20>; - vback-porch = <2>; - vsync-len = <1>; - hsync-active = <1>; - vsync-active = <1>; - pupdelay = <10>; - pondelay = <10>; - }; - }; - }; - - vmmcsd_fixed: fixedregulator@0 { - compatible = "regulator-fixed"; - regulator-name = "vmmcsd_fixed"; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; - }; - - pwm0: omap-pwm@timer5 { - compatible = "ti,omap-dmtimer-pwm"; - ti,timers = <&timer5>; - #pwm-cells = <3>; - }; - - pwm1: omap-pwm@timer6 { - compatible = "ti,omap-dmtimer-pwm"; - ti,timers = <&timer6>; - #pwm-cells = <3>; - }; - - beeper: pwm-beep { - compatible = "pwm-beeper"; - pwms = <&pwm0 0 0 0>; - }; - - pwmbacklight: pwm-bkl { - compatible = "pwm-backlight"; - pwms = <&pwm1 0 5000000 0>; - - default-brightness-level = <255>; - brightness-levels = <0 16 32 64 128 170 202 234 255>; - - power-supply = <&vmmcsd_fixed>; - enable-gpios = <&gpio0 7 GPIO_ACTIVE_HIGH>; - }; -}; - -&uart0 { /* console uart */ - u-boot,dm-spl; - status = "okay"; -}; - -&uart1 { - status = "okay"; -}; - -&i2c0 { - u-boot,dm-spl; - status = "okay"; - clock-frequency = <400000>; - - tps: tps@24 { /* PMIC controller */ - u-boot,dm-spl; - reg = <0x24>; - compatible = "ti,tps65217"; - - tps_bl: backlight { - compatible = "ti,tps65217-bl"; - isel = <1>; /* 1 - ISET1, 2 ISET2 */ - fdim = <1000>; /* TPS65217_BL_FDIM_1kHZ */ - default-brightness = <50>; - }; - }; -}; - -&i2c2 { - status = "okay"; - clock-frequency = <100000>; -}; - -&spi0 { - u-boot,dm-spl; - status = "okay"; - - cs-gpios = <&gpio0 5 GPIO_ACTIVE_HIGH>, - <&gpio0 6 GPIO_ACTIVE_HIGH>, - <0>, - <0>; - - spi-max-frequency = <24000000>; - - spi_flash: spiflash@0 { - u-boot,dm-spl; - u-boot,dm-pre-reloc; - compatible = "spidev", "jedec,spi-nor"; - spi-max-frequency = <24000000>; - reg = <0>; - }; -}; - -&edma { - status = "okay"; -}; - -&cppi41dma { - status = "okay"; -}; - -&usb { - status = "okay"; -}; - -&usb_ctrl_mod { - status = "okay"; -}; - -&usb0_phy { - status = "okay"; -}; - -&usb1_phy { - status = "okay"; -}; - -&usb0 { - status = "okay"; - dr_mode = "host"; -}; - -&usb1 { - status = "okay"; - dr_mode = "host"; -}; - -&davinci_mdio { - status = "okay"; - - phy0: ethernet-phy@0 { - reg = <1>; - }; - - phy1: ethernet-phy@1 { - reg = <2>; - }; -}; - -&mac { - status = "okay"; -}; - -&cpsw_emac0 { - phy-handle = <&phy0>; - dual_emac_res_vlan = <1>; - phy-mode = "mii"; -}; - -&cpsw_emac1 { - phy-handle = <&phy1>; - dual_emac_res_vlan = <2>; - phy-mode = "mii"; -}; - -&mmc1 { - u-boot,dm-spl; - vmmc-supply = <&vmmcsd_fixed>; - bus-width = <0x4>; - ti,non-removable; - ti,needs-special-hs-handling; - ti,vcc-aux-disable-is-sleep; - status = "okay"; -}; - -&mmc2 { - u-boot,dm-spl; - vmmc-supply = <&vmmcsd_fixed>; - bus-width = <0x8>; - ti,non-removable; - ti,needs-special-hs-handling; - ti,vcc-aux-disable-is-sleep; - status = "okay"; -}; - -&l4_per { - - segment@300000 { - - target-module@e000 { - u-boot,dm-pre-reloc; - - lcdc: lcdc@0 { - u-boot,dm-pre-reloc; - status = "disabled"; - }; - }; - }; -}; - -&elm { - status = "okay"; -}; - -&sham { - status = "okay"; -}; - -&aes { - status = "okay"; -}; - -&gpio0 { - u-boot,dm-spl; - ti,no-reset-on-init; -}; - -&gpio1 { - u-boot,dm-spl; - ti,no-reset-on-init; -}; - -&gpio2 { - u-boot,dm-spl; - ti,no-reset-on-init; -}; - -&gpio3 { - u-boot,dm-spl; - ti,no-reset-on-init; -}; - -&wdt2 { - ti,no-reset-on-init; - ti,no-idle-on-init; -}; - -&tscadc { - status = "okay"; - tsc { - ti,wires = <4>; - ti,x-plate-resistance = <200>; - ti,zx-cutoff-ratio = <40>; - ti,min_deviation = <60>; - ti,max_deviation = <600>; - ti,coordinate-readouts = <5>; - ti,wire-config = <0x00 0x11 0x22 0x33>; - - bnr-buttons { - Home-Button {}; - }; - }; - - adc { - ti,adc-channels = <5 6 7>; - }; -}; - -&timer6 { /* used for cpsw end device */ - status = "okay"; - ti,no-reset-on-init; - ti,no-idle-on-init; -}; - -&timer7 { /* used for cpsw end device */ - status = "okay"; - ti,no-reset-on-init; - ti,no-idle-on-init; -}; - -&wdt2 { - status = "okay"; - ti,no-reset-on-init; - ti,no-idle-on-init; -}; - -&epwmss0 { - status = "okay"; -}; - -&tscadc { - status = "okay"; -}; - -&dcan0 { - status = "okay"; -}; - -&dcan1 { - status = "okay"; -}; - -&sham { - status = "disabled"; -}; - -&aes { - status = "disabled"; -}; - -&rng { - status = "disabled"; -}; diff --git a/board/BuR/brppt1/board.c b/board/BuR/brppt1/board.c index 7df37e4e66..c8dc186cdd 100644 --- a/board/BuR/brppt1/board.c +++ b/board/BuR/brppt1/board.c @@ -151,9 +151,7 @@ int board_init(void) hw_watchdog_init(); #endif gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100; -#ifdef CONFIG_MTD_RAW_NAND - gpmc_init(); -#endif + return 0; } diff --git a/board/BuR/brppt1/mux.c b/board/BuR/brppt1/mux.c index b863d37335..5d2c7a201e 100644 --- a/board/BuR/brppt1/mux.c +++ b/board/BuR/brppt1/mux.c @@ -26,6 +26,7 @@ static struct module_pin_mux uart0_pin_mux[] = { {OFFSET(uart0_txd), (MODE(0) | PULLUDEN)}, {-1}, }; + static struct module_pin_mux uart1_pin_mux[] = { /* UART1_RTS as I2C2-SCL */ {OFFSET(uart1_rtsn), (MODE(3) | PULLUDEN | PULLUP_EN | RXACTIVE)}, @@ -37,7 +38,7 @@ static struct module_pin_mux uart1_pin_mux[] = { {OFFSET(uart1_txd), (MODE(0) | PULLUDEN)}, {-1}, }; -#ifdef CONFIG_MMC + static struct module_pin_mux mmc1_pin_mux[] = { {OFFSET(gpmc_ad7), (MODE(1) | RXACTIVE | PULLUP_EN)}, /* MMC1_DAT7 */ {OFFSET(gpmc_ad6), (MODE(1) | RXACTIVE | PULLUP_EN)}, /* MMC1_DAT6 */ @@ -54,7 +55,7 @@ static struct module_pin_mux mmc1_pin_mux[] = { {OFFSET(gpmc_advn_ale), (MODE(7) | RXACTIVE | PULLUP_EN)},/* MMC1_CD */ {-1}, }; -#endif + static struct module_pin_mux i2c0_pin_mux[] = { /* I2C_DATA */ {OFFSET(i2c0_sda), (MODE(0) | RXACTIVE | PULLUDEN | SLEWCTRL)}, @@ -118,26 +119,7 @@ static struct module_pin_mux mii2_pin_mux[] = { {OFFSET(gpmc_be1n), (MODE(1) | RXACTIVE)},/* MII1_COL */ {-1}, }; -#ifdef CONFIG_MTD_RAW_NAND -static struct module_pin_mux nand_pin_mux[] = { - {OFFSET(gpmc_ad0), (MODE(0) | PULLUP_EN | RXACTIVE)}, /* NAND AD0 */ - {OFFSET(gpmc_ad1), (MODE(0) | PULLUP_EN | RXACTIVE)}, /* NAND AD1 */ - {OFFSET(gpmc_ad2), (MODE(0) | PULLUP_EN | RXACTIVE)}, /* NAND AD2 */ - {OFFSET(gpmc_ad3), (MODE(0) | PULLUP_EN | RXACTIVE)}, /* NAND AD3 */ - {OFFSET(gpmc_ad4), (MODE(0) | PULLUP_EN | RXACTIVE)}, /* NAND AD4 */ - {OFFSET(gpmc_ad5), (MODE(0) | PULLUP_EN | RXACTIVE)}, /* NAND AD5 */ - {OFFSET(gpmc_ad6), (MODE(0) | PULLUP_EN | RXACTIVE)}, /* NAND AD6 */ - {OFFSET(gpmc_ad7), (MODE(0) | PULLUP_EN | RXACTIVE)}, /* NAND AD7 */ - {OFFSET(gpmc_clk), (MODE(2) | RXACTIVE | PULLUP_EN)}, /* NAND WAIT */ - {OFFSET(gpmc_wpn), (MODE(7) | PULLUP_EN | RXACTIVE)}, /* NAND_WPN */ - {OFFSET(gpmc_csn0), (MODE(0) | PULLUDEN)}, /* NAND_CS0 */ - {OFFSET(gpmc_advn_ale), (MODE(0) | PULLUDEN)}, /* NAND_ADV_ALE */ - {OFFSET(gpmc_oen_ren), (MODE(0) | PULLUDEN)}, /* NAND_OE */ - {OFFSET(gpmc_wen), (MODE(0) | PULLUDEN)}, /* NAND_WEN */ - {OFFSET(gpmc_be0n_cle), (MODE(0) | PULLUDEN)}, /* NAND_BE_CLE */ - {-1}, -}; -#endif + static struct module_pin_mux gpIOs[] = { /* GPIO0_6 (SPI0_CS1) - 3v3_PWR_nEN (Display Power Supply) */ {OFFSET(spi0_cs1), (MODE(7) | PULLUDEN | PULLUP_EN | RXACTIVE)}, @@ -180,14 +162,6 @@ static struct module_pin_mux gpIOs[] = { {OFFSET(mcasp0_axr0), (MODE(7) | PULLUDDIS) }, /* GPIO3_17 (MCASP0_AHCLKR) - ETH2_LEDY */ {OFFSET(mcasp0_ahclkr), (MODE(7) | PULLUDDIS) }, -#ifndef CONFIG_MTD_RAW_NAND - /* GPIO2_3 - NAND_OE */ - {OFFSET(gpmc_oen_ren), (MODE(7) | PULLDOWN_EN | RXACTIVE)}, - /* GPIO2_4 - NAND_WEN */ - {OFFSET(gpmc_wen), (MODE(7) | PULLDOWN_EN | RXACTIVE)}, - /* GPIO2_5 - NAND_BE_CLE */ - {OFFSET(gpmc_be0n_cle), (MODE(7) | PULLDOWN_EN | RXACTIVE)}, -#endif {-1}, }; @@ -222,7 +196,6 @@ static struct module_pin_mux lcd_pin_mux[] = { {OFFSET(lcd_hsync), (MODE(0) | PULLUDDIS)}, /* LCD-HSync */ {OFFSET(lcd_ac_bias_en), (MODE(0) | PULLUDDIS)},/* LCD-DE */ {OFFSET(lcd_pclk), (MODE(0) | PULLUDDIS)}, /* LCD-CLK */ - {-1}, }; @@ -241,11 +214,7 @@ void enable_board_pin_mux(void) configure_module_pin_mux(i2c0_pin_mux); configure_module_pin_mux(mii1_pin_mux); configure_module_pin_mux(mii2_pin_mux); -#ifdef CONFIG_MTD_RAW_NAND - configure_module_pin_mux(nand_pin_mux); -#elif defined(CONFIG_MMC) configure_module_pin_mux(mmc1_pin_mux); -#endif configure_module_pin_mux(spi0_pin_mux); configure_module_pin_mux(lcd_pin_mux); configure_module_pin_mux(uart1_pin_mux); diff --git a/configs/brppt1_nand_defconfig b/configs/brppt1_nand_defconfig deleted file mode 100644 index c5981bad49..0000000000 --- a/configs/brppt1_nand_defconfig +++ /dev/null @@ -1,122 +0,0 @@ -CONFIG_ARM=y -CONFIG_ARCH_OMAP2PLUS=y -CONFIG_SYS_MALLOC_LEN=0x500000 -CONFIG_SPL_GPIO=y -CONFIG_SPL_LIBCOMMON_SUPPORT=y -CONFIG_SPL_LIBGENERIC_SUPPORT=y -CONFIG_NR_DRAM_BANKS=1 -CONFIG_ENV_SIZE=0x10000 -CONFIG_ENV_OFFSET=0x60000 -CONFIG_DM_GPIO=y -CONFIG_DEFAULT_DEVICE_TREE="am335x-brppt1-nand" -CONFIG_AM33XX=y -CONFIG_TARGET_BRPPT1=y -CONFIG_SPL_SERIAL=y -CONFIG_SPL=y -CONFIG_SYS_LOAD_ADDR=0x80000000 -CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y -CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0x4030ff00 -# CONFIG_EXPERT is not set -# CONFIG_FIT is not set -CONFIG_OF_BOARD_SETUP=y -CONFIG_BOOTDELAY=0 -CONFIG_USE_BOOTCOMMAND=y -CONFIG_BOOTCOMMAND="run b_default" -CONFIG_USE_PREBOOT=y -CONFIG_PREBOOT="run cfgscr; run brdefaultip" -CONFIG_SYS_CONSOLE_IS_IN_ENV=y -CONFIG_SYS_CONSOLE_OVERWRITE_ROUTINE=y -CONFIG_SYS_CONSOLE_INFO_QUIET=y -# CONFIG_DISPLAY_CPUINFO is not set -# CONFIG_DISPLAY_BOARDINFO is not set -CONFIG_ARCH_MISC_INIT=y -CONFIG_SPL_SYS_MALLOC_SIMPLE=y -CONFIG_SYS_SPL_MALLOC=y -CONFIG_SYS_SPL_MALLOC_SIZE=0x500000 -# CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR is not set -CONFIG_SPL_I2C=y -CONFIG_SPL_NAND_DRIVERS=y -CONFIG_SPL_NAND_ECC=y -CONFIG_SPL_NAND_BASE=y -CONFIG_SPL_POWER=y -CONFIG_SPL_WATCHDOG=y -CONFIG_SPL_YMODEM_SUPPORT=y -CONFIG_HUSH_PARSER=y -CONFIG_SYS_MAXARGS=64 -CONFIG_SYS_CBSIZE=512 -CONFIG_SYS_PBSIZE=532 -CONFIG_CMD_BOOTZ=y -CONFIG_SYS_BOOTM_LEN=0x2000000 -# CONFIG_CMD_IMI is not set -# CONFIG_CMD_XIMG is not set -# CONFIG_CMD_EDITENV is not set -# CONFIG_CMD_CRC32 is not set -# CONFIG_CMD_FLASH is not set -CONFIG_CMD_GPIO=y -CONFIG_CMD_I2C=y -# CONFIG_CMD_LOADS is not set -CONFIG_CMD_NAND=y -CONFIG_CMD_PART=y -CONFIG_CMD_USB=y -# CONFIG_CMD_ITEST is not set -CONFIG_CMD_DHCP=y -CONFIG_BOOTP_MAY_FAIL=y -# CONFIG_CMD_NFS is not set -CONFIG_SYS_DISABLE_AUTOLOAD=y -CONFIG_CMD_MII=y -CONFIG_CMD_PING=y -CONFIG_CMD_BOOTCOUNT=y -CONFIG_CMD_CACHE=y -CONFIG_CMD_TIME=y -CONFIG_CMD_EXT4=y -CONFIG_CMD_EXT4_WRITE=y -CONFIG_CMD_FAT=y -CONFIG_CMD_FS_GENERIC=y -CONFIG_CMD_MTDPARTS=y -CONFIG_MTDIDS_DEFAULT="nand0=omap2-nand.0" -CONFIG_MTDPARTS_DEFAULT="mtdparts=omap2-nand.0:128k(MLO),128k(cfgscr),128k(dtb),128k(u-boot-env),512k(u-boot),4m(kernel),128m(rootfs),-(user)" -# CONFIG_SPL_DOS_PARTITION is not set -CONFIG_OF_CONTROL=y -CONFIG_SPL_OF_CONTROL=y -CONFIG_OF_SPL_REMOVE_PROPS="pinctrl-0 pinctrl-names clocks clock-names interrupt-parent interrupt-controller interrupt-cells dma-names dmas " -CONFIG_ENV_OVERWRITE=y -CONFIG_ENV_IS_IN_NAND=y -CONFIG_SYS_RELOC_GD_ENV_ADDR=y -CONFIG_VERSION_VARIABLE=y -CONFIG_NET_RETRY_COUNT=10 -CONFIG_BOOTP_SEND_HOSTNAME=y -CONFIG_NET_RANDOM_ETHADDR=y -CONFIG_NETCONSOLE=y -CONFIG_DM=y -CONFIG_SPL_DM=y -CONFIG_SPL_DM_SEQ_ALIAS=y -# CONFIG_OF_TRANSLATE is not set -CONFIG_BOOTCOUNT_LIMIT=y -CONFIG_DM_I2C=y -CONFIG_I2C_SET_DEFAULT_BUS_NUM=y -CONFIG_MISC=y -# CONFIG_MMC is not set -CONFIG_MTD=y -CONFIG_MTD_RAW_NAND=y -CONFIG_SYS_NAND_BLOCK_SIZE=0x20000 -CONFIG_SYS_NAND_PAGE_COUNT=0x40 -CONFIG_SYS_NAND_PAGE_SIZE=0x800 -CONFIG_SYS_NAND_OOBSIZE=0x40 -CONFIG_SYS_NAND_U_BOOT_LOCATIONS=y -CONFIG_SYS_NAND_U_BOOT_OFFS=0x80000 -CONFIG_PHY_NATSEMI=y -CONFIG_DRIVER_TI_CPSW=y -CONFIG_DM_PMIC=y -# CONFIG_SPL_DM_PMIC is not set -CONFIG_PMIC_TPS65217=y -CONFIG_DM_SERIAL=y -CONFIG_USB=y -CONFIG_USB_MUSB_HOST=y -CONFIG_USB_MUSB_GADGET=y -CONFIG_USB_MUSB_TI=y -CONFIG_USB_STORAGE=y -CONFIG_USB_GADGET=y -CONFIG_FAT_WRITE=y -CONFIG_LZO=y -# CONFIG_OF_LIBFDT_OVERLAY is not set -# CONFIG_EFI_LOADER is not set diff --git a/configs/brppt1_spi_defconfig b/configs/brppt1_spi_defconfig deleted file mode 100644 index fa6b840d9e..0000000000 --- a/configs/brppt1_spi_defconfig +++ /dev/null @@ -1,130 +0,0 @@ -CONFIG_ARM=y -CONFIG_ARCH_OMAP2PLUS=y -CONFIG_SYS_MALLOC_LEN=0x500000 -CONFIG_SYS_MALLOC_F_LEN=0x4000 -CONFIG_SPL_GPIO=y -CONFIG_SPL_LIBCOMMON_SUPPORT=y -CONFIG_SPL_LIBGENERIC_SUPPORT=y -CONFIG_NR_DRAM_BANKS=1 -CONFIG_ENV_SIZE=0x10000 -CONFIG_ENV_OFFSET=0x20000 -CONFIG_ENV_SECT_SIZE=0x10000 -CONFIG_DM_GPIO=y -CONFIG_SPL_DM_SPI=y -CONFIG_DEFAULT_DEVICE_TREE="am335x-brppt1-spi" -CONFIG_AM33XX=y -CONFIG_TARGET_BRPPT1=y -CONFIG_SPL_SERIAL=y -CONFIG_SPL=y -CONFIG_ENV_OFFSET_REDUND=0x30000 -CONFIG_SPL_SPI_FLASH_SUPPORT=y -CONFIG_SPL_SPI=y -CONFIG_SYS_LOAD_ADDR=0x80000000 -CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y -CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0x4030ff00 -# CONFIG_EXPERT is not set -# CONFIG_FIT is not set -CONFIG_OF_BOARD_SETUP=y -CONFIG_SPI_BOOT=y -CONFIG_BOOTDELAY=0 -CONFIG_USE_BOOTCOMMAND=y -CONFIG_BOOTCOMMAND="run b_default" -CONFIG_USE_PREBOOT=y -CONFIG_PREBOOT="run cfgscr; run brdefaultip" -CONFIG_SYS_CONSOLE_IS_IN_ENV=y -CONFIG_SYS_CONSOLE_OVERWRITE_ROUTINE=y -CONFIG_SYS_CONSOLE_INFO_QUIET=y -# CONFIG_DISPLAY_CPUINFO is not set -# CONFIG_DISPLAY_BOARDINFO is not set -CONFIG_ARCH_MISC_INIT=y -CONFIG_SPL_SYS_MALLOC_SIMPLE=y -CONFIG_SYS_SPL_MALLOC=y -CONFIG_SYS_SPL_MALLOC_SIZE=0x500000 -# CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR is not set -CONFIG_SPL_I2C=y -# CONFIG_SPL_NAND_SUPPORT is not set -CONFIG_SPL_DM_SPI_FLASH=y -CONFIG_SPL_POWER=y -CONFIG_SPL_SPI_LOAD=y -CONFIG_SYS_SPI_U_BOOT_OFFS=0x40000 -CONFIG_SPL_WATCHDOG=y -CONFIG_SPL_YMODEM_SUPPORT=y -CONFIG_HUSH_PARSER=y -CONFIG_SYS_MAXARGS=64 -CONFIG_SYS_CBSIZE=512 -CONFIG_SYS_PBSIZE=532 -CONFIG_CMD_BOOTZ=y -CONFIG_SYS_BOOTM_LEN=0x2000000 -# CONFIG_CMD_IMI is not set -# CONFIG_CMD_XIMG is not set -# CONFIG_CMD_EDITENV is not set -# CONFIG_CMD_CRC32 is not set -# CONFIG_CMD_FLASH is not set -CONFIG_CMD_GPIO=y -CONFIG_CMD_I2C=y -# CONFIG_CMD_LOADS is not set -CONFIG_CMD_MMC=y -CONFIG_CMD_BKOPS_ENABLE=y -CONFIG_CMD_PART=y -CONFIG_CMD_USB=y -# CONFIG_CMD_ITEST is not set -CONFIG_CMD_DHCP=y -CONFIG_BOOTP_MAY_FAIL=y -# CONFIG_CMD_NFS is not set -CONFIG_SYS_DISABLE_AUTOLOAD=y -CONFIG_CMD_MII=y -CONFIG_CMD_PING=y -CONFIG_CMD_BOOTCOUNT=y -CONFIG_CMD_CACHE=y -CONFIG_CMD_TIME=y -CONFIG_CMD_EXT4=y -CONFIG_CMD_EXT4_WRITE=y -CONFIG_CMD_FAT=y -CONFIG_CMD_FS_GENERIC=y -# CONFIG_SPL_DOS_PARTITION is not set -CONFIG_OF_CONTROL=y -CONFIG_SPL_OF_CONTROL=y -CONFIG_OF_SPL_REMOVE_PROPS="pinctrl-0 pinctrl-names clocks clock-names interrupt-parent interrupt-controller interrupt-cells dma-names dmas " -CONFIG_ENV_OVERWRITE=y -CONFIG_ENV_IS_IN_SPI_FLASH=y -CONFIG_SYS_REDUNDAND_ENVIRONMENT=y -CONFIG_SYS_RELOC_GD_ENV_ADDR=y -CONFIG_VERSION_VARIABLE=y -CONFIG_NET_RETRY_COUNT=10 -CONFIG_BOOTP_SEND_HOSTNAME=y -CONFIG_NET_RANDOM_ETHADDR=y -CONFIG_NETCONSOLE=y -CONFIG_DM=y -CONFIG_SPL_DM=y -CONFIG_SPL_DM_SEQ_ALIAS=y -# CONFIG_OF_TRANSLATE is not set -CONFIG_BOOTCOUNT_LIMIT=y -CONFIG_DM_I2C=y -CONFIG_I2C_SET_DEFAULT_BUS_NUM=y -CONFIG_MISC=y -CONFIG_MMC_OMAP_HS=y -CONFIG_MTD=y -CONFIG_DM_SPI_FLASH=y -CONFIG_SF_DEFAULT_SPEED=24000000 -CONFIG_SPI_FLASH_STMICRO=y -CONFIG_SPI_FLASH_WINBOND=y -# CONFIG_SPI_FLASH_USE_4K_SECTORS is not set -CONFIG_PHY_NATSEMI=y -CONFIG_DRIVER_TI_CPSW=y -CONFIG_DM_PMIC=y -# CONFIG_SPL_DM_PMIC is not set -CONFIG_PMIC_TPS65217=y -CONFIG_DM_SERIAL=y -CONFIG_SPI=y -CONFIG_DM_SPI=y -CONFIG_OMAP3_SPI=y -CONFIG_USB=y -CONFIG_USB_MUSB_HOST=y -CONFIG_USB_MUSB_GADGET=y -CONFIG_USB_MUSB_TI=y -CONFIG_USB_STORAGE=y -CONFIG_USB_GADGET=y -CONFIG_FAT_WRITE=y -CONFIG_LZO=y -# CONFIG_OF_LIBFDT_OVERLAY is not set -# CONFIG_EFI_LOADER is not set diff --git a/include/configs/brppt1.h b/include/configs/brppt1.h index 6cb1a10600..481473ae2c 100644 --- a/include/configs/brppt1.h +++ b/include/configs/brppt1.h @@ -27,31 +27,7 @@ * the Linux kernel. */ -#ifdef CONFIG_SPL_OS_BOOT -/* RAW SD card / eMMC */ - -#endif /* CONFIG_SPL_OS_BOOT */ - -#ifdef CONFIG_MTD_RAW_NAND -#define CONFIG_SYS_NAND_U_BOOT_START CONFIG_SYS_TEXT_BASE -#endif /* CONFIG_MTD_RAW_NAND */ - -#ifdef CONFIG_MTD_RAW_NAND -#define NANDTGTS \ -"cfgscr=mw ${dtbaddr} 0; nand read ${cfgaddr} cfgscr && source ${cfgaddr};" \ -" fdt addr ${dtbaddr} || cp ${fdtcontroladdr} ${dtbaddr} 4000\0" \ -"nandargs=setenv bootargs console=${console} ${optargs} ${optargs_rot} " \ - "root=mtd6 rootfstype=jffs2 b_mode=${b_mode}\0" \ -"b_nand=nand read ${loadaddr} kernel; nand read ${dtbaddr} dtb; " \ - "run nandargs; run cfgscr; bootz ${loadaddr} - ${dtbaddr}\0" \ -"b_tgts_std=usb0 nand net\0" \ -"b_tgts_rcy=net usb0 nand\0" \ -"b_tgts_pme=usb0 nand net\0" -#else -#define NANDTGTS "" -#endif /* CONFIG_MTD_RAW_NAND */ - -#define MMCSPI_TGTS \ +#define MMC_TGTS \ "t30args#0=setenv bootargs ${optargs_rot} ${optargs} console=${console} " \ "b_mode=${b_mode} root=/dev/mmcblk0p2 rootfstype=ext4\0" \ "b_t30lgcy#0=" \ @@ -76,7 +52,7 @@ #ifdef CONFIG_ENV_IS_IN_MMC #define MMCTGTS \ -MMCSPI_TGTS \ +MMC_TGTS \ "cfgscr=mw ${dtbaddr} 0;" \ " mmc dev 1; mmc read ${cfgaddr} 200 80; source ${cfgaddr};" \ " fdt addr ${dtbaddr} || cp ${fdtcontroladdr} ${dtbaddr} 4000\0" @@ -84,16 +60,6 @@ MMCSPI_TGTS \ #define MMCTGTS "" #endif /* CONFIG_MMC */ -#ifdef CONFIG_SPI -#define SPITGTS \ -MMCSPI_TGTS \ -"cfgscr=mw ${dtbaddr} 0;" \ -" sf probe; sf read ${cfgaddr} 0xC0000 10000; source ${cfgaddr};" \ -" fdt addr ${dtbaddr} || cp ${fdtcontroladdr} ${dtbaddr} 4000\0" -#else -#define SPITGTS "" -#endif /* CONFIG_SPI */ - #define LOAD_OFFSET(x) 0x8##x #define CONFIG_EXTRA_ENV_SETTINGS \ @@ -110,8 +76,6 @@ BUR_COMMON_ENV \ "b_usb0=usb start && load usb 0 ${scraddr} bootscr.img && source ${scraddr}\0" \ "b_net=tftp ${scraddr} netscript.img && source ${scraddr}\0" \ MMCTGTS \ -SPITGTS \ -NANDTGTS \ "b_deftgts=if test ${b_mode} = 12; then setenv b_tgts ${b_tgts_pme};" \ " elif test ${b_mode} = 0; then setenv b_tgts ${b_tgts_rcy};" \ " else setenv b_tgts ${b_tgts_std}; fi\0" \ @@ -119,28 +83,4 @@ NANDTGTS \ " do echo \"### booting ${target} ###\"; run b_${target};" \ " if test ${b_break} = 1; then; exit; fi; done\0" -#ifdef CONFIG_MTD_RAW_NAND -/* - * GPMC block. We support 1 device and the physical address to - * access CS0 at is 0x8000000. - */ -#define CONFIG_SYS_MAX_NAND_DEVICE 1 -#define CONFIG_SYS_NAND_BASE 0x8000000 -/* don't change OMAP_ELM, ECCSCHEME. ROM code only supports this */ -#define CONFIG_SYS_NAND_ECCPOS {2, 3, 4, 5, 6, 7, 8, 9, \ - 10, 11, 12, 13, 14, 15, 16, 17, \ - 18, 19, 20, 21, 22, 23, 24, 25, \ - 26, 27, 28, 29, 30, 31, 32, 33, \ - 34, 35, 36, 37, 38, 39, 40, 41, \ - 42, 43, 44, 45, 46, 47, 48, 49, \ - 50, 51, 52, 53, 54, 55, 56, 57, } - -#define CONFIG_SYS_NAND_ECCSIZE 512 -#define CONFIG_SYS_NAND_ECCBYTES 14 - -#define CONFIG_SYS_NAND_U_BOOT_START CONFIG_SYS_TEXT_BASE - -#define CONFIG_NAND_OMAP_GPMC_WSCFG 1 -#endif /* CONFIG_MTD_RAW_NAND */ - #endif /* ! __CONFIG_BRPPT1_H__ */ From b0a18f1f9fe822d6a0c6d8ca7161193a86a66332 Mon Sep 17 00:00:00 2001 From: Bernhard Messerklinger Date: Thu, 25 Aug 2022 08:54:01 +0200 Subject: [PATCH 160/374] brppt1: Fix SPL boot stage Commit 6337d53fdf45 ("arm: dts: sync am33xx with Linux 5.9-rc7") syncs the am335x device tree with the latest linux kernel am335x device tree. That causes problems with device tree in SPL stage. To fix the issues CONFIG_SPL_OF_TRANSLATE must be set to handle the synced bus addresses correctly. A custom U-Boot device tree is also needed since the SPL build removes bus properties from bus nodes which are not explicitly marked with the u-boot,dm-spl or u-boot,dm-pre-reloc flag. Therefore all parent buses of the in the SPL needed devices must be marked with u-boot,dm-pre-reloc. Also since there is no driver for "ti,sysc" compatible property in SPL the buses marked with this compatible string must also be marked with compatible = "simple-bus" to make the underlying devices visible in SPL. Otherwise the matching device drivers aren't found and the uclass drivers are dropped. Signed-off-by: Bernhard Messerklinger Reviewed-by: Wolfgang Wallner --- arch/arm/dts/am335x-brppt1-mmc-u-boot.dtsi | 80 ++++++++++++++++++++++ configs/brppt1_mmc_defconfig | 2 +- 2 files changed, 81 insertions(+), 1 deletion(-) create mode 100644 arch/arm/dts/am335x-brppt1-mmc-u-boot.dtsi diff --git a/arch/arm/dts/am335x-brppt1-mmc-u-boot.dtsi b/arch/arm/dts/am335x-brppt1-mmc-u-boot.dtsi new file mode 100644 index 0000000000..0b9a1ccef4 --- /dev/null +++ b/arch/arm/dts/am335x-brppt1-mmc-u-boot.dtsi @@ -0,0 +1,80 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2022 B&R Industrial Automation GmbH - + * https://www.br-automation.com/ + */ + +/ { + ocp { + u-boot,dm-pre-reloc; + }; +}; + +&l4_wkup { + u-boot,dm-pre-reloc; + segment@200000 { + u-boot,dm-pre-reloc; + target-module@0 + { + u-boot,dm-pre-reloc; + compatible = "simple-bus"; + }; + target-module@7000 { + u-boot,dm-pre-reloc; + compatible = "simple-bus"; + }; + target-module@9000 { + u-boot,dm-pre-reloc; + compatible = "simple-bus"; + }; + }; +}; + +&wkup_cm { + u-boot,dm-pre-reloc; +}; + +&l4_wkup_clkctrl { + u-boot,dm-pre-reloc; +}; + +&l4_per { + u-boot,dm-pre-reloc; + segment@0 { + u-boot,dm-pre-reloc; + compatible = "simple-bus"; + target-module@4c000 { + u-boot,dm-pre-reloc; + compatible = "simple-bus"; + }; + }; + + segment@100000 { + u-boot,dm-pre-reloc; + compatible = "simple-bus"; + target-module@ac000 { + u-boot,dm-pre-reloc; + compatible = "simple-bus"; + }; + target-module@ae000 { + u-boot,dm-pre-reloc; + compatible = "simple-bus"; + }; + }; +}; + +&prcm { + u-boot,dm-pre-reloc; +}; + +&gpio0_target { + u-boot,dm-pre-reloc; +}; + +&prcm_clocks { + compatible = "simple-bus"; +}; + +&scm_clocks { + compatible = "simple-bus"; +}; diff --git a/configs/brppt1_mmc_defconfig b/configs/brppt1_mmc_defconfig index b1ed2bcd68..716650aac9 100644 --- a/configs/brppt1_mmc_defconfig +++ b/configs/brppt1_mmc_defconfig @@ -90,7 +90,7 @@ CONFIG_NETCONSOLE=y CONFIG_DM=y CONFIG_SPL_DM=y CONFIG_SPL_DM_SEQ_ALIAS=y -# CONFIG_OF_TRANSLATE is not set +CONFIG_SPL_OF_TRANSLATE=y CONFIG_BOOTCOUNT_LIMIT=y CONFIG_DM_I2C=y CONFIG_I2C_SET_DEFAULT_BUS_NUM=y From febd82c45e8ca1841659e9c13cb0acd38463bc46 Mon Sep 17 00:00:00 2001 From: Bernhard Messerklinger Date: Thu, 25 Aug 2022 08:54:02 +0200 Subject: [PATCH 161/374] brppt1: Cleanup device tree * Remove unnecessary device tree nodes which are not needed in U-Boot directly. * Move all U-Boot specific device tree properties to u-boot dtsi. Signed-off-by: Bernhard Messerklinger Reviewed-by: Wolfgang Wallner --- arch/arm/dts/am335x-brppt1-mmc-u-boot.dtsi | 32 ++++ arch/arm/dts/am335x-brppt1-mmc.dts | 201 --------------------- 2 files changed, 32 insertions(+), 201 deletions(-) diff --git a/arch/arm/dts/am335x-brppt1-mmc-u-boot.dtsi b/arch/arm/dts/am335x-brppt1-mmc-u-boot.dtsi index 0b9a1ccef4..a3d5650e48 100644 --- a/arch/arm/dts/am335x-brppt1-mmc-u-boot.dtsi +++ b/arch/arm/dts/am335x-brppt1-mmc-u-boot.dtsi @@ -78,3 +78,35 @@ &scm_clocks { compatible = "simple-bus"; }; + +&i2c0 { + u-boot,dm-pre-reloc; +}; + +&uart0 { + u-boot,dm-pre-reloc; +}; + +&mmc1 { + u-boot,dm-pre-reloc; +}; + +&mmc2 { + u-boot,dm-pre-reloc; +}; + +&gpio0 { + u-boot,dm-pre-reloc; +}; + +&gpio1 { + u-boot,dm-pre-reloc; +}; + +&gpio2 { + u-boot,dm-pre-reloc; +}; + +&gpio3 { + u-boot,dm-pre-reloc; +}; diff --git a/arch/arm/dts/am335x-brppt1-mmc.dts b/arch/arm/dts/am335x-brppt1-mmc.dts index bd2f6c2e3e..4db279b65e 100644 --- a/arch/arm/dts/am335x-brppt1-mmc.dts +++ b/arch/arm/dts/am335x-brppt1-mmc.dts @@ -12,25 +12,10 @@ model = "BRPPT1 (MMC) Panel"; compatible = "ti,am33xx"; - fset: factory-settings { - bl-version = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456890"; - version = <0x0100>; - order-no = "6PPT30 (MMC)"; - hw-revision = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456890"; - serial-no = "0"; - device-id = <0x0>; - parent-id = <0x0>; - hw-variant = <0x1>; - }; aliases { - ds1bkl0 = &pwmbacklight; - ds1bkl1 = &tps_bl; - ds1timing = &timing0; - ds1ctrl = &lcdc; gpmc = &gpmc; mmc = &mmc2; - fset = &fset; }; chosen { @@ -43,110 +28,21 @@ reg = <0x80000000 0x10000000>; /* 256 MB */ }; - panel { - status = "disabled"; - - compatible = "ti,tilcdc,panel"; - enable-gpios = <&gpio0 6 GPIO_ACTIVE_LOW>; - - backlight = <&pwmbacklight>; - bkl-pwm = <&pwmbacklight>; - bkl-tps = <&tps_bl>; - - panel-info { - ac-bias = <255>; - ac-bias-intrpt = <0>; - dma-burst-sz = <16>; - bpp = <32>; - fdd = <0x80>; - sync-edge = <0>; - sync-ctrl = <1>; - raster-order = <0>; - fifo-th = <0>; - }; - - display-timings { - native-mode = <&timing0>; - timing0: lcd { - clock-frequency = <32000000>; - hactive = <800>; - vactive = <480>; - hfront-porch = <2>; - hback-porch = <192>; - hsync-len = <1>; - vfront-porch = <20>; - vback-porch = <2>; - vsync-len = <1>; - hsync-active = <1>; - vsync-active = <1>; - pupdelay = <10>; - pondelay = <10>; - }; - }; - }; - vmmcsd_fixed: fixedregulator@0 { compatible = "regulator-fixed"; regulator-name = "vmmcsd_fixed"; regulator-min-microvolt = <3300000>; regulator-max-microvolt = <3300000>; }; - - pwm0: omap-pwm@timer5 { - compatible = "ti,omap-dmtimer-pwm"; - ti,timers = <&timer5>; - #pwm-cells = <3>; - }; - - pwm1: omap-pwm@timer6 { - compatible = "ti,omap-dmtimer-pwm"; - ti,timers = <&timer6>; - #pwm-cells = <3>; - }; - - beeper: pwm-beep { - compatible = "pwm-beeper"; - pwms = <&pwm0 0 0 0>; - }; - - pwmbacklight: pwm-bkl { - compatible = "pwm-backlight"; - pwms = <&pwm1 0 5000000 0>; - - default-brightness-level = <255>; - brightness-levels = <0 16 32 64 128 170 202 234 255>; - - power-supply = <&vmmcsd_fixed>; - enable-gpios = <&gpio0 7 GPIO_ACTIVE_HIGH>; - }; }; &uart0 { /* console uart */ - u-boot,dm-spl; - status = "okay"; -}; - -&uart1 { status = "okay"; }; &i2c0 { - u-boot,dm-spl; status = "okay"; clock-frequency = <400000>; - - tps: tps@24 { /* PMIC controller */ - u-boot,dm-spl; - reg = <0x24>; - compatible = "ti,tps65217"; - - tps_bl: backlight { - compatible = "ti,tps65217-bl"; - isel = <1>; /* 1 - ISET1, 2 ISET2 */ - fdim = <1000>; /* TPS65217_BL_FDIM_1kHZ */ - default-brightness = <50>; - }; - }; }; &i2c2 { @@ -158,10 +54,6 @@ status = "okay"; }; -&cppi41dma { - status = "okay"; -}; - &usb { status = "okay"; }; @@ -217,7 +109,6 @@ }; &mmc1 { - u-boot,dm-spl; vmmc-supply = <&vmmcsd_fixed>; bus-width = <0x4>; ti,non-removable; @@ -227,7 +118,6 @@ }; &mmc2 { - u-boot,dm-spl; vmmc-supply = <&vmmcsd_fixed>; bus-width = <0x8>; ti,non-removable; @@ -236,79 +126,22 @@ status = "okay"; }; -&l4_per { - - segment@300000 { - - target-module@e000 { - u-boot,dm-pre-reloc; - - lcdc: lcdc@0 { - u-boot,dm-pre-reloc; - status = "disabled"; - }; - }; - }; -}; - -&elm { - status = "okay"; -}; - -&sham { - status = "okay"; -}; - -&aes { - status = "okay"; -}; - &gpio0 { - u-boot,dm-spl; ti,no-reset-on-init; }; &gpio1 { - u-boot,dm-spl; ti,no-reset-on-init; }; &gpio2 { - u-boot,dm-spl; ti,no-reset-on-init; }; &gpio3 { - u-boot,dm-spl; ti,no-reset-on-init; }; -&wdt2 { - ti,no-reset-on-init; - ti,no-idle-on-init; -}; - -&tscadc { - status = "okay"; - tsc { - ti,wires = <4>; - ti,x-plate-resistance = <200>; - ti,zx-cutoff-ratio = <40>; - ti,min_deviation = <60>; - ti,max_deviation = <600>; - ti,coordinate-readouts = <5>; - ti,wire-config = <0x00 0x11 0x22 0x33>; - - bnr-buttons { - Home-Button {}; - }; - }; - - adc { - ti,adc-channels = <5 6 7>; - }; -}; - &timer6 { /* used for cpsw end device */ status = "okay"; ti,no-reset-on-init; @@ -320,37 +153,3 @@ ti,no-reset-on-init; ti,no-idle-on-init; }; - -&wdt2 { - status = "okay"; - ti,no-reset-on-init; - ti,no-idle-on-init; -}; - -&epwmss0 { - status = "okay"; -}; - -&tscadc { - status = "okay"; -}; - -&dcan0 { - status = "okay"; -}; - -&dcan1 { - status = "okay"; -}; - -&sham { - status = "disabled"; -}; - -&aes { - status = "disabled"; -}; - -&rng { - status = "disabled"; -}; From 0daeadbbd2513a9f79dae113aa47e1a71e5d9153 Mon Sep 17 00:00:00 2001 From: Bernhard Messerklinger Date: Thu, 25 Aug 2022 08:54:03 +0200 Subject: [PATCH 162/374] include: configs: brppt1: Fix commit 0ea4fc4dcf90 Commit 0ea4fc4dcf90 ("board/BuR: invalidate ${dtbaddr} before cfgscr") destroys the boot targets b_t30lgcy#0 and b_t30lgcy#1. The reason behind this is, that b_t30lgcy#0 and b_t30lgcy#1 both load the for booting needed device trees from mmc and the cfgscr script patches those. Because of this, cfgscr is not allowed to destroy the previously loaded device tree otherwise cfgscr will fail. This patch moves the device trees invalidation on warm restart to the PREBOOT cmd to fix that issue. Fixes: 0ea4fc4dcf90 ("board/BuR: invalidate ${dtbaddr} before cfgscr") Signed-off-by: Bernhard Messerklinger Reviewed-by: Wolfgang Wallner --- configs/brppt1_mmc_defconfig | 2 +- include/configs/brppt1.h | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/configs/brppt1_mmc_defconfig b/configs/brppt1_mmc_defconfig index 716650aac9..6da6d58bfd 100644 --- a/configs/brppt1_mmc_defconfig +++ b/configs/brppt1_mmc_defconfig @@ -26,7 +26,7 @@ CONFIG_BOOTDELAY=0 CONFIG_USE_BOOTCOMMAND=y CONFIG_BOOTCOMMAND="run b_default" CONFIG_USE_PREBOOT=y -CONFIG_PREBOOT="run cfgscr; run brdefaultip" +CONFIG_PREBOOT="mw ${dtbaddr} 0; run cfgscr; run brdefaultip" CONFIG_SYS_CONSOLE_IS_IN_ENV=y CONFIG_SYS_CONSOLE_OVERWRITE_ROUTINE=y CONFIG_SYS_CONSOLE_INFO_QUIET=y diff --git a/include/configs/brppt1.h b/include/configs/brppt1.h index 481473ae2c..aaf3f8b4a5 100644 --- a/include/configs/brppt1.h +++ b/include/configs/brppt1.h @@ -53,7 +53,6 @@ #ifdef CONFIG_ENV_IS_IN_MMC #define MMCTGTS \ MMC_TGTS \ -"cfgscr=mw ${dtbaddr} 0;" \ " mmc dev 1; mmc read ${cfgaddr} 200 80; source ${cfgaddr};" \ " fdt addr ${dtbaddr} || cp ${fdtcontroladdr} ${dtbaddr} 4000\0" #else From c79c0b46924c748c7618e113cf6feb304d1a0ee0 Mon Sep 17 00:00:00 2001 From: Bernhard Messerklinger Date: Thu, 25 Aug 2022 08:54:04 +0200 Subject: [PATCH 163/374] brppt1: Update environment to support new boot concept * Drop legacy /boot/PPTImage.md5 check * Update device tree naming * Update t30args#0 root cmd line property to support latest kernel versions (root=/dev/mmcblk0p2 for linux < 4 and root=/dev/mmcblk1p2 for linux >= 4) * Add custom bootloader version string * Destroy invalid dtb at ${dtbaddr} and configuration script at ${cfgaddr} to ensure proper boot in warm restart case. Signed-off-by: Bernhard Messerklinger Reviewed-by: Wolfgang Wallner --- configs/brppt1_mmc_defconfig | 4 +++- include/configs/brppt1.h | 18 ++++++++++++------ 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/configs/brppt1_mmc_defconfig b/configs/brppt1_mmc_defconfig index 6da6d58bfd..a45604de16 100644 --- a/configs/brppt1_mmc_defconfig +++ b/configs/brppt1_mmc_defconfig @@ -17,6 +17,8 @@ CONFIG_SPL_SERIAL=y CONFIG_SPL=y CONFIG_ENV_OFFSET_REDUND=0x50000 CONFIG_SYS_LOAD_ADDR=0x80000000 +CONFIG_LOCALVERSION="-2.0.0" +# CONFIG_LOCALVERSION_AUTO is not set CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0x4030ff00 # CONFIG_EXPERT is not set @@ -26,7 +28,7 @@ CONFIG_BOOTDELAY=0 CONFIG_USE_BOOTCOMMAND=y CONFIG_BOOTCOMMAND="run b_default" CONFIG_USE_PREBOOT=y -CONFIG_PREBOOT="mw ${dtbaddr} 0; run cfgscr; run brdefaultip" +CONFIG_PREBOOT="mw ${cfgaddr} 0; mw ${dtbaddr} 0; run cfgscr; run brdefaultip" CONFIG_SYS_CONSOLE_IS_IN_ENV=y CONFIG_SYS_CONSOLE_OVERWRITE_ROUTINE=y CONFIG_SYS_CONSOLE_INFO_QUIET=y diff --git a/include/configs/brppt1.h b/include/configs/brppt1.h index aaf3f8b4a5..2c5236aa58 100644 --- a/include/configs/brppt1.h +++ b/include/configs/brppt1.h @@ -29,18 +29,16 @@ #define MMC_TGTS \ "t30args#0=setenv bootargs ${optargs_rot} ${optargs} console=${console} " \ - "b_mode=${b_mode} root=/dev/mmcblk0p2 rootfstype=ext4\0" \ + "b_mode=${b_mode} root=${root_dev} rootfstype=ext4 rootwait\0" \ "b_t30lgcy#0=" \ - "load ${loaddev}:2 ${loadaddr} /boot/PPTImage.md5 && " \ "load ${loaddev}:2 ${loadaddr} /boot/zImage && " \ - "load ${loaddev}:2 ${dtbaddr} /boot/am335x-ppt30.dtb || " \ - "load ${loaddev}:1 ${dtbaddr} am335x-ppt30-legacy.dtb; "\ + "run load_dtb && " \ "run t30args#0; run cfgscr; bootz ${loadaddr} - ${dtbaddr}\0" \ "t30args#1=setenv bootargs ${optargs_rot} ${optargs} console=${console} " \ "b_mode=${b_mode}\0" \ "b_t30lgcy#1=" \ "load ${loaddev}:1 ${loadaddr} zImage && " \ - "load ${loaddev}:1 ${dtbaddr} am335x-ppt30.dtb && " \ + "load ${loaddev}:1 ${dtbaddr} am335x-brppt30.dtb && " \ "load ${loaddev}:1 ${ramaddr} rootfsPPT30.uboot && " \ "run t30args#1; run cfgscr; bootz ${loadaddr} ${ramaddr} ${dtbaddr}\0" \ "b_mmc0=load ${loaddev}:1 ${scraddr} bootscr.img && source ${scraddr}\0" \ @@ -48,11 +46,19 @@ "b_tgts_std=mmc0 mmc1 t30lgcy#0 t30lgcy#1 usb0 net\0" \ "b_tgts_rcy=t30lgcy#1 usb0 net\0" \ "b_tgts_pme=net usb0 mmc0 mmc1\0" \ -"loaddev=mmc 1\0" +"loaddev=mmc 1\0" \ +"root_dev=/dev/mmcblk0p2\0" \ +"load_dtb=load ${loaddev}:2 ${dtbaddr} /boot/am335x-brppt30.dtb; " \ + "if test $? -eq 0; then " \ + "setenv root_dev /dev/mmcblk1p2; " \ + "else; " \ + "load ${loaddev}:1 ${dtbaddr} am335x-brppt30-legacy.dtb; " \ + "fi;\0" #ifdef CONFIG_ENV_IS_IN_MMC #define MMCTGTS \ MMC_TGTS \ +"cfgscr=mw ${cfgaddr} 0;" \ " mmc dev 1; mmc read ${cfgaddr} 200 80; source ${cfgaddr};" \ " fdt addr ${dtbaddr} || cp ${fdtcontroladdr} ${dtbaddr} 4000\0" #else From 360c7f46f39242bab1d5bae3cd7b1d16fc33c304 Mon Sep 17 00:00:00 2001 From: Andrew Davis Date: Tue, 30 Aug 2022 15:54:29 +0530 Subject: [PATCH 164/374] configs: Add configs for J7200 High Security EVM Add J7200 High Security EVM defconfig. These defconfigs are the same as for the non-secure part, except for: CONFIG_TI_SECURE_DEVICE option set to 'y' CONFIG_BOOTCOMMAND uses FIT images for booting Signed-off-by: Andrew Davis [j-choudhary@ti.com: add few configs from GP variant which were missing] Signed-off-by: Jayesh Choudhary --- MAINTAINERS | 4 +- configs/j7200_hs_evm_a72_defconfig | 208 +++++++++++++++++++++++++++++ configs/j7200_hs_evm_r5_defconfig | 172 ++++++++++++++++++++++++ 3 files changed, 383 insertions(+), 1 deletion(-) create mode 100644 configs/j7200_hs_evm_a72_defconfig create mode 100644 configs/j7200_hs_evm_r5_defconfig diff --git a/MAINTAINERS b/MAINTAINERS index 25a11a06c6..d66e3825b1 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1389,8 +1389,10 @@ F: configs/k2g_hs_evm_defconfig F: configs/k2l_hs_evm_defconfig F: configs/am65x_hs_evm_r5_defconfig F: configs/am65x_hs_evm_a53_defconfig -F: configs/j721e_hs_evm_r5_defconfig +F: configs/j7200_hs_evm_a72_defconfig +F: configs/j7200_hs_evm_r5_defconfig F: configs/j721e_hs_evm_a72_defconfig +F: configs/j721e_hs_evm_r5_defconfig TPM DRIVERS M: Ilias Apalodimas diff --git a/configs/j7200_hs_evm_a72_defconfig b/configs/j7200_hs_evm_a72_defconfig new file mode 100644 index 0000000000..0583a2ab62 --- /dev/null +++ b/configs/j7200_hs_evm_a72_defconfig @@ -0,0 +1,208 @@ +CONFIG_ARM=y +CONFIG_ARCH_K3=y +CONFIG_TI_SECURE_DEVICE=y +CONFIG_SYS_MALLOC_LEN=0x2000000 +CONFIG_SYS_MALLOC_F_LEN=0x8000 +CONFIG_SPL_GPIO=y +CONFIG_SPL_LIBCOMMON_SUPPORT=y +CONFIG_SPL_LIBGENERIC_SUPPORT=y +CONFIG_NR_DRAM_BANKS=2 +CONFIG_SOC_K3_J721E=y +CONFIG_TARGET_J7200_A72_EVM=y +CONFIG_ENV_SIZE=0x20000 +CONFIG_ENV_OFFSET=0x680000 +CONFIG_DM_GPIO=y +CONFIG_SPL_DM_SPI=y +CONFIG_DEFAULT_DEVICE_TREE="k3-j7200-common-proc-board" +CONFIG_SPL_TEXT_BASE=0x80080000 +CONFIG_SPL_MMC=y +CONFIG_SPL_SERIAL=y +CONFIG_SPL_DRIVERS_MISC=y +CONFIG_SPL_STACK_R_ADDR=0x82000000 +CONFIG_ENV_OFFSET_REDUND=0x6A0000 +CONFIG_SPL_FS_FAT=y +CONFIG_SPL_LIBDISK_SUPPORT=y +CONFIG_SPL_SPI_FLASH_SUPPORT=y +CONFIG_SPL_SPI=y +# CONFIG_PSCI_RESET is not set +CONFIG_DISTRO_DEFAULTS=y +CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y +CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0x80480000 +# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set +CONFIG_SPL_LOAD_FIT=y +CONFIG_SPL_LOAD_FIT_ADDRESS=0x81000000 +CONFIG_FIT_IMAGE_POST_PROCESS=y +CONFIG_SPL_FIT_IMAGE_POST_PROCESS=y +# CONFIG_USE_SPL_FIT_GENERATOR is not set +CONFIG_OF_BOARD_SETUP=y +CONFIG_BOOTCOMMAND="run findfdt; run envboot; run init_${boot}; run boot_rprocs; run get_fit_${boot}; run get_overlaystring; run run_fit" +CONFIG_LOGLEVEL=7 +CONFIG_SPL_MAX_SIZE=0xc0000 +CONFIG_SPL_HAS_BSS_LINKER_SECTION=y +CONFIG_SPL_BSS_START_ADDR=0x80a00000 +CONFIG_SPL_BSS_MAX_SIZE=0x80000 +CONFIG_SPL_BOARD_INIT=y +CONFIG_SPL_SYS_MALLOC_SIMPLE=y +CONFIG_SPL_STACK_R=y +CONFIG_SYS_SPL_MALLOC=y +CONFIG_SYS_SPL_MALLOC_SIZE=0x800000 +CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR=y +CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR=0x1400 +CONFIG_SPL_DMA=y +CONFIG_SPL_ENV_SUPPORT=y +CONFIG_SPL_FS_LOAD_PAYLOAD_NAME="u-boot.img" +CONFIG_SPL_I2C=y +CONFIG_SPL_DM_MAILBOX=y +CONFIG_SPL_MTD_SUPPORT=y +CONFIG_SPL_DM_SPI_FLASH=y +CONFIG_SPL_NOR_SUPPORT=y +CONFIG_SPL_DM_RESET=y +CONFIG_SPL_POWER_DOMAIN=y +CONFIG_SPL_RAM_SUPPORT=y +CONFIG_SPL_RAM_DEVICE=y +# CONFIG_SPL_SPI_FLASH_TINY is not set +CONFIG_SPL_SPI_FLASH_SFDP_SUPPORT=y +CONFIG_SPL_SPI_LOAD=y +CONFIG_SYS_SPI_U_BOOT_OFFS=0x280000 +CONFIG_SPL_USB_GADGET=y +CONFIG_SPL_DFU=y +CONFIG_SPL_YMODEM_SUPPORT=y +CONFIG_SYS_MAXARGS=64 +CONFIG_CMD_ASKENV=y +CONFIG_CMD_DFU=y +# CONFIG_CMD_FLASH is not set +CONFIG_CMD_GPIO=y +CONFIG_CMD_GPT=y +CONFIG_CMD_I2C=y +CONFIG_CMD_MMC=y +CONFIG_CMD_MTD=y +CONFIG_CMD_REMOTEPROC=y +CONFIG_CMD_UFS=y +CONFIG_CMD_USB=y +CONFIG_CMD_USB_MASS_STORAGE=y +# CONFIG_CMD_SETEXPR is not set +CONFIG_CMD_TIME=y +CONFIG_CMD_EXT4_WRITE=y +CONFIG_MTDIDS_DEFAULT="nor0=47040000.spi.0,nor0=47034000.hyperbus" +CONFIG_MTDPARTS_DEFAULT="mtdparts=47040000.spi.0:512k(ospi.tiboot3),2m(ospi.tispl),4m(ospi.u-boot),128k(ospi.env),128k(ospi.env.backup),1m(ospi.sysfw),-@8m(ospi.rootfs);47034000.hyperbus:512k(hbmc.tiboot3),2m(hbmc.tispl),4m(hbmc.u-boot),256k(hbmc.env),1m(hbmc.sysfw),-@8m(hbmc.rootfs)" +CONFIG_CMD_UBI=y +# CONFIG_ISO_PARTITION is not set +# CONFIG_SPL_EFI_PARTITION is not set +CONFIG_OF_CONTROL=y +CONFIG_SPL_OF_CONTROL=y +CONFIG_SPL_MULTI_DTB_FIT=y +CONFIG_SPL_MULTI_DTB_FIT_NO_COMPRESSION=y +CONFIG_ENV_OVERWRITE=y +CONFIG_ENV_IS_IN_MMC=y +CONFIG_SYS_REDUNDAND_ENVIRONMENT=y +CONFIG_SYS_RELOC_GD_ENV_ADDR=y +CONFIG_NET_RANDOM_ETHADDR=y +CONFIG_DM=y +CONFIG_SPL_DM=y +CONFIG_SPL_DM_SEQ_ALIAS=y +CONFIG_REGMAP=y +CONFIG_SPL_REGMAP=y +CONFIG_SYSCON=y +CONFIG_SPL_SYSCON=y +CONFIG_SPL_OF_TRANSLATE=y +CONFIG_CLK=y +CONFIG_SPL_CLK=y +CONFIG_CLK_CCF=y +CONFIG_CLK_TI_SCI=y +CONFIG_DFU_MMC=y +CONFIG_DFU_RAM=y +CONFIG_DFU_SF=y +CONFIG_SYS_DFU_DATA_BUF_SIZE=0x40000 +CONFIG_SYS_DFU_MAX_FILE_SIZE=0x800000 +CONFIG_DMA_CHANNELS=y +CONFIG_TI_K3_NAVSS_UDMA=y +CONFIG_USB_FUNCTION_FASTBOOT=y +CONFIG_FASTBOOT_BUF_ADDR=0x82000000 +CONFIG_FASTBOOT_BUF_SIZE=0x2F000000 +CONFIG_FASTBOOT_FLASH=y +CONFIG_FASTBOOT_FLASH_MMC_DEV=0 +CONFIG_FASTBOOT_CMD_OEM_FORMAT=y +CONFIG_TI_SCI_PROTOCOL=y +CONFIG_DA8XX_GPIO=y +CONFIG_DM_PCA953X=y +CONFIG_DM_I2C=y +CONFIG_DM_I2C_GPIO=y +CONFIG_SYS_I2C_OMAP24XX=y +CONFIG_DM_MAILBOX=y +CONFIG_K3_SEC_PROXY=y +CONFIG_SUPPORT_EMMC_BOOT=y +CONFIG_MMC_IO_VOLTAGE=y +CONFIG_MMC_UHS_SUPPORT=y +CONFIG_MMC_HS400_SUPPORT=y +CONFIG_SPL_MMC_HS400_SUPPORT=y +CONFIG_MMC_SDHCI=y +CONFIG_MMC_SDHCI_ADMA=y +CONFIG_SPL_MMC_SDHCI_ADMA=y +CONFIG_MMC_SDHCI_AM654=y +CONFIG_MTD=y +CONFIG_DM_MTD=y +CONFIG_MTD_NOR_FLASH=y +CONFIG_CFI_FLASH=y +CONFIG_SYS_FLASH_USE_BUFFER_WRITE=y +CONFIG_FLASH_CFI_MTD=y +CONFIG_SYS_FLASH_CFI=y +CONFIG_HBMC_AM654=y +CONFIG_SYS_MAX_FLASH_BANKS_DETECT=y +CONFIG_DM_SPI_FLASH=y +CONFIG_SPI_FLASH_STMICRO=y +# CONFIG_SPI_FLASH_USE_4K_SECTORS is not set +CONFIG_SPI_FLASH_MTD=y +CONFIG_MULTIPLEXER=y +CONFIG_MUX_MMIO=y +CONFIG_PHY_FIXED=y +CONFIG_DM_ETH=y +CONFIG_TI_AM65_CPSW_NUSS=y +CONFIG_PHY=y +CONFIG_SPL_PHY=y +CONFIG_PHY_CADENCE_TORRENT=y +CONFIG_PHY_J721E_WIZ=y +CONFIG_PINCTRL=y +# CONFIG_PINCTRL_GENERIC is not set +CONFIG_SPL_PINCTRL=y +# CONFIG_SPL_PINCTRL_GENERIC is not set +CONFIG_PINCTRL_SINGLE=y +CONFIG_POWER_DOMAIN=y +CONFIG_TI_SCI_POWER_DOMAIN=y +CONFIG_DM_REGULATOR=y +CONFIG_DM_REGULATOR_FIXED=y +CONFIG_DM_REGULATOR_GPIO=y +CONFIG_RAM=y +CONFIG_SPL_RAM=y +CONFIG_REMOTEPROC_TI_K3_R5F=y +CONFIG_DM_RESET=y +CONFIG_RESET_TI_SCI=y +CONFIG_SCSI=y +CONFIG_DM_SCSI=y +CONFIG_DM_SERIAL=y +CONFIG_SOC_DEVICE=y +CONFIG_SOC_DEVICE_TI_K3=y +CONFIG_SOC_TI=y +CONFIG_SPI=y +CONFIG_DM_SPI=y +CONFIG_CADENCE_QSPI=y +CONFIG_HAS_CQSPI_REF_CLK=y +CONFIG_CQSPI_REF_CLK=133333333 +CONFIG_SYSRESET=y +CONFIG_SPL_SYSRESET=y +CONFIG_SYSRESET_TI_SCI=y +CONFIG_USB=y +CONFIG_DM_USB_GADGET=y +CONFIG_SPL_DM_USB_GADGET=y +CONFIG_USB_XHCI_HCD=y +CONFIG_USB_CDNS3=y +CONFIG_USB_CDNS3_GADGET=y +CONFIG_USB_CDNS3_HOST=y +CONFIG_SPL_USB_CDNS3_GADGET=y +CONFIG_USB_GADGET=y +CONFIG_USB_GADGET_MANUFACTURER="Texas Instruments" +CONFIG_USB_GADGET_VENDOR_NUM=0x0451 +CONFIG_USB_GADGET_PRODUCT_NUM=0x6164 +CONFIG_UFS=y +CONFIG_CADENCE_UFS=y +CONFIG_TI_J721E_UFS=y +CONFIG_OF_LIBFDT_OVERLAY=y diff --git a/configs/j7200_hs_evm_r5_defconfig b/configs/j7200_hs_evm_r5_defconfig new file mode 100644 index 0000000000..975cbb8a50 --- /dev/null +++ b/configs/j7200_hs_evm_r5_defconfig @@ -0,0 +1,172 @@ +CONFIG_ARM=y +CONFIG_ARCH_K3=y +CONFIG_TI_SECURE_DEVICE=y +CONFIG_SYS_MALLOC_LEN=0x2000000 +CONFIG_SYS_MALLOC_F_LEN=0x70000 +CONFIG_SPL_GPIO=y +CONFIG_SPL_LIBCOMMON_SUPPORT=y +CONFIG_SPL_LIBGENERIC_SUPPORT=y +CONFIG_SOC_K3_J721E=y +CONFIG_K3_EARLY_CONS=y +CONFIG_TARGET_J7200_R5_EVM=y +CONFIG_ENV_SIZE=0x20000 +CONFIG_DM_GPIO=y +CONFIG_SPL_DM_SPI=y +CONFIG_DEFAULT_DEVICE_TREE="k3-j7200-r5-common-proc-board" +CONFIG_SPL_TEXT_BASE=0x41c00000 +CONFIG_SPL_MMC=y +CONFIG_SPL_SERIAL=y +CONFIG_SPL_DRIVERS_MISC=y +CONFIG_SPL_STACK_R_ADDR=0x82000000 +CONFIG_SPL_FS_FAT=y +CONFIG_SPL_LIBDISK_SUPPORT=y +CONFIG_SPL_SPI_FLASH_SUPPORT=y +CONFIG_SPL_SPI=y +CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y +CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0x41cf5bfc +# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set +CONFIG_SPL_LOAD_FIT=y +CONFIG_SPL_LOAD_FIT_ADDRESS=0x80080000 +CONFIG_SPL_FIT_IMAGE_POST_PROCESS=y +# CONFIG_USE_SPL_FIT_GENERATOR is not set +CONFIG_USE_BOOTCOMMAND=y +# CONFIG_DISPLAY_CPUINFO is not set +CONFIG_SPL_MAX_SIZE=0xc0000 +CONFIG_SPL_HAS_BSS_LINKER_SECTION=y +CONFIG_SPL_BSS_START_ADDR=0x41cf5bfc +CONFIG_SPL_BSS_MAX_SIZE=0xa000 +CONFIG_SPL_BOARD_INIT=y +CONFIG_SPL_STACK_R=y +CONFIG_SPL_SEPARATE_BSS=y +CONFIG_SYS_SPL_MALLOC=y +CONFIG_HAS_CUSTOM_SPL_MALLOC_START=y +CONFIG_CUSTOM_SYS_SPL_MALLOC_ADDR=0x84000000 +CONFIG_SYS_SPL_MALLOC_SIZE=0x1000000 +CONFIG_SPL_EARLY_BSS=y +CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR=y +CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR=0x400 +CONFIG_SPL_DMA=y +CONFIG_SPL_ENV_SUPPORT=y +CONFIG_SPL_FS_EXT4=y +CONFIG_SPL_I2C=y +CONFIG_SPL_DM_MAILBOX=y +CONFIG_SPL_MTD_SUPPORT=y +CONFIG_SPL_DM_SPI_FLASH=y +CONFIG_SPL_NOR_SUPPORT=y +CONFIG_SPL_DM_RESET=y +CONFIG_SPL_POWER_DOMAIN=y +CONFIG_SPL_RAM_SUPPORT=y +CONFIG_SPL_RAM_DEVICE=y +CONFIG_SPL_REMOTEPROC=y +# CONFIG_SPL_SPI_FLASH_TINY is not set +CONFIG_SPL_SPI_FLASH_SFDP_SUPPORT=y +CONFIG_SPL_SPI_LOAD=y +CONFIG_SYS_SPI_U_BOOT_OFFS=0x80000 +CONFIG_SPL_USB_GADGET=y +CONFIG_SPL_DFU=y +CONFIG_SPL_YMODEM_SUPPORT=y +CONFIG_HUSH_PARSER=y +CONFIG_SYS_MAXARGS=64 +CONFIG_SYS_BOOTM_LEN=0x4000000 +CONFIG_CMD_DFU=y +# CONFIG_CMD_FLASH is not set +CONFIG_CMD_GPT=y +CONFIG_CMD_MMC=y +CONFIG_CMD_REMOTEPROC=y +# CONFIG_CMD_SETEXPR is not set +CONFIG_CMD_TIME=y +CONFIG_CMD_FAT=y +CONFIG_OF_CONTROL=y +CONFIG_SPL_OF_CONTROL=y +CONFIG_SYS_RELOC_GD_ENV_ADDR=y +CONFIG_DM=y +CONFIG_SPL_DM=y +CONFIG_SPL_DM_SEQ_ALIAS=y +CONFIG_REGMAP=y +CONFIG_SPL_REGMAP=y +CONFIG_SYSCON=y +CONFIG_SPL_SYSCON=y +CONFIG_SPL_OF_TRANSLATE=y +CONFIG_CLK=y +CONFIG_SPL_CLK=y +CONFIG_SPL_CLK_CCF=y +CONFIG_SPL_CLK_K3_PLL=y +CONFIG_SPL_CLK_K3=y +CONFIG_SYS_DFU_DATA_BUF_SIZE=0x40000 +CONFIG_DMA_CHANNELS=y +CONFIG_TI_K3_NAVSS_UDMA=y +CONFIG_TI_SCI_PROTOCOL=y +CONFIG_DA8XX_GPIO=y +CONFIG_DM_PCA953X=y +CONFIG_DM_I2C=y +CONFIG_I2C_SET_DEFAULT_BUS_NUM=y +CONFIG_SYS_I2C_OMAP24XX=y +CONFIG_DM_MAILBOX=y +CONFIG_K3_SEC_PROXY=y +CONFIG_FS_LOADER=y +CONFIG_SPL_FS_LOADER=y +CONFIG_K3_AVS0=y +CONFIG_SUPPORT_EMMC_BOOT=y +CONFIG_SPL_MMC_HS400_SUPPORT=y +CONFIG_MMC_SDHCI=y +CONFIG_SPL_MMC_SDHCI_ADMA=y +CONFIG_MMC_SDHCI_AM654=y +CONFIG_MTD=y +CONFIG_DM_MTD=y +CONFIG_MTD_NOR_FLASH=y +CONFIG_CFI_FLASH=y +CONFIG_SYS_FLASH_USE_BUFFER_WRITE=y +CONFIG_FLASH_CFI_MTD=y +CONFIG_SYS_FLASH_CFI=y +CONFIG_HBMC_AM654=y +CONFIG_SYS_MAX_FLASH_BANKS_DETECT=y +CONFIG_DM_SPI_FLASH=y +CONFIG_SPI_FLASH_SFDP_SUPPORT=y +CONFIG_SPI_FLASH_STMICRO=y +CONFIG_PINCTRL=y +# CONFIG_PINCTRL_GENERIC is not set +CONFIG_SPL_PINCTRL=y +# CONFIG_SPL_PINCTRL_GENERIC is not set +CONFIG_PINCTRL_SINGLE=y +CONFIG_POWER_DOMAIN=y +CONFIG_TI_SCI_POWER_DOMAIN=y +CONFIG_TI_POWER_DOMAIN=y +CONFIG_DM_PMIC=y +CONFIG_PMIC_TPS65941=y +CONFIG_DM_REGULATOR=y +CONFIG_SPL_DM_REGULATOR=y +CONFIG_DM_REGULATOR_TPS65941=y +CONFIG_K3_SYSTEM_CONTROLLER=y +CONFIG_REMOTEPROC_TI_K3_ARM64=y +CONFIG_DM_RESET=y +CONFIG_RESET_TI_SCI=y +CONFIG_DM_SERIAL=y +CONFIG_SOC_DEVICE=y +CONFIG_SOC_DEVICE_TI_K3=y +CONFIG_SOC_TI=y +CONFIG_SPI=y +CONFIG_DM_SPI=y +CONFIG_CADENCE_QSPI=y +CONFIG_HAS_CQSPI_REF_CLK=y +CONFIG_CQSPI_REF_CLK=133333333 +CONFIG_SYSRESET=y +CONFIG_SPL_SYSRESET=y +CONFIG_SYSRESET_TI_SCI=y +CONFIG_TIMER=y +CONFIG_SPL_TIMER=y +CONFIG_OMAP_TIMER=y +CONFIG_USB=y +CONFIG_DM_USB_GADGET=y +CONFIG_SPL_DM_USB_GADGET=y +CONFIG_USB_CDNS3=y +CONFIG_USB_CDNS3_GADGET=y +CONFIG_SPL_USB_CDNS3_GADGET=y +CONFIG_USB_GADGET=y +CONFIG_USB_GADGET_MANUFACTURER="Texas Instruments" +CONFIG_USB_GADGET_VENDOR_NUM=0x0451 +CONFIG_USB_GADGET_PRODUCT_NUM=0x6164 +CONFIG_USB_GADGET_DOWNLOAD=y +CONFIG_FS_EXT4=y +CONFIG_FS_FAT_MAX_CLUSTSIZE=16384 +CONFIG_LIB_RATIONAL=y +CONFIG_SPL_LIB_RATIONAL=y From 29e1044741e3afb17babde6bea583c6d704466c7 Mon Sep 17 00:00:00 2001 From: Jayesh Choudhary Date: Tue, 30 Aug 2022 15:54:30 +0530 Subject: [PATCH 165/374] configs: Add configs for j721s2 High Security EVM Add j721s2 High Security EVM defconfig. These configs are same as for the non-secure part, except for: CONFIG_TI_SECURE_DEVICE option set to 'y' CONFIG_FIT_IMAGE_POST_PROCESS option set to 'y' CONFIG_SPL_FIT_IMAGE_POST_PROCESS option set to 'y' CONFIG_BOOTCOMMAND uses FIT images for booting Signed-off-by: Jayesh Choudhary --- MAINTAINERS | 2 + configs/j721s2_hs_evm_a72_defconfig | 217 ++++++++++++++++++++++++++++ configs/j721s2_hs_evm_r5_defconfig | 178 +++++++++++++++++++++++ 3 files changed, 397 insertions(+) create mode 100644 configs/j721s2_hs_evm_a72_defconfig create mode 100644 configs/j721s2_hs_evm_r5_defconfig diff --git a/MAINTAINERS b/MAINTAINERS index d66e3825b1..1a7a56335f 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1393,6 +1393,8 @@ F: configs/j7200_hs_evm_a72_defconfig F: configs/j7200_hs_evm_r5_defconfig F: configs/j721e_hs_evm_a72_defconfig F: configs/j721e_hs_evm_r5_defconfig +F: configs/j721s2_hs_evm_a72_defconfig +F: configs/j721s2_hs_evm_r5_defconfig TPM DRIVERS M: Ilias Apalodimas diff --git a/configs/j721s2_hs_evm_a72_defconfig b/configs/j721s2_hs_evm_a72_defconfig new file mode 100644 index 0000000000..851c98577d --- /dev/null +++ b/configs/j721s2_hs_evm_a72_defconfig @@ -0,0 +1,217 @@ +CONFIG_ARM=y +CONFIG_ARCH_K3=y +CONFIG_TI_SECURE_DEVICE=y +CONFIG_SYS_MALLOC_LEN=0x2000000 +CONFIG_SYS_MALLOC_F_LEN=0x8000 +CONFIG_SPL_GPIO=y +CONFIG_SPL_LIBCOMMON_SUPPORT=y +CONFIG_SPL_LIBGENERIC_SUPPORT=y +CONFIG_NR_DRAM_BANKS=2 +CONFIG_SOC_K3_J721S2=y +CONFIG_TARGET_J721S2_A72_EVM=y +CONFIG_ENV_SIZE=0x20000 +CONFIG_ENV_OFFSET=0x680000 +CONFIG_DM_GPIO=y +CONFIG_SPL_DM_SPI=y +CONFIG_DEFAULT_DEVICE_TREE="k3-j721s2-common-proc-board" +CONFIG_SPL_TEXT_BASE=0x80080000 +CONFIG_SPL_MMC=y +CONFIG_SPL_SERIAL=y +CONFIG_SPL_DRIVERS_MISC=y +CONFIG_SPL_STACK_R_ADDR=0x82000000 +CONFIG_ENV_OFFSET_REDUND=0x6A0000 +CONFIG_SPL_FS_FAT=y +CONFIG_SPL_LIBDISK_SUPPORT=y +CONFIG_SPL_SPI_FLASH_SUPPORT=y +CONFIG_SPL_SPI=y +# CONFIG_PSCI_RESET is not set +CONFIG_DISTRO_DEFAULTS=y +CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y +CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0x80480000 +# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set +CONFIG_SPL_LOAD_FIT=y +CONFIG_SPL_LOAD_FIT_ADDRESS=0x81000000 +CONFIG_FIT_IMAGE_POST_PROCESS=y +CONFIG_SPL_FIT_IMAGE_POST_PROCESS=y +# CONFIG_USE_SPL_FIT_GENERATOR is not set +CONFIG_OF_BOARD_SETUP=y +CONFIG_BOOTCOMMAND="run findfdt; run envboot; run init_${boot}; run boot_rprocs; run get_fit_${boot}; run get_overlaystring; run run_fit" +CONFIG_LOGLEVEL=7 +CONFIG_SPL_MAX_SIZE=0xc0000 +CONFIG_SPL_HAS_BSS_LINKER_SECTION=y +CONFIG_SPL_BSS_START_ADDR=0x80a00000 +CONFIG_SPL_BSS_MAX_SIZE=0x80000 +CONFIG_SPL_BOARD_INIT=y +CONFIG_SPL_SYS_MALLOC_SIMPLE=y +CONFIG_SPL_STACK_R=y +CONFIG_SYS_SPL_MALLOC=y +CONFIG_SYS_SPL_MALLOC_SIZE=0x800000 +CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR=y +CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR=0x1400 +CONFIG_SPL_DMA=y +CONFIG_SPL_ENV_SUPPORT=y +CONFIG_SPL_FS_LOAD_PAYLOAD_NAME="u-boot.img" +CONFIG_SPL_I2C=y +CONFIG_SPL_DM_MAILBOX=y +CONFIG_SPL_MTD_SUPPORT=y +CONFIG_SPL_DM_SPI_FLASH=y +CONFIG_SPL_NOR_SUPPORT=y +CONFIG_SPL_DM_RESET=y +CONFIG_SPL_POWER_DOMAIN=y +CONFIG_SPL_RAM_SUPPORT=y +CONFIG_SPL_RAM_DEVICE=y +# CONFIG_SPL_SPI_FLASH_TINY is not set +CONFIG_SPL_SPI_FLASH_SFDP_SUPPORT=y +CONFIG_SPL_SPI_LOAD=y +CONFIG_SYS_SPI_U_BOOT_OFFS=0x280000 +CONFIG_SPL_THERMAL=y +CONFIG_SPL_USB_GADGET=y +CONFIG_SPL_DFU=y +CONFIG_SPL_YMODEM_SUPPORT=y +CONFIG_SYS_MAXARGS=64 +CONFIG_CMD_ASKENV=y +CONFIG_CMD_DFU=y +# CONFIG_CMD_FLASH is not set +CONFIG_CMD_GPIO=y +CONFIG_CMD_GPT=y +CONFIG_CMD_I2C=y +CONFIG_CMD_MMC=y +CONFIG_CMD_MTD=y +CONFIG_CMD_REMOTEPROC=y +CONFIG_CMD_UFS=y +CONFIG_CMD_USB=y +CONFIG_CMD_USB_MASS_STORAGE=y +# CONFIG_CMD_SETEXPR is not set +CONFIG_CMD_TIME=y +CONFIG_CMD_EXT4_WRITE=y +CONFIG_MTDIDS_DEFAULT="nor0=47040000.spi.0,nor0=47034000.hyperbus" +CONFIG_MTDPARTS_DEFAULT="mtdparts=47040000.spi.0:512k(ospi.tiboot3),2m(ospi.tispl),4m(ospi.u-boot),256k(ospi.env),256k(ospi.env.backup),57088k@8m(ospi.rootfs),256k(ospi.phypattern);47034000.hyperbus:512k(hbmc.tiboot3),2m(hbmc.tispl),4m(hbmc.u-boot),256k(hbmc.env),-@8m(hbmc.rootfs)" +CONFIG_CMD_UBI=y +# CONFIG_ISO_PARTITION is not set +# CONFIG_SPL_EFI_PARTITION is not set +CONFIG_OF_CONTROL=y +CONFIG_SPL_OF_CONTROL=y +CONFIG_SPL_MULTI_DTB_FIT=y +CONFIG_SPL_MULTI_DTB_FIT_NO_COMPRESSION=y +CONFIG_ENV_OVERWRITE=y +CONFIG_ENV_IS_IN_MMC=y +CONFIG_SYS_REDUNDAND_ENVIRONMENT=y +CONFIG_SYS_RELOC_GD_ENV_ADDR=y +CONFIG_NET_RANDOM_ETHADDR=y +CONFIG_DM=y +CONFIG_SPL_DM=y +CONFIG_SPL_DM_SEQ_ALIAS=y +CONFIG_REGMAP=y +CONFIG_SPL_REGMAP=y +CONFIG_SYSCON=y +CONFIG_SPL_SYSCON=y +CONFIG_SPL_OF_TRANSLATE=y +CONFIG_CLK=y +CONFIG_SPL_CLK=y +CONFIG_CLK_CCF=y +CONFIG_CLK_TI_SCI=y +CONFIG_DFU_MMC=y +CONFIG_DFU_RAM=y +CONFIG_DFU_SF=y +CONFIG_SYS_DFU_DATA_BUF_SIZE=0x40000 +CONFIG_SYS_DFU_MAX_FILE_SIZE=0x800000 +CONFIG_DMA_CHANNELS=y +CONFIG_TI_K3_NAVSS_UDMA=y +CONFIG_USB_FUNCTION_FASTBOOT=y +CONFIG_FASTBOOT_BUF_ADDR=0x82000000 +CONFIG_FASTBOOT_BUF_SIZE=0x2F000000 +CONFIG_FASTBOOT_FLASH=y +CONFIG_FASTBOOT_FLASH_MMC_DEV=0 +CONFIG_FASTBOOT_CMD_OEM_FORMAT=y +CONFIG_TI_SCI_PROTOCOL=y +CONFIG_DA8XX_GPIO=y +CONFIG_DM_PCA953X=y +CONFIG_DM_I2C=y +CONFIG_DM_I2C_GPIO=y +CONFIG_SYS_I2C_OMAP24XX=y +CONFIG_DM_MAILBOX=y +CONFIG_K3_SEC_PROXY=y +CONFIG_SUPPORT_EMMC_BOOT=y +CONFIG_MMC_IO_VOLTAGE=y +CONFIG_MMC_UHS_SUPPORT=y +CONFIG_MMC_HS400_SUPPORT=y +CONFIG_SPL_MMC_HS400_SUPPORT=y +CONFIG_MMC_SDHCI=y +CONFIG_MMC_SDHCI_ADMA=y +CONFIG_SPL_MMC_SDHCI_ADMA=y +CONFIG_MMC_SDHCI_AM654=y +CONFIG_MTD=y +CONFIG_DM_MTD=y +CONFIG_MTD_NOR_FLASH=y +CONFIG_CFI_FLASH=y +CONFIG_SYS_FLASH_USE_BUFFER_WRITE=y +CONFIG_FLASH_CFI_MTD=y +CONFIG_SYS_FLASH_CFI=y +CONFIG_SYS_MAX_FLASH_BANKS_DETECT=y +CONFIG_DM_SPI_FLASH=y +CONFIG_SPI_FLASH_SFDP_SUPPORT=y +CONFIG_SPI_FLASH_SOFT_RESET=y +CONFIG_SPI_FLASH_SOFT_RESET_ON_BOOT=y +CONFIG_SPI_FLASH_SPANSION=y +CONFIG_SPI_FLASH_S28HS512T=y +CONFIG_SPI_FLASH_STMICRO=y +CONFIG_SPI_FLASH_MT35XU=y +# CONFIG_SPI_FLASH_USE_4K_SECTORS is not set +CONFIG_SPI_FLASH_MTD=y +CONFIG_MULTIPLEXER=y +CONFIG_MUX_MMIO=y +CONFIG_PHY_TI_DP83867=y +CONFIG_PHY_FIXED=y +CONFIG_DM_ETH=y +CONFIG_TI_AM65_CPSW_NUSS=y +CONFIG_PHY=y +CONFIG_SPL_PHY=y +CONFIG_PHY_CADENCE_TORRENT=y +CONFIG_PHY_J721E_WIZ=y +CONFIG_PINCTRL=y +# CONFIG_PINCTRL_GENERIC is not set +CONFIG_SPL_PINCTRL=y +# CONFIG_SPL_PINCTRL_GENERIC is not set +CONFIG_PINCTRL_SINGLE=y +CONFIG_POWER_DOMAIN=y +CONFIG_TI_SCI_POWER_DOMAIN=y +CONFIG_DM_REGULATOR=y +CONFIG_DM_REGULATOR_FIXED=y +CONFIG_DM_REGULATOR_GPIO=y +CONFIG_RAM=y +CONFIG_SPL_RAM=y +CONFIG_REMOTEPROC_TI_K3_DSP=y +CONFIG_REMOTEPROC_TI_K3_R5F=y +CONFIG_DM_RESET=y +CONFIG_RESET_TI_SCI=y +CONFIG_SCSI=y +CONFIG_DM_SCSI=y +CONFIG_DM_SERIAL=y +CONFIG_SOC_DEVICE=y +CONFIG_SOC_DEVICE_TI_K3=y +CONFIG_SOC_TI=y +CONFIG_SPI=y +CONFIG_DM_SPI=y +CONFIG_CADENCE_QSPI=y +CONFIG_HAS_CQSPI_REF_CLK=y +CONFIG_CQSPI_REF_CLK=133333333 +CONFIG_SYSRESET=y +CONFIG_SPL_SYSRESET=y +CONFIG_SYSRESET_TI_SCI=y +CONFIG_DM_THERMAL=y +CONFIG_USB=y +CONFIG_DM_USB_GADGET=y +CONFIG_SPL_DM_USB_GADGET=y +CONFIG_USB_XHCI_HCD=y +CONFIG_USB_CDNS3=y +CONFIG_USB_CDNS3_GADGET=y +CONFIG_USB_CDNS3_HOST=y +CONFIG_SPL_USB_CDNS3_GADGET=y +CONFIG_USB_GADGET=y +CONFIG_USB_GADGET_MANUFACTURER="Texas Instruments" +CONFIG_USB_GADGET_VENDOR_NUM=0x0451 +CONFIG_USB_GADGET_PRODUCT_NUM=0x6168 +CONFIG_UFS=y +CONFIG_CADENCE_UFS=y +CONFIG_TI_J721E_UFS=y +CONFIG_OF_LIBFDT_OVERLAY=y diff --git a/configs/j721s2_hs_evm_r5_defconfig b/configs/j721s2_hs_evm_r5_defconfig new file mode 100644 index 0000000000..696674ec42 --- /dev/null +++ b/configs/j721s2_hs_evm_r5_defconfig @@ -0,0 +1,178 @@ +CONFIG_ARM=y +CONFIG_ARCH_K3=y +CONFIG_TI_SECURE_DEVICE=y +CONFIG_SYS_MALLOC_LEN=0x2000000 +CONFIG_SYS_MALLOC_F_LEN=0x10000 +CONFIG_SPL_GPIO=y +CONFIG_SPL_LIBCOMMON_SUPPORT=y +CONFIG_SPL_LIBGENERIC_SUPPORT=y +CONFIG_SOC_K3_J721S2=y +CONFIG_K3_EARLY_CONS=y +CONFIG_TARGET_J721S2_R5_EVM=y +CONFIG_ENV_SIZE=0x20000 +CONFIG_DM_GPIO=y +CONFIG_SPL_DM_SPI=y +CONFIG_DEFAULT_DEVICE_TREE="k3-j721s2-r5-common-proc-board" +CONFIG_SPL_TEXT_BASE=0x41c00000 +CONFIG_SPL_MMC=y +CONFIG_SPL_SERIAL=y +CONFIG_SPL_DRIVERS_MISC=y +CONFIG_SPL_STACK_R_ADDR=0x82000000 +CONFIG_SPL_SIZE_LIMIT=0x80000 +CONFIG_SPL_SIZE_LIMIT_PROVIDE_STACK=0x4000 +CONFIG_SPL_FS_FAT=y +CONFIG_SPL_LIBDISK_SUPPORT=y +CONFIG_SPL_SPI_FLASH_SUPPORT=y +CONFIG_SPL_SPI=y +CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y +CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0x41c76000 +# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set +CONFIG_SPL_LOAD_FIT=y +CONFIG_SPL_LOAD_FIT_ADDRESS=0x80080000 +CONFIG_SPL_FIT_IMAGE_POST_PROCESS=y +# CONFIG_USE_SPL_FIT_GENERATOR is not set +CONFIG_USE_BOOTCOMMAND=y +# CONFIG_DISPLAY_CPUINFO is not set +CONFIG_SPL_SIZE_LIMIT_SUBTRACT_GD=y +CONFIG_SPL_SIZE_LIMIT_SUBTRACT_MALLOC=y +CONFIG_SPL_MAX_SIZE=0xc0000 +CONFIG_SPL_HAS_BSS_LINKER_SECTION=y +CONFIG_SPL_BSS_START_ADDR=0x41c76000 +CONFIG_SPL_BSS_MAX_SIZE=0xa000 +CONFIG_SPL_SYS_REPORT_STACK_F_USAGE=y +CONFIG_SPL_BOARD_INIT=y +CONFIG_SPL_SYS_MALLOC_SIMPLE=y +CONFIG_SPL_STACK_R=y +CONFIG_SPL_SEPARATE_BSS=y +CONFIG_SYS_SPL_MALLOC=y +CONFIG_HAS_CUSTOM_SPL_MALLOC_START=y +CONFIG_CUSTOM_SYS_SPL_MALLOC_ADDR=0x84000000 +CONFIG_SYS_SPL_MALLOC_SIZE=0x1000000 +CONFIG_SPL_EARLY_BSS=y +CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR=y +CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR=0x400 +CONFIG_SPL_DMA=y +CONFIG_SPL_ENV_SUPPORT=y +CONFIG_SPL_FS_EXT4=y +CONFIG_SPL_I2C=y +CONFIG_SPL_DM_MAILBOX=y +CONFIG_SPL_MTD_SUPPORT=y +CONFIG_SPL_DM_SPI_FLASH=y +CONFIG_SPL_NOR_SUPPORT=y +CONFIG_SPL_DM_RESET=y +CONFIG_SPL_POWER_DOMAIN=y +CONFIG_SPL_RAM_SUPPORT=y +CONFIG_SPL_RAM_DEVICE=y +CONFIG_SPL_REMOTEPROC=y +# CONFIG_SPL_SPI_FLASH_TINY is not set +CONFIG_SPL_SPI_FLASH_SFDP_SUPPORT=y +CONFIG_SPL_SPI_LOAD=y +CONFIG_SYS_SPI_U_BOOT_OFFS=0x80000 +CONFIG_SPL_THERMAL=y +CONFIG_SPL_USB_GADGET=y +CONFIG_SPL_DFU=y +CONFIG_SPL_YMODEM_SUPPORT=y +CONFIG_HUSH_PARSER=y +CONFIG_SYS_MAXARGS=64 +CONFIG_SYS_BOOTM_LEN=0x4000000 +CONFIG_CMD_DFU=y +# CONFIG_CMD_FLASH is not set +CONFIG_CMD_GPT=y +CONFIG_CMD_MMC=y +CONFIG_CMD_REMOTEPROC=y +# CONFIG_CMD_SETEXPR is not set +CONFIG_CMD_TIME=y +CONFIG_CMD_FAT=y +CONFIG_OF_CONTROL=y +CONFIG_SPL_OF_CONTROL=y +CONFIG_SYS_RELOC_GD_ENV_ADDR=y +CONFIG_DM=y +CONFIG_SPL_DM=y +CONFIG_SPL_DM_SEQ_ALIAS=y +CONFIG_REGMAP=y +CONFIG_SPL_REGMAP=y +CONFIG_SYSCON=y +CONFIG_SPL_SYSCON=y +CONFIG_SPL_OF_TRANSLATE=y +CONFIG_CLK=y +CONFIG_SPL_CLK=y +CONFIG_SPL_CLK_CCF=y +CONFIG_SPL_CLK_K3_PLL=y +CONFIG_SPL_CLK_K3=y +CONFIG_SYS_DFU_DATA_BUF_SIZE=0x40000 +CONFIG_DMA_CHANNELS=y +CONFIG_TI_K3_NAVSS_UDMA=y +CONFIG_TI_SCI_PROTOCOL=y +CONFIG_DA8XX_GPIO=y +CONFIG_DM_PCA953X=y +CONFIG_DM_I2C=y +CONFIG_I2C_SET_DEFAULT_BUS_NUM=y +CONFIG_SYS_I2C_OMAP24XX=y +CONFIG_DM_MAILBOX=y +CONFIG_K3_SEC_PROXY=y +CONFIG_FS_LOADER=y +CONFIG_SPL_FS_LOADER=y +CONFIG_SUPPORT_EMMC_BOOT=y +CONFIG_SPL_MMC_HS400_SUPPORT=y +CONFIG_MMC_SDHCI=y +CONFIG_SPL_MMC_SDHCI_ADMA=y +CONFIG_MMC_SDHCI_AM654=y +CONFIG_MTD=y +CONFIG_DM_MTD=y +CONFIG_MTD_NOR_FLASH=y +CONFIG_CFI_FLASH=y +CONFIG_SYS_FLASH_USE_BUFFER_WRITE=y +CONFIG_FLASH_CFI_MTD=y +CONFIG_SYS_FLASH_CFI=y +CONFIG_SYS_MAX_FLASH_BANKS_DETECT=y +CONFIG_DM_SPI_FLASH=y +CONFIG_SPI_FLASH_SFDP_SUPPORT=y +CONFIG_SPI_FLASH_SOFT_RESET=y +CONFIG_SPI_FLASH_SOFT_RESET_ON_BOOT=y +CONFIG_SPI_FLASH_SPANSION=y +CONFIG_SPI_FLASH_S28HS512T=y +CONFIG_SPI_FLASH_STMICRO=y +CONFIG_SPI_FLASH_MT35XU=y +CONFIG_PINCTRL=y +# CONFIG_PINCTRL_GENERIC is not set +CONFIG_SPL_PINCTRL=y +# CONFIG_SPL_PINCTRL_GENERIC is not set +CONFIG_PINCTRL_SINGLE=y +CONFIG_POWER_DOMAIN=y +CONFIG_TI_POWER_DOMAIN=y +CONFIG_K3_SYSTEM_CONTROLLER=y +CONFIG_REMOTEPROC_TI_K3_ARM64=y +CONFIG_DM_RESET=y +CONFIG_RESET_TI_SCI=y +CONFIG_DM_SERIAL=y +CONFIG_SOC_DEVICE=y +CONFIG_SOC_DEVICE_TI_K3=y +CONFIG_SOC_TI=y +CONFIG_SPI=y +CONFIG_DM_SPI=y +CONFIG_CADENCE_QSPI=y +CONFIG_HAS_CQSPI_REF_CLK=y +CONFIG_CQSPI_REF_CLK=133333333 +CONFIG_SYSRESET=y +CONFIG_SPL_SYSRESET=y +CONFIG_SYSRESET_TI_SCI=y +CONFIG_DM_THERMAL=y +CONFIG_TIMER=y +CONFIG_SPL_TIMER=y +CONFIG_OMAP_TIMER=y +CONFIG_USB=y +CONFIG_DM_USB_GADGET=y +CONFIG_SPL_DM_USB_GADGET=y +CONFIG_USB_CDNS3=y +CONFIG_USB_CDNS3_GADGET=y +CONFIG_SPL_USB_CDNS3_GADGET=y +CONFIG_USB_GADGET=y +CONFIG_USB_GADGET_MANUFACTURER="Texas Instruments" +CONFIG_USB_GADGET_VENDOR_NUM=0x0451 +CONFIG_USB_GADGET_PRODUCT_NUM=0x6168 +CONFIG_USB_GADGET_DOWNLOAD=y +CONFIG_FS_EXT4=y +CONFIG_FS_FAT_MAX_CLUSTSIZE=16384 +CONFIG_PANIC_HANG=y +CONFIG_LIB_RATIONAL=y +CONFIG_SPL_LIB_RATIONAL=y From 0b6924cc0f192deffe546135224d3b3c4ecadbb8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Sun, 4 Sep 2022 03:28:58 +0200 Subject: [PATCH 166/374] Nokia RX-51: Remove label copy_kernel_start from lowlevel_init.S MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Label copy_kernel_start is now unused. Remove it. Signed-off-by: Pali Rohár --- board/nokia/rx51/lowlevel_init.S | 1 - 1 file changed, 1 deletion(-) diff --git a/board/nokia/rx51/lowlevel_init.S b/board/nokia/rx51/lowlevel_init.S index c1785bc3f7..53697fd4e1 100644 --- a/board/nokia/rx51/lowlevel_init.S +++ b/board/nokia/rx51/lowlevel_init.S @@ -46,7 +46,6 @@ save_boot_params: * (CONFIG_SYS_TEXT_BASE). */ -copy_kernel_start: /* r0 - start of kernel before */ adr r0, kernoffs /* r0 - current address of kernoffs section */ ldr r1, kernoffs /* r1 - offset of kernel image from kernoffs section */ From 5c9bf1d65530d85dcdcca329bee7ce93818a6e3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Sun, 4 Sep 2022 03:28:59 +0200 Subject: [PATCH 167/374] Nokia RX-51: Do not clear unknown memory in lowlevel_init.S MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If kernel image in uImage or zImage format is not detected by lowlevel_init.S code then do not clear memory location where image was expected. If image is not detected then this memory region is unknown. So do not unconditionally clear it. Signed-off-by: Pali Rohár --- board/nokia/rx51/lowlevel_init.S | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/board/nokia/rx51/lowlevel_init.S b/board/nokia/rx51/lowlevel_init.S index 53697fd4e1..1cf8f8d8b2 100644 --- a/board/nokia/rx51/lowlevel_init.S +++ b/board/nokia/rx51/lowlevel_init.S @@ -76,7 +76,7 @@ save_boot_params: ldr r4, [r0, #36] /* r4 - 4 bytes header of kernel at offset 36 */ ldr r5, z_magic /* r5 - LINUX_ARM_ZIMAGE_MAGIC */ cmp r4, r5 - bne copy_kernel_end /* skip if invalid image */ + bne skip_copy /* skip if invalid image */ copy_kernel_loop: ldmdb r1!, {r3 - r10} @@ -84,12 +84,12 @@ copy_kernel_loop: cmp r1, r0 bhi copy_kernel_loop -copy_kernel_end: - /* remove header in source kernel image */ mov r5, #0 str r5, [r0] /* remove 4 bytes header of kernel uImage */ str r5, [r0, #36] /* remove 4 bytes header of kernel zImage */ +skip_copy: + /* Returns */ b save_boot_params_ret From e1da01d7b10057de27baf579912d188da3550a4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Sun, 4 Sep 2022 03:29:00 +0200 Subject: [PATCH 168/374] Nokia RX-51: Set default SYS_LOAD_ADDR to 0x80008000 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit At address 0x80000100 are stored initial atags passed to U-Boot by NOLO. So do not overwrite them when using $loadaddr variable which value is set from CONFIG_SYS_LOAD_ADDR option. Signed-off-by: Pali Rohár --- configs/nokia_rx51_defconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configs/nokia_rx51_defconfig b/configs/nokia_rx51_defconfig index 41f8268ec2..6629137d00 100644 --- a/configs/nokia_rx51_defconfig +++ b/configs/nokia_rx51_defconfig @@ -4,7 +4,7 @@ CONFIG_SYS_L2CACHE_OFF=y CONFIG_ARCH_OMAP2PLUS=y CONFIG_SYS_MALLOC_LEN=0xc0000 CONFIG_TARGET_NOKIA_RX51=y -CONFIG_SYS_LOAD_ADDR=0x80000000 +CONFIG_SYS_LOAD_ADDR=0x80008000 CONFIG_OPTIMIZE_INLINING=y CONFIG_LTO=y # CONFIG_FIT is not set From fd986d6021e3a9f31bd062631132c493bae5cea6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Sun, 4 Sep 2022 03:29:01 +0200 Subject: [PATCH 169/374] Nokia RX-51: Change UBIFS volume size to 1870 LEBs in test script MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Original Nokia UBIFS system image has 1870 LEBs, so set UBIFS volume size in test script to the same value. Number of 1870 LEBs corresponds to 230MiB (LEB size * num of LEBs = 126KiB * 1870 = 230MiB). Signed-off-by: Pali Rohár --- test/nokia_rx51_test.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/nokia_rx51_test.sh b/test/nokia_rx51_test.sh index 28aa554ed8..abd1712fd7 100755 --- a/test/nokia_rx51_test.sh +++ b/test/nokia_rx51_test.sh @@ -129,7 +129,7 @@ cat > ubi.ini << EOF mode=ubi image=ubifs.img vol_id=0 -vol_size=160MiB +vol_size=230MiB # 1870 LEBs vol_type=dynamic vol_name=rootfs vol_alignment=1 From 7506965885fe5eea4945c9706377a679a2974aa7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Sun, 4 Sep 2022 03:29:02 +0200 Subject: [PATCH 170/374] Nokia RX-51: Call bootm in test script only when image is valid MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When reading of image fails then do not call bootm. This prevents false positive test result in case something bootable is present in memory. Signed-off-by: Pali Rohár --- test/nokia_rx51_test.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/nokia_rx51_test.sh b/test/nokia_rx51_test.sh index abd1712fd7..d2417a98bf 100755 --- a/test/nokia_rx51_test.sh +++ b/test/nokia_rx51_test.sh @@ -180,7 +180,7 @@ EOF # Generate bootmenu for OneNAND booting cat > bootmenu_nand << EOF -setenv bootmenu_0 'uImage-2.6.28-omap1 from OneNAND=mtd read initfs \${kernaddr}; setenv bootargs; setenv setup_omap_atag 1; bootm \${kernaddr}'; +setenv bootmenu_0 'uImage-2.6.28-omap1 from OneNAND=setenv bootargs; setenv setup_omap_atag 1; mtd read initfs \${kernaddr} && bootm \${kernaddr}'; setenv bootmenu_1; setenv bootmenu_delay 1; setenv bootdelay 1; From 05159cc6b6be7a841b88fd4714600c3d11a3f359 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Sun, 4 Sep 2022 03:29:03 +0200 Subject: [PATCH 171/374] Nokia RX-51: Fix documentation how to enable UBI support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Disable UBI fastmap support which is not supported by original Maemo 5 kernel and explicitly set UBI BEB limit to 10%, which is the value used by original Maemo 5 kernel. U-Boot default value is 20%. Signed-off-by: Pali Rohár --- doc/board/nokia/rx51.rst | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/doc/board/nokia/rx51.rst b/doc/board/nokia/rx51.rst index 061fe7677e..7c6647bce2 100644 --- a/doc/board/nokia/rx51.rst +++ b/doc/board/nokia/rx51.rst @@ -158,8 +158,7 @@ UBIFS support add following lines into file ``configs/nokia_rx51_defconfig``:: CONFIG_CMD_UBI=y CONFIG_CMD_UBIFS=y - CONFIG_MTD_UBI_FASTMAP=y - CONFIG_MTD_UBI_FASTMAP_AUTOCONVERT=1 + CONFIG_MTD_UBI_BEB_LIMIT=10 Run in QEMU ----------- From 92e08722c9df93030e591681bd847b60af58779f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Sun, 4 Sep 2022 03:29:04 +0200 Subject: [PATCH 172/374] Nokia RX-51: Do not set useless ARCH= in test script MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit U-Boot ignores ARCH= variable. Signed-off-by: Pali Rohár --- test/nokia_rx51_test.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/nokia_rx51_test.sh b/test/nokia_rx51_test.sh index d2417a98bf..3fabc0e9b4 100755 --- a/test/nokia_rx51_test.sh +++ b/test/nokia_rx51_test.sh @@ -36,7 +36,7 @@ echo # First compile u-boot.bin binary for Nokia RX-51 board make nokia_rx51_config -make -j4 u-boot.bin ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- +make -j4 u-boot.bin CROSS_COMPILE=arm-linux-gnueabi- # And then do all stuff in temporary directory mkdir -p nokia_rx51_tmp From 21dc5efbf4185857f4ab35eae1174e8ac233999b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Sun, 4 Sep 2022 03:29:05 +0200 Subject: [PATCH 173/374] Nokia RX-51: Add comment describing kernel image type into test script MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Pali Rohár --- test/nokia_rx51_test.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/nokia_rx51_test.sh b/test/nokia_rx51_test.sh index 3fabc0e9b4..fc5fe1c911 100755 --- a/test/nokia_rx51_test.sh +++ b/test/nokia_rx51_test.sh @@ -178,7 +178,7 @@ setenv bootdelay 1; EOF ./mkimage -A arm -O linux -T script -C none -a 0 -e 0 -n bootmenu_emmc2 -d bootmenu_emmc2 bootmenu_emmc2.scr -# Generate bootmenu for OneNAND booting +# Generate bootmenu for OneNAND booting (uImage) cat > bootmenu_nand << EOF setenv bootmenu_0 'uImage-2.6.28-omap1 from OneNAND=setenv bootargs; setenv setup_omap_atag 1; mtd read initfs \${kernaddr} && bootm \${kernaddr}'; setenv bootmenu_1; @@ -221,7 +221,7 @@ mformat -m 0xf8 -F -h 4 -s 16 -c 1 -t $((50*1024*1024/(4*16*512))) :: -i emmc_em mcopy zImage-2.6.28-omap1 ::/zImage-2.6.28-omap1 -i emmc_emmc2.img mcopy bootmenu_emmc2.scr ::/bootmenu.scr -i emmc_emmc2.img -# Generate FAT32 eMMC image for OneNAND booting +# Generate FAT32 eMMC image for OneNAND booting (uImage) truncate -s 50MiB emmc_nand.img mformat -m 0xf8 -F -h 4 -s 16 -c 1 -t $((50*1024*1024/(4*16*512))) :: -i emmc_nand.img mcopy bootmenu_nand.scr ::/bootmenu.scr -i emmc_nand.img From 43f7b81f9d138942d6f393f6836dfccbb4bd0539 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Thu, 15 Sep 2022 20:59:48 +0200 Subject: [PATCH 174/374] Nokia RX-51: Add booting from UBI into test script MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Compile U-Boot with UBI/UBIFS support according to doc/board/nokia/rx51.rst instructions and add test case for loading kernel image from UBI volume. Signed-off-by: Pali Rohár --- test/nokia_rx51_test.sh | 95 +++++++++++++++++++++++++++++++++-------- 1 file changed, 77 insertions(+), 18 deletions(-) diff --git a/test/nokia_rx51_test.sh b/test/nokia_rx51_test.sh index fc5fe1c911..a516ec2967 100755 --- a/test/nokia_rx51_test.sh +++ b/test/nokia_rx51_test.sh @@ -34,7 +34,18 @@ echo "========== Compiling U-Boot for Nokia RX-51 board ==========" echo "============================================================" echo -# First compile u-boot.bin binary for Nokia RX-51 board +# First compile u-boot-ubifs.bin binary with UBI/UBIFS support for Nokia RX-51 board according to doc/board/nokia/rx51.rst +make nokia_rx51_config +cat >> .config << EOF +CONFIG_CMD_UBI=y +CONFIG_CMD_UBIFS=y +CONFIG_MTD_UBI_BEB_LIMIT=10 +EOF +make olddefconfig +make -j4 u-boot.bin CROSS_COMPILE=arm-linux-gnueabi- +mv u-boot.bin u-boot-ubifs.bin + +# Then compile standard u-boot.bin binary for Nokia RX-51 board make nokia_rx51_config make -j4 u-boot.bin CROSS_COMPILE=arm-linux-gnueabi- @@ -44,6 +55,7 @@ cd nokia_rx51_tmp test -f mkimage || ln -s ../tools/mkimage . test -f u-boot.bin || ln -s ../u-boot.bin . +test -f u-boot-ubifs.bin || ln -s ../u-boot-ubifs.bin . echo echo "==========================================================================" @@ -99,6 +111,10 @@ echo "========== Generating images ==========" echo "=======================================" echo +# Generate kernel image in zImage and uImage format from FIASCO format +dd if=kernel_2.6.28/boot/zImage-2.6.28-20103103+0m5.fiasco of=zImage-2.6.28-omap1 skip=95 bs=1 +./mkimage -A arm -O linux -T kernel -C none -a 80008000 -e 80008000 -n zImage-2.6.28-omap1 -d zImage-2.6.28-omap1 uImage-2.6.28-omap1 + # Generate rootfs directory mkdir -p rootfs mkdir -p rootfs/dev/ @@ -123,20 +139,7 @@ echo EOF chmod +x rootfs/sbin/preinit -# Generate ubi config file for ubi rootfs image -cat > ubi.ini << EOF -[rootfs] -mode=ubi -image=ubifs.img -vol_id=0 -vol_size=230MiB # 1870 LEBs -vol_type=dynamic -vol_name=rootfs -vol_alignment=1 -vol_flags=autoresize -EOF - -# Generate ubi rootfs image from rootfs directory +# Generate ubifs image from rootfs directory # NOTE: Character device on host filesystem can be created only by root # But we do not need it on host filesystem, just in ubifs image # So run mknod and mkfs.ubifs commands under fakeroot program @@ -149,8 +152,35 @@ fakeroot sh -c ' mknod rootfs/dev/console c 5 1; /usr/sbin/mkfs.ubifs -m 2048 -e 129024 -c 2047 -r rootfs ubifs.img; ' + +# Generate ubi image with rootfs on first volume +cat > ubi.ini << EOF +[rootfs] +mode=ubi +image=ubifs.img +vol_id=0 +vol_size=230MiB # 1870 LEBs +vol_type=dynamic +vol_name=rootfs +vol_alignment=1 +vol_flags=autoresize +EOF /usr/sbin/ubinize -o ubi.img -p 128KiB -m 2048 -s 512 ubi.ini +# Generate ubi image with rootfs on first volume and kernel in zImage format on second volume for UBI booting +cp ubi.ini ubi_with_kernel.ini +cat >> ubi_with_kernel.ini << EOF +[kernel] +mode=ubi +image=zImage-2.6.28-omap1 +vol_id=1 +vol_size=2MiB +vol_type=dynamic +vol_name=kernel +vol_alignment=1 +EOF +/usr/sbin/ubinize -o ubi_with_kernel.img -p 128KiB -m 2048 -s 512 ubi_with_kernel.ini + # Generate bootmenu for U-Boot serial console testing cat > bootmenu_uboot << EOF setenv bootmenu_0 'Serial console test=echo; echo "Testing serial console"; echo; echo "Successfully booted"; echo; poweroff'; @@ -187,6 +217,15 @@ setenv bootdelay 1; EOF ./mkimage -A arm -O linux -T script -C none -a 0 -e 0 -n bootmenu_nand -d bootmenu_nand bootmenu_nand.scr +# Generate bootmenu for UBI booting (zImage) +cat > bootmenu_ubi << EOF +setenv bootmenu_0 'zImage-2.6.28-omap1 from UBI=setenv bootargs; setenv setup_omap_atag 1; ubi part rootfs && ubi read \${kernaddr} kernel && bootz \${kernaddr}'; +setenv bootmenu_1; +setenv bootmenu_delay 1; +setenv bootdelay 1; +EOF +./mkimage -A arm -O linux -T script -C none -a 0 -e 0 -n bootmenu_ubi -d bootmenu_ubi bootmenu_ubi.scr + # Generate bootmenu for default booting cat > bootmenu_default << EOF setenv bootmenu_delay 1; @@ -195,9 +234,7 @@ EOF ./mkimage -A arm -O linux -T script -C none -a 0 -e 0 -n bootmenu_default -d bootmenu_default bootmenu_default.scr # Generate combined image from u-boot and Maemo fiasco kernel -dd if=kernel_2.6.28/boot/zImage-2.6.28-20103103+0m5.fiasco of=zImage-2.6.28-omap1 skip=95 bs=1 ./u-boot-gen-combined u-boot.bin zImage-2.6.28-omap1 combined_zimage.bin -./mkimage -A arm -O linux -T kernel -C none -a 80008000 -e 80008000 -n zImage-2.6.28-omap1 -d zImage-2.6.28-omap1 uImage-2.6.28-omap1 ./u-boot-gen-combined u-boot.bin uImage-2.6.28-omap1 combined_uimage.bin # Generate combined hack image from u-boot and Maemo fiasco kernel (kernel starts at 2MB offset and qflasher puts 2kB header before supplied image) @@ -226,6 +263,11 @@ truncate -s 50MiB emmc_nand.img mformat -m 0xf8 -F -h 4 -s 16 -c 1 -t $((50*1024*1024/(4*16*512))) :: -i emmc_nand.img mcopy bootmenu_nand.scr ::/bootmenu.scr -i emmc_nand.img +# Generate FAT32 eMMC image for UBI booting (zImage) +truncate -s 50MiB emmc_ubi.img +mformat -m 0xf8 -F -h 4 -s 16 -c 1 -t $((50*1024*1024/(4*16*512))) :: -i emmc_ubi.img +mcopy bootmenu_ubi.scr ::/bootmenu.scr -i emmc_ubi.img + # Generate FAT32 eMMC image for default booting truncate -s 50MiB emmc_default.img mformat -m 0xf8 -F -h 4 -s 16 -c 1 -t $((50*1024*1024/(4*16*512))) :: -i emmc_default.img @@ -251,6 +293,10 @@ rm -f mtd_emmc.img rm -f mtd_nand.img ./qflasher -v -x xloader-qemu.bin -s secondary-qemu.bin -k combined_hack.bin -r ubi.img -m rx51 -p k=4094,i=2 -o mtd_nand.img +# Generate MTD image for UBI booting from bootloader nolo images, u-boot image with UBI/UBIFS support and rootfs image with kernel volume +rm -f mtd_ubi.img +./qflasher -v -x xloader-qemu.bin -s secondary-qemu.bin -k u-boot-ubifs.bin -r ubi_with_kernel.img -m rx51 -o mtd_ubi.img + echo echo "======================================================" echo "========== Running test images in n900 qemu ==========" @@ -329,6 +375,18 @@ wait -n $sleep_pid $qemu_pid || true kill -9 $tail_pid $sleep_pid $qemu_pid 2>/dev/null || true wait || true +# Run MTD image in qemu and wait for 300s if kernel from UBI is correctly booted +rm -f qemu_ubi.log +./qemu-system-arm -M n900 -mtdblock mtd_ubi.img -sd emmc_ubi.img -serial /dev/stdout -display none > qemu_ubi.log & +qemu_pid=$! +tail -F qemu_ubi.log & +tail_pid=$! +sleep 300 & +sleep_pid=$! +wait -n $sleep_pid $qemu_pid || true +kill -9 $tail_pid $sleep_pid $qemu_pid 2>/dev/null || true +wait || true + echo echo "=============================" echo "========== Results ==========" @@ -341,10 +399,11 @@ if grep -q 'Successfully booted' qemu_ram2.log; then echo "Kernel (zImage) was s if grep -q 'Successfully booted' qemu_emmc.log; then echo "Kernel (uImage) was successfully booted from eMMC"; else echo "Failed to boot kernel (uImage) from eMMC"; fi if grep -q 'Successfully booted' qemu_emmc2.log; then echo "Kernel (zImage) was successfully booted from eMMC"; else echo "Failed to boot kernel (zImage) from eMMC"; fi if grep -q 'Successfully booted' qemu_nand.log; then echo "Kernel (uImage) was successfully booted from OneNAND"; else echo "Failed to boot kernel (uImage) from OneNAND"; fi +if grep -q 'Successfully booted' qemu_ubi.log; then echo "Kernel (zImage) was successfully booted from UBI"; else echo "Failed to boot kernel (zImage) from UBI"; fi echo -if grep -q 'Successfully booted' qemu_uboot.log && grep -q 'Successfully booted' qemu_ram.log && grep -q 'Successfully booted' qemu_ram2.log && grep -q 'Successfully booted' qemu_emmc.log && grep -q 'Successfully booted' qemu_emmc2.log && grep -q 'Successfully booted' qemu_nand.log; then +if grep -q 'Successfully booted' qemu_uboot.log && grep -q 'Successfully booted' qemu_ram.log && grep -q 'Successfully booted' qemu_ram2.log && grep -q 'Successfully booted' qemu_emmc.log && grep -q 'Successfully booted' qemu_emmc2.log && grep -q 'Successfully booted' qemu_nand.log && grep -q 'Successfully booted' qemu_ubi.log; then echo "All tests passed" exit 0 else From e7b1018dd377849780138a2b9aae59cf840fade6 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 11 Aug 2022 19:34:40 -0600 Subject: [PATCH 175/374] disk: Correct help for TPL_PARTITIONS Fix a few typos in this help text. Fix a typo in SPL_PARTITIONS while we are here. Signed-off-by: Simon Glass --- disk/Kconfig | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/disk/Kconfig b/disk/Kconfig index 81d8867ed7..c9b9dbaf1a 100644 --- a/disk/Kconfig +++ b/disk/Kconfig @@ -24,7 +24,7 @@ config SPL_PARTITIONS select SPL_STRTO help Enable this for base partition support in SPL. The required - partition table types shold be enabled separately. This add a + partition table types shold be enabled separately. This adds a small amount of size to SPL, typically 500 bytes. config TPL_PARTITIONS @@ -32,9 +32,9 @@ config TPL_PARTITIONS select TPL_SPRINTF select TPL_STRTO help - Enable this for base partition support in SPL. The required - partition table types shold be enabled separately. This add a - small amount of size to SPL, typically 500 bytes. + Enable this for base partition support in TPL. The required + partition table types shold be enabled separately. This adds a + small amount of size to TPL, typically 500 bytes. config MAC_PARTITION bool "Enable Apple's MacOS partition table" From 6b03b9d5b7b9efee81bdb01d17c291107818371e Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 11 Aug 2022 19:34:41 -0600 Subject: [PATCH 176/374] blk: Enable CONFIG_BLK for all media Enable this option on all boards which support block devices. Drop the related depencies on BLK since these are not needed anymore. Disable BLOCK_CACHE on M5253DEMO as this causes a build error. Signed-off-by: Simon Glass --- arch/arm/Kconfig | 1 - configs/M5253DEMO_defconfig | 1 + drivers/ata/Kconfig | 1 - drivers/block/Kconfig | 3 ++- drivers/nvme/Kconfig | 1 - drivers/scsi/Kconfig | 1 - drivers/virtio/Kconfig | 1 - 7 files changed, 3 insertions(+), 6 deletions(-) diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 3649222470..03169eba8d 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1026,7 +1026,6 @@ config ARCH_NPCM config ARCH_APPLE bool "Apple SoCs" select ARM64 - select BLK select CLK select CMD_USB select DM diff --git a/configs/M5253DEMO_defconfig b/configs/M5253DEMO_defconfig index 79382eb0fe..a73aca082c 100644 --- a/configs/M5253DEMO_defconfig +++ b/configs/M5253DEMO_defconfig @@ -25,6 +25,7 @@ CONFIG_CMD_EXT2=y CONFIG_CMD_FAT=y CONFIG_MAC_PARTITION=y CONFIG_SYS_RELOC_GD_ENV_ADDR=y +# CONFIG_BLOCK_CACHE is not set CONFIG_SYS_IDE_MAXBUS=1 CONFIG_SYS_ATA_STRIDE=4 CONFIG_SYS_ATA_DATA_OFFSET=0xA0 diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index 7715c40365..7d2315bd4a 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig @@ -9,7 +9,6 @@ config AHCI config SATA bool "Support SATA controllers" - depends on BLK select HAVE_BLOCK_DEVICE help This enables support for SATA (Serial Advanced Technology diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig index b5b482086a..df242df9c5 100644 --- a/drivers/block/Kconfig +++ b/drivers/block/Kconfig @@ -1,7 +1,8 @@ config BLK bool "Support block devices" depends on DM - default y if DM_MMC || DM_USB + default y if MMC || USB || SCSI || NVME || IDE || AHCI || SATA + default y if EFI_MEDIA || VIRTIO_BLK || PVBLOCK help Enable support for block devices, such as SCSI, MMC and USB flash sticks. These provide a block-level interface which permits diff --git a/drivers/nvme/Kconfig b/drivers/nvme/Kconfig index 0cb465160b..2a103ab5ed 100644 --- a/drivers/nvme/Kconfig +++ b/drivers/nvme/Kconfig @@ -4,7 +4,6 @@ config NVME bool "NVM Express device support" - depends on BLK select HAVE_BLOCK_DEVICE help This option enables support for NVM Express devices. diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig index c400e2de16..19872fb52d 100644 --- a/drivers/scsi/Kconfig +++ b/drivers/scsi/Kconfig @@ -10,7 +10,6 @@ config SCSI config DM_SCSI bool "Support SCSI controllers with driver model" - depends on BLK help This option enables the SCSI (Small Computer System Interface) uclass which supports SCSI and SATA HDDs. For every device configuration diff --git a/drivers/virtio/Kconfig b/drivers/virtio/Kconfig index 586263ec88..852f6735b6 100644 --- a/drivers/virtio/Kconfig +++ b/drivers/virtio/Kconfig @@ -64,7 +64,6 @@ config VIRTIO_NET config VIRTIO_BLK bool "virtio block driver" depends on VIRTIO - depends on BLK help This is the virtual block driver for virtio. It can be used with QEMU based targets. From 6c0405576a0f0b32acc68cb1860b43d89ec30cfa Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 11 Aug 2022 19:34:42 -0600 Subject: [PATCH 177/374] ata: Fix an instance of SPL_SATA_SUPPORT The _SUPPORT suffix should be dropped. This happened because the rename was applied around the same time as this new option, so did not include renaming the new option. The relevant commits are: f7560376ae sata: Rename SATA_SUPPORT to SATA 73059529b2 ata: ahci-pci: Add new option CONFIG_SPL_AHCI_PCI Fix it. Signed-off-by: Simon Glass --- drivers/ata/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index 7d2315bd4a..70e6bd321a 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig @@ -47,7 +47,7 @@ config SPL_AHCI_PCI bool "Support for PCI-based AHCI controller for SPL" depends on SPL depends on SPL_PCI - depends on SPL_SATA_SUPPORT && DM_SCSI + depends on SPL_SATA && DM_SCSI config DWC_AHCI bool "Enable Synopsys DWC AHCI driver support" From 1bbfdc575cdaf3afde6485b204d95b26ad2c5677 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 11 Aug 2022 19:34:43 -0600 Subject: [PATCH 178/374] sandbox: Avoid defining HAVE_BLOCK_DEVICE in Konfig This is not needed as it is implied or selected by other options anyway. Signed-off-by: Simon Glass --- arch/Kconfig | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/Kconfig b/arch/Kconfig index c4dc47dccb..994fd3b7f8 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -146,7 +146,6 @@ config SANDBOX select DM_SPI select DM_SPI_FLASH select GZIP_COMPRESSED - select HAVE_BLOCK_DEVICE select LZO select OF_BOARD_SETUP select PCI_ENDPOINT From fc614d2044a41ce98588f591349ac0f8c1c43ff6 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 11 Aug 2022 19:34:44 -0600 Subject: [PATCH 179/374] disk: Use Makefile to omit partition drivers At present these files have an #ifdef covering the whole file. Move the condition to the Makefile instead. Add BLK to the condition since future patches will adjust things so that HAVE_BLOCK_DEVICE is only for SPL, but the partition drivers are needed in U-Boot proper too. Signed-off-by: Simon Glass --- disk/Makefile | 4 ++++ disk/part_amiga.c | 4 ---- disk/part_dos.c | 4 ---- disk/part_efi.c | 3 --- disk/part_iso.c | 3 --- disk/part_mac.c | 3 --- drivers/Makefile | 1 + 7 files changed, 5 insertions(+), 17 deletions(-) diff --git a/disk/Makefile b/disk/Makefile index ec148832b3..458e21e3fb 100644 --- a/disk/Makefile +++ b/disk/Makefile @@ -9,8 +9,12 @@ obj-$(CONFIG_$(SPL_TPL_)PARTITIONS) += part.o ifdef CONFIG_$(SPL_TPL_)BLK obj-$(CONFIG_$(SPL_TPL_)PARTITIONS) += disk-uclass.o endif + +# Must have BLK or HAVE_BLOCK_DEVICE to support partitions +ifneq ($(CONFIG_$(SPL_TPL_)BLK),$(CONFIG_HAVE_BLOCK_DEVICE),) obj-$(CONFIG_$(SPL_TPL_)MAC_PARTITION) += part_mac.o obj-$(CONFIG_$(SPL_TPL_)DOS_PARTITION) += part_dos.o obj-$(CONFIG_$(SPL_TPL_)ISO_PARTITION) += part_iso.o obj-$(CONFIG_$(SPL_TPL_)AMIGA_PARTITION) += part_amiga.o obj-$(CONFIG_$(SPL_TPL_)EFI_PARTITION) += part_efi.o +endif diff --git a/disk/part_amiga.c b/disk/part_amiga.c index ac7ada5478..45d3a70486 100644 --- a/disk/part_amiga.c +++ b/disk/part_amiga.c @@ -11,8 +11,6 @@ #include "part_amiga.h" #include -#ifdef CONFIG_HAVE_BLOCK_DEVICE - #undef AMIGA_DEBUG #ifdef AMIGA_DEBUG @@ -387,5 +385,3 @@ U_BOOT_PART_TYPE(amiga) = { .print = part_print_amiga, .test = part_test_amiga, }; - -#endif diff --git a/disk/part_dos.c b/disk/part_dos.c index 94fae7166d..a94702c5f3 100644 --- a/disk/part_dos.c +++ b/disk/part_dos.c @@ -23,8 +23,6 @@ #include "part_dos.h" #include -#ifdef CONFIG_HAVE_BLOCK_DEVICE - #define DOS_PART_DEFAULT_SECTOR 512 /* should this be configurable? It looks like it's not very common at all @@ -518,5 +516,3 @@ U_BOOT_PART_TYPE(dos) = { .print = part_print_ptr(part_print_dos), .test = part_test_dos, }; - -#endif diff --git a/disk/part_efi.c b/disk/part_efi.c index 5090efd119..ad94504ed9 100644 --- a/disk/part_efi.c +++ b/disk/part_efi.c @@ -28,8 +28,6 @@ #include #include -#ifdef CONFIG_HAVE_BLOCK_DEVICE - /* GUID for basic data partitons */ #if CONFIG_IS_ENABLED(EFI_PARTITION) static const efi_guid_t partition_basic_data_guid = PARTITION_BASIC_DATA_GUID; @@ -1204,4 +1202,3 @@ U_BOOT_PART_TYPE(a_efi) = { .print = part_print_ptr(part_print_efi), .test = part_test_efi, }; -#endif /* CONFIG_HAVE_BLOCK_DEVICE */ diff --git a/disk/part_iso.c b/disk/part_iso.c index 1061f341d3..4cd619bf46 100644 --- a/disk/part_iso.c +++ b/disk/part_iso.c @@ -12,8 +12,6 @@ #include #include "part_iso.h" -#ifdef CONFIG_HAVE_BLOCK_DEVICE - /* #define ISO_PART_DEBUG */ #ifdef ISO_PART_DEBUG @@ -241,4 +239,3 @@ U_BOOT_PART_TYPE(iso) = { .print = part_print_iso, .test = part_test_iso, }; -#endif diff --git a/disk/part_mac.c b/disk/part_mac.c index e01ae74566..ae8263f755 100644 --- a/disk/part_mac.c +++ b/disk/part_mac.c @@ -20,8 +20,6 @@ #include "part_mac.h" #include -#ifdef CONFIG_HAVE_BLOCK_DEVICE - /* stdlib.h causes some compatibility problems; should fixe these! -- wd */ #ifndef __ldiv_t_defined typedef struct { @@ -247,4 +245,3 @@ U_BOOT_PART_TYPE(mac) = { .print = part_print_mac, .test = part_test_mac, }; -#endif diff --git a/drivers/Makefile b/drivers/Makefile index eba9940231..f2154e15d6 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -60,6 +60,7 @@ obj-$(CONFIG_SPL_USB_HOST) += usb/host/ obj-$(CONFIG_OMAP_USB_PHY) += usb/phy/ obj-$(CONFIG_SPL_SATA) += ata/ scsi/ obj-$(CONFIG_HAVE_BLOCK_DEVICE) += block/ +obj-$(CONFIG_SPL_BLK) += block/ obj-$(CONFIG_SPL_THERMAL) += thermal/ endif From a51eb8de31492d2139e66a7e66b8fb3f03ddca50 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 11 Aug 2022 19:34:45 -0600 Subject: [PATCH 180/374] blk: Use a function for whether block devices are available At present we use HAVE_BLOCK_DEVICE to indicate when block devices are available. This is a very strange option, since it partially duplicates the BLK option used by driver model. It also covers both U-Boot proper and SPL, even though one might have block devices and another not. As a first step towards correcting this, create a new inline function called blk_enabled() which indicates if block devices are available. This cannot be used in Makefiles, or #if clauses, but can be used in C code. A function is useful because we cannot use CONFIG_IS_ENABLED(BLK) to decide if block devices are needed, since we must consider the legacy block interface, enabled by HAVE_BLOCK_DEVICE Update a few places where it can be used and drop some unnecessary #if checks around some functions in disk/part.c - rely on the compiler's dead-code elimination instead. Signed-off-by: Simon Glass --- disk/part.c | 80 ++++++++++++++++---------------------- drivers/block/blk-uclass.c | 3 +- fs/fat/fat.c | 2 +- include/blk.h | 5 +++ 4 files changed, 40 insertions(+), 50 deletions(-) diff --git a/disk/part.c b/disk/part.c index 79955c7fb0..9594bb432c 100644 --- a/disk/part.c +++ b/disk/part.c @@ -54,12 +54,13 @@ static struct part_driver *part_driver_lookup_type(struct blk_desc *dev_desc) return NULL; } -#ifdef CONFIG_HAVE_BLOCK_DEVICE static struct blk_desc *get_dev_hwpart(const char *ifname, int dev, int hwpart) { struct blk_desc *dev_desc; int ret; + if (!blk_enabled()) + return NULL; dev_desc = blk_get_devnum_by_typename(ifname, dev); if (!dev_desc) { debug("%s: No device for iface '%s', dev %d\n", __func__, @@ -78,21 +79,11 @@ static struct blk_desc *get_dev_hwpart(const char *ifname, int dev, int hwpart) struct blk_desc *blk_get_dev(const char *ifname, int dev) { + if (!blk_enabled()) + return NULL; + return get_dev_hwpart(ifname, dev, 0); } -#else -struct blk_desc *get_dev_hwpart(const char *ifname, int dev, int hwpart) -{ - return NULL; -} - -struct blk_desc *blk_get_dev(const char *ifname, int dev) -{ - return NULL; -} -#endif - -#ifdef CONFIG_HAVE_BLOCK_DEVICE /* ------------------------------------------------------------------------- */ /* @@ -228,9 +219,6 @@ void dev_print (struct blk_desc *dev_desc) puts (" Capacity: not available\n"); } } -#endif - -#ifdef CONFIG_HAVE_BLOCK_DEVICE void part_init(struct blk_desc *dev_desc) { @@ -325,38 +313,36 @@ void part_print(struct blk_desc *dev_desc) drv->print(dev_desc); } -#endif /* CONFIG_HAVE_BLOCK_DEVICE */ - int part_get_info(struct blk_desc *dev_desc, int part, struct disk_partition *info) { -#ifdef CONFIG_HAVE_BLOCK_DEVICE struct part_driver *drv; + if (blk_enabled()) { #if CONFIG_IS_ENABLED(PARTITION_UUIDS) - /* The common case is no UUID support */ - info->uuid[0] = 0; + /* The common case is no UUID support */ + info->uuid[0] = 0; #endif #ifdef CONFIG_PARTITION_TYPE_GUID - info->type_guid[0] = 0; + info->type_guid[0] = 0; #endif - drv = part_driver_lookup_type(dev_desc); - if (!drv) { - debug("## Unknown partition table type %x\n", - dev_desc->part_type); - return -EPROTONOSUPPORT; + drv = part_driver_lookup_type(dev_desc); + if (!drv) { + debug("## Unknown partition table type %x\n", + dev_desc->part_type); + return -EPROTONOSUPPORT; + } + if (!drv->get_info) { + PRINTF("## Driver %s does not have the get_info() method\n", + drv->name); + return -ENOSYS; + } + if (drv->get_info(dev_desc, part, info) == 0) { + PRINTF("## Valid %s partition found ##\n", drv->name); + return 0; + } } - if (!drv->get_info) { - PRINTF("## Driver %s does not have the get_info() method\n", - drv->name); - return -ENOSYS; - } - if (drv->get_info(dev_desc, part, info) == 0) { - PRINTF("## Valid %s partition found ##\n", drv->name); - return 0; - } -#endif /* CONFIG_HAVE_BLOCK_DEVICE */ return -ENOENT; } @@ -424,15 +410,15 @@ int blk_get_device_by_str(const char *ifname, const char *dev_hwpart_str, goto cleanup; } -#ifdef CONFIG_HAVE_BLOCK_DEVICE - /* - * Updates the partition table for the specified hw partition. - * Always should be done, otherwise hw partition 0 will return stale - * data after displaying a non-zero hw partition. - */ - if ((*dev_desc)->if_type == IF_TYPE_MMC) - part_init(*dev_desc); -#endif + if (blk_enabled()) { + /* + * Updates the partition table for the specified hw partition. + * Always should be done, otherwise hw partition 0 will return + * stale data after displaying a non-zero hw partition. + */ + if ((*dev_desc)->if_type == IF_TYPE_MMC) + part_init(*dev_desc); + } cleanup: free(dup_str); diff --git a/drivers/block/blk-uclass.c b/drivers/block/blk-uclass.c index 21c5209bb6..1a6e8f8c29 100644 --- a/drivers/block/blk-uclass.c +++ b/drivers/block/blk-uclass.c @@ -743,8 +743,7 @@ int blk_unbind_all(int if_type) static int blk_post_probe(struct udevice *dev) { - if (CONFIG_IS_ENABLED(PARTITIONS) && - IS_ENABLED(CONFIG_HAVE_BLOCK_DEVICE)) { + if (CONFIG_IS_ENABLED(PARTITIONS) && blk_enabled()) { struct blk_desc *desc = dev_get_uclass_plat(dev); part_init(desc); diff --git a/fs/fat/fat.c b/fs/fat/fat.c index df9ea2c028..c64e253abd 100644 --- a/fs/fat/fat.c +++ b/fs/fat/fat.c @@ -1144,7 +1144,7 @@ int file_fat_detectfs(void) return 1; } - if (IS_ENABLED(CONFIG_HAVE_BLOCK_DEVICE)) { + if (blk_enabled()) { printf("Interface: %s\n", blk_get_if_type_name(cur_dev->if_type)); printf(" Device %d: ", cur_dev->devnum); dev_print(cur_dev); diff --git a/include/blk.h b/include/blk.h index 9503369db8..332481a90b 100644 --- a/include/blk.h +++ b/include/blk.h @@ -21,6 +21,11 @@ typedef ulong lbaint_t; struct udevice; +static inline bool blk_enabled(void) +{ + return CONFIG_IS_ENABLED(BLK) || IS_ENABLED(CONFIG_HAVE_BLOCK_DEVICE); +} + /* Interface types: */ enum if_type { IF_TYPE_UNKNOWN = 0, From 003357cc48dbf6e45ee408f114e4a5de862e7b2e Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 11 Aug 2022 19:34:46 -0600 Subject: [PATCH 181/374] cmd: Drop use of HAVE_BLOCK_DEVICE This condition is not needed for these commands, since BLK is enabled for all boards which use block devices and commands are not available in SPL, so even if SPL_BLK is not enabled, it doesn't affect commands. Signed-off-by: Simon Glass --- cmd/Kconfig | 5 ----- cmd/Makefile | 2 +- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/cmd/Kconfig b/cmd/Kconfig index 08821b0bd4..6db76e9da8 100644 --- a/cmd/Kconfig +++ b/cmd/Kconfig @@ -1092,7 +1092,6 @@ config CMD_PWM config CMD_GPT bool "GPT (GUID Partition Table) command" select EFI_PARTITION - select HAVE_BLOCK_DEVICE select PARTITION_UUIDS imply RANDOM_UUID help @@ -1211,7 +1210,6 @@ config CMD_LSBLK config CMD_MBR bool "MBR (Master Boot Record) command" select DOS_PARTITION - select HAVE_BLOCK_DEVICE help Enable the 'mbr' command to ready and write MBR (Master Boot Record) style partition tables. @@ -1343,7 +1341,6 @@ config CMD_OSD config CMD_PART bool "part" depends on PARTITIONS - select HAVE_BLOCK_DEVICE select PARTITION_UUIDS help Read and display information about the partition table on @@ -1474,7 +1471,6 @@ config CMD_UNIVERSE config CMD_USB bool "usb" depends on USB_HOST - select HAVE_BLOCK_DEVICE help USB support. @@ -1514,7 +1510,6 @@ config CMD_PVBLOCK config CMD_VIRTIO bool "virtio" depends on VIRTIO - depends on HAVE_BLOCK_DEVICE default y if VIRTIO help VirtIO block device support diff --git a/cmd/Makefile b/cmd/Makefile index 0ef4e2e466..cf6ce1bd6f 100644 --- a/cmd/Makefile +++ b/cmd/Makefile @@ -18,7 +18,7 @@ obj-$(CONFIG_CMD_AES) += aes.o obj-$(CONFIG_CMD_AB_SELECT) += ab_select.o obj-$(CONFIG_CMD_ADC) += adc.o obj-$(CONFIG_CMD_ARMFLASH) += armflash.o -obj-$(CONFIG_HAVE_BLOCK_DEVICE) += blk_common.o +obj-$(CONFIG_BLK) += blk_common.o obj-$(CONFIG_CMD_BOOTDEV) += bootdev.o obj-$(CONFIG_CMD_BOOTFLOW) += bootflow.o obj-$(CONFIG_CMD_BOOTMETH) += bootmeth.o From 14d2c5d819bb9f011b518c5394af90c3d8e0d17f Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 11 Aug 2022 19:34:47 -0600 Subject: [PATCH 182/374] blk: Drop unnecessary #ifdef in in blk_legacy We can rely on the compiler to eliminate any dead code. Signed-off-by: Simon Glass --- drivers/block/blk_legacy.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/block/blk_legacy.c b/drivers/block/blk_legacy.c index df9a359754..bd8a17df6a 100644 --- a/drivers/block/blk_legacy.c +++ b/drivers/block/blk_legacy.c @@ -70,7 +70,6 @@ static int get_desc(struct blk_driver *drv, int devnum, struct blk_desc **descp) return drv->get_dev(devnum, descp); } -#ifdef CONFIG_HAVE_BLOCK_DEVICE int blk_list_part(enum if_type if_type) { struct blk_driver *drv; @@ -174,7 +173,6 @@ int blk_show_device(enum if_type if_type, int devnum) return 0; } -#endif /* CONFIG_HAVE_BLOCK_DEVICE */ struct blk_desc *blk_get_devnum_by_type(enum if_type if_type, int devnum) { From 7f8967c2b82f9917987b69fbf43f8f591f3a8516 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 11 Aug 2022 19:34:48 -0600 Subject: [PATCH 183/374] blk: Rename HAVE_BLOCK_DEVICE This option is fact really related to SPL. For U-Boot proper we always use driver model for block devices, so CONFIG_BLK is enabled if block devices are in use. It is only for SPL that we have two cases: - SPL_BLK is enabled, in which case we use driver model and blk-uclass.c - SPL_BLK is not enabled, in which case (if we need block devices) we must use blk_legacy.c Rename the symbol to SPL_LEGACY_BLOCK to make this clear. This is different enough from BLK and SPL_BLK that there should be no confusion. Signed-off-by: Simon Glass --- common/spl/Kconfig | 4 ++-- configs/axm_defconfig | 2 +- configs/bcm968380gerg_ram_defconfig | 2 +- configs/gardena-smart-gateway-mt7688_defconfig | 2 +- configs/nsim_hs38_defconfig | 3 ++- configs/qemu-ppce500_defconfig | 2 +- disk/Makefile | 4 ++-- disk/disk-uclass.c | 3 +-- doc/develop/driver-model/migration.rst | 2 +- drivers/Makefile | 2 +- drivers/ata/Kconfig | 2 +- drivers/block/Kconfig | 8 ++++---- drivers/block/Makefile | 2 +- drivers/mmc/Kconfig | 2 +- drivers/nvme/Kconfig | 2 +- drivers/scsi/Kconfig | 2 +- drivers/xen/Kconfig | 2 +- include/blk.h | 2 +- lib/efi_loader/Kconfig | 2 +- 19 files changed, 25 insertions(+), 25 deletions(-) diff --git a/common/spl/Kconfig b/common/spl/Kconfig index 70d97815f0..222472a6fb 100644 --- a/common/spl/Kconfig +++ b/common/spl/Kconfig @@ -792,7 +792,7 @@ config SPL_DM_MAILBOX config SPL_MMC bool "Support MMC" depends on MMC - select HAVE_BLOCK_DEVICE + select SPL_LEGACY_BLOCK help Enable support for MMC (Multimedia Card) within SPL. This enables the MMC protocol implementation and allows any enabled drivers to @@ -1318,7 +1318,7 @@ config SPL_THERMAL config SPL_USB_HOST bool "Support USB host drivers" - select HAVE_BLOCK_DEVICE + select SPL_LEGACY_BLOCK help Enable access to USB (Universal Serial Bus) host devices so that SPL can load U-Boot from a connected USB peripheral, such as a USB diff --git a/configs/axm_defconfig b/configs/axm_defconfig index dc262c95a3..293052b901 100644 --- a/configs/axm_defconfig +++ b/configs/axm_defconfig @@ -80,7 +80,7 @@ CONFIG_SYS_REDUNDAND_ENVIRONMENT=y CONFIG_SYS_RELOC_GD_ENV_ADDR=y CONFIG_SPL_DM=y CONFIG_BLK=y -CONFIG_HAVE_BLOCK_DEVICE=y +CONFIG_SPL_LEGACY_BLOCK=y CONFIG_CLK=y CONFIG_CLK_AT91=y CONFIG_AT91_GPIO=y diff --git a/configs/bcm968380gerg_ram_defconfig b/configs/bcm968380gerg_ram_defconfig index a0924689e4..55d74266b7 100644 --- a/configs/bcm968380gerg_ram_defconfig +++ b/configs/bcm968380gerg_ram_defconfig @@ -42,7 +42,7 @@ CONFIG_CMD_NAND=y CONFIG_SYS_RELOC_GD_ENV_ADDR=y # CONFIG_NET is not set # CONFIG_DM_DEVICE_REMOVE is not set -CONFIG_HAVE_BLOCK_DEVICE=y +CONFIG_SPL_LEGACY_BLOCK=y CONFIG_BCM6345_GPIO=y CONFIG_LED=y CONFIG_LED_BCM6328=y diff --git a/configs/gardena-smart-gateway-mt7688_defconfig b/configs/gardena-smart-gateway-mt7688_defconfig index b9ee281be9..fdfab14d53 100644 --- a/configs/gardena-smart-gateway-mt7688_defconfig +++ b/configs/gardena-smart-gateway-mt7688_defconfig @@ -78,7 +78,7 @@ CONFIG_VERSION_VARIABLE=y CONFIG_NET_RANDOM_ETHADDR=y CONFIG_SPL_DM=y # CONFIG_DM_DEVICE_REMOVE is not set -CONFIG_HAVE_BLOCK_DEVICE=y +CONFIG_SPL_LEGACY_BLOCK=y CONFIG_BOOTCOUNT_LIMIT=y CONFIG_LED=y CONFIG_LED_BLINK=y diff --git a/configs/nsim_hs38_defconfig b/configs/nsim_hs38_defconfig index 8e5e8ea305..22690e7236 100644 --- a/configs/nsim_hs38_defconfig +++ b/configs/nsim_hs38_defconfig @@ -30,7 +30,8 @@ CONFIG_SYS_RELOC_GD_ENV_ADDR=y CONFIG_USE_BOOTFILE=y CONFIG_BOOTFILE="uImage" CONFIG_BLK=y -CONFIG_HAVE_BLOCK_DEVICE=y +CONFIG_SPL_LEGACY_BLOCK=y +CONFIG_DM_ETH=y CONFIG_DM_SERIAL=y CONFIG_DEBUG_UART_SHIFT=2 CONFIG_SYS_NS16550=y diff --git a/configs/qemu-ppce500_defconfig b/configs/qemu-ppce500_defconfig index 172ac18351..4ef0157224 100644 --- a/configs/qemu-ppce500_defconfig +++ b/configs/qemu-ppce500_defconfig @@ -40,7 +40,7 @@ CONFIG_NET_RANDOM_ETHADDR=y CONFIG_DM=y CONFIG_SIMPLE_BUS_CORRECT_RANGE=y CONFIG_BLK=y -CONFIG_HAVE_BLOCK_DEVICE=y +CONFIG_SPL_LEGACY_BLOCK=y CONFIG_LBA48=y CONFIG_CHIP_SELECTS_PER_CTRL=0 CONFIG_MPC8XXX_GPIO=y diff --git a/disk/Makefile b/disk/Makefile index 458e21e3fb..45588cf66e 100644 --- a/disk/Makefile +++ b/disk/Makefile @@ -10,8 +10,8 @@ ifdef CONFIG_$(SPL_TPL_)BLK obj-$(CONFIG_$(SPL_TPL_)PARTITIONS) += disk-uclass.o endif -# Must have BLK or HAVE_BLOCK_DEVICE to support partitions -ifneq ($(CONFIG_$(SPL_TPL_)BLK),$(CONFIG_HAVE_BLOCK_DEVICE),) +# Must have BLK or SPL_LEGACY_BLOCK to support partitions +ifneq ($(CONFIG_$(SPL_TPL_)BLK),$(CONFIG_SPL_LEGACY_BLOCK),) obj-$(CONFIG_$(SPL_TPL_)MAC_PARTITION) += part_mac.o obj-$(CONFIG_$(SPL_TPL_)DOS_PARTITION) += part_dos.o obj-$(CONFIG_$(SPL_TPL_)ISO_PARTITION) += part_iso.o diff --git a/disk/disk-uclass.c b/disk/disk-uclass.c index f3fb942a6b..9351a5cfa6 100644 --- a/disk/disk-uclass.c +++ b/disk/disk-uclass.c @@ -27,8 +27,7 @@ int part_create_block_devices(struct udevice *blk_dev) struct udevice *dev; int ret; - if (!CONFIG_IS_ENABLED(PARTITIONS) || - !CONFIG_IS_ENABLED(HAVE_BLOCK_DEVICE)) + if (!CONFIG_IS_ENABLED(PARTITIONS) || !blk_enabled()) return 0; if (device_get_uclass_id(blk_dev) != UCLASS_BLK) diff --git a/doc/develop/driver-model/migration.rst b/doc/develop/driver-model/migration.rst index 5a60436925..742fea5515 100644 --- a/doc/develop/driver-model/migration.rst +++ b/doc/develop/driver-model/migration.rst @@ -57,7 +57,7 @@ In concert with maintainers migrating their block device usage to the appropriate DM driver, CONFIG_BLK needs to be set as well. The final deadline here coincides with the final deadline for migration of the various block subsystems. At this point we will be able to audit and correct the logic in -Kconfig around using CONFIG_PARTITIONS and CONFIG_HAVE_BLOCK_DEVICE and make +Kconfig around using CONFIG_PARTITIONS and CONFIG_SPL_LEGACY_BLOCK and make use of CONFIG_BLK / CONFIG_SPL_BLK as needed. CONFIG_DM_SPI / CONFIG_DM_SPI_FLASH diff --git a/drivers/Makefile b/drivers/Makefile index f2154e15d6..9d9f69a3c9 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -59,7 +59,7 @@ obj-$(CONFIG_SPL_WATCHDOG) += watchdog/ obj-$(CONFIG_SPL_USB_HOST) += usb/host/ obj-$(CONFIG_OMAP_USB_PHY) += usb/phy/ obj-$(CONFIG_SPL_SATA) += ata/ scsi/ -obj-$(CONFIG_HAVE_BLOCK_DEVICE) += block/ +obj-$(CONFIG_SPL_LEGACY_BLOCK) += block/ obj-$(CONFIG_SPL_BLK) += block/ obj-$(CONFIG_SPL_THERMAL) += thermal/ diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index 70e6bd321a..c3f2ac058a 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig @@ -9,7 +9,7 @@ config AHCI config SATA bool "Support SATA controllers" - select HAVE_BLOCK_DEVICE + select SPL_LEGACY_BLOCK help This enables support for SATA (Serial Advanced Technology Attachment), a serial bus standard for connecting to hard drives and diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig index df242df9c5..5a0c434058 100644 --- a/drivers/block/Kconfig +++ b/drivers/block/Kconfig @@ -11,7 +11,7 @@ config BLK be partitioned into several areas, called 'partitions' in U-Boot. A filesystem can be placed in each partition. -config HAVE_BLOCK_DEVICE +config SPL_LEGACY_BLOCK bool "Enable Legacy Block Device" help Some devices require block support whether or not DM is enabled @@ -109,7 +109,7 @@ endif # EFI_MEDIA config IDE bool "Support IDE controllers" - select HAVE_BLOCK_DEVICE + select SPL_LEGACY_BLOCK help Enables support for IDE (Integrated Drive Electronics) hard drives. This allows access to raw blocks and filesystems on an IDE drive @@ -222,7 +222,7 @@ endif # IDE config LBA48 bool "Enable LBA support for disks larger than 137GB" - depends on HAVE_BLOCK_DEVICE + depends on SPL_LEGACY_BLOCK help Set this to enable support for disks larger than 137GB. Also look at CONFIG_SYS_64BIT_LBA. Without both of these, LBA48 @@ -231,7 +231,7 @@ config LBA48 config SYS_64BIT_LBA bool "Enable 64bit number of blocks on a block device" - depends on HAVE_BLOCK_DEVICE + depends on SPL_LEGACY_BLOCK help Make the block subsystem use 64bit sector addresses, rather than the default of 32bit. diff --git a/drivers/block/Makefile b/drivers/block/Makefile index b221a7c6ee..f48d3e1214 100644 --- a/drivers/block/Makefile +++ b/drivers/block/Makefile @@ -6,7 +6,7 @@ obj-$(CONFIG_$(SPL_)BLK) += blk-uclass.o ifndef CONFIG_$(SPL_)BLK -obj-$(CONFIG_HAVE_BLOCK_DEVICE) += blk_legacy.o +obj-$(CONFIG_SPL_LEGACY_BLOCK) += blk_legacy.o endif ifndef CONFIG_SPL_BUILD diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig index 0dcec8adce..5cd29758be 100644 --- a/drivers/mmc/Kconfig +++ b/drivers/mmc/Kconfig @@ -3,7 +3,7 @@ menu "MMC Host controller Support" config MMC bool "MMC/SD/SDIO card support" default ARM || PPC || SANDBOX - select HAVE_BLOCK_DEVICE + select SPL_LEGACY_BLOCK select DM_MMC if DM help This selects MultiMediaCard, Secure Digital and Secure diff --git a/drivers/nvme/Kconfig b/drivers/nvme/Kconfig index 2a103ab5ed..7b6d54615f 100644 --- a/drivers/nvme/Kconfig +++ b/drivers/nvme/Kconfig @@ -4,7 +4,7 @@ config NVME bool "NVM Express device support" - select HAVE_BLOCK_DEVICE + select SPL_LEGACY_BLOCK help This option enables support for NVM Express devices. It supports basic functions of NVMe (read/write). diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig index 19872fb52d..4d643816fc 100644 --- a/drivers/scsi/Kconfig +++ b/drivers/scsi/Kconfig @@ -1,6 +1,6 @@ config SCSI bool "Support SCSI controllers" - select HAVE_BLOCK_DEVICE + select SPL_LEGACY_BLOCK help This enables support for SCSI (Small Computer System Interface), a parallel interface widely used with storage peripherals such as diff --git a/drivers/xen/Kconfig b/drivers/xen/Kconfig index 6ad2a93668..20db2c5306 100644 --- a/drivers/xen/Kconfig +++ b/drivers/xen/Kconfig @@ -2,7 +2,7 @@ config PVBLOCK bool "Xen para-virtualized block device" depends on DM select BLK - select HAVE_BLOCK_DEVICE + select SPL_LEGACY_BLOCK help This driver implements the front-end of the Xen virtual block device driver. It communicates with a back-end driver diff --git a/include/blk.h b/include/blk.h index 332481a90b..5bdffe7401 100644 --- a/include/blk.h +++ b/include/blk.h @@ -23,7 +23,7 @@ struct udevice; static inline bool blk_enabled(void) { - return CONFIG_IS_ENABLED(BLK) || IS_ENABLED(CONFIG_HAVE_BLOCK_DEVICE); + return CONFIG_IS_ENABLED(BLK) || IS_ENABLED(CONFIG_SPL_LEGACY_BLOCK); } /* Interface types: */ diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig index 5cfff8c56b..c4e812594f 100644 --- a/lib/efi_loader/Kconfig +++ b/lib/efi_loader/Kconfig @@ -20,7 +20,7 @@ config EFI_LOADER select EVENT_DYNAMIC select LIB_UUID imply PARTITION_UUIDS - select HAVE_BLOCK_DEVICE + select SPL_LEGACY_BLOCK select REGEX imply FAT imply FAT_WRITE From ca28baf17c54bd723e704923f2d71828f34d1f1f Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 11 Aug 2022 19:34:49 -0600 Subject: [PATCH 184/374] blk: Select SPL_LEGACY_BLOCK automatically Selecting this option can be handled in the Kconfig option itself, as it is with BLK. Update this an drop the various 'select' clauses. Signed-off-by: Simon Glass --- common/spl/Kconfig | 2 -- drivers/ata/Kconfig | 1 - drivers/block/Kconfig | 11 +++++++---- drivers/mmc/Kconfig | 1 - drivers/nvme/Kconfig | 1 - drivers/scsi/Kconfig | 1 - drivers/xen/Kconfig | 1 - lib/efi_loader/Kconfig | 1 - 8 files changed, 7 insertions(+), 12 deletions(-) diff --git a/common/spl/Kconfig b/common/spl/Kconfig index 222472a6fb..e1b2a421cd 100644 --- a/common/spl/Kconfig +++ b/common/spl/Kconfig @@ -792,7 +792,6 @@ config SPL_DM_MAILBOX config SPL_MMC bool "Support MMC" depends on MMC - select SPL_LEGACY_BLOCK help Enable support for MMC (Multimedia Card) within SPL. This enables the MMC protocol implementation and allows any enabled drivers to @@ -1318,7 +1317,6 @@ config SPL_THERMAL config SPL_USB_HOST bool "Support USB host drivers" - select SPL_LEGACY_BLOCK help Enable access to USB (Universal Serial Bus) host devices so that SPL can load U-Boot from a connected USB peripheral, such as a USB diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index c3f2ac058a..a063b221cd 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig @@ -9,7 +9,6 @@ config AHCI config SATA bool "Support SATA controllers" - select SPL_LEGACY_BLOCK help This enables support for SATA (Serial Advanced Technology Attachment), a serial bus standard for connecting to hard drives and diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig index 5a0c434058..e82a779e6b 100644 --- a/drivers/block/Kconfig +++ b/drivers/block/Kconfig @@ -13,8 +13,14 @@ config BLK config SPL_LEGACY_BLOCK bool "Enable Legacy Block Device" + depends on SPL && !DM_SPL + default y if SPL_MMC || SPL_USB_STORAGE || SCSI || NVME || IDE + default y if SPL_AHCI_PCI help - Some devices require block support whether or not DM is enabled + Some devices require block support whether or not DM is enabled. This + is only supported in SPL. With this, the blk uclass is not used, but + instead a legacy implementation of block devices is used, with all + devices consisting of 'struct blk_desc' records. config SPL_BLK bool "Support block devices in SPL" @@ -109,7 +115,6 @@ endif # EFI_MEDIA config IDE bool "Support IDE controllers" - select SPL_LEGACY_BLOCK help Enables support for IDE (Integrated Drive Electronics) hard drives. This allows access to raw blocks and filesystems on an IDE drive @@ -222,7 +227,6 @@ endif # IDE config LBA48 bool "Enable LBA support for disks larger than 137GB" - depends on SPL_LEGACY_BLOCK help Set this to enable support for disks larger than 137GB. Also look at CONFIG_SYS_64BIT_LBA. Without both of these, LBA48 @@ -231,7 +235,6 @@ config LBA48 config SYS_64BIT_LBA bool "Enable 64bit number of blocks on a block device" - depends on SPL_LEGACY_BLOCK help Make the block subsystem use 64bit sector addresses, rather than the default of 32bit. diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig index 5cd29758be..f799f70e43 100644 --- a/drivers/mmc/Kconfig +++ b/drivers/mmc/Kconfig @@ -3,7 +3,6 @@ menu "MMC Host controller Support" config MMC bool "MMC/SD/SDIO card support" default ARM || PPC || SANDBOX - select SPL_LEGACY_BLOCK select DM_MMC if DM help This selects MultiMediaCard, Secure Digital and Secure diff --git a/drivers/nvme/Kconfig b/drivers/nvme/Kconfig index 7b6d54615f..73edb35516 100644 --- a/drivers/nvme/Kconfig +++ b/drivers/nvme/Kconfig @@ -4,7 +4,6 @@ config NVME bool "NVM Express device support" - select SPL_LEGACY_BLOCK help This option enables support for NVM Express devices. It supports basic functions of NVMe (read/write). diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig index 4d643816fc..ad484ce8e8 100644 --- a/drivers/scsi/Kconfig +++ b/drivers/scsi/Kconfig @@ -1,6 +1,5 @@ config SCSI bool "Support SCSI controllers" - select SPL_LEGACY_BLOCK help This enables support for SCSI (Small Computer System Interface), a parallel interface widely used with storage peripherals such as diff --git a/drivers/xen/Kconfig b/drivers/xen/Kconfig index 20db2c5306..0ee74d036c 100644 --- a/drivers/xen/Kconfig +++ b/drivers/xen/Kconfig @@ -2,7 +2,6 @@ config PVBLOCK bool "Xen para-virtualized block device" depends on DM select BLK - select SPL_LEGACY_BLOCK help This driver implements the front-end of the Xen virtual block device driver. It communicates with a back-end driver diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig index c4e812594f..476a22d7ea 100644 --- a/lib/efi_loader/Kconfig +++ b/lib/efi_loader/Kconfig @@ -20,7 +20,6 @@ config EFI_LOADER select EVENT_DYNAMIC select LIB_UUID imply PARTITION_UUIDS - select SPL_LEGACY_BLOCK select REGEX imply FAT imply FAT_WRITE From a21eb38183eb8a8225fb06c7d831702457f3da75 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 11 Aug 2022 19:34:50 -0600 Subject: [PATCH 185/374] blk: Drop unnecessary CONFIG_SPL_LEGACY_BLOCK in defconfigs This is defined automatically when needed, so drop it from the few defconfig files that define it manually. Signed-off-by: Simon Glass --- configs/axm_defconfig | 1 - configs/bcm968380gerg_ram_defconfig | 1 - configs/gardena-smart-gateway-mt7688_defconfig | 1 - configs/nsim_hs38_defconfig | 1 - configs/qemu-ppce500_defconfig | 1 - 5 files changed, 5 deletions(-) diff --git a/configs/axm_defconfig b/configs/axm_defconfig index 293052b901..b1e0090f35 100644 --- a/configs/axm_defconfig +++ b/configs/axm_defconfig @@ -80,7 +80,6 @@ CONFIG_SYS_REDUNDAND_ENVIRONMENT=y CONFIG_SYS_RELOC_GD_ENV_ADDR=y CONFIG_SPL_DM=y CONFIG_BLK=y -CONFIG_SPL_LEGACY_BLOCK=y CONFIG_CLK=y CONFIG_CLK_AT91=y CONFIG_AT91_GPIO=y diff --git a/configs/bcm968380gerg_ram_defconfig b/configs/bcm968380gerg_ram_defconfig index 55d74266b7..284fa2fdef 100644 --- a/configs/bcm968380gerg_ram_defconfig +++ b/configs/bcm968380gerg_ram_defconfig @@ -42,7 +42,6 @@ CONFIG_CMD_NAND=y CONFIG_SYS_RELOC_GD_ENV_ADDR=y # CONFIG_NET is not set # CONFIG_DM_DEVICE_REMOVE is not set -CONFIG_SPL_LEGACY_BLOCK=y CONFIG_BCM6345_GPIO=y CONFIG_LED=y CONFIG_LED_BCM6328=y diff --git a/configs/gardena-smart-gateway-mt7688_defconfig b/configs/gardena-smart-gateway-mt7688_defconfig index fdfab14d53..992e850999 100644 --- a/configs/gardena-smart-gateway-mt7688_defconfig +++ b/configs/gardena-smart-gateway-mt7688_defconfig @@ -78,7 +78,6 @@ CONFIG_VERSION_VARIABLE=y CONFIG_NET_RANDOM_ETHADDR=y CONFIG_SPL_DM=y # CONFIG_DM_DEVICE_REMOVE is not set -CONFIG_SPL_LEGACY_BLOCK=y CONFIG_BOOTCOUNT_LIMIT=y CONFIG_LED=y CONFIG_LED_BLINK=y diff --git a/configs/nsim_hs38_defconfig b/configs/nsim_hs38_defconfig index 22690e7236..740de7a409 100644 --- a/configs/nsim_hs38_defconfig +++ b/configs/nsim_hs38_defconfig @@ -30,7 +30,6 @@ CONFIG_SYS_RELOC_GD_ENV_ADDR=y CONFIG_USE_BOOTFILE=y CONFIG_BOOTFILE="uImage" CONFIG_BLK=y -CONFIG_SPL_LEGACY_BLOCK=y CONFIG_DM_ETH=y CONFIG_DM_SERIAL=y CONFIG_DEBUG_UART_SHIFT=2 diff --git a/configs/qemu-ppce500_defconfig b/configs/qemu-ppce500_defconfig index 4ef0157224..79cfa829e6 100644 --- a/configs/qemu-ppce500_defconfig +++ b/configs/qemu-ppce500_defconfig @@ -40,7 +40,6 @@ CONFIG_NET_RANDOM_ETHADDR=y CONFIG_DM=y CONFIG_SIMPLE_BUS_CORRECT_RANGE=y CONFIG_BLK=y -CONFIG_SPL_LEGACY_BLOCK=y CONFIG_LBA48=y CONFIG_CHIP_SELECTS_PER_CTRL=0 CONFIG_MPC8XXX_GPIO=y From 0417b8523c474e142979f99f978f270762502366 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 11 Aug 2022 19:34:51 -0600 Subject: [PATCH 186/374] blk: Hide the BLK and SPL_LEGACY_BLOCK options We don't want boards to be able to change these. They can be handled as dependencies of options that need them, such as SPL_MMC. There is no point in enabling the block interface without any storage devices to create a block device. Hide both options from the 'menuconfig' display and deny their use in defconfig files. Signed-off-by: Simon Glass --- drivers/block/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig index e82a779e6b..707e2bcd23 100644 --- a/drivers/block/Kconfig +++ b/drivers/block/Kconfig @@ -1,5 +1,5 @@ config BLK - bool "Support block devices" + bool # "Support block devices" depends on DM default y if MMC || USB || SCSI || NVME || IDE || AHCI || SATA default y if EFI_MEDIA || VIRTIO_BLK || PVBLOCK @@ -12,7 +12,7 @@ config BLK A filesystem can be placed in each partition. config SPL_LEGACY_BLOCK - bool "Enable Legacy Block Device" + bool # "Enable Legacy Block Device" depends on SPL && !DM_SPL default y if SPL_MMC || SPL_USB_STORAGE || SCSI || NVME || IDE default y if SPL_AHCI_PCI From 1c2e255334a222dc4070afff13a8b985ec9bb1b2 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 11 Aug 2022 19:34:52 -0600 Subject: [PATCH 187/374] blk: Drop IF_TYPE_DOC This doesn't seem to be used for anything and it isn't clear what it is. It dates from the first U-Boot commit. Drop it. Signed-off-by: Simon Glass --- disk/part.c | 9 --------- drivers/block/blk-uclass.c | 2 -- include/blk.h | 1 - 3 files changed, 12 deletions(-) diff --git a/disk/part.c b/disk/part.c index 9594bb432c..5f64da54e5 100644 --- a/disk/part.c +++ b/disk/part.c @@ -150,9 +150,6 @@ void dev_print (struct blk_desc *dev_desc) case IF_TYPE_VIRTIO: printf("%s VirtIO Block Device\n", dev_desc->vendor); break; - case IF_TYPE_DOC: - puts("device type DOC\n"); - return; case IF_TYPE_UNKNOWN: puts("device type unknown\n"); return; @@ -266,9 +263,6 @@ static void print_part_header(const char *type, struct blk_desc *dev_desc) case IF_TYPE_USB: puts ("USB"); break; - case IF_TYPE_DOC: - puts ("DOC"); - break; case IF_TYPE_MMC: puts ("MMC"); break; @@ -782,9 +776,6 @@ void part_set_generic_name(const struct blk_desc *dev_desc, case IF_TYPE_USB: devtype = "usbd"; break; - case IF_TYPE_DOC: - devtype = "docd"; - break; case IF_TYPE_MMC: case IF_TYPE_SD: devtype = "mmcsd"; diff --git a/drivers/block/blk-uclass.c b/drivers/block/blk-uclass.c index 1a6e8f8c29..f16cb279d4 100644 --- a/drivers/block/blk-uclass.c +++ b/drivers/block/blk-uclass.c @@ -22,7 +22,6 @@ static const char *if_typename_str[IF_TYPE_COUNT] = { [IF_TYPE_SCSI] = "scsi", [IF_TYPE_ATAPI] = "atapi", [IF_TYPE_USB] = "usb", - [IF_TYPE_DOC] = "doc", [IF_TYPE_MMC] = "mmc", [IF_TYPE_SD] = "sd", [IF_TYPE_SATA] = "sata", @@ -39,7 +38,6 @@ static enum uclass_id if_type_uclass_id[IF_TYPE_COUNT] = { [IF_TYPE_SCSI] = UCLASS_SCSI, [IF_TYPE_ATAPI] = UCLASS_INVALID, [IF_TYPE_USB] = UCLASS_MASS_STORAGE, - [IF_TYPE_DOC] = UCLASS_INVALID, [IF_TYPE_MMC] = UCLASS_MMC, [IF_TYPE_SD] = UCLASS_INVALID, [IF_TYPE_SATA] = UCLASS_AHCI, diff --git a/include/blk.h b/include/blk.h index 5bdffe7401..1898ebdda5 100644 --- a/include/blk.h +++ b/include/blk.h @@ -33,7 +33,6 @@ enum if_type { IF_TYPE_SCSI, IF_TYPE_ATAPI, IF_TYPE_USB, - IF_TYPE_DOC, IF_TYPE_MMC, IF_TYPE_SD, IF_TYPE_SATA, From 606e0542b591efa5cf2927dfbfe9569c7264b01a Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 11 Aug 2022 19:34:53 -0600 Subject: [PATCH 188/374] ide: Use a flag for an ATAPI device Rather than setting a different interface type, use a flag to indicate that a device is ATAPI. Signed-off-by: Simon Glass --- drivers/block/ide.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/block/ide.c b/drivers/block/ide.c index 3270a9f032..6bc48e3402 100644 --- a/drivers/block/ide.c +++ b/drivers/block/ide.c @@ -525,8 +525,8 @@ static void ide_ident(struct blk_desc *dev_desc) { unsigned char c; hd_driveid_t iop; - #ifdef CONFIG_ATAPI + bool is_atapi = false; int retries = 0; #endif int device; @@ -550,7 +550,7 @@ static void ide_ident(struct blk_desc *dev_desc) (ide_inb(device, ATA_CYL_LOW) == 0x14) && (ide_inb(device, ATA_CYL_HIGH) == 0xEB)) { /* ATAPI Signature found */ - dev_desc->if_type = IF_TYPE_ATAPI; + is_atapi = true; /* * Start Ident Command */ @@ -623,7 +623,7 @@ static void ide_ident(struct blk_desc *dev_desc) dev_desc->removable = 0; #ifdef CONFIG_ATAPI - if (dev_desc->if_type == IF_TYPE_ATAPI) { + if (is_atapi) { atapi_inquiry(dev_desc); return; } From f512388ed8fbea6e5aefa2950e4b9673706ebfbe Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 11 Aug 2022 19:34:54 -0600 Subject: [PATCH 189/374] blk: Drop IF_TYPE_ATAPI This is not really needed since it does the same things as IDE. Drop it. Signed-off-by: Simon Glass --- disk/part.c | 5 ----- drivers/block/blk-uclass.c | 2 -- include/blk.h | 1 - 3 files changed, 8 deletions(-) diff --git a/disk/part.c b/disk/part.c index 5f64da54e5..a5c1d7a0ae 100644 --- a/disk/part.c +++ b/disk/part.c @@ -128,7 +128,6 @@ void dev_print (struct blk_desc *dev_desc) dev_desc->product, dev_desc->revision); break; - case IF_TYPE_ATAPI: case IF_TYPE_IDE: case IF_TYPE_SATA: printf ("Model: %s Firm: %s Ser#: %s\n", @@ -257,9 +256,6 @@ static void print_part_header(const char *type, struct blk_desc *dev_desc) case IF_TYPE_SCSI: puts ("SCSI"); break; - case IF_TYPE_ATAPI: - puts ("ATAPI"); - break; case IF_TYPE_USB: puts ("USB"); break; @@ -767,7 +763,6 @@ void part_set_generic_name(const struct blk_desc *dev_desc, switch (dev_desc->if_type) { case IF_TYPE_IDE: case IF_TYPE_SATA: - case IF_TYPE_ATAPI: devtype = "hd"; break; case IF_TYPE_SCSI: diff --git a/drivers/block/blk-uclass.c b/drivers/block/blk-uclass.c index f16cb279d4..57230e9bab 100644 --- a/drivers/block/blk-uclass.c +++ b/drivers/block/blk-uclass.c @@ -20,7 +20,6 @@ static const char *if_typename_str[IF_TYPE_COUNT] = { [IF_TYPE_IDE] = "ide", [IF_TYPE_SCSI] = "scsi", - [IF_TYPE_ATAPI] = "atapi", [IF_TYPE_USB] = "usb", [IF_TYPE_MMC] = "mmc", [IF_TYPE_SD] = "sd", @@ -36,7 +35,6 @@ static const char *if_typename_str[IF_TYPE_COUNT] = { static enum uclass_id if_type_uclass_id[IF_TYPE_COUNT] = { [IF_TYPE_IDE] = UCLASS_IDE, [IF_TYPE_SCSI] = UCLASS_SCSI, - [IF_TYPE_ATAPI] = UCLASS_INVALID, [IF_TYPE_USB] = UCLASS_MASS_STORAGE, [IF_TYPE_MMC] = UCLASS_MMC, [IF_TYPE_SD] = UCLASS_INVALID, diff --git a/include/blk.h b/include/blk.h index 1898ebdda5..c7461f9f35 100644 --- a/include/blk.h +++ b/include/blk.h @@ -31,7 +31,6 @@ enum if_type { IF_TYPE_UNKNOWN = 0, IF_TYPE_IDE, IF_TYPE_SCSI, - IF_TYPE_ATAPI, IF_TYPE_USB, IF_TYPE_MMC, IF_TYPE_SD, From 1dbe71fbb83891967cd4ce58118e008b03a90e73 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 11 Aug 2022 19:34:55 -0600 Subject: [PATCH 190/374] blk: Drop IF_TYPE_SD This is not really needed since it does the same things as MMC. Drop it. Signed-off-by: Simon Glass --- disk/part.c | 2 -- drivers/block/blk-uclass.c | 2 -- include/blk.h | 1 - 3 files changed, 5 deletions(-) diff --git a/disk/part.c b/disk/part.c index a5c1d7a0ae..2bcc6f4f40 100644 --- a/disk/part.c +++ b/disk/part.c @@ -135,7 +135,6 @@ void dev_print (struct blk_desc *dev_desc) dev_desc->revision, dev_desc->product); break; - case IF_TYPE_SD: case IF_TYPE_MMC: case IF_TYPE_USB: case IF_TYPE_NVME: @@ -772,7 +771,6 @@ void part_set_generic_name(const struct blk_desc *dev_desc, devtype = "usbd"; break; case IF_TYPE_MMC: - case IF_TYPE_SD: devtype = "mmcsd"; break; default: diff --git a/drivers/block/blk-uclass.c b/drivers/block/blk-uclass.c index 57230e9bab..2fa6a7e688 100644 --- a/drivers/block/blk-uclass.c +++ b/drivers/block/blk-uclass.c @@ -22,7 +22,6 @@ static const char *if_typename_str[IF_TYPE_COUNT] = { [IF_TYPE_SCSI] = "scsi", [IF_TYPE_USB] = "usb", [IF_TYPE_MMC] = "mmc", - [IF_TYPE_SD] = "sd", [IF_TYPE_SATA] = "sata", [IF_TYPE_HOST] = "host", [IF_TYPE_NVME] = "nvme", @@ -37,7 +36,6 @@ static enum uclass_id if_type_uclass_id[IF_TYPE_COUNT] = { [IF_TYPE_SCSI] = UCLASS_SCSI, [IF_TYPE_USB] = UCLASS_MASS_STORAGE, [IF_TYPE_MMC] = UCLASS_MMC, - [IF_TYPE_SD] = UCLASS_INVALID, [IF_TYPE_SATA] = UCLASS_AHCI, [IF_TYPE_HOST] = UCLASS_ROOT, [IF_TYPE_NVME] = UCLASS_NVME, diff --git a/include/blk.h b/include/blk.h index c7461f9f35..cc30e3861f 100644 --- a/include/blk.h +++ b/include/blk.h @@ -33,7 +33,6 @@ enum if_type { IF_TYPE_SCSI, IF_TYPE_USB, IF_TYPE_MMC, - IF_TYPE_SD, IF_TYPE_SATA, IF_TYPE_HOST, IF_TYPE_NVME, From b8f8f6c8702368a5e6bd6e58556c03d5f8e3f1c7 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 11 Aug 2022 19:34:56 -0600 Subject: [PATCH 191/374] blk: Rename var in blk_get_devnum_by_typename() At present we use a variable with the same name as the enum. Change this since we plan to #define the enum to uclass_id. Signed-off-by: Simon Glass --- drivers/block/blk-uclass.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/block/blk-uclass.c b/drivers/block/blk-uclass.c index 2fa6a7e688..3738517d8d 100644 --- a/drivers/block/blk-uclass.c +++ b/drivers/block/blk-uclass.c @@ -90,21 +90,21 @@ struct blk_desc *blk_get_devnum_by_type(enum if_type if_type, int devnum) struct blk_desc *blk_get_devnum_by_typename(const char *if_typename, int devnum) { enum uclass_id uclass_id; - enum if_type if_type; + enum if_type type; struct udevice *dev; struct uclass *uc; int ret; - if_type = if_typename_to_iftype(if_typename); - if (if_type == IF_TYPE_UNKNOWN) { + type = if_typename_to_iftype(if_typename); + if (type == IF_TYPE_UNKNOWN) { debug("%s: Unknown interface type '%s'\n", __func__, if_typename); return NULL; } - uclass_id = if_type_to_uclass_id(if_type); + uclass_id = if_type_to_uclass_id(type); if (uclass_id == UCLASS_INVALID) { debug("%s: Unknown uclass for interface type'\n", - if_typename_str[if_type]); + if_typename_str[type]); return NULL; } @@ -115,7 +115,7 @@ struct blk_desc *blk_get_devnum_by_typename(const char *if_typename, int devnum) struct blk_desc *desc = dev_get_uclass_plat(dev); debug("%s: if_type=%d, devnum=%d: %s, %d, %d\n", __func__, - if_type, devnum, dev->name, desc->if_type, desc->devnum); + type, devnum, dev->name, desc->if_type, desc->devnum); if (desc->devnum != devnum) continue; From bb2c9a30c23752accd53119d3964f6e6d1ae4f32 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 11 Aug 2022 19:34:57 -0600 Subject: [PATCH 192/374] blk: Rewrite if_type to name functions These are currently using a simple array lookup in one direction, and relying on if_type being sequential. With the move to uclass IDs this needs to change. Update the code to prepare for the new way. This patch is intended to introduce no functional change. The returning of "(none)" from blk_get_if_type_name() is handling a case that should not happen in either case. Signed-off-by: Simon Glass --- drivers/block/blk-uclass.c | 45 +++++++++++++++++++++++--------------- 1 file changed, 27 insertions(+), 18 deletions(-) diff --git a/drivers/block/blk-uclass.c b/drivers/block/blk-uclass.c index 3738517d8d..a68158c3f2 100644 --- a/drivers/block/blk-uclass.c +++ b/drivers/block/blk-uclass.c @@ -17,18 +17,21 @@ #include #include -static const char *if_typename_str[IF_TYPE_COUNT] = { - [IF_TYPE_IDE] = "ide", - [IF_TYPE_SCSI] = "scsi", - [IF_TYPE_USB] = "usb", - [IF_TYPE_MMC] = "mmc", - [IF_TYPE_SATA] = "sata", - [IF_TYPE_HOST] = "host", - [IF_TYPE_NVME] = "nvme", - [IF_TYPE_EFI_MEDIA] = "efi", - [IF_TYPE_EFI_LOADER] = "efiloader", - [IF_TYPE_VIRTIO] = "virtio", - [IF_TYPE_PVBLOCK] = "pvblock", +static struct { + enum uclass_id id; + const char *name; +} if_typename_str[] = { + { IF_TYPE_IDE, "ide" }, + { IF_TYPE_SCSI, "scsi" }, + { IF_TYPE_USB, "usb" }, + { IF_TYPE_MMC, "mmc" }, + { IF_TYPE_SCSI, "sata" }, + { IF_TYPE_HOST, "host" }, + { IF_TYPE_NVME, "nvme" }, + { IF_TYPE_EFI_MEDIA, "efi" }, + { IF_TYPE_EFI_LOADER, "efiloader" }, + { IF_TYPE_VIRTIO, "virtio" }, + { IF_TYPE_PVBLOCK, "pvblock" }, }; static enum uclass_id if_type_uclass_id[IF_TYPE_COUNT] = { @@ -49,10 +52,9 @@ static enum if_type if_typename_to_iftype(const char *if_typename) { int i; - for (i = 0; i < IF_TYPE_COUNT; i++) { - if (if_typename_str[i] && - !strcmp(if_typename, if_typename_str[i])) - return i; + for (i = 0; i < ARRAY_SIZE(if_typename_str); i++) { + if (!strcmp(if_typename, if_typename_str[i].name)) + return if_typename_str[i].id; } return IF_TYPE_UNKNOWN; @@ -65,7 +67,14 @@ static enum uclass_id if_type_to_uclass_id(enum if_type if_type) const char *blk_get_if_type_name(enum if_type if_type) { - return if_typename_str[if_type]; + int i; + + for (i = 0; i < ARRAY_SIZE(if_typename_str); i++) { + if ((int)if_typename_str[i].id == if_type) + return if_typename_str[i].name; + } + + return "(none)"; } struct blk_desc *blk_get_devnum_by_type(enum if_type if_type, int devnum) @@ -104,7 +113,7 @@ struct blk_desc *blk_get_devnum_by_typename(const char *if_typename, int devnum) uclass_id = if_type_to_uclass_id(type); if (uclass_id == UCLASS_INVALID) { debug("%s: Unknown uclass for interface type'\n", - if_typename_str[type]); + blk_get_if_type_name(type)); return NULL; } From adbfe8edc3389ba635229195a95217d8b0dfa182 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 11 Aug 2022 19:34:58 -0600 Subject: [PATCH 193/374] efi: Correct assumption about if_type efi_set_blk_dev_to_system_partition() assumes that 0 is an invalid if_type. This is true now but is about to be false. Fix this bug to avoid a test failure. Signed-off-by: Simon Glass --- lib/efi_loader/efi_var_file.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/efi_loader/efi_var_file.c b/lib/efi_loader/efi_var_file.c index 76a2ff9e41..994e66392f 100644 --- a/lib/efi_loader/efi_var_file.c +++ b/lib/efi_loader/efi_var_file.c @@ -38,7 +38,7 @@ static efi_status_t __maybe_unused efi_set_blk_dev_to_system_partition(void) char part_str[PART_STR_LEN]; int r; - if (!efi_system_partition.if_type) { + if (efi_system_partition.if_type == UCLASS_INVALID) { log_err("No EFI system partition\n"); return EFI_DEVICE_ERROR; } From e33a5c6be55e7c012b2851f9bdf90e7f607e72bf Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 11 Aug 2022 19:34:59 -0600 Subject: [PATCH 194/374] blk: Switch over to using uclass IDs We currently have an if_type (interface type) and a uclass id. These are closely related and we don't need to have both. Drop the if_type values and use the uclass ones instead. Maintain the existing, subtle, one-way conversion between UCLASS_USB and UCLASS_MASS_STORAGE for now, and add a comment. Signed-off-by: Simon Glass --- .../mach-stm32mp/cmd_stm32prog/stm32prog.c | 4 +- board/toradex/common/tdx-cfg-block.c | 4 +- cmd/bcb.c | 4 +- cmd/ide.c | 2 +- cmd/mmc.c | 8 +-- cmd/mvebu/bubt.c | 2 +- cmd/nvme.c | 4 +- cmd/pvblock.c | 2 +- cmd/sata.c | 4 +- cmd/scsi.c | 2 +- cmd/usb.c | 2 +- cmd/virtio.c | 2 +- common/spl/spl_sata.c | 2 +- common/spl/spl_usb.c | 2 +- common/usb_storage.c | 8 +-- disk/part.c | 52 +++++++-------- doc/develop/uefi/uefi.rst | 2 +- drivers/ata/dwc_ahsata.c | 2 +- drivers/ata/fsl_sata.c | 2 +- drivers/ata/sata.c | 2 +- drivers/ata/sata_mv.c | 2 +- drivers/ata/sata_sil.c | 2 +- drivers/block/blk-uclass.c | 64 ++++++++++--------- drivers/block/efi_blk.c | 2 +- drivers/block/ide.c | 8 +-- drivers/block/sandbox.c | 12 ++-- drivers/dfu/dfu_mmc.c | 6 +- drivers/mmc/mmc-uclass.c | 10 +-- drivers/mmc/mmc_legacy.c | 6 +- drivers/mmc/mmc_write.c | 4 +- drivers/nvme/nvme.c | 2 +- drivers/scsi/scsi.c | 10 +-- drivers/tee/optee/rpmb.c | 4 +- drivers/virtio/virtio_blk.c | 4 +- drivers/xen/pvblock.c | 6 +- env/mmc.c | 4 +- include/blk.h | 18 +----- include/mmc.h | 2 +- lib/efi_driver/efi_block_device.c | 4 +- lib/efi_loader/efi_disk.c | 4 +- test/dm/blk.c | 24 +++---- 41 files changed, 151 insertions(+), 159 deletions(-) diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c index c391b6c7ab..a720d0ba71 100644 --- a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c +++ b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c @@ -1823,7 +1823,7 @@ static int part_delete(struct stm32prog_data *data, * need to switch to associated hwpart 1 or 2 */ if (part->part_id < 0) - if (blk_select_hwpart_devnum(IF_TYPE_MMC, + if (blk_select_hwpart_devnum(UCLASS_MMC, part->dev->dev_id, -part->part_id)) return -1; @@ -1832,7 +1832,7 @@ static int part_delete(struct stm32prog_data *data, /* return to user partition */ if (part->part_id < 0) - blk_select_hwpart_devnum(IF_TYPE_MMC, + blk_select_hwpart_devnum(UCLASS_MMC, part->dev->dev_id, 0); if (blks != blks_size) { ret = -1; diff --git a/board/toradex/common/tdx-cfg-block.c b/board/toradex/common/tdx-cfg-block.c index 22c67c6e38..11f4d5e14a 100644 --- a/board/toradex/common/tdx-cfg-block.c +++ b/board/toradex/common/tdx-cfg-block.c @@ -211,7 +211,7 @@ static int tdx_cfg_block_mmc_storage(u8 *config_block, int write) return -EINVAL; } if (part != mmc_get_blk_desc(mmc)->hwpart) { - if (blk_select_hwpart_devnum(IF_TYPE_MMC, dev, part)) { + if (blk_select_hwpart_devnum(UCLASS_MMC, dev, part)) { puts("MMC partition switch failed\n"); ret = -ENODEV; goto out; @@ -239,7 +239,7 @@ static int tdx_cfg_block_mmc_storage(u8 *config_block, int write) out: /* Switch back to regular eMMC user partition */ - blk_select_hwpart_devnum(IF_TYPE_MMC, 0, 0); + blk_select_hwpart_devnum(UCLASS_MMC, 0, 0); return ret; } diff --git a/cmd/bcb.c b/cmd/bcb.c index 1bbd1fae99..8b87aa062f 100644 --- a/cmd/bcb.c +++ b/cmd/bcb.c @@ -122,7 +122,7 @@ static int __bcb_load(int devnum, const char *partp) char *endp; int part, ret; - desc = blk_get_devnum_by_type(IF_TYPE_MMC, devnum); + desc = blk_get_devnum_by_type(UCLASS_MMC, devnum); if (!desc) { ret = -ENODEV; goto err_read_fail; @@ -287,7 +287,7 @@ static int __bcb_store(void) u64 cnt; int ret; - desc = blk_get_devnum_by_type(IF_TYPE_MMC, bcb_dev); + desc = blk_get_devnum_by_type(UCLASS_MMC, bcb_dev); if (!desc) { ret = -ENODEV; goto err; diff --git a/cmd/ide.c b/cmd/ide.c index b78c38e159..6739f0b12d 100644 --- a/cmd/ide.c +++ b/cmd/ide.c @@ -37,7 +37,7 @@ int do_ide(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) } } - return blk_common_cmd(argc, argv, IF_TYPE_IDE, &curr_device); + return blk_common_cmd(argc, argv, UCLASS_IDE, &curr_device); } int do_diskboot(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) diff --git a/cmd/mmc.c b/cmd/mmc.c index 7bd4cd9e01..0f1f4e0a71 100644 --- a/cmd/mmc.c +++ b/cmd/mmc.c @@ -331,13 +331,13 @@ static int do_mmcrpmb(struct cmd_tbl *cmdtp, int flag, #else original_part = mmc_get_blk_desc(mmc)->hwpart; #endif - if (blk_select_hwpart_devnum(IF_TYPE_MMC, curr_device, MMC_PART_RPMB) != + if (blk_select_hwpart_devnum(UCLASS_MMC, curr_device, MMC_PART_RPMB) != 0) return CMD_RET_FAILURE; ret = cp->cmd(cmdtp, flag, argc, argv); /* Return to original partition */ - if (blk_select_hwpart_devnum(IF_TYPE_MMC, curr_device, original_part) != + if (blk_select_hwpart_devnum(UCLASS_MMC, curr_device, original_part) != 0) return CMD_RET_FAILURE; return ret; @@ -530,7 +530,7 @@ static int do_mmc_part(struct cmd_tbl *cmdtp, int flag, if (!mmc) return CMD_RET_FAILURE; - mmc_dev = blk_get_devnum_by_type(IF_TYPE_MMC, curr_device); + mmc_dev = blk_get_devnum_by_type(UCLASS_MMC, curr_device); if (mmc_dev != NULL && mmc_dev->type != DEV_TYPE_UNKNOWN) { part_print(mmc_dev); return CMD_RET_SUCCESS; @@ -580,7 +580,7 @@ static int do_mmc_dev(struct cmd_tbl *cmdtp, int flag, if (!mmc) return CMD_RET_FAILURE; - ret = blk_select_hwpart_devnum(IF_TYPE_MMC, dev, part); + ret = blk_select_hwpart_devnum(UCLASS_MMC, dev, part); printf("switch to partitions #%d, %s\n", part, (!ret) ? "OK" : "ERROR"); if (ret) diff --git a/cmd/mvebu/bubt.c b/cmd/mvebu/bubt.c index 2136af6416..825d4beb89 100644 --- a/cmd/mvebu/bubt.c +++ b/cmd/mvebu/bubt.c @@ -412,7 +412,7 @@ static size_t usb_read_file(const char *file_name) } /* Try to recognize storage devices immediately */ - blk_first_device(IF_TYPE_USB, &dev); + blk_first_device(UCLASS_USB, &dev); if (!dev) { printf("Error: USB storage device not found\n"); return 0; diff --git a/cmd/nvme.c b/cmd/nvme.c index e715c570a3..09d5f438fb 100644 --- a/cmd/nvme.c +++ b/cmd/nvme.c @@ -28,7 +28,7 @@ static int do_nvme(struct cmd_tbl *cmdtp, int flag, int argc, if (strncmp(argv[1], "deta", 4) == 0) { struct udevice *udev; - ret = blk_get_device(IF_TYPE_NVME, nvme_curr_dev, + ret = blk_get_device(UCLASS_NVME, nvme_curr_dev, &udev); if (ret < 0) return CMD_RET_FAILURE; @@ -39,7 +39,7 @@ static int do_nvme(struct cmd_tbl *cmdtp, int flag, int argc, } } - return blk_common_cmd(argc, argv, IF_TYPE_NVME, &nvme_curr_dev); + return blk_common_cmd(argc, argv, UCLASS_NVME, &nvme_curr_dev); } U_BOOT_CMD( diff --git a/cmd/pvblock.c b/cmd/pvblock.c index 56ce8b18d5..1b604c3737 100644 --- a/cmd/pvblock.c +++ b/cmd/pvblock.c @@ -14,7 +14,7 @@ static int pvblock_curr_device; int do_pvblock(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) { - return blk_common_cmd(argc, argv, IF_TYPE_PVBLOCK, + return blk_common_cmd(argc, argv, UCLASS_PVBLOCK, &pvblock_curr_device); } diff --git a/cmd/sata.c b/cmd/sata.c index 76da1906b7..9c9fe111d1 100644 --- a/cmd/sata.c +++ b/cmd/sata.c @@ -27,7 +27,7 @@ int sata_remove(int devnum) struct udevice *dev; int rc; - blk_unbind_all(IF_TYPE_SATA); + blk_unbind_all(UCLASS_AHCI); rc = uclass_find_device(UCLASS_AHCI, devnum, &dev); if (!rc && !dev) @@ -111,7 +111,7 @@ static int do_sata(struct cmd_tbl *cmdtp, int flag, int argc, sata_curr_device = 0; } - return blk_common_cmd(argc, argv, IF_TYPE_SATA, &sata_curr_device); + return blk_common_cmd(argc, argv, UCLASS_AHCI, &sata_curr_device); } U_BOOT_CMD( diff --git a/cmd/scsi.c b/cmd/scsi.c index 5f710d2895..4549995ba7 100644 --- a/cmd/scsi.c +++ b/cmd/scsi.c @@ -50,7 +50,7 @@ static int do_scsi(struct cmd_tbl *cmdtp, int flag, int argc, } } - return blk_common_cmd(argc, argv, IF_TYPE_SCSI, &scsi_curr_dev); + return blk_common_cmd(argc, argv, UCLASS_SCSI, &scsi_curr_dev); } U_BOOT_CMD( diff --git a/cmd/usb.c b/cmd/usb.c index 3d87376525..2ba056982c 100644 --- a/cmd/usb.c +++ b/cmd/usb.c @@ -719,7 +719,7 @@ static int do_usb(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) if (strncmp(argv[1], "stor", 4) == 0) return usb_stor_info(); - return blk_common_cmd(argc, argv, IF_TYPE_USB, &usb_stor_curr_dev); + return blk_common_cmd(argc, argv, UCLASS_USB, &usb_stor_curr_dev); #else return CMD_RET_USAGE; #endif /* CONFIG_USB_STORAGE */ diff --git a/cmd/virtio.c b/cmd/virtio.c index ea3ed2e631..ec87d4f02c 100644 --- a/cmd/virtio.c +++ b/cmd/virtio.c @@ -40,7 +40,7 @@ static int do_virtio(struct cmd_tbl *cmdtp, int flag, int argc, return CMD_RET_SUCCESS; } - return blk_common_cmd(argc, argv, IF_TYPE_VIRTIO, &virtio_curr_dev); + return blk_common_cmd(argc, argv, UCLASS_VIRTIO, &virtio_curr_dev); } U_BOOT_CMD( diff --git a/common/spl/spl_sata.c b/common/spl/spl_sata.c index 1351d78612..ea9f1756c0 100644 --- a/common/spl/spl_sata.c +++ b/common/spl/spl_sata.c @@ -71,7 +71,7 @@ static int spl_sata_load_image(struct spl_image_info *spl_image, /* try to recognize storage devices immediately */ scsi_scan(false); - stor_dev = blk_get_devnum_by_type(IF_TYPE_SCSI, 0); + stor_dev = blk_get_devnum_by_type(UCLASS_SCSI, 0); if (!stor_dev) return -ENODEV; diff --git a/common/spl/spl_usb.c b/common/spl/spl_usb.c index ccf01c8276..63c00f872b 100644 --- a/common/spl/spl_usb.c +++ b/common/spl/spl_usb.c @@ -41,7 +41,7 @@ int spl_usb_load(struct spl_image_info *spl_image, /* try to recognize storage devices immediately */ usb_stor_curr_dev = usb_stor_scan(1); - stor_dev = blk_get_devnum_by_type(IF_TYPE_USB, usb_stor_curr_dev); + stor_dev = blk_get_devnum_by_type(UCLASS_USB, usb_stor_curr_dev); if (!stor_dev) return -ENODEV; diff --git a/common/usb_storage.c b/common/usb_storage.c index eaa31374ef..7d420160cd 100644 --- a/common/usb_storage.c +++ b/common/usb_storage.c @@ -144,7 +144,7 @@ int usb_stor_info(void) #if CONFIG_IS_ENABLED(BLK) struct udevice *dev; - for (blk_first_device(IF_TYPE_USB, &dev); + for (blk_first_device(UCLASS_USB, &dev); dev; blk_next_device(&dev)) { struct blk_desc *desc = dev_get_uclass_plat(dev); @@ -219,7 +219,7 @@ static int usb_stor_probe_device(struct usb_device *udev) snprintf(str, sizeof(str), "lun%d", lun); ret = blk_create_devicef(udev->dev, "usb_storage_blk", str, - IF_TYPE_USB, usb_max_devs, 512, 0, + UCLASS_USB, usb_max_devs, 512, 0, &dev); if (ret) { debug("Cannot bind driver\n"); @@ -279,7 +279,7 @@ static int usb_stor_probe_device(struct usb_device *udev) blkdev = &usb_dev_desc[usb_max_devs]; memset(blkdev, '\0', sizeof(struct blk_desc)); - blkdev->if_type = IF_TYPE_USB; + blkdev->if_type = UCLASS_USB; blkdev->devnum = usb_max_devs; blkdev->part_type = PART_TYPE_UNKNOWN; blkdev->target = 0xff; @@ -1578,7 +1578,7 @@ U_BOOT_DRIVER(usb_storage_blk) = { #else U_BOOT_LEGACY_BLK(usb) = { .if_typename = "usb", - .if_type = IF_TYPE_USB, + .if_type = UCLASS_USB, .max_devs = USB_MAX_STOR_DEV, .desc = usb_dev_desc, }; diff --git a/disk/part.c b/disk/part.c index 2bcc6f4f40..75aff7eba5 100644 --- a/disk/part.c +++ b/disk/part.c @@ -121,34 +121,34 @@ void dev_print (struct blk_desc *dev_desc) } switch (dev_desc->if_type) { - case IF_TYPE_SCSI: + case UCLASS_SCSI: printf ("(%d:%d) Vendor: %s Prod.: %s Rev: %s\n", dev_desc->target,dev_desc->lun, dev_desc->vendor, dev_desc->product, dev_desc->revision); break; - case IF_TYPE_IDE: - case IF_TYPE_SATA: + case UCLASS_IDE: + case UCLASS_AHCI: printf ("Model: %s Firm: %s Ser#: %s\n", dev_desc->vendor, dev_desc->revision, dev_desc->product); break; - case IF_TYPE_MMC: - case IF_TYPE_USB: - case IF_TYPE_NVME: - case IF_TYPE_PVBLOCK: - case IF_TYPE_HOST: + case UCLASS_MMC: + case UCLASS_USB: + case UCLASS_NVME: + case UCLASS_PVBLOCK: + case UCLASS_ROOT: printf ("Vendor: %s Rev: %s Prod: %s\n", dev_desc->vendor, dev_desc->revision, dev_desc->product); break; - case IF_TYPE_VIRTIO: + case UCLASS_VIRTIO: printf("%s VirtIO Block Device\n", dev_desc->vendor); break; - case IF_TYPE_UNKNOWN: + case UCLASS_INVALID: puts("device type unknown\n"); return; default: @@ -246,34 +246,34 @@ static void print_part_header(const char *type, struct blk_desc *dev_desc) CONFIG_IS_ENABLED(EFI_PARTITION) puts ("\nPartition Map for "); switch (dev_desc->if_type) { - case IF_TYPE_IDE: + case UCLASS_IDE: puts ("IDE"); break; - case IF_TYPE_SATA: + case UCLASS_AHCI: puts ("SATA"); break; - case IF_TYPE_SCSI: + case UCLASS_SCSI: puts ("SCSI"); break; - case IF_TYPE_USB: + case UCLASS_USB: puts ("USB"); break; - case IF_TYPE_MMC: + case UCLASS_MMC: puts ("MMC"); break; - case IF_TYPE_HOST: + case UCLASS_ROOT: puts ("HOST"); break; - case IF_TYPE_NVME: + case UCLASS_NVME: puts ("NVMe"); break; - case IF_TYPE_PVBLOCK: + case UCLASS_PVBLOCK: puts("PV BLOCK"); break; - case IF_TYPE_VIRTIO: + case UCLASS_VIRTIO: puts("VirtIO"); break; - case IF_TYPE_EFI_MEDIA: + case UCLASS_EFI_MEDIA: puts("EFI"); break; default: @@ -405,7 +405,7 @@ int blk_get_device_by_str(const char *ifname, const char *dev_hwpart_str, * Always should be done, otherwise hw partition 0 will return * stale data after displaying a non-zero hw partition. */ - if ((*dev_desc)->if_type == IF_TYPE_MMC) + if ((*dev_desc)->if_type == UCLASS_MMC) part_init(*dev_desc); } @@ -760,17 +760,17 @@ void part_set_generic_name(const struct blk_desc *dev_desc, char *devtype; switch (dev_desc->if_type) { - case IF_TYPE_IDE: - case IF_TYPE_SATA: + case UCLASS_IDE: + case UCLASS_AHCI: devtype = "hd"; break; - case IF_TYPE_SCSI: + case UCLASS_SCSI: devtype = "sd"; break; - case IF_TYPE_USB: + case UCLASS_USB: devtype = "usbd"; break; - case IF_TYPE_MMC: + case UCLASS_MMC: devtype = "mmcsd"; break; default: diff --git a/doc/develop/uefi/uefi.rst b/doc/develop/uefi/uefi.rst index 941e427093..cd84706953 100644 --- a/doc/develop/uefi/uefi.rst +++ b/doc/develop/uefi/uefi.rst @@ -748,7 +748,7 @@ UEFI block IO driver The UEFI block IO driver supports devices exposing the EFI_BLOCK_IO_PROTOCOL. When connected it creates a new U-Boot block IO device with interface type -IF_TYPE_EFI_LOADER, adds child controllers mapping the partitions, and installs +UCLASS_EFI_LOADER, adds child controllers mapping the partitions, and installs the EFI_SIMPLE_FILE_SYSTEM_PROTOCOL on these. This can be used together with the software iPXE to boot from iSCSI network drives [4]. diff --git a/drivers/ata/dwc_ahsata.c b/drivers/ata/dwc_ahsata.c index 1a2c3c2fe7..167b5a395f 100644 --- a/drivers/ata/dwc_ahsata.c +++ b/drivers/ata/dwc_ahsata.c @@ -880,7 +880,7 @@ int dwc_ahsata_scan(struct udevice *dev) device_find_first_child(dev, &blk); if (!blk) { ret = blk_create_devicef(dev, "dwc_ahsata_blk", "blk", - IF_TYPE_SATA, -1, 512, 0, &blk); + UCLASS_AHCI, -1, 512, 0, &blk); if (ret) { debug("Can't create device\n"); return ret; diff --git a/drivers/ata/fsl_sata.c b/drivers/ata/fsl_sata.c index 6db4247368..972101b29c 100644 --- a/drivers/ata/fsl_sata.c +++ b/drivers/ata/fsl_sata.c @@ -888,7 +888,7 @@ static int fsl_ata_probe(struct udevice *dev) for (i = 0; i < nr_ports; i++) { snprintf(sata_name, sizeof(sata_name), "fsl_sata%d", i); ret = blk_create_devicef(dev, "sata_fsl_blk", sata_name, - IF_TYPE_SATA, -1, 512, 0, &blk); + UCLASS_AHCI, -1, 512, 0, &blk); if (ret) { debug("Can't create device\n"); return ret; diff --git a/drivers/ata/sata.c b/drivers/ata/sata.c index 0e6c8cdd42..604c721cfd 100644 --- a/drivers/ata/sata.c +++ b/drivers/ata/sata.c @@ -79,7 +79,7 @@ int __sata_initialize(void) for (i = 0; i < CONFIG_SYS_SATA_MAX_DEVICE; i++) { memset(&sata_dev_desc[i], 0, sizeof(struct blk_desc)); - sata_dev_desc[i].if_type = IF_TYPE_SATA; + sata_dev_desc[i].if_type = UCLASS_AHCI; sata_dev_desc[i].devnum = i; sata_dev_desc[i].part_type = PART_TYPE_UNKNOWN; sata_dev_desc[i].type = DEV_TYPE_HARDDISK; diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index a187796dfc..18c7a66db1 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c @@ -1076,7 +1076,7 @@ static int sata_mv_probe(struct udevice *dev) for (i = 0; i < nr_ports; i++) { ret = blk_create_devicef(dev, "sata_mv_blk", "blk", - IF_TYPE_SATA, -1, 512, 0, &blk); + UCLASS_AHCI, -1, 512, 0, &blk); if (ret) { debug("Can't create device\n"); continue; diff --git a/drivers/ata/sata_sil.c b/drivers/ata/sata_sil.c index 7065154572..b5e150d568 100644 --- a/drivers/ata/sata_sil.c +++ b/drivers/ata/sata_sil.c @@ -730,7 +730,7 @@ static int sil_pci_probe(struct udevice *dev) for (i = sata_info.portbase; i < sata_info.maxport; i++) { snprintf(sata_name, sizeof(sata_name), "sil_sata%d", i); ret = blk_create_devicef(dev, "sata_sil_blk", sata_name, - IF_TYPE_SATA, -1, 512, 0, &blk); + UCLASS_AHCI, -1, 512, 0, &blk); if (ret) { debug("Can't create device\n"); return ret; diff --git a/drivers/block/blk-uclass.c b/drivers/block/blk-uclass.c index a68158c3f2..436af764f9 100644 --- a/drivers/block/blk-uclass.c +++ b/drivers/block/blk-uclass.c @@ -21,31 +21,17 @@ static struct { enum uclass_id id; const char *name; } if_typename_str[] = { - { IF_TYPE_IDE, "ide" }, - { IF_TYPE_SCSI, "scsi" }, - { IF_TYPE_USB, "usb" }, - { IF_TYPE_MMC, "mmc" }, - { IF_TYPE_SCSI, "sata" }, - { IF_TYPE_HOST, "host" }, - { IF_TYPE_NVME, "nvme" }, - { IF_TYPE_EFI_MEDIA, "efi" }, - { IF_TYPE_EFI_LOADER, "efiloader" }, - { IF_TYPE_VIRTIO, "virtio" }, - { IF_TYPE_PVBLOCK, "pvblock" }, -}; - -static enum uclass_id if_type_uclass_id[IF_TYPE_COUNT] = { - [IF_TYPE_IDE] = UCLASS_IDE, - [IF_TYPE_SCSI] = UCLASS_SCSI, - [IF_TYPE_USB] = UCLASS_MASS_STORAGE, - [IF_TYPE_MMC] = UCLASS_MMC, - [IF_TYPE_SATA] = UCLASS_AHCI, - [IF_TYPE_HOST] = UCLASS_ROOT, - [IF_TYPE_NVME] = UCLASS_NVME, - [IF_TYPE_EFI_MEDIA] = UCLASS_EFI_MEDIA, - [IF_TYPE_EFI_LOADER] = UCLASS_EFI_LOADER, - [IF_TYPE_VIRTIO] = UCLASS_VIRTIO, - [IF_TYPE_PVBLOCK] = UCLASS_PVBLOCK, + { UCLASS_IDE, "ide" }, + { UCLASS_SCSI, "scsi" }, + { UCLASS_USB, "usb" }, + { UCLASS_MMC, "mmc" }, + { UCLASS_AHCI, "sata" }, + { UCLASS_ROOT, "host" }, + { UCLASS_NVME, "nvme" }, + { UCLASS_EFI_MEDIA, "efi" }, + { UCLASS_EFI_LOADER, "efiloader" }, + { UCLASS_VIRTIO, "virtio" }, + { UCLASS_PVBLOCK, "pvblock" }, }; static enum if_type if_typename_to_iftype(const char *if_typename) @@ -57,12 +43,32 @@ static enum if_type if_typename_to_iftype(const char *if_typename) return if_typename_str[i].id; } - return IF_TYPE_UNKNOWN; + return UCLASS_INVALID; } static enum uclass_id if_type_to_uclass_id(enum if_type if_type) { - return if_type_uclass_id[if_type]; + /* + * This strange adjustment is used because we use UCLASS_MASS_STORAGE + * for USB storage devices, so need to return this as the uclass to + * use for USB. In fact USB_UCLASS is for USB controllers, not + * peripherals. + * + * The name of the UCLASS_MASS_STORAGE uclass driver is + * "usb_mass_storage", but we want to use "usb" in things like the + * 'part list' command and when showing interfaces. + * + * So for now we have this one-way conversion. + * + * The fix for this is possibly to: + * - rename UCLASS_MASS_STORAGE name to "usb" + * - rename UCLASS_USB name to "usb_ctlr" + * - use UCLASS_MASS_STORAGE instead of UCLASS_USB in if_typename_str + */ + if (if_type == UCLASS_USB) + return UCLASS_MASS_STORAGE; + + return if_type; } const char *blk_get_if_type_name(enum if_type if_type) @@ -70,7 +76,7 @@ const char *blk_get_if_type_name(enum if_type if_type) int i; for (i = 0; i < ARRAY_SIZE(if_typename_str); i++) { - if ((int)if_typename_str[i].id == if_type) + if (if_typename_str[i].id == if_type) return if_typename_str[i].name; } @@ -105,7 +111,7 @@ struct blk_desc *blk_get_devnum_by_typename(const char *if_typename, int devnum) int ret; type = if_typename_to_iftype(if_typename); - if (type == IF_TYPE_UNKNOWN) { + if (type == UCLASS_INVALID) { debug("%s: Unknown interface type '%s'\n", __func__, if_typename); return NULL; diff --git a/drivers/block/efi_blk.c b/drivers/block/efi_blk.c index 9d25ecbf37..917a19f602 100644 --- a/drivers/block/efi_blk.c +++ b/drivers/block/efi_blk.c @@ -94,7 +94,7 @@ static int efi_media_bind(struct udevice *dev) struct udevice *blk; int ret; - ret = blk_create_devicef(dev, "efi_block", "blk", IF_TYPE_EFI_MEDIA, + ret = blk_create_devicef(dev, "efi_block", "blk", UCLASS_EFI_MEDIA, dev_seq(dev), plat->blkio->media->block_size, plat->blkio->media->last_block, &blk); if (ret) { diff --git a/drivers/block/ide.c b/drivers/block/ide.c index 6bc48e3402..73da29ad55 100644 --- a/drivers/block/ide.c +++ b/drivers/block/ide.c @@ -537,7 +537,7 @@ static void ide_ident(struct blk_desc *dev_desc) /* Select device */ ide_outb(device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device)); - dev_desc->if_type = IF_TYPE_IDE; + dev_desc->if_type = UCLASS_IDE; #ifdef CONFIG_ATAPI retries = 0; @@ -752,7 +752,7 @@ void ide_init(void) for (i = 0; i < CONFIG_SYS_IDE_MAXDEVICE; ++i) { ide_dev_desc[i].type = DEV_TYPE_UNKNOWN; - ide_dev_desc[i].if_type = IF_TYPE_IDE; + ide_dev_desc[i].if_type = UCLASS_IDE; ide_dev_desc[i].devnum = i; ide_dev_desc[i].part_type = PART_TYPE_UNKNOWN; ide_dev_desc[i].blksz = 0; @@ -1110,7 +1110,7 @@ static int ide_probe(struct udevice *udev) if (!blksz) continue; ret = blk_create_devicef(udev, "ide_blk", name, - IF_TYPE_IDE, i, + UCLASS_IDE, i, blksz, size, &blk_dev); if (ret) return ret; @@ -1144,7 +1144,7 @@ UCLASS_DRIVER(ide) = { #else U_BOOT_LEGACY_BLK(ide) = { .if_typename = "ide", - .if_type = IF_TYPE_IDE, + .if_type = UCLASS_IDE, .max_devs = CONFIG_SYS_IDE_MAXDEVICE, .desc = ide_dev_desc, }; diff --git a/drivers/block/sandbox.c b/drivers/block/sandbox.c index 1388498a1d..2de12e0a93 100644 --- a/drivers/block/sandbox.c +++ b/drivers/block/sandbox.c @@ -98,7 +98,7 @@ int host_dev_bind(int devnum, char *filename, bool removable) int ret, fd; /* Remove and unbind the old device, if any */ - ret = blk_get_device(IF_TYPE_HOST, devnum, &dev); + ret = blk_get_device(UCLASS_ROOT, devnum, &dev); if (ret == 0) { ret = device_remove(dev, DM_REMOVE_NORMAL); if (ret) @@ -135,7 +135,7 @@ int host_dev_bind(int devnum, char *filename, bool removable) } } ret = blk_create_device(gd->dm_root, "sandbox_host_blk", str, - IF_TYPE_HOST, devnum, 512, + UCLASS_ROOT, devnum, 512, os_lseek(fd, 0, OS_SEEK_END) / 512, &dev); if (ret) goto err_file; @@ -150,7 +150,7 @@ int host_dev_bind(int devnum, char *filename, bool removable) goto err_file; } - desc = blk_get_devnum_by_type(IF_TYPE_HOST, devnum); + desc = blk_get_devnum_by_type(UCLASS_ROOT, devnum); desc->removable = removable; snprintf(desc->vendor, BLK_VEN_SIZE, "U-Boot"); snprintf(desc->product, BLK_PRD_SIZE, "hostfile"); @@ -192,7 +192,7 @@ int host_dev_bind(int dev, char *filename, bool removable) } struct blk_desc *blk_dev = &host_dev->blk_dev; - blk_dev->if_type = IF_TYPE_HOST; + blk_dev->if_type = UCLASS_ROOT; blk_dev->priv = host_dev; blk_dev->blksz = 512; blk_dev->lba = os_lseek(host_dev->fd, 0, OS_SEEK_END) / blk_dev->blksz; @@ -216,7 +216,7 @@ int host_get_dev_err(int devnum, struct blk_desc **blk_devp) struct udevice *dev; int ret; - ret = blk_get_device(IF_TYPE_HOST, devnum, &dev); + ret = blk_get_device(UCLASS_ROOT, devnum, &dev); if (ret) return ret; *blk_devp = dev_get_uclass_plat(dev); @@ -263,7 +263,7 @@ U_BOOT_DRIVER(sandbox_host_blk) = { #else U_BOOT_LEGACY_BLK(sandbox_host) = { .if_typename = "host", - .if_type = IF_TYPE_HOST, + .if_type = UCLASS_ROOT, .max_devs = SANDBOX_HOST_MAX_DEVICES, .get_dev = host_get_dev_err, }; diff --git a/drivers/dfu/dfu_mmc.c b/drivers/dfu/dfu_mmc.c index a91da972d4..f5832083ba 100644 --- a/drivers/dfu/dfu_mmc.c +++ b/drivers/dfu/dfu_mmc.c @@ -52,7 +52,7 @@ static int mmc_block_op(enum dfu_op op, struct dfu_entity *dfu, if (dfu->data.mmc.hw_partition >= 0) { part_num_bkp = mmc_get_blk_desc(mmc)->hwpart; - ret = blk_select_hwpart_devnum(IF_TYPE_MMC, + ret = blk_select_hwpart_devnum(UCLASS_MMC, dfu->data.mmc.dev_num, dfu->data.mmc.hw_partition); if (ret) @@ -77,14 +77,14 @@ static int mmc_block_op(enum dfu_op op, struct dfu_entity *dfu, if (n != blk_count) { pr_err("MMC operation failed"); if (dfu->data.mmc.hw_partition >= 0) - blk_select_hwpart_devnum(IF_TYPE_MMC, + blk_select_hwpart_devnum(UCLASS_MMC, dfu->data.mmc.dev_num, part_num_bkp); return -EIO; } if (dfu->data.mmc.hw_partition >= 0) { - ret = blk_select_hwpart_devnum(IF_TYPE_MMC, + ret = blk_select_hwpart_devnum(UCLASS_MMC, dfu->data.mmc.dev_num, part_num_bkp); if (ret) diff --git a/drivers/mmc/mmc-uclass.c b/drivers/mmc/mmc-uclass.c index 688bdc06d4..b1bd4ae1bc 100644 --- a/drivers/mmc/mmc-uclass.c +++ b/drivers/mmc/mmc-uclass.c @@ -290,7 +290,7 @@ struct mmc *find_mmc_device(int dev_num) struct udevice *dev, *mmc_dev; int ret; - ret = blk_find_device(IF_TYPE_MMC, dev_num, &dev); + ret = blk_find_device(UCLASS_MMC, dev_num, &dev); if (ret) { #if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT) @@ -308,12 +308,12 @@ struct mmc *find_mmc_device(int dev_num) int get_mmc_num(void) { - return max((blk_find_max_devnum(IF_TYPE_MMC) + 1), 0); + return max((blk_find_max_devnum(UCLASS_MMC) + 1), 0); } int mmc_get_next_devnum(void) { - return blk_find_max_devnum(IF_TYPE_MMC); + return blk_find_max_devnum(UCLASS_MMC); } int mmc_get_blk(struct udevice *dev, struct udevice **blkp) @@ -411,8 +411,8 @@ int mmc_bind(struct udevice *dev, struct mmc *mmc, const struct mmc_config *cfg) /* Use the fixed index with aliases node's index */ debug("%s: alias devnum=%d\n", __func__, dev_seq(dev)); - ret = blk_create_devicef(dev, "mmc_blk", "blk", IF_TYPE_MMC, - dev_seq(dev), 512, 0, &bdev); + ret = blk_create_devicef(dev, "mmc_blk", "blk", UCLASS_MMC, + dev_seq(dev), 512, 0, &bdev); if (ret) { debug("Cannot create block device\n"); return ret; diff --git a/drivers/mmc/mmc_legacy.c b/drivers/mmc/mmc_legacy.c index a05da6c2e8..4e0891e5df 100644 --- a/drivers/mmc/mmc_legacy.c +++ b/drivers/mmc/mmc_legacy.c @@ -132,7 +132,7 @@ static struct mmc mmc_static = { .dsr_imp = 0, .dsr = 0xffffffff, .block_dev = { - .if_type = IF_TYPE_MMC, + .if_type = UCLASS_MMC, .removable = 1, .devnum = 0, .block_read = mmc_bread, @@ -194,7 +194,7 @@ struct mmc *mmc_create(const struct mmc_config *cfg, void *priv) mmc->dsr = 0xffffffff; /* Setup the universal parts of the block interface just once */ bdesc = mmc_get_blk_desc(mmc); - bdesc->if_type = IF_TYPE_MMC; + bdesc->if_type = UCLASS_MMC; bdesc->removable = 1; bdesc->devnum = mmc_get_next_devnum(); bdesc->block_read = mmc_bread; @@ -254,7 +254,7 @@ static int mmc_get_dev(int dev, struct blk_desc **descp) U_BOOT_LEGACY_BLK(mmc) = { .if_typename = "mmc", - .if_type = IF_TYPE_MMC, + .if_type = UCLASS_MMC, .max_devs = -1, .get_dev = mmc_get_dev, .select_hwpart = mmc_select_hwpartp, diff --git a/drivers/mmc/mmc_write.c b/drivers/mmc/mmc_write.c index eab94c7b60..5b7aeeb012 100644 --- a/drivers/mmc/mmc_write.c +++ b/drivers/mmc/mmc_write.c @@ -85,7 +85,7 @@ ulong mmc_berase(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt) if (!mmc) return -1; - err = blk_select_hwpart_devnum(IF_TYPE_MMC, dev_num, + err = blk_select_hwpart_devnum(UCLASS_MMC, dev_num, block_dev->hwpart); if (err < 0) return -1; @@ -203,7 +203,7 @@ ulong mmc_bwrite(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt, if (!mmc) return 0; - err = blk_select_hwpart_devnum(IF_TYPE_MMC, dev_num, block_dev->hwpart); + err = blk_select_hwpart_devnum(UCLASS_MMC, dev_num, block_dev->hwpart); if (err < 0) return 0; diff --git a/drivers/nvme/nvme.c b/drivers/nvme/nvme.c index 31cf700633..3510f797e0 100644 --- a/drivers/nvme/nvme.c +++ b/drivers/nvme/nvme.c @@ -880,7 +880,7 @@ int nvme_init(struct udevice *udev) sprintf(name, "blk#%d", i); /* The real blksz and size will be set by nvme_blk_probe() */ - ret = blk_create_devicef(udev, "nvme-blk", name, IF_TYPE_NVME, + ret = blk_create_devicef(udev, "nvme-blk", name, UCLASS_NVME, -1, 512, 0, &ns_udev); if (ret) goto free_id; diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index 78d729d809..99be5aef87 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c @@ -456,7 +456,7 @@ static void scsi_init_dev_desc(struct blk_desc *dev_desc, int devnum) { dev_desc->lba = 0; dev_desc->blksz = 0; - dev_desc->if_type = IF_TYPE_SCSI; + dev_desc->if_type = UCLASS_SCSI; dev_desc->devnum = devnum; dev_desc->part_type = PART_TYPE_UNKNOWN; @@ -574,8 +574,8 @@ static int do_scsi_scan_one(struct udevice *dev, int id, int lun, bool verbose) * block devices created */ snprintf(str, sizeof(str), "id%dlun%d", id, lun); - ret = blk_create_devicef(dev, "scsi_blk", str, IF_TYPE_SCSI, -1, - bd.blksz, bd.lba, &bdev); + ret = blk_create_devicef(dev, "scsi_blk", str, UCLASS_SCSI, -1, + bd.blksz, bd.lba, &bdev); if (ret) { debug("Can't create device\n"); return ret; @@ -638,7 +638,7 @@ int scsi_scan(bool verbose) if (verbose) printf("scanning bus for devices...\n"); - blk_unbind_all(IF_TYPE_SCSI); + blk_unbind_all(UCLASS_SCSI); ret = uclass_get(UCLASS_SCSI, &uc); if (ret) @@ -707,7 +707,7 @@ U_BOOT_DRIVER(scsi_blk) = { #else U_BOOT_LEGACY_BLK(scsi) = { .if_typename = "scsi", - .if_type = IF_TYPE_SCSI, + .if_type = UCLASS_SCSI, .max_devs = SCSI_MAX_DEVICE, .desc = scsi_dev_desc, }; diff --git a/drivers/tee/optee/rpmb.c b/drivers/tee/optee/rpmb.c index cf5e0a08e6..5bc13757ea 100644 --- a/drivers/tee/optee/rpmb.c +++ b/drivers/tee/optee/rpmb.c @@ -48,7 +48,7 @@ static void release_mmc(struct optee_private *priv) if (!priv->rpmb_mmc) return; - rc = blk_select_hwpart_devnum(IF_TYPE_MMC, priv->rpmb_dev_id, + rc = blk_select_hwpart_devnum(UCLASS_MMC, priv->rpmb_dev_id, priv->rpmb_original_part); if (rc) debug("%s: blk_select_hwpart_devnum() failed: %d\n", @@ -88,7 +88,7 @@ static struct mmc *get_mmc(struct optee_private *priv, int dev_id) priv->rpmb_original_part = mmc_get_blk_desc(mmc)->hwpart; - rc = blk_select_hwpart_devnum(IF_TYPE_MMC, dev_id, MMC_PART_RPMB); + rc = blk_select_hwpart_devnum(UCLASS_MMC, dev_id, MMC_PART_RPMB); if (rc) { debug("Device id %d: cannot select RPMB partition: %d\n", dev_id, rc); diff --git a/drivers/virtio/virtio_blk.c b/drivers/virtio/virtio_blk.c index 3ff74f4a97..9710b79117 100644 --- a/drivers/virtio/virtio_blk.c +++ b/drivers/virtio/virtio_blk.c @@ -75,14 +75,14 @@ static int virtio_blk_bind(struct udevice *dev) struct blk_desc *desc = dev_get_uclass_plat(dev); int devnum; - desc->if_type = IF_TYPE_VIRTIO; + desc->if_type = UCLASS_VIRTIO; /* * Initialize the devnum to -ENODEV. This is to make sure that * blk_next_free_devnum() works as expected, since the default * value 0 is a valid devnum. */ desc->devnum = -ENODEV; - devnum = blk_next_free_devnum(IF_TYPE_VIRTIO); + devnum = blk_next_free_devnum(UCLASS_VIRTIO); if (devnum < 0) return devnum; desc->devnum = devnum; diff --git a/drivers/xen/pvblock.c b/drivers/xen/pvblock.c index c25c3ea4ff..1090e528d0 100644 --- a/drivers/xen/pvblock.c +++ b/drivers/xen/pvblock.c @@ -665,14 +665,14 @@ static int pvblock_blk_bind(struct udevice *udev) struct blk_desc *desc = dev_get_uclass_plat(udev); int devnum; - desc->if_type = IF_TYPE_PVBLOCK; + desc->if_type = UCLASS_PVBLOCK; /* * Initialize the devnum to -ENODEV. This is to make sure that * blk_next_free_devnum() works as expected, since the default * value 0 is a valid devnum. */ desc->devnum = -ENODEV; - devnum = blk_next_free_devnum(IF_TYPE_PVBLOCK); + devnum = blk_next_free_devnum(UCLASS_PVBLOCK); if (devnum < 0) return devnum; desc->devnum = devnum; @@ -804,7 +804,7 @@ static void print_pvblock_devices(void) const char *class_name; class_name = uclass_get_name(UCLASS_PVBLOCK); - for (blk_first_device(IF_TYPE_PVBLOCK, &udev); udev; + for (blk_first_device(UCLASS_PVBLOCK, &udev); udev; blk_next_device(&udev), first = false) { struct blk_desc *desc = dev_get_uclass_plat(udev); diff --git a/env/mmc.c b/env/mmc.c index 0c498d9a46..c28f4c6c6d 100644 --- a/env/mmc.c +++ b/env/mmc.c @@ -143,7 +143,7 @@ static int mmc_set_env_part(struct mmc *mmc, uint part) int dev = mmc_get_env_dev(); int ret = 0; - ret = blk_select_hwpart_devnum(IF_TYPE_MMC, dev, part); + ret = blk_select_hwpart_devnum(UCLASS_MMC, dev, part); if (ret) puts("MMC partition switch failed\n"); @@ -179,7 +179,7 @@ static void fini_mmc_for_env(struct mmc *mmc) #ifdef CONFIG_SYS_MMC_ENV_PART int dev = mmc_get_env_dev(); - blk_select_hwpart_devnum(IF_TYPE_MMC, dev, env_mmc_orig_hwpart); + blk_select_hwpart_devnum(UCLASS_MMC, dev, env_mmc_orig_hwpart); #endif } diff --git a/include/blk.h b/include/blk.h index cc30e3861f..548cd09d6b 100644 --- a/include/blk.h +++ b/include/blk.h @@ -7,6 +7,7 @@ #ifndef BLK_H #define BLK_H +#include #include #ifdef CONFIG_SYS_64BIT_LBA @@ -27,22 +28,7 @@ static inline bool blk_enabled(void) } /* Interface types: */ -enum if_type { - IF_TYPE_UNKNOWN = 0, - IF_TYPE_IDE, - IF_TYPE_SCSI, - IF_TYPE_USB, - IF_TYPE_MMC, - IF_TYPE_SATA, - IF_TYPE_HOST, - IF_TYPE_NVME, - IF_TYPE_EFI_LOADER, - IF_TYPE_PVBLOCK, - IF_TYPE_VIRTIO, - IF_TYPE_EFI_MEDIA, - - IF_TYPE_COUNT, /* Number of interface types */ -}; +#define if_type uclass_id #define BLK_VEN_SIZE 40 #define BLK_PRD_SIZE 20 diff --git a/include/mmc.h b/include/mmc.h index f519d86972..027e8bcc73 100644 --- a/include/mmc.h +++ b/include/mmc.h @@ -767,7 +767,7 @@ struct mmc *mmc_create(const struct mmc_config *cfg, void *priv); /** * mmc_bind() - Set up a new MMC device ready for probing * - * A child block device is bound with the IF_TYPE_MMC interface type. This + * A child block device is bound with the UCLASS_MMC interface type. This * allows the device to be used with CONFIG_BLK * * @dev: MMC device to set up diff --git a/lib/efi_driver/efi_block_device.c b/lib/efi_driver/efi_block_device.c index d57d281f85..3177ab67b8 100644 --- a/lib/efi_driver/efi_block_device.c +++ b/lib/efi_driver/efi_block_device.c @@ -128,7 +128,7 @@ static int efi_bl_bind(efi_handle_t handle, void *interface) if (!obj) return -ENOENT; - devnum = blk_find_max_devnum(IF_TYPE_EFI_LOADER); + devnum = blk_find_max_devnum(UCLASS_EFI_LOADER); if (devnum == -ENODEV) devnum = 0; else if (devnum < 0) @@ -140,7 +140,7 @@ static int efi_bl_bind(efi_handle_t handle, void *interface) sprintf(name, "efiblk#%d", devnum); /* Create driver model udevice for the EFI block io device */ - ret = blk_create_device(parent, "efi_blk", name, IF_TYPE_EFI_LOADER, + ret = blk_create_device(parent, "efi_blk", name, UCLASS_EFI_LOADER, devnum, io->media->block_size, (lbaint_t)io->media->last_block, &bdev); if (ret) diff --git a/lib/efi_loader/efi_disk.c b/lib/efi_loader/efi_disk.c index a34ca46a11..819dcb4f13 100644 --- a/lib/efi_loader/efi_disk.c +++ b/lib/efi_loader/efi_disk.c @@ -640,7 +640,7 @@ static int efi_disk_probe(void *ctx, struct event *event) * has already created an efi_disk at this moment. */ desc = dev_get_uclass_plat(dev); - if (desc->if_type != IF_TYPE_EFI_LOADER) { + if (desc->if_type != UCLASS_EFI_LOADER) { ret = efi_disk_create_raw(dev); if (ret) return -1; @@ -675,7 +675,7 @@ static int efi_disk_delete_raw(struct udevice *dev) return -1; desc = dev_get_uclass_plat(dev); - if (desc->if_type != IF_TYPE_EFI_LOADER) { + if (desc->if_type != UCLASS_EFI_LOADER) { diskobj = container_of(handle, struct efi_disk_obj, header); efi_free_pool(diskobj->dp); } diff --git a/test/dm/blk.c b/test/dm/blk.c index 85c3a3bd45..35bd5318f0 100644 --- a/test/dm/blk.c +++ b/test/dm/blk.c @@ -25,19 +25,19 @@ static int dm_test_blk_base(struct unit_test_state *uts) /* Create two, one the parent of the other */ ut_assertok(blk_create_device(gd->dm_root, "sandbox_host_blk", "test", - IF_TYPE_HOST, 1, 512, 2, &blk1)); + UCLASS_ROOT, 1, 512, 2, &blk1)); ut_assertok(blk_create_device(blk1, "sandbox_host_blk", "test", - IF_TYPE_HOST, 3, 512, 2, &blk3)); + UCLASS_ROOT, 3, 512, 2, &blk3)); /* Check we can find them */ - ut_asserteq(-ENODEV, blk_get_device(IF_TYPE_HOST, 0, &dev)); - ut_assertok(blk_get_device(IF_TYPE_HOST, 1, &dev)); + ut_asserteq(-ENODEV, blk_get_device(UCLASS_ROOT, 0, &dev)); + ut_assertok(blk_get_device(UCLASS_ROOT, 1, &dev)); ut_asserteq_ptr(blk1, dev); - ut_assertok(blk_get_device(IF_TYPE_HOST, 3, &dev)); + ut_assertok(blk_get_device(UCLASS_ROOT, 3, &dev)); ut_asserteq_ptr(blk3, dev); /* Check we can iterate */ - ut_assertok(blk_first_device(IF_TYPE_HOST, &dev)); + ut_assertok(blk_first_device(UCLASS_ROOT, &dev)); ut_asserteq_ptr(blk1, dev); ut_assertok(blk_next_device(&dev)); ut_asserteq_ptr(blk3, dev); @@ -79,7 +79,7 @@ static int dm_test_blk_usb(struct unit_test_state *uts) ut_assertok(blk_get_device_by_str("usb", "0", &dev_desc)); /* The parent should be a block device */ - ut_assertok(blk_get_device(IF_TYPE_USB, 0, &dev)); + ut_assertok(blk_get_device(UCLASS_USB, 0, &dev)); ut_asserteq_ptr(usb_dev, dev_get_parent(dev)); /* Check we have one block device for each mass storage device */ @@ -101,14 +101,14 @@ static int dm_test_blk_find(struct unit_test_state *uts) struct udevice *blk, *dev; ut_assertok(blk_create_device(gd->dm_root, "sandbox_host_blk", "test", - IF_TYPE_HOST, 1, 512, 2, &blk)); - ut_asserteq(-ENODEV, blk_find_device(IF_TYPE_HOST, 0, &dev)); - ut_assertok(blk_find_device(IF_TYPE_HOST, 1, &dev)); + UCLASS_ROOT, 1, 512, 2, &blk)); + ut_asserteq(-ENODEV, blk_find_device(UCLASS_ROOT, 0, &dev)); + ut_assertok(blk_find_device(UCLASS_ROOT, 1, &dev)); ut_asserteq_ptr(blk, dev); ut_asserteq(false, device_active(dev)); /* Now activate it */ - ut_assertok(blk_get_device(IF_TYPE_HOST, 1, &dev)); + ut_assertok(blk_get_device(UCLASS_ROOT, 1, &dev)); ut_asserteq_ptr(blk, dev); ut_asserteq(true, device_active(dev)); @@ -134,7 +134,7 @@ static int dm_test_blk_devnum(struct unit_test_state *uts) /* Check that the bblock device is attached */ ut_assertok(uclass_get_device_by_seq(UCLASS_MMC, i, &mmc_dev)); - ut_assertok(blk_find_device(IF_TYPE_MMC, i, &dev)); + ut_assertok(blk_find_device(UCLASS_MMC, i, &dev)); parent = dev_get_parent(dev); ut_asserteq_ptr(parent, mmc_dev); ut_asserteq(trailing_strtol(mmc_dev->name), i); From ef4b66bcd189e0db142e257cea1d225833cdc3b1 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 11 Aug 2022 19:35:00 -0600 Subject: [PATCH 195/374] disk: Handle UCLASS_EFI_MEDIA in dev_print() This is currently missing. Add it. Fix the code style for the function while we are here. Suggested-by: AKASHI Takahiro Signed-off-by: Simon Glass --- disk/part.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/disk/part.c b/disk/part.c index 75aff7eba5..5705c229d5 100644 --- a/disk/part.c +++ b/disk/part.c @@ -111,7 +111,7 @@ static lba512_t lba512_muldiv(lba512_t block_count, lba512_t mul_by, return bc_quot * mul_by + ((bc_rem * mul_by) >> right_shift); } -void dev_print (struct blk_desc *dev_desc) +void dev_print(struct blk_desc *dev_desc) { lba512_t lba512; /* number of blocks if 512bytes block size */ @@ -148,6 +148,9 @@ void dev_print (struct blk_desc *dev_desc) case UCLASS_VIRTIO: printf("%s VirtIO Block Device\n", dev_desc->vendor); break; + case UCLASS_EFI_MEDIA: + printf("EFI media Block Device %d\n", dev_desc->devnum); + break; case UCLASS_INVALID: puts("device type unknown\n"); return; From ec8bdc914c8328993cee62e01b4107b802cf45cc Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 11 Aug 2022 19:35:01 -0600 Subject: [PATCH 196/374] blk: Drop if_type Use the uclass ID instead. Signed-off-by: Simon Glass Acked-by: Heinrich Schuchardt --- cmd/blk_common.c | 2 +- drivers/block/blk-uclass.c | 34 +++++++++++++++---------------- drivers/block/blk_legacy.c | 20 +++++++++---------- include/blk.h | 41 ++++++++++++++++++-------------------- include/efi_loader.h | 2 +- 5 files changed, 48 insertions(+), 51 deletions(-) diff --git a/cmd/blk_common.c b/cmd/blk_common.c index 4e442f2918..369c5ae4bb 100644 --- a/cmd/blk_common.c +++ b/cmd/blk_common.c @@ -12,7 +12,7 @@ #include #include -int blk_common_cmd(int argc, char *const argv[], enum if_type if_type, +int blk_common_cmd(int argc, char *const argv[], enum uclass_id if_type, int *cur_devnump) { const char *if_name = blk_get_if_type_name(if_type); diff --git a/drivers/block/blk-uclass.c b/drivers/block/blk-uclass.c index 436af764f9..a9a85aa37f 100644 --- a/drivers/block/blk-uclass.c +++ b/drivers/block/blk-uclass.c @@ -34,7 +34,7 @@ static struct { { UCLASS_PVBLOCK, "pvblock" }, }; -static enum if_type if_typename_to_iftype(const char *if_typename) +static enum uclass_id if_typename_to_iftype(const char *if_typename) { int i; @@ -46,7 +46,7 @@ static enum if_type if_typename_to_iftype(const char *if_typename) return UCLASS_INVALID; } -static enum uclass_id if_type_to_uclass_id(enum if_type if_type) +static enum uclass_id if_type_to_uclass_id(enum uclass_id if_type) { /* * This strange adjustment is used because we use UCLASS_MASS_STORAGE @@ -71,7 +71,7 @@ static enum uclass_id if_type_to_uclass_id(enum if_type if_type) return if_type; } -const char *blk_get_if_type_name(enum if_type if_type) +const char *blk_get_if_type_name(enum uclass_id if_type) { int i; @@ -83,7 +83,7 @@ const char *blk_get_if_type_name(enum if_type if_type) return "(none)"; } -struct blk_desc *blk_get_devnum_by_type(enum if_type if_type, int devnum) +struct blk_desc *blk_get_devnum_by_type(enum uclass_id if_type, int devnum) { struct blk_desc *desc; struct udevice *dev; @@ -105,7 +105,7 @@ struct blk_desc *blk_get_devnum_by_type(enum if_type if_type, int devnum) struct blk_desc *blk_get_devnum_by_typename(const char *if_typename, int devnum) { enum uclass_id uclass_id; - enum if_type type; + enum uclass_id type; struct udevice *dev; struct uclass *uc; int ret; @@ -185,7 +185,7 @@ struct blk_desc *blk_get_by_device(struct udevice *dev) * with a higher device number, -ENOENT if there is no such device but there * is one with a higher number, or other -ve on other error. */ -static int get_desc(enum if_type if_type, int devnum, struct blk_desc **descp) +static int get_desc(enum uclass_id if_type, int devnum, struct blk_desc **descp) { bool found_more = false; struct udevice *dev; @@ -218,7 +218,7 @@ static int get_desc(enum if_type if_type, int devnum, struct blk_desc **descp) return found_more ? -ENOENT : -ENODEV; } -int blk_select_hwpart_devnum(enum if_type if_type, int devnum, int hwpart) +int blk_select_hwpart_devnum(enum uclass_id if_type, int devnum, int hwpart) { struct udevice *dev; int ret; @@ -230,7 +230,7 @@ int blk_select_hwpart_devnum(enum if_type if_type, int devnum, int hwpart) return blk_select_hwpart(dev, hwpart); } -int blk_list_part(enum if_type if_type) +int blk_list_part(enum uclass_id if_type) { struct blk_desc *desc; int devnum, ok; @@ -255,7 +255,7 @@ int blk_list_part(enum if_type if_type) return 0; } -int blk_print_part_devnum(enum if_type if_type, int devnum) +int blk_print_part_devnum(enum uclass_id if_type, int devnum) { struct blk_desc *desc; int ret; @@ -270,7 +270,7 @@ int blk_print_part_devnum(enum if_type if_type, int devnum) return 0; } -void blk_list_devices(enum if_type if_type) +void blk_list_devices(enum uclass_id if_type) { struct blk_desc *desc; int ret; @@ -289,7 +289,7 @@ void blk_list_devices(enum if_type if_type) } } -int blk_print_device_num(enum if_type if_type, int devnum) +int blk_print_device_num(enum uclass_id if_type, int devnum) { struct blk_desc *desc; int ret; @@ -303,7 +303,7 @@ int blk_print_device_num(enum if_type if_type, int devnum) return 0; } -int blk_show_device(enum if_type if_type, int devnum) +int blk_show_device(enum uclass_id if_type, int devnum) { struct blk_desc *desc; int ret; @@ -324,7 +324,7 @@ int blk_show_device(enum if_type if_type, int devnum) return 0; } -ulong blk_read_devnum(enum if_type if_type, int devnum, lbaint_t start, +ulong blk_read_devnum(enum uclass_id if_type, int devnum, lbaint_t start, lbaint_t blkcnt, void *buffer) { struct blk_desc *desc; @@ -341,7 +341,7 @@ ulong blk_read_devnum(enum if_type if_type, int devnum, lbaint_t start, return n; } -ulong blk_write_devnum(enum if_type if_type, int devnum, lbaint_t start, +ulong blk_write_devnum(enum uclass_id if_type, int devnum, lbaint_t start, lbaint_t blkcnt, const void *buffer) { struct blk_desc *desc; @@ -525,7 +525,7 @@ const char *blk_get_devtype(struct udevice *dev) return uclass_get_name(device_get_uclass_id(parent)); }; -int blk_find_max_devnum(enum if_type if_type) +int blk_find_max_devnum(enum uclass_id if_type) { struct udevice *dev; int max_devnum = -ENODEV; @@ -545,7 +545,7 @@ int blk_find_max_devnum(enum if_type if_type) return max_devnum; } -int blk_next_free_devnum(enum if_type if_type) +int blk_next_free_devnum(enum uclass_id if_type) { int ret; @@ -631,7 +631,7 @@ int blk_count_devices(enum blk_flag_t flag) return count; } -static int blk_claim_devnum(enum if_type if_type, int devnum) +static int blk_claim_devnum(enum uclass_id if_type, int devnum) { struct udevice *dev; struct uclass *uc; diff --git a/drivers/block/blk_legacy.c b/drivers/block/blk_legacy.c index bd8a17df6a..8c6f9cb208 100644 --- a/drivers/block/blk_legacy.c +++ b/drivers/block/blk_legacy.c @@ -39,7 +39,7 @@ static struct blk_driver *blk_driver_lookup_typename(const char *if_typename) return NULL; } -const char *blk_get_if_type_name(enum if_type if_type) +const char *blk_get_if_type_name(enum uclass_id if_type) { struct blk_driver *drv = blk_driver_lookup_type(if_type); @@ -70,7 +70,7 @@ static int get_desc(struct blk_driver *drv, int devnum, struct blk_desc **descp) return drv->get_dev(devnum, descp); } -int blk_list_part(enum if_type if_type) +int blk_list_part(enum uclass_id if_type) { struct blk_driver *drv; struct blk_desc *desc; @@ -97,7 +97,7 @@ int blk_list_part(enum if_type if_type) return 0; } -int blk_print_part_devnum(enum if_type if_type, int devnum) +int blk_print_part_devnum(enum uclass_id if_type, int devnum) { struct blk_driver *drv = blk_driver_lookup_type(if_type); struct blk_desc *desc; @@ -115,7 +115,7 @@ int blk_print_part_devnum(enum if_type if_type, int devnum) return 0; } -void blk_list_devices(enum if_type if_type) +void blk_list_devices(enum uclass_id if_type) { struct blk_driver *drv = blk_driver_lookup_type(if_type); struct blk_desc *desc; @@ -133,7 +133,7 @@ void blk_list_devices(enum if_type if_type) } } -int blk_print_device_num(enum if_type if_type, int devnum) +int blk_print_device_num(enum uclass_id if_type, int devnum) { struct blk_driver *drv = blk_driver_lookup_type(if_type); struct blk_desc *desc; @@ -150,7 +150,7 @@ int blk_print_device_num(enum if_type if_type, int devnum) return 0; } -int blk_show_device(enum if_type if_type, int devnum) +int blk_show_device(enum uclass_id if_type, int devnum) { struct blk_driver *drv = blk_driver_lookup_type(if_type); struct blk_desc *desc; @@ -174,7 +174,7 @@ int blk_show_device(enum if_type if_type, int devnum) return 0; } -struct blk_desc *blk_get_devnum_by_type(enum if_type if_type, int devnum) +struct blk_desc *blk_get_devnum_by_type(enum uclass_id if_type, int devnum) { struct blk_driver *drv = blk_driver_lookup_type(if_type); struct blk_desc *desc; @@ -214,7 +214,7 @@ struct blk_desc *blk_get_devnum_by_typename(const char *if_typename, int devnum) return desc; } -ulong blk_read_devnum(enum if_type if_type, int devnum, lbaint_t start, +ulong blk_read_devnum(enum uclass_id if_type, int devnum, lbaint_t start, lbaint_t blkcnt, void *buffer) { struct blk_driver *drv = blk_driver_lookup_type(if_type); @@ -234,7 +234,7 @@ ulong blk_read_devnum(enum if_type if_type, int devnum, lbaint_t start, return n; } -ulong blk_write_devnum(enum if_type if_type, int devnum, lbaint_t start, +ulong blk_write_devnum(enum uclass_id if_type, int devnum, lbaint_t start, lbaint_t blkcnt, const void *buffer) { struct blk_driver *drv = blk_driver_lookup_type(if_type); @@ -249,7 +249,7 @@ ulong blk_write_devnum(enum if_type if_type, int devnum, lbaint_t start, return desc->block_write(desc, start, blkcnt, buffer); } -int blk_select_hwpart_devnum(enum if_type if_type, int devnum, int hwpart) +int blk_select_hwpart_devnum(enum uclass_id if_type, int devnum, int hwpart) { struct blk_driver *drv = blk_driver_lookup_type(if_type); struct blk_desc *desc; diff --git a/include/blk.h b/include/blk.h index 548cd09d6b..279f9ea4a9 100644 --- a/include/blk.h +++ b/include/blk.h @@ -27,9 +27,6 @@ static inline bool blk_enabled(void) return CONFIG_IS_ENABLED(BLK) || IS_ENABLED(CONFIG_SPL_LEGACY_BLOCK); } -/* Interface types: */ -#define if_type uclass_id - #define BLK_VEN_SIZE 40 #define BLK_PRD_SIZE 20 #define BLK_REV_SIZE 8 @@ -57,7 +54,7 @@ struct blk_desc { * TODO: With driver model we should be able to use the parent * device's uclass instead. */ - enum if_type if_type; /* type of the interface */ + enum uclass_id if_type; /* type of the interface */ int devnum; /* device number */ unsigned char part_type; /* partition type */ unsigned char target; /* target SCSI ID */ @@ -282,7 +279,7 @@ unsigned long blk_derase(struct blk_desc *block_dev, lbaint_t start, * This function does not activate the device. The device will be returned * whether or not it is activated. * - * @if_type: Interface type (enum if_type_t) + * @if_type: Interface type (enum uclass_id_t) * @devnum: Device number (specific to each interface type) * @devp: the device, if found * Return: 0 if found, -ENODEV if no device found, or other -ve error value @@ -292,7 +289,7 @@ int blk_find_device(int if_type, int devnum, struct udevice **devp); /** * blk_get_device() - Find and probe a block device ready for use * - * @if_type: Interface type (enum if_type_t) + * @if_type: Interface type (enum uclass_id_t) * @devnum: Device number (specific to each interface type) * @devp: the device, if found * Return: 0 if found, -ENODEV if no device found, or other -ve error value @@ -330,7 +327,7 @@ int blk_next_device(struct udevice **devp); * @parent: Parent of the new device * @drv_name: Driver name to use for the block device * @name: Name for the device - * @if_type: Interface type (enum if_type_t) + * @if_type: Interface type (enum uclass_id_t) * @devnum: Device number, specific to the interface type, or -1 to * allocate the next available number * @blksz: Block size of the device in bytes (typically 512) @@ -347,7 +344,7 @@ int blk_create_device(struct udevice *parent, const char *drv_name, * @parent: Parent of the new device * @drv_name: Driver name to use for the block device * @name: Name for the device (parent name is prepended) - * @if_type: Interface type (enum if_type_t) + * @if_type: Interface type (enum uclass_id_t) * @devnum: Device number, specific to the interface type, or -1 to * allocate the next available number * @blksz: Block size of the device in bytes (typically 512) @@ -390,7 +387,7 @@ int blk_unbind_all(int if_type); * Return: maximum device number found, or -ENODEV if none, or other -ve on * error */ -int blk_find_max_devnum(enum if_type if_type); +int blk_find_max_devnum(enum uclass_id if_type); /** * blk_next_free_devnum() - get the next device number for an interface type @@ -401,7 +398,7 @@ int blk_find_max_devnum(enum if_type if_type); * @if_type: Interface type to scan * Return: next device number safe to use, or -ve on error */ -int blk_next_free_devnum(enum if_type if_type); +int blk_next_free_devnum(enum uclass_id if_type); /** * blk_select_hwpart() - select a hardware partition @@ -496,7 +493,7 @@ static inline ulong blk_derase(struct blk_desc *block_dev, lbaint_t start, */ struct blk_driver { const char *if_typename; - enum if_type if_type; + enum uclass_id if_type; int max_devs; struct blk_desc *desc; /** @@ -557,7 +554,7 @@ struct blk_driver *blk_driver_lookup_type(int if_type); * @devnum: Device number * Return: point to block device descriptor, or NULL if not found */ -struct blk_desc *blk_get_devnum_by_type(enum if_type if_type, int devnum); +struct blk_desc *blk_get_devnum_by_type(enum uclass_id if_type, int devnum); /** * blk_get_devnum_by_type() - Get a block device by type name, and number @@ -594,7 +591,7 @@ int blk_dselect_hwpart(struct blk_desc *desc, int hwpart); * @if_type: Block device type * Return: 0 if OK, -ENODEV if there is none of that type */ -int blk_list_part(enum if_type if_type); +int blk_list_part(enum uclass_id if_type); /** * blk_list_devices() - list the block devices of a given type @@ -604,7 +601,7 @@ int blk_list_part(enum if_type if_type); * * @if_type: Block device type */ -void blk_list_devices(enum if_type if_type); +void blk_list_devices(enum uclass_id if_type); /** * blk_show_device() - show information about a given block device @@ -615,7 +612,7 @@ void blk_list_devices(enum if_type if_type); * @devnum: Device number * Return: 0 if OK, -ENODEV for invalid device number */ -int blk_show_device(enum if_type if_type, int devnum); +int blk_show_device(enum uclass_id if_type, int devnum); /** * blk_print_device_num() - show information about a given block device @@ -628,7 +625,7 @@ int blk_show_device(enum if_type if_type, int devnum); * Return: 0 if OK, -ENODEV for invalid device number, -ENOENT if the block * device is not connected */ -int blk_print_device_num(enum if_type if_type, int devnum); +int blk_print_device_num(enum uclass_id if_type, int devnum); /** * blk_print_part_devnum() - print the partition information for a device @@ -638,7 +635,7 @@ int blk_print_device_num(enum if_type if_type, int devnum); * Return: 0 if OK, -ENOENT if the block device is not connected, -ENOSYS if * the interface type is not supported, other -ve on other error */ -int blk_print_part_devnum(enum if_type if_type, int devnum); +int blk_print_part_devnum(enum uclass_id if_type, int devnum); /** * blk_read_devnum() - read blocks from a device @@ -649,7 +646,7 @@ int blk_print_part_devnum(enum if_type if_type, int devnum); * @buffer: Address to write data to * Return: number of blocks read, or -ve error number on error */ -ulong blk_read_devnum(enum if_type if_type, int devnum, lbaint_t start, +ulong blk_read_devnum(enum uclass_id if_type, int devnum, lbaint_t start, lbaint_t blkcnt, void *buffer); /** @@ -661,7 +658,7 @@ ulong blk_read_devnum(enum if_type if_type, int devnum, lbaint_t start, * @buffer: Address to read data from * Return: number of blocks written, or -ve error number on error */ -ulong blk_write_devnum(enum if_type if_type, int devnum, lbaint_t start, +ulong blk_write_devnum(enum uclass_id if_type, int devnum, lbaint_t start, lbaint_t blkcnt, const void *buffer); /** @@ -675,7 +672,7 @@ ulong blk_write_devnum(enum if_type if_type, int devnum, lbaint_t start, * @hwpart: Partition number to select * Return: 0 if OK, -ve on error */ -int blk_select_hwpart_devnum(enum if_type if_type, int devnum, int hwpart); +int blk_select_hwpart_devnum(enum uclass_id if_type, int devnum, int hwpart); /** * blk_get_if_type_name() - Get the name of an interface type @@ -683,7 +680,7 @@ int blk_select_hwpart_devnum(enum if_type if_type, int devnum, int hwpart); * @if_type: Interface type to check * Return: name of interface, or NULL if none */ -const char *blk_get_if_type_name(enum if_type if_type); +const char *blk_get_if_type_name(enum uclass_id if_type); /** * blk_common_cmd() - handle common commands with block devices @@ -694,7 +691,7 @@ const char *blk_get_if_type_name(enum if_type if_type); * @cur_devnump: Current device number for this interface type * Return: 0 if OK, CMD_RET_ERROR on error */ -int blk_common_cmd(int argc, char *const argv[], enum if_type if_type, +int blk_common_cmd(int argc, char *const argv[], enum uclass_id if_type, int *cur_devnump); enum blk_flag_t { diff --git a/include/efi_loader.h b/include/efi_loader.h index 6b63ae8dde..fb35087ddb 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -161,7 +161,7 @@ extern bool efi_st_keep_devices; /* EFI system partition */ extern struct efi_system_partition { - enum if_type if_type; + enum uclass_id if_type; int devnum; u8 part; } efi_system_partition; From d219fc06b30d4b1ac4fac6c40b2ca69cb5ecf642 Mon Sep 17 00:00:00 2001 From: Tom Rini Date: Fri, 16 Sep 2022 16:06:46 -0400 Subject: [PATCH 197/374] configs: Resync with savedefconfig Rsync all defconfig files using moveconfig.py Signed-off-by: Tom Rini --- configs/axm_defconfig | 1 - configs/bcm963158_ram_defconfig | 2 -- configs/bcm968360bg_ram_defconfig | 1 - configs/bcm968580xref_ram_defconfig | 2 -- configs/crs305-1g-4s-bit_defconfig | 2 -- configs/crs305-1g-4s_defconfig | 2 -- configs/crs326-24g-2s-bit_defconfig | 2 -- configs/crs326-24g-2s_defconfig | 2 -- configs/crs328-4c-20s-4s-bit_defconfig | 2 -- configs/crs328-4c-20s-4s_defconfig | 2 -- configs/durian_defconfig | 1 - .../gardena-smart-gateway-at91sam_defconfig | 1 - configs/j7200_hs_evm_a72_defconfig | 3 -- configs/j7200_hs_evm_r5_defconfig | 1 - configs/j721s2_hs_evm_a72_defconfig | 3 -- configs/j721s2_hs_evm_r5_defconfig | 1 - configs/lschlv2_defconfig | 1 - configs/lsxhl_defconfig | 1 - configs/netspace_mini_v2_defconfig | 1 - configs/nsim_hs38_defconfig | 2 -- configs/octeon_nic23_defconfig | 1 - configs/pg_wcom_expu1_defconfig | 1 - configs/pg_wcom_expu1_update_defconfig | 1 - configs/pg_wcom_seli8_defconfig | 1 - configs/pg_wcom_seli8_update_defconfig | 1 - configs/pm9261_defconfig | 1 - configs/pm9263_defconfig | 1 - configs/qcs404evb_defconfig | 32 +++++++++---------- configs/qemu-ppce500_defconfig | 1 - configs/sandbox_defconfig | 2 +- configs/stm32mp13_defconfig | 1 - configs/stm32mp15_defconfig | 1 - configs/stm32mp15_trusted_defconfig | 1 - 33 files changed, 16 insertions(+), 62 deletions(-) diff --git a/configs/axm_defconfig b/configs/axm_defconfig index b1e0090f35..dd5efbca86 100644 --- a/configs/axm_defconfig +++ b/configs/axm_defconfig @@ -79,7 +79,6 @@ CONFIG_ENV_IS_IN_NAND=y CONFIG_SYS_REDUNDAND_ENVIRONMENT=y CONFIG_SYS_RELOC_GD_ENV_ADDR=y CONFIG_SPL_DM=y -CONFIG_BLK=y CONFIG_CLK=y CONFIG_CLK_AT91=y CONFIG_AT91_GPIO=y diff --git a/configs/bcm963158_ram_defconfig b/configs/bcm963158_ram_defconfig index 424eca7946..c0fda57ff7 100644 --- a/configs/bcm963158_ram_defconfig +++ b/configs/bcm963158_ram_defconfig @@ -38,7 +38,6 @@ CONFIG_ISO_PARTITION=y CONFIG_EFI_PARTITION=y CONFIG_SYS_RELOC_GD_ENV_ADDR=y # CONFIG_NET is not set -CONFIG_BLK=y CONFIG_CLK=y CONFIG_BCM6345_GPIO=y CONFIG_LED=y @@ -64,4 +63,3 @@ CONFIG_BCM63XX_HSSPI=y CONFIG_SYSRESET=y CONFIG_SYSRESET_WATCHDOG=y CONFIG_WDT_BCM6345=y -# CONFIG_GENERATE_SMBIOS_TABLE is not set diff --git a/configs/bcm968360bg_ram_defconfig b/configs/bcm968360bg_ram_defconfig index 7f9093c6f6..a83d4efd55 100644 --- a/configs/bcm968360bg_ram_defconfig +++ b/configs/bcm968360bg_ram_defconfig @@ -34,7 +34,6 @@ CONFIG_ISO_PARTITION=y CONFIG_EFI_PARTITION=y CONFIG_SYS_RELOC_GD_ENV_ADDR=y # CONFIG_NET is not set -CONFIG_BLK=y CONFIG_CLK=y CONFIG_BCM6345_GPIO=y CONFIG_LED=y diff --git a/configs/bcm968580xref_ram_defconfig b/configs/bcm968580xref_ram_defconfig index a8c7ffa748..4320739809 100644 --- a/configs/bcm968580xref_ram_defconfig +++ b/configs/bcm968580xref_ram_defconfig @@ -34,7 +34,6 @@ CONFIG_ISO_PARTITION=y CONFIG_EFI_PARTITION=y CONFIG_SYS_RELOC_GD_ENV_ADDR=y # CONFIG_NET is not set -CONFIG_BLK=y CONFIG_CLK=y CONFIG_BCM6345_GPIO=y CONFIG_LED=y @@ -61,4 +60,3 @@ CONFIG_BCM63XX_HSSPI=y CONFIG_SYSRESET=y CONFIG_SYSRESET_WATCHDOG=y CONFIG_WDT_BCM6345=y -# CONFIG_GENERATE_SMBIOS_TABLE is not set diff --git a/configs/crs305-1g-4s-bit_defconfig b/configs/crs305-1g-4s-bit_defconfig index 1b46ab4bf9..463f474a8f 100644 --- a/configs/crs305-1g-4s-bit_defconfig +++ b/configs/crs305-1g-4s-bit_defconfig @@ -37,7 +37,6 @@ CONFIG_ENV_IS_IN_SPI_FLASH=y CONFIG_SYS_RELOC_GD_ENV_ADDR=y CONFIG_ARP_TIMEOUT=200 CONFIG_NET_RETRY_COUNT=50 -CONFIG_BLK=y CONFIG_BOOTCOUNT_LIMIT=y CONFIG_BOOTCOUNT_ENV=y # CONFIG_MMC is not set @@ -51,4 +50,3 @@ CONFIG_PCI=y CONFIG_PCI_MVEBU=y CONFIG_SYS_NS16550=y CONFIG_KIRKWOOD_SPI=y -# CONFIG_EFI_LOADER is not set diff --git a/configs/crs305-1g-4s_defconfig b/configs/crs305-1g-4s_defconfig index a7a3ffe481..84d23a24cc 100644 --- a/configs/crs305-1g-4s_defconfig +++ b/configs/crs305-1g-4s_defconfig @@ -38,7 +38,6 @@ CONFIG_ENV_IS_IN_SPI_FLASH=y CONFIG_SYS_RELOC_GD_ENV_ADDR=y CONFIG_ARP_TIMEOUT=200 CONFIG_NET_RETRY_COUNT=50 -CONFIG_BLK=y CONFIG_BOOTCOUNT_LIMIT=y CONFIG_BOOTCOUNT_ENV=y # CONFIG_MMC is not set @@ -52,4 +51,3 @@ CONFIG_PCI=y CONFIG_PCI_MVEBU=y CONFIG_SYS_NS16550=y CONFIG_KIRKWOOD_SPI=y -# CONFIG_EFI_LOADER is not set diff --git a/configs/crs326-24g-2s-bit_defconfig b/configs/crs326-24g-2s-bit_defconfig index 70f71de6ae..1eb70e5a32 100644 --- a/configs/crs326-24g-2s-bit_defconfig +++ b/configs/crs326-24g-2s-bit_defconfig @@ -37,7 +37,6 @@ CONFIG_ENV_IS_IN_SPI_FLASH=y CONFIG_SYS_RELOC_GD_ENV_ADDR=y CONFIG_ARP_TIMEOUT=200 CONFIG_NET_RETRY_COUNT=50 -CONFIG_BLK=y CONFIG_BOOTCOUNT_LIMIT=y CONFIG_BOOTCOUNT_ENV=y # CONFIG_MMC is not set @@ -51,4 +50,3 @@ CONFIG_PCI=y CONFIG_PCI_MVEBU=y CONFIG_SYS_NS16550=y CONFIG_KIRKWOOD_SPI=y -# CONFIG_EFI_LOADER is not set diff --git a/configs/crs326-24g-2s_defconfig b/configs/crs326-24g-2s_defconfig index 5991b62923..44cb0b0663 100644 --- a/configs/crs326-24g-2s_defconfig +++ b/configs/crs326-24g-2s_defconfig @@ -37,7 +37,6 @@ CONFIG_ENV_IS_IN_SPI_FLASH=y CONFIG_SYS_RELOC_GD_ENV_ADDR=y CONFIG_ARP_TIMEOUT=200 CONFIG_NET_RETRY_COUNT=50 -CONFIG_BLK=y CONFIG_BOOTCOUNT_LIMIT=y CONFIG_BOOTCOUNT_ENV=y # CONFIG_MMC is not set @@ -51,4 +50,3 @@ CONFIG_PCI=y CONFIG_PCI_MVEBU=y CONFIG_SYS_NS16550=y CONFIG_KIRKWOOD_SPI=y -# CONFIG_EFI_LOADER is not set diff --git a/configs/crs328-4c-20s-4s-bit_defconfig b/configs/crs328-4c-20s-4s-bit_defconfig index 434e9fb90f..95008cf1cb 100644 --- a/configs/crs328-4c-20s-4s-bit_defconfig +++ b/configs/crs328-4c-20s-4s-bit_defconfig @@ -37,7 +37,6 @@ CONFIG_ENV_IS_IN_SPI_FLASH=y CONFIG_SYS_RELOC_GD_ENV_ADDR=y CONFIG_ARP_TIMEOUT=200 CONFIG_NET_RETRY_COUNT=50 -CONFIG_BLK=y CONFIG_BOOTCOUNT_LIMIT=y CONFIG_BOOTCOUNT_ENV=y # CONFIG_MMC is not set @@ -51,4 +50,3 @@ CONFIG_PCI=y CONFIG_PCI_MVEBU=y CONFIG_SYS_NS16550=y CONFIG_KIRKWOOD_SPI=y -# CONFIG_EFI_LOADER is not set diff --git a/configs/crs328-4c-20s-4s_defconfig b/configs/crs328-4c-20s-4s_defconfig index 8e08cceaac..2f6cade9bd 100644 --- a/configs/crs328-4c-20s-4s_defconfig +++ b/configs/crs328-4c-20s-4s_defconfig @@ -37,7 +37,6 @@ CONFIG_ENV_IS_IN_SPI_FLASH=y CONFIG_SYS_RELOC_GD_ENV_ADDR=y CONFIG_ARP_TIMEOUT=200 CONFIG_NET_RETRY_COUNT=50 -CONFIG_BLK=y CONFIG_BOOTCOUNT_LIMIT=y CONFIG_BOOTCOUNT_ENV=y # CONFIG_MMC is not set @@ -51,4 +50,3 @@ CONFIG_PCI=y CONFIG_PCI_MVEBU=y CONFIG_SYS_NS16550=y CONFIG_KIRKWOOD_SPI=y -# CONFIG_EFI_LOADER is not set diff --git a/configs/durian_defconfig b/configs/durian_defconfig index d9e3768bb0..4d2ccab8a0 100644 --- a/configs/durian_defconfig +++ b/configs/durian_defconfig @@ -32,7 +32,6 @@ CONFIG_SYS_RELOC_GD_ENV_ADDR=y CONFIG_DM=y CONFIG_SCSI_AHCI=y CONFIG_AHCI_PCI=y -CONFIG_BLK=y # CONFIG_MMC is not set CONFIG_PCI=y CONFIG_PCI_PHYTIUM=y diff --git a/configs/gardena-smart-gateway-at91sam_defconfig b/configs/gardena-smart-gateway-at91sam_defconfig index 8de93e49ff..5574b9d17f 100644 --- a/configs/gardena-smart-gateway-at91sam_defconfig +++ b/configs/gardena-smart-gateway-at91sam_defconfig @@ -89,7 +89,6 @@ CONFIG_VERSION_VARIABLE=y CONFIG_NET_RANDOM_ETHADDR=y CONFIG_DM=y CONFIG_SPL_DM=y -CONFIG_BLK=y CONFIG_CLK=y CONFIG_CLK_AT91=y CONFIG_AT91_GPIO=y diff --git a/configs/j7200_hs_evm_a72_defconfig b/configs/j7200_hs_evm_a72_defconfig index 0583a2ab62..7c95b00af5 100644 --- a/configs/j7200_hs_evm_a72_defconfig +++ b/configs/j7200_hs_evm_a72_defconfig @@ -31,8 +31,6 @@ CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0x80480000 # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set CONFIG_SPL_LOAD_FIT=y CONFIG_SPL_LOAD_FIT_ADDRESS=0x81000000 -CONFIG_FIT_IMAGE_POST_PROCESS=y -CONFIG_SPL_FIT_IMAGE_POST_PROCESS=y # CONFIG_USE_SPL_FIT_GENERATOR is not set CONFIG_OF_BOARD_SETUP=y CONFIG_BOOTCOMMAND="run findfdt; run envboot; run init_${boot}; run boot_rprocs; run get_fit_${boot}; run get_overlaystring; run run_fit" @@ -155,7 +153,6 @@ CONFIG_SPI_FLASH_MTD=y CONFIG_MULTIPLEXER=y CONFIG_MUX_MMIO=y CONFIG_PHY_FIXED=y -CONFIG_DM_ETH=y CONFIG_TI_AM65_CPSW_NUSS=y CONFIG_PHY=y CONFIG_SPL_PHY=y diff --git a/configs/j7200_hs_evm_r5_defconfig b/configs/j7200_hs_evm_r5_defconfig index 975cbb8a50..0cf9c688e4 100644 --- a/configs/j7200_hs_evm_r5_defconfig +++ b/configs/j7200_hs_evm_r5_defconfig @@ -27,7 +27,6 @@ CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0x41cf5bfc # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set CONFIG_SPL_LOAD_FIT=y CONFIG_SPL_LOAD_FIT_ADDRESS=0x80080000 -CONFIG_SPL_FIT_IMAGE_POST_PROCESS=y # CONFIG_USE_SPL_FIT_GENERATOR is not set CONFIG_USE_BOOTCOMMAND=y # CONFIG_DISPLAY_CPUINFO is not set diff --git a/configs/j721s2_hs_evm_a72_defconfig b/configs/j721s2_hs_evm_a72_defconfig index 851c98577d..7ae0c3ba7b 100644 --- a/configs/j721s2_hs_evm_a72_defconfig +++ b/configs/j721s2_hs_evm_a72_defconfig @@ -31,8 +31,6 @@ CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0x80480000 # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set CONFIG_SPL_LOAD_FIT=y CONFIG_SPL_LOAD_FIT_ADDRESS=0x81000000 -CONFIG_FIT_IMAGE_POST_PROCESS=y -CONFIG_SPL_FIT_IMAGE_POST_PROCESS=y # CONFIG_USE_SPL_FIT_GENERATOR is not set CONFIG_OF_BOARD_SETUP=y CONFIG_BOOTCOMMAND="run findfdt; run envboot; run init_${boot}; run boot_rprocs; run get_fit_${boot}; run get_overlaystring; run run_fit" @@ -162,7 +160,6 @@ CONFIG_MULTIPLEXER=y CONFIG_MUX_MMIO=y CONFIG_PHY_TI_DP83867=y CONFIG_PHY_FIXED=y -CONFIG_DM_ETH=y CONFIG_TI_AM65_CPSW_NUSS=y CONFIG_PHY=y CONFIG_SPL_PHY=y diff --git a/configs/j721s2_hs_evm_r5_defconfig b/configs/j721s2_hs_evm_r5_defconfig index 696674ec42..8df968c65c 100644 --- a/configs/j721s2_hs_evm_r5_defconfig +++ b/configs/j721s2_hs_evm_r5_defconfig @@ -29,7 +29,6 @@ CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0x41c76000 # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set CONFIG_SPL_LOAD_FIT=y CONFIG_SPL_LOAD_FIT_ADDRESS=0x80080000 -CONFIG_SPL_FIT_IMAGE_POST_PROCESS=y # CONFIG_USE_SPL_FIT_GENERATOR is not set CONFIG_USE_BOOTCOMMAND=y # CONFIG_DISPLAY_CPUINFO is not set diff --git a/configs/lschlv2_defconfig b/configs/lschlv2_defconfig index e9cc632696..cfccfdcfc4 100644 --- a/configs/lschlv2_defconfig +++ b/configs/lschlv2_defconfig @@ -60,7 +60,6 @@ CONFIG_MTD=y CONFIG_DM_SPI_FLASH=y CONFIG_SF_DEFAULT_SPEED=25000000 CONFIG_SPI_FLASH_STMICRO=y -CONFIG_DM_ETH=y CONFIG_DM_MDIO=y CONFIG_MVGBE=y CONFIG_MII=y diff --git a/configs/lsxhl_defconfig b/configs/lsxhl_defconfig index b83a072b04..1945b72450 100644 --- a/configs/lsxhl_defconfig +++ b/configs/lsxhl_defconfig @@ -61,7 +61,6 @@ CONFIG_MTD=y CONFIG_DM_SPI_FLASH=y CONFIG_SF_DEFAULT_SPEED=25000000 CONFIG_SPI_FLASH_STMICRO=y -CONFIG_DM_ETH=y CONFIG_DM_MDIO=y CONFIG_MVGBE=y CONFIG_MII=y diff --git a/configs/netspace_mini_v2_defconfig b/configs/netspace_mini_v2_defconfig index c48063500a..5ce2fbdb93 100644 --- a/configs/netspace_mini_v2_defconfig +++ b/configs/netspace_mini_v2_defconfig @@ -54,7 +54,6 @@ CONFIG_SYS_FAULT_ECHO_LINK_DOWN=y CONFIG_DM=y CONFIG_SATA_MV=y CONFIG_SYS_SATA_MAX_DEVICE=1 -CONFIG_BLK=y CONFIG_LBA48=y CONFIG_SYS_64BIT_LBA=y CONFIG_KIRKWOOD_GPIO=y diff --git a/configs/nsim_hs38_defconfig b/configs/nsim_hs38_defconfig index 740de7a409..9b85dc4141 100644 --- a/configs/nsim_hs38_defconfig +++ b/configs/nsim_hs38_defconfig @@ -29,8 +29,6 @@ CONFIG_OF_EMBED=y CONFIG_SYS_RELOC_GD_ENV_ADDR=y CONFIG_USE_BOOTFILE=y CONFIG_BOOTFILE="uImage" -CONFIG_BLK=y -CONFIG_DM_ETH=y CONFIG_DM_SERIAL=y CONFIG_DEBUG_UART_SHIFT=2 CONFIG_SYS_NS16550=y diff --git a/configs/octeon_nic23_defconfig b/configs/octeon_nic23_defconfig index 098831e0b1..abc7914437 100644 --- a/configs/octeon_nic23_defconfig +++ b/configs/octeon_nic23_defconfig @@ -43,7 +43,6 @@ CONFIG_CMD_TIME=y CONFIG_CMD_EXT4=y CONFIG_CMD_FAT=y CONFIG_CMD_FS_GENERIC=y -CONFIG_CMD_CYCLIC=y CONFIG_EFI_PARTITION=y CONFIG_ENV_IS_IN_SPI_FLASH=y CONFIG_TFTP_TSIZE=y diff --git a/configs/pg_wcom_expu1_defconfig b/configs/pg_wcom_expu1_defconfig index 5dae75f0f9..aa4deac3df 100644 --- a/configs/pg_wcom_expu1_defconfig +++ b/configs/pg_wcom_expu1_defconfig @@ -40,7 +40,6 @@ CONFIG_AUTOBOOT_STOP_STR=" " CONFIG_USE_BOOTARGS=y CONFIG_BOOTARGS="console=ttyS0,115200 root=/dev/ram0" CONFIG_SILENT_CONSOLE=y -CONFIG_EVENT=y CONFIG_LAST_STAGE_INIT=y CONFIG_MISC_INIT_R=y CONFIG_SYS_MAXARGS=32 diff --git a/configs/pg_wcom_expu1_update_defconfig b/configs/pg_wcom_expu1_update_defconfig index 68fa48d0da..ba82a4f0d0 100644 --- a/configs/pg_wcom_expu1_update_defconfig +++ b/configs/pg_wcom_expu1_update_defconfig @@ -38,7 +38,6 @@ CONFIG_AUTOBOOT_STOP_STR=" " CONFIG_USE_BOOTARGS=y CONFIG_BOOTARGS="console=ttyS0,115200 root=/dev/ram0" CONFIG_SILENT_CONSOLE=y -CONFIG_EVENT=y CONFIG_LAST_STAGE_INIT=y CONFIG_MISC_INIT_R=y CONFIG_SYS_MAXARGS=32 diff --git a/configs/pg_wcom_seli8_defconfig b/configs/pg_wcom_seli8_defconfig index f56f3eb534..c1b60aa516 100644 --- a/configs/pg_wcom_seli8_defconfig +++ b/configs/pg_wcom_seli8_defconfig @@ -40,7 +40,6 @@ CONFIG_AUTOBOOT_STOP_STR=" " CONFIG_USE_BOOTARGS=y CONFIG_BOOTARGS="console=ttyS0,115200 root=/dev/ram0" CONFIG_SILENT_CONSOLE=y -CONFIG_EVENT=y CONFIG_LAST_STAGE_INIT=y CONFIG_MISC_INIT_R=y CONFIG_SYS_MAXARGS=32 diff --git a/configs/pg_wcom_seli8_update_defconfig b/configs/pg_wcom_seli8_update_defconfig index 2840266e89..5aef18d586 100644 --- a/configs/pg_wcom_seli8_update_defconfig +++ b/configs/pg_wcom_seli8_update_defconfig @@ -38,7 +38,6 @@ CONFIG_AUTOBOOT_STOP_STR=" " CONFIG_USE_BOOTARGS=y CONFIG_BOOTARGS="console=ttyS0,115200 root=/dev/ram0" CONFIG_SILENT_CONSOLE=y -CONFIG_EVENT=y CONFIG_LAST_STAGE_INIT=y CONFIG_MISC_INIT_R=y CONFIG_SYS_MAXARGS=32 diff --git a/configs/pm9261_defconfig b/configs/pm9261_defconfig index 68fb02bd35..cd73fe41f9 100644 --- a/configs/pm9261_defconfig +++ b/configs/pm9261_defconfig @@ -39,7 +39,6 @@ CONFIG_ENV_OVERWRITE=y CONFIG_ENV_IS_IN_FLASH=y # CONFIG_NET is not set CONFIG_DM=y -CONFIG_BLK=y CONFIG_CLK=y CONFIG_CLK_AT91=y CONFIG_AT91_GPIO=y diff --git a/configs/pm9263_defconfig b/configs/pm9263_defconfig index 470ae9efa8..67fb1b9483 100644 --- a/configs/pm9263_defconfig +++ b/configs/pm9263_defconfig @@ -43,7 +43,6 @@ CONFIG_OF_CONTROL=y CONFIG_ENV_OVERWRITE=y CONFIG_ENV_IS_IN_FLASH=y CONFIG_DM=y -CONFIG_BLK=y CONFIG_CLK=y CONFIG_CLK_AT91=y CONFIG_AT91_GPIO=y diff --git a/configs/qcs404evb_defconfig b/configs/qcs404evb_defconfig index 432d5d50c1..dae1551411 100644 --- a/configs/qcs404evb_defconfig +++ b/configs/qcs404evb_defconfig @@ -22,35 +22,33 @@ CONFIG_CMD_GPIO=y CONFIG_CMD_GPT=y CONFIG_CMD_MMC=y CONFIG_CMD_PART=y +CONFIG_CMD_USB=y CONFIG_CMD_EXT2=y CONFIG_CMD_EXT4=y CONFIG_CMD_EXT4_WRITE=y CONFIG_CMD_FAT=y CONFIG_CMD_FS_GENERIC=y -CONFIG_CMD_USB=y # CONFIG_NET is not set CONFIG_CLK=y +CONFIG_QCOM_PMIC_GPIO=y +CONFIG_MISC=y CONFIG_MMC_HS400_SUPPORT=y CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI_ADMA=y CONFIG_MMC_SDHCI_MSM=y -CONFIG_PINCTRL=y -CONFIG_MSM_SERIAL=y -CONFIG_SPMI_MSM=y -CONFIG_DM_PMIC=y -CONFIG_PMIC_QCOM=y -CONFIG_QCOM_PMIC_GPIO=y -CONFIG_MISC=y -CONFIG_USB=y -CONFIG_DM_USB=y -CONFIG_USB_STORAGE=y -CONFIG_USB_DWC3=y -CONFIG_USB_DWC3_GENERIC=y -CONFIG_USB_XHCI_HCD=y -CONFIG_USB_XHCI_DWC3=y -CONFIG_DM_RESET=y -CONFIG_RESET_QCOM=y CONFIG_PHY=y CONFIG_PHY_QCOM_USB_HS_28NM=y CONFIG_PHY_QCOM_USB_SS=y +CONFIG_PINCTRL=y +CONFIG_DM_PMIC=y +CONFIG_PMIC_QCOM=y +CONFIG_DM_RESET=y +CONFIG_MSM_SERIAL=y +CONFIG_SPMI_MSM=y +CONFIG_USB=y +CONFIG_USB_XHCI_HCD=y +CONFIG_USB_XHCI_DWC3=y +CONFIG_USB_DWC3=y +CONFIG_USB_DWC3_GENERIC=y +CONFIG_USB_STORAGE=y CONFIG_LMB_MAX_REGIONS=64 diff --git a/configs/qemu-ppce500_defconfig b/configs/qemu-ppce500_defconfig index 79cfa829e6..7756f5f4ae 100644 --- a/configs/qemu-ppce500_defconfig +++ b/configs/qemu-ppce500_defconfig @@ -39,7 +39,6 @@ CONFIG_BOOTFILE="uImage" CONFIG_NET_RANDOM_ETHADDR=y CONFIG_DM=y CONFIG_SIMPLE_BUS_CORRECT_RANGE=y -CONFIG_BLK=y CONFIG_LBA48=y CONFIG_CHIP_SELECTS_PER_CTRL=0 CONFIG_MPC8XXX_GPIO=y diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig index 830b149251..caecb50ad9 100644 --- a/configs/sandbox_defconfig +++ b/configs/sandbox_defconfig @@ -93,8 +93,8 @@ CONFIG_CMD_LINK_LOCAL=y CONFIG_CMD_ETHSW=y CONFIG_CMD_BMP=y CONFIG_CMD_BOOTCOUNT=y -CONFIG_CMD_EFICONFIG=y CONFIG_CMD_EFIDEBUG=y +CONFIG_CMD_EFICONFIG=y CONFIG_CMD_RTC=y CONFIG_CMD_TIME=y CONFIG_CMD_PAUSE=y diff --git a/configs/stm32mp13_defconfig b/configs/stm32mp13_defconfig index 26beb73e84..af6b1839d0 100644 --- a/configs/stm32mp13_defconfig +++ b/configs/stm32mp13_defconfig @@ -64,7 +64,6 @@ CONFIG_DM_REGULATOR_GPIO=y CONFIG_DM_REGULATOR_SCMI=y CONFIG_RESET_SCMI=y CONFIG_DM_RNG=y -CONFIG_RNG_OPTEE=y CONFIG_DM_RTC=y CONFIG_RTC_STM32=y CONFIG_SERIAL_RX_BUFFER=y diff --git a/configs/stm32mp15_defconfig b/configs/stm32mp15_defconfig index fd2a5de8d1..4bc2e8e1d8 100644 --- a/configs/stm32mp15_defconfig +++ b/configs/stm32mp15_defconfig @@ -123,7 +123,6 @@ CONFIG_DM_REGULATOR_STPMIC1=y CONFIG_REMOTEPROC_STM32_COPRO=y CONFIG_RESET_SCMI=y CONFIG_DM_RNG=y -CONFIG_RNG_OPTEE=y CONFIG_RNG_STM32MP1=y CONFIG_DM_RTC=y CONFIG_RTC_STM32=y diff --git a/configs/stm32mp15_trusted_defconfig b/configs/stm32mp15_trusted_defconfig index 1154eec210..9cfa9a20f3 100644 --- a/configs/stm32mp15_trusted_defconfig +++ b/configs/stm32mp15_trusted_defconfig @@ -124,7 +124,6 @@ CONFIG_DM_REGULATOR_STPMIC1=y CONFIG_REMOTEPROC_STM32_COPRO=y CONFIG_RESET_SCMI=y CONFIG_DM_RNG=y -CONFIG_RNG_OPTEE=y CONFIG_RNG_STM32MP1=y CONFIG_DM_RTC=y CONFIG_RTC_STM32=y From c2fd0ca1a8226903e6e00f970c58f23742d6a418 Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Thu, 18 Aug 2022 13:22:46 +0200 Subject: [PATCH 198/374] watchdog: Integrate watchdog triggering into the cyclic framework This patch integrates the watchdog triggering into the recently added cyclic infrastructure. Each watchdog device that shall be triggered registers it's own cyclic function. This way, multiple watchdog devices are still supported, each via a cyclic function with separate trigger intervals. Signed-off-by: Stefan Roese Reviewed-by: Simon Glass Tested-by: Tom Rini [am335x_evm, mx6cuboxi, rpi_3,dra7xx_evm, pine64_plus, am65x_evm, j721e_evm] --- drivers/watchdog/Kconfig | 2 + drivers/watchdog/wdt-uclass.c | 73 ++++++++++++++++++++--------------- 2 files changed, 43 insertions(+), 32 deletions(-) diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index 50e6a1efba..e55deaf906 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -3,6 +3,7 @@ menu "Watchdog Timer Support" config WATCHDOG bool "Enable U-Boot watchdog reset" depends on !HW_WATCHDOG + select CYCLIC help This option enables U-Boot watchdog support where U-Boot is using watchdog_reset function to service watchdog device in U-Boot. Enable @@ -74,6 +75,7 @@ config WDT bool "Enable driver model for watchdog timer drivers" depends on DM imply WATCHDOG + select CYCLIC help Enable driver model for watchdog timer. At the moment the API is very simple and only supports four operations: diff --git a/drivers/watchdog/wdt-uclass.c b/drivers/watchdog/wdt-uclass.c index dbf556467d..3f342cd99f 100644 --- a/drivers/watchdog/wdt-uclass.c +++ b/drivers/watchdog/wdt-uclass.c @@ -6,6 +6,7 @@ #define LOG_CATEGORY UCLASS_WDT #include +#include #include #include #include @@ -38,8 +39,25 @@ struct wdt_priv { bool running; /* No autostart */ bool noautostart; + + struct cyclic_info *cyclic; }; +static void wdt_cyclic(void *ctx) +{ + struct udevice *dev = ctx; + struct wdt_priv *priv; + + if (!device_active(dev)) + return; + + priv = dev_get_uclass_priv(dev); + if (!priv->running) + return; + + wdt_reset(dev); +} + static void init_watchdog_dev(struct udevice *dev) { struct wdt_priv *priv; @@ -64,9 +82,6 @@ static void init_watchdog_dev(struct udevice *dev) printf("WDT: Failed to start %s\n", dev->name); return; } - - printf("WDT: Started %s with%s servicing (%ds timeout)\n", dev->name, - IS_ENABLED(CONFIG_WATCHDOG) ? "" : "out", priv->timeout); } int initr_watchdog(void) @@ -105,8 +120,29 @@ int wdt_start(struct udevice *dev, u64 timeout_ms, ulong flags) ret = ops->start(dev, timeout_ms, flags); if (ret == 0) { struct wdt_priv *priv = dev_get_uclass_priv(dev); + char str[16]; priv->running = true; + + memset(str, 0, 16); + if (IS_ENABLED(CONFIG_WATCHDOG)) { + /* Register the watchdog driver as a cyclic function */ + priv->cyclic = cyclic_register(wdt_cyclic, + priv->reset_period * 1000, + dev->name, dev); + if (!priv->cyclic) { + printf("cyclic_register for %s failed\n", + dev->name); + return -ENODEV; + } else { + snprintf(str, 16, "every %ldms", + priv->reset_period); + } + } + + printf("WDT: Started %s with%s servicing %s (%ds timeout)\n", + dev->name, IS_ENABLED(CONFIG_WATCHDOG) ? "" : "out", + str, priv->timeout); } return ret; @@ -194,37 +230,10 @@ int wdt_expire_now(struct udevice *dev, ulong flags) */ void watchdog_reset(void) { - struct wdt_priv *priv; - struct udevice *dev; - struct uclass *uc; - ulong now; - - /* Exit if GD is not ready or watchdog is not initialized yet */ - if (!gd || !(gd->flags & GD_FLG_WDT_READY)) - return; - - if (uclass_get(UCLASS_WDT, &uc)) - return; - /* - * All devices bound to the wdt uclass should have been probed - * in initr_watchdog(). But just in case something went wrong, - * check device_active() before accessing the uclass private - * data. + * Empty function for now. The actual WDT handling is now done in + * the cyclic function instead. */ - uclass_foreach_dev(dev, uc) { - if (!device_active(dev)) - continue; - priv = dev_get_uclass_priv(dev); - if (!priv->running) - continue; - /* Do not reset the watchdog too often */ - now = get_timer(0); - if (time_after_eq(now, priv->next_reset)) { - priv->next_reset = now + priv->reset_period; - wdt_reset(dev); - } - } } #endif From 881d4108257a45ac890ef27c523783dbe401e462 Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Fri, 2 Sep 2022 14:10:45 +0200 Subject: [PATCH 199/374] cyclic: Introduce schedule() function This patch introduces a schedule() function, which shall be used instead of the old WATCHDOG_RESET. Follow-up patches will make sure, that this new function is used. Signed-off-by: Stefan Roese Reviewed-by: Simon Glass Tested-by: Tom Rini [am335x_evm, mx6cuboxi, rpi_3,dra7xx_evm, pine64_plus, am65x_evm, j721e_evm] --- common/cyclic.c | 16 ++++++++++++++++ include/cyclic.h | 12 ++++++++++++ 2 files changed, 28 insertions(+) diff --git a/common/cyclic.c b/common/cyclic.c index cd5dcb1f2b..b3c180bd1a 100644 --- a/common/cyclic.c +++ b/common/cyclic.c @@ -18,6 +18,8 @@ DECLARE_GLOBAL_DATA_PTR; +void hw_watchdog_reset(void); + struct list_head *cyclic_get_list(void) { return &gd->cyclic->cyclic_list; @@ -96,6 +98,20 @@ void cyclic_run(void) gd->cyclic->cyclic_running = false; } +void schedule(void) +{ + /* The HW watchdog is not integrated into the cyclic IF (yet) */ + if (IS_ENABLED(CONFIG_HW_WATCHDOG)) + hw_watchdog_reset(); + + /* + * schedule() might get called very early before the cyclic IF is + * ready. Make sure to only call cyclic_run() when it's initalized. + */ + if (gd && gd->cyclic && gd->cyclic->cyclic_ready) + cyclic_run(); +} + int cyclic_uninit(void) { struct cyclic_info *cyclic, *tmp; diff --git a/include/cyclic.h b/include/cyclic.h index 23902234cc..7601636433 100644 --- a/include/cyclic.h +++ b/include/cyclic.h @@ -106,6 +106,14 @@ struct list_head *cyclic_get_list(void); * needs to be executed, then call into these registered functions. */ void cyclic_run(void); + +/** + * schedule() - Schedule all potentially waiting tasks + * + * Basically a wrapper for cyclic_run(), pontentially enhanced by some + * other parts, that need to get handled periodically. + */ +void schedule(void); #else static inline struct cyclic_info *cyclic_register(cyclic_func_t func, uint64_t delay_us, @@ -124,6 +132,10 @@ static inline void cyclic_run(void) { } +static inline void schedule(void) +{ +} + static inline int cyclic_init(void) { return 0; From 29caf9305b6fafe8f6d6b18fa1f825dff8686e61 Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Fri, 2 Sep 2022 14:10:46 +0200 Subject: [PATCH 200/374] cyclic: Use schedule() instead of WATCHDOG_RESET() Globally replace all occurances of WATCHDOG_RESET() with schedule(), which handles the HW_WATCHDOG functionality and the cyclic infrastructure. Signed-off-by: Stefan Roese Reviewed-by: Simon Glass Tested-by: Tom Rini [am335x_evm, mx6cuboxi, rpi_3,dra7xx_evm, pine64_plus, am65x_evm, j721e_evm] --- arch/arm/mach-at91/phy.c | 2 +- arch/arm/mach-imx/i2c-mxv7.c | 2 +- arch/arm/mach-socfpga/spl_a10.c | 8 ++--- .../cmd_stm32prog/stm32prog_serial.c | 6 ++-- arch/m68k/lib/time.c | 2 +- arch/powerpc/cpu/mpc8xx/cpu_init.c | 2 +- arch/powerpc/lib/bootm.c | 6 ++-- arch/powerpc/lib/cache.c | 2 +- arch/powerpc/lib/interrupts.c | 2 +- board/astro/mcf5373l/fpga.c | 4 +-- board/dhelectronics/dh_stm32mp1/board.c | 2 +- board/liebherr/display5/spl.c | 2 +- board/nokia/rx51/rx51.c | 2 +- board/st/stm32mp1/stm32mp1.c | 2 +- boot/bootretry.c | 2 +- boot/image-board.c | 2 +- cmd/fastboot.c | 2 +- cmd/mem.c | 16 ++++----- cmd/usb_mass_storage.c | 2 +- cmd/ximg.c | 2 +- common/board_f.c | 4 +-- common/board_r.c | 2 +- common/cli_readline.c | 4 +-- common/console.c | 2 +- common/dfu.c | 2 +- common/lcd.c | 10 +++--- common/menu.c | 6 ++-- common/usb_kbd.c | 2 +- common/xyzModem.c | 2 +- drivers/block/ide.c | 8 ++--- drivers/crypto/aspeed/aspeed_hace.c | 2 +- drivers/crypto/hash/hash_sw.c | 2 +- drivers/ddr/altera/sdram_arria10.c | 4 +-- drivers/ddr/altera/sdram_n5x.c | 4 +-- drivers/ddr/altera/sdram_soc64.c | 2 +- drivers/fpga/intel_sdm_mb.c | 8 ++--- drivers/fpga/socfpga_arria10.c | 8 ++--- drivers/i2c/mxc_i2c.c | 4 +-- drivers/mmc/octeontx_hsmmc.c | 12 +++---- drivers/mmc/sh_mmcif.c | 6 ++-- drivers/mmc/stm32_sdmmc2.c | 2 +- drivers/mtd/cfi_flash.c | 4 +-- drivers/mtd/nand/core.c | 2 +- drivers/mtd/nand/raw/atmel_nand.c | 6 ++-- drivers/mtd/nand/raw/nand_base.c | 10 +++--- drivers/mtd/nand/raw/nand_util.c | 6 ++-- drivers/mtd/nand/spi/core.c | 4 +-- drivers/mtd/onenand/onenand_base.c | 4 +-- drivers/mtd/spi/spi-nor-core.c | 4 +-- drivers/net/octeontx2/nix.c | 2 +- drivers/net/octeontx2/nix_af.c | 32 ++++++++--------- drivers/ram/stm32mp1/stm32mp1_tests.c | 2 +- drivers/serial/atmel_usart.c | 2 +- drivers/serial/ns16550.c | 6 ++-- drivers/serial/serial-uclass.c | 2 +- drivers/serial/serial_bcm283x_mu.c | 2 +- drivers/serial/serial_lpuart.c | 8 ++--- drivers/serial/serial_mpc8xx.c | 4 +-- drivers/serial/serial_mt7620.c | 2 +- drivers/serial/serial_mtk.c | 4 +-- drivers/serial/serial_mxc.c | 6 ++-- drivers/serial/serial_octeon_bootcmd.c | 2 +- drivers/serial/serial_octeon_pcie_console.c | 4 +-- drivers/serial/serial_pl01x.c | 8 ++--- drivers/serial/serial_sifive.c | 2 +- drivers/serial/serial_zynq.c | 2 +- drivers/spi/mtk_snfi_spi.c | 2 +- drivers/spi/octeon_spi.c | 2 +- drivers/spi/stm32_qspi.c | 2 +- drivers/timer/mpc83xx_timer.c | 4 +-- drivers/usb/eth/lan7x.h | 4 +-- drivers/usb/gadget/f_acm.c | 4 +-- drivers/usb/gadget/f_sdp.c | 4 +-- drivers/usb/host/ehci-hcd.c | 2 +- drivers/usb/musb-new/musb_uboot.c | 2 +- drivers/video/video_bmp.c | 4 +-- env/common.c | 2 +- fs/cramfs/uncompress.c | 3 +- fs/jffs2/jffs2_1pass.c | 2 +- include/linux/compat.h | 2 +- include/wait_bit.h | 2 +- include/watchdog.h | 8 ----- lib/bzip2/bzlib.c | 2 +- lib/bzip2/bzlib_decompress.c | 8 ++--- lib/crc32.c | 2 +- lib/efi_loader/efi_boottime.c | 4 +-- lib/gunzip.c | 2 +- lib/lzma/LzmaDec.c | 16 ++++----- lib/lzma/LzmaTools.c | 2 +- lib/md5.c | 2 +- lib/sha1.c | 2 +- lib/sha256.c | 2 +- lib/sha512.c | 4 +-- lib/time.c | 2 +- lib/zlib/inflate.c | 8 ++--- net/net.c | 2 +- post/cpu/mpc83xx/ecc.c | 2 +- post/drivers/memory.c | 36 +++++++++---------- post/lib_powerpc/cpu.c | 16 ++++----- post/lib_powerpc/fpu/fpu.c | 4 +-- post/post.c | 4 +-- test/common/cyclic.c | 2 +- test/dm/wdt.c | 9 ++--- 103 files changed, 235 insertions(+), 241 deletions(-) diff --git a/arch/arm/mach-at91/phy.c b/arch/arm/mach-at91/phy.c index 6101eee358..f4484a77c7 100644 --- a/arch/arm/mach-at91/phy.c +++ b/arch/arm/mach-at91/phy.c @@ -42,7 +42,7 @@ void at91_phy_reset(void) /* Wait for end of hardware reset */ while (!(readl(&rstc->sr) & AT91_RSTC_SR_NRSTL)) { /* avoid shutdown by watchdog */ - WATCHDOG_RESET(); + schedule(); mdelay(10); /* timeout for not getting stuck in an endless loop */ diff --git a/arch/arm/mach-imx/i2c-mxv7.c b/arch/arm/mach-imx/i2c-mxv7.c index d36347d8e8..85d648b56e 100644 --- a/arch/arm/mach-imx/i2c-mxv7.c +++ b/arch/arm/mach-imx/i2c-mxv7.c @@ -46,7 +46,7 @@ int force_idle_bus(void *priv) scl = gpio_get_value(p->scl.gp); if ((sda & scl) == 1) break; - WATCHDOG_RESET(); + schedule(); elapsed = get_timer(start_time); if (elapsed > (CONFIG_SYS_HZ / 5)) { /* .2 seconds */ ret = -EBUSY; diff --git a/arch/arm/mach-socfpga/spl_a10.c b/arch/arm/mach-socfpga/spl_a10.c index ec67a5b0eb..2c567edd50 100644 --- a/arch/arm/mach-socfpga/spl_a10.c +++ b/arch/arm/mach-socfpga/spl_a10.c @@ -117,7 +117,7 @@ void spl_board_init(void) /* enable console uart printing */ preloader_console_init(); - WATCHDOG_RESET(); + schedule(); arch_early_init_r(); @@ -203,7 +203,7 @@ void spl_board_init(void) */ set_regular_boot(true); - WATCHDOG_RESET(); + schedule(); reset_cpu(); } @@ -268,11 +268,11 @@ void board_init_f(ulong dummy) /* reconfigure and enable the watchdog */ hw_watchdog_init(); - WATCHDOG_RESET(); + schedule(); #endif /* CONFIG_HW_WATCHDOG */ config_dedicated_pins(gd->fdt_blob); - WATCHDOG_RESET(); + schedule(); } /* board specific function prior loading SSBL / U-Boot proper */ diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_serial.c b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_serial.c index 2932eae757..1a69bc3897 100644 --- a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_serial.c +++ b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_serial.c @@ -247,7 +247,7 @@ static int stm32prog_serial_getc_err(void) err = ops->getc(down_serial_dev); if (err == -EAGAIN) { ctrlc(); - WATCHDOG_RESET(); + schedule(); } } while ((err == -EAGAIN) && (!had_ctrlc())); @@ -276,7 +276,7 @@ static bool stm32prog_serial_get_buffer(u8 *buffer, u32 *count) *count -= 1; } else if (err == -EAGAIN) { ctrlc(); - WATCHDOG_RESET(); + schedule(); if (get_timer(start) > TIMEOUT_SERIAL_BUFFER) { err = -ETIMEDOUT; break; @@ -852,7 +852,7 @@ bool stm32prog_serial_loop(struct stm32prog_data *data) stm32prog_serial_result(ACK_BYTE); cmd_func[counter](data); } - WATCHDOG_RESET(); + schedule(); } /* clean device */ diff --git a/arch/m68k/lib/time.c b/arch/m68k/lib/time.c index ebb2ac54db..cd7437b3e2 100644 --- a/arch/m68k/lib/time.c +++ b/arch/m68k/lib/time.c @@ -72,7 +72,7 @@ void dtimer_interrupt(void *not_used) #if defined(CONFIG_WATCHDOG) || defined (CONFIG_HW_WATCHDOG) if (CONFIG_SYS_WATCHDOG_FREQ && (timestamp % (CONFIG_SYS_WATCHDOG_FREQ)) == 0) { - WATCHDOG_RESET (); + schedule(); } #endif /* CONFIG_WATCHDOG || CONFIG_HW_WATCHDOG */ return; diff --git a/arch/powerpc/cpu/mpc8xx/cpu_init.c b/arch/powerpc/cpu/mpc8xx/cpu_init.c index c8d06b0508..86b08a6174 100644 --- a/arch/powerpc/cpu/mpc8xx/cpu_init.c +++ b/arch/powerpc/cpu/mpc8xx/cpu_init.c @@ -31,7 +31,7 @@ void cpu_init_f(immap_t __iomem *immr) out_be32(&immr->im_siu_conf.sc_sypcr, CONFIG_SYS_SYPCR & ~SYPCR_SWE); #endif - WATCHDOG_RESET(); + schedule(); /* SIUMCR - contains debug pin configuration (11-6) */ setbits_be32(&immr->im_siu_conf.sc_siumcr, CONFIG_SYS_SIUMCR); diff --git a/arch/powerpc/lib/bootm.c b/arch/powerpc/lib/bootm.c index e52aa75703..b92df9543e 100644 --- a/arch/powerpc/lib/bootm.c +++ b/arch/powerpc/lib/bootm.c @@ -84,7 +84,7 @@ static void boot_jump_linux(bootm_headers_t *images) * r9: 0 */ debug(" Booting using OF flat tree...\n"); - WATCHDOG_RESET (); + schedule(); (*kernel) ((struct bd_info *)of_flat_tree, 0, 0, EPAPR_MAGIC, env_get_bootm_mapsize(), 0, 0); /* does not return */ @@ -108,7 +108,7 @@ static void boot_jump_linux(bootm_headers_t *images) struct bd_info *kbd = images->kbd; debug(" Booting using board info...\n"); - WATCHDOG_RESET (); + schedule(); (*kernel) (kbd, initrd_start, initrd_end, cmd_start, cmd_end, 0, 0); /* does not return */ @@ -319,7 +319,7 @@ void boot_jump_vxworks(bootm_headers_t *images) * r9: 0 * TCR: WRC = 0, no watchdog timer reset will occur */ - WATCHDOG_RESET(); + schedule(); ((void (*)(void *, ulong, ulong, ulong, ulong, ulong, ulong))images->ep)(images->ft_addr, diff --git a/arch/powerpc/lib/cache.c b/arch/powerpc/lib/cache.c index 19162511ce..c4c5c2d451 100644 --- a/arch/powerpc/lib/cache.c +++ b/arch/powerpc/lib/cache.c @@ -13,7 +13,7 @@ static ulong maybe_watchdog_reset(ulong flushed) { flushed += CONFIG_SYS_CACHELINE_SIZE; if (flushed >= CONFIG_CACHE_FLUSH_WATCHDOG_THRESHOLD) { - WATCHDOG_RESET(); + schedule(); flushed = 0; } return flushed; diff --git a/arch/powerpc/lib/interrupts.c b/arch/powerpc/lib/interrupts.c index 5ba4cd0c13..bdb8030c27 100644 --- a/arch/powerpc/lib/interrupts.c +++ b/arch/powerpc/lib/interrupts.c @@ -81,7 +81,7 @@ void timer_interrupt(struct pt_regs *regs) #if defined(CONFIG_WATCHDOG) || defined (CONFIG_HW_WATCHDOG) if (CONFIG_SYS_WATCHDOG_FREQ && (timestamp % (CONFIG_SYS_WATCHDOG_FREQ)) == 0) - WATCHDOG_RESET (); + schedule(); #endif /* CONFIG_WATCHDOG || CONFIG_HW_WATCHDOG */ #ifdef CONFIG_LED_STATUS diff --git a/board/astro/mcf5373l/fpga.c b/board/astro/mcf5373l/fpga.c index 50a3830b85..f85737432b 100644 --- a/board/astro/mcf5373l/fpga.c +++ b/board/astro/mcf5373l/fpga.c @@ -123,7 +123,7 @@ int altera_write_fn(const void *buf, size_t len, int flush, int cookie) if (bytecount % len_40 == 0) { #if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG) - WATCHDOG_RESET(); + schedule(); #endif #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK putc('.'); /* let them know we are alive */ @@ -343,7 +343,7 @@ int xilinx_fastwr_config_fn(void *buf, size_t len, int flush, int cookie) } if (bytecount % len_40 == 0) { #if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG) - WATCHDOG_RESET(); + schedule(); #endif #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK putc('.'); /* let them know we are alive */ diff --git a/board/dhelectronics/dh_stm32mp1/board.c b/board/dhelectronics/dh_stm32mp1/board.c index e3c7ed1049..7e4f3ff157 100644 --- a/board/dhelectronics/dh_stm32mp1/board.c +++ b/board/dhelectronics/dh_stm32mp1/board.c @@ -423,7 +423,7 @@ static void __maybe_unused led_error_blink(u32 nb_blink) for (i = 0; i < 2 * nb_blink; i++) { led_set_state(led, LEDST_TOGGLE); mdelay(125); - WATCHDOG_RESET(); + schedule(); } } #endif diff --git a/board/liebherr/display5/spl.c b/board/liebherr/display5/spl.c index 5c1af1a772..4219d002fe 100644 --- a/board/liebherr/display5/spl.c +++ b/board/liebherr/display5/spl.c @@ -329,7 +329,7 @@ void board_init_f(ulong dummy) /* Initialize and reset WDT in SPL */ #ifdef CONFIG_SPL_WATCHDOG hw_watchdog_init(); - WATCHDOG_RESET(); + schedule(); #endif /* load/boot image from boot device */ diff --git a/board/nokia/rx51/rx51.c b/board/nokia/rx51/rx51.c index 460d248eaa..9548c3c7be 100644 --- a/board/nokia/rx51/rx51.c +++ b/board/nokia/rx51/rx51.c @@ -722,7 +722,7 @@ static int rx51_kp_getc(struct udevice *dev) { keybuf_head %= KEYBUF_SIZE; while (!rx51_kp_tstc(dev)) - WATCHDOG_RESET(); + schedule(); return keybuf[keybuf_head++]; } diff --git a/board/st/stm32mp1/stm32mp1.c b/board/st/stm32mp1/stm32mp1.c index 9496890d16..6028a0b6de 100644 --- a/board/st/stm32mp1/stm32mp1.c +++ b/board/st/stm32mp1/stm32mp1.c @@ -289,7 +289,7 @@ static void __maybe_unused led_error_blink(u32 nb_blink) for (i = 0; i < 2 * nb_blink; i++) { led_set_state(led, LEDST_TOGGLE); mdelay(125); - WATCHDOG_RESET(); + schedule(); } led_set_state(led, LEDST_ON); } diff --git a/boot/bootretry.c b/boot/bootretry.c index 2bc9c6866e..8d850df9d4 100644 --- a/boot/bootretry.c +++ b/boot/bootretry.c @@ -44,7 +44,7 @@ int bootretry_tstc_timeout(void) while (!tstc()) { /* while no incoming data */ if (retry_time >= 0 && get_ticks() > endtime) return -ETIMEDOUT; - WATCHDOG_RESET(); + schedule(); } return 0; diff --git a/boot/image-board.c b/boot/image-board.c index 1be0a359ab..98f903f93f 100644 --- a/boot/image-board.c +++ b/boot/image-board.c @@ -181,7 +181,7 @@ void memmove_wd(void *to, void *from, size_t len, ulong chunksz) while (len > 0) { size_t tail = (len > chunksz) ? chunksz : len; - WATCHDOG_RESET(); + schedule(); if (to > from) { to -= tail; from -= tail; diff --git a/cmd/fastboot.c b/cmd/fastboot.c index 033a2c95e8..dd223b1554 100644 --- a/cmd/fastboot.c +++ b/cmd/fastboot.c @@ -76,7 +76,7 @@ static int do_fastboot_usb(int argc, char *const argv[], break; if (ctrlc()) break; - WATCHDOG_RESET(); + schedule(); usb_gadget_handle_interrupts(controller_index); } diff --git a/cmd/mem.c b/cmd/mem.c index 6a7b4014ed..1e39348195 100644 --- a/cmd/mem.c +++ b/cmd/mem.c @@ -300,7 +300,7 @@ static int do_mem_cmp(struct cmd_tbl *cmdtp, int flag, int argc, /* reset watchdog from time to time */ if ((ngood % (64 << 10)) == 0) - WATCHDOG_RESET(); + schedule(); } unmap_sysmem(buf1); unmap_sysmem(buf2); @@ -848,7 +848,7 @@ static ulong mem_test_alt(vu_long *buf, ulong start_addr, ulong end_addr, } } addr[test_offset] = pattern; - WATCHDOG_RESET(); + schedule(); /* * Check for addr bits stuck low or shorted. @@ -890,7 +890,7 @@ static ulong mem_test_alt(vu_long *buf, ulong start_addr, ulong end_addr, * Fill memory with a known pattern. */ for (pattern = 1, offset = 0; offset < num_words; pattern++, offset++) { - WATCHDOG_RESET(); + schedule(); addr[offset] = pattern; } @@ -898,7 +898,7 @@ static ulong mem_test_alt(vu_long *buf, ulong start_addr, ulong end_addr, * Check each location and invert it for the second pass. */ for (pattern = 1, offset = 0; offset < num_words; pattern++, offset++) { - WATCHDOG_RESET(); + schedule(); temp = addr[offset]; if (temp != pattern) { printf("\nFAILURE (read/write) @ 0x%.8lx:" @@ -918,7 +918,7 @@ static ulong mem_test_alt(vu_long *buf, ulong start_addr, ulong end_addr, * Check each location for the inverted pattern and zero it. */ for (pattern = 1, offset = 0; offset < num_words; pattern++, offset++) { - WATCHDOG_RESET(); + schedule(); anti_pattern = ~pattern; temp = addr[offset]; if (temp != anti_pattern) { @@ -972,7 +972,7 @@ static ulong test_bitflip_comparison(volatile unsigned long *bufa, for (k = 0; k < max; k++) { q = 0x00000001L << k; for (j = 0; j < 8; j++) { - WATCHDOG_RESET(); + schedule(); q = ~q; p1 = (volatile unsigned long *)bufa; p2 = (volatile unsigned long *)bufb; @@ -1033,7 +1033,7 @@ static ulong mem_test_quick(vu_long *buf, ulong start_addr, ulong end_addr, pattern, ""); for (addr = buf, val = pattern; addr < end; addr++) { - WATCHDOG_RESET(); + schedule(); *addr = val; val += incr; } @@ -1041,7 +1041,7 @@ static ulong mem_test_quick(vu_long *buf, ulong start_addr, ulong end_addr, puts("Reading..."); for (addr = buf, val = pattern; addr < end; addr++) { - WATCHDOG_RESET(); + schedule(); readback = *addr; if (readback != val) { ulong offset = addr - buf; diff --git a/cmd/usb_mass_storage.c b/cmd/usb_mass_storage.c index d4e619b842..b7daaa6e8e 100644 --- a/cmd/usb_mass_storage.c +++ b/cmd/usb_mass_storage.c @@ -231,7 +231,7 @@ static int do_usb_mass_storage(struct cmd_tbl *cmdtp, int flag, goto cleanup_register; } - WATCHDOG_RESET(); + schedule(); } cleanup_register: diff --git a/cmd/ximg.c b/cmd/ximg.c index 65ba41320a..8533d0d238 100644 --- a/cmd/ximg.c +++ b/cmd/ximg.c @@ -200,7 +200,7 @@ do_imgextract(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) while (l > 0) { tail = (l > CHUNKSZ) ? CHUNKSZ : l; - WATCHDOG_RESET(); + schedule(); memmove(to, from, tail); to += tail; from += tail; diff --git a/common/board_f.c b/common/board_f.c index deb46be182..f92d7b9faf 100644 --- a/common/board_f.c +++ b/common/board_f.c @@ -114,14 +114,14 @@ static int init_func_watchdog_init(void) hw_watchdog_init(); puts(" Watchdog enabled\n"); # endif - WATCHDOG_RESET(); + schedule(); return 0; } int init_func_watchdog_reset(void) { - WATCHDOG_RESET(); + schedule(); return 0; } diff --git a/common/board_r.c b/common/board_r.c index 062bc3e688..50670b5615 100644 --- a/common/board_r.c +++ b/common/board_r.c @@ -341,7 +341,7 @@ static int initr_flash(void) /* * Compute and print flash CRC if flashchecksum is set to 'y' * - * NOTE: Maybe we should add some WATCHDOG_RESET()? XXX + * NOTE: Maybe we should add some schedule()? XXX */ if (env_get_yesno("flashchecksum") == 1) { const uchar *flash_base = (const uchar *)CONFIG_SYS_FLASH_BASE; diff --git a/common/cli_readline.c b/common/cli_readline.c index f883b7ffac..f6e2bcdece 100644 --- a/common/cli_readline.c +++ b/common/cli_readline.c @@ -274,7 +274,7 @@ static int cread_line(const char *const prompt, char *buf, unsigned int *len, while (!tstc()) { /* while no incoming data */ if (get_ticks() >= etime) return -2; /* timed out */ - WATCHDOG_RESET(); + schedule(); } first = 0; } @@ -595,7 +595,7 @@ int cli_readline_into_buffer(const char *const prompt, char *buffer, for (;;) { if (bootretry_tstc_timeout()) return -2; /* timed out */ - WATCHDOG_RESET(); /* Trigger watchdog, if needed */ + schedule(); /* Trigger watchdog, if needed */ c = getchar(); diff --git a/common/console.c b/common/console.c index bde9412239..66b9813b3a 100644 --- a/common/console.c +++ b/common/console.c @@ -480,7 +480,7 @@ int fgetc(int file) * Effectively poll for input wherever it may be available. */ for (;;) { - WATCHDOG_RESET(); + schedule(); if (CONFIG_IS_ENABLED(CONSOLE_MUX)) { /* * Upper layer may have already called tstc() so diff --git a/common/dfu.c b/common/dfu.c index 16bd1ba588..96190889ab 100644 --- a/common/dfu.c +++ b/common/dfu.c @@ -101,7 +101,7 @@ int run_usb_dnl_gadget(int usbctrl_index, char *usb_dnl_gadget) if (dfu_reinit_needed) goto exit; - WATCHDOG_RESET(); + schedule(); usb_gadget_handle_interrupts(usbctrl_index); } exit: diff --git a/common/lcd.c b/common/lcd.c index 0898bc025d..a462b22a47 100644 --- a/common/lcd.c +++ b/common/lcd.c @@ -294,9 +294,9 @@ void lcd_logo_plot(int x, int y) BMP_LOGO_WIDTH, BMP_LOGO_HEIGHT, BMP_LOGO_COLORS); if (bpix < 12) { - WATCHDOG_RESET(); + schedule(); lcd_logo_set_cmap(); - WATCHDOG_RESET(); + schedule(); for (i = 0; i < BMP_LOGO_HEIGHT; ++i) { memcpy(fb, bmap, BMP_LOGO_WIDTH); @@ -320,7 +320,7 @@ void lcd_logo_plot(int x, int y) } } - WATCHDOG_RESET(); + schedule(); lcd_sync(); } #else @@ -459,7 +459,7 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y) byte_width = width * 2; for (i = 0; i < height; ++i) { - WATCHDOG_RESET(); + schedule(); for (j = 0; j < width; j++) { if (bpix != 16) { fb_put_byte(&fb, &bmap); @@ -488,7 +488,7 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y) #if defined(CONFIG_BMP_16BPP) case 16: for (i = 0; i < height; ++i) { - WATCHDOG_RESET(); + schedule(); for (j = 0; j < width; j++) fb_put_word(&fb, &bmap); diff --git a/common/menu.c b/common/menu.c index 0d19601cf5..8fe00965c0 100644 --- a/common/menu.c +++ b/common/menu.c @@ -435,7 +435,7 @@ void bootmenu_autoboot_loop(struct bootmenu_data *menu, printf("Hit any key to stop autoboot: %d ", menu->delay); for (i = 0; i < 100; ++i) { if (!tstc()) { - WATCHDOG_RESET(); + schedule(); mdelay(10); continue; } @@ -483,7 +483,7 @@ void bootmenu_loop(struct bootmenu_data *menu, if (tstc()) { c = getchar(); } else { - WATCHDOG_RESET(); + schedule(); mdelay(10); if (tstc()) c = getchar(); @@ -492,7 +492,7 @@ void bootmenu_loop(struct bootmenu_data *menu, } } else { while (!tstc()) { - WATCHDOG_RESET(); + schedule(); mdelay(10); } c = getchar(); diff --git a/common/usb_kbd.c b/common/usb_kbd.c index d385bea532..4cbc9acb73 100644 --- a/common/usb_kbd.c +++ b/common/usb_kbd.c @@ -446,7 +446,7 @@ static int usb_kbd_getc(struct stdio_dev *sdev) data = usb_kbd_dev->privptr; while (data->usb_in_pointer == data->usb_out_pointer) { - WATCHDOG_RESET(); + schedule(); usb_kbd_poll_for_event(usb_kbd_dev); } diff --git a/common/xyzModem.c b/common/xyzModem.c index a68d392902..fb319f7119 100644 --- a/common/xyzModem.c +++ b/common/xyzModem.c @@ -68,7 +68,7 @@ CYGACC_COMM_IF_GETC_TIMEOUT (char chan, char *c) { ulong now = get_timer(0); - WATCHDOG_RESET(); + schedule(); while (!tstc ()) { if (get_timer(now) > xyzModem_CHAR_TIMEOUT) diff --git a/drivers/block/ide.c b/drivers/block/ide.c index 73da29ad55..b8840d29c2 100644 --- a/drivers/block/ide.c +++ b/drivers/block/ide.c @@ -62,7 +62,7 @@ static void ide_reset(void) /* the reset signal shall be asserted for et least 25 us */ udelay(25); - WATCHDOG_RESET(); + schedule(); /* de-assert RESET signal */ ide_set_reset(0); @@ -695,7 +695,7 @@ void ide_init(void) unsigned char c; int i, bus; - WATCHDOG_RESET(); + schedule(); /* ATAPI Drives seems to need a proper IDE Reset */ ide_reset(); @@ -745,7 +745,7 @@ void ide_init(void) puts("OK "); ide_bus_ok[bus] = 1; } - WATCHDOG_RESET(); + schedule(); } putc('\n'); @@ -775,7 +775,7 @@ void ide_init(void) } #endif } - WATCHDOG_RESET(); + schedule(); #ifdef CONFIG_BLK struct udevice *dev; diff --git a/drivers/crypto/aspeed/aspeed_hace.c b/drivers/crypto/aspeed/aspeed_hace.c index 1178cc6a76..a1b0b9f564 100644 --- a/drivers/crypto/aspeed/aspeed_hace.c +++ b/drivers/crypto/aspeed/aspeed_hace.c @@ -302,7 +302,7 @@ static int aspeed_hace_digest_wd(struct udevice *dev, enum HASH_ALGO algo, return rc; cur += chunk; - WATCHDOG_RESET(); + schedule(); } } else { rc = aspeed_hace_update(dev, ctx, ibuf, ilen); diff --git a/drivers/crypto/hash/hash_sw.c b/drivers/crypto/hash/hash_sw.c index fea9d12609..553c068010 100644 --- a/drivers/crypto/hash/hash_sw.c +++ b/drivers/crypto/hash/hash_sw.c @@ -258,7 +258,7 @@ static int sw_hash_digest_wd(struct udevice *dev, enum HASH_ALGO algo, return rc; cur += chunk; - WATCHDOG_RESET(); + schedule(); } } else { rc = sw_hash_update(dev, ctx, ibuf, ilen); diff --git a/drivers/ddr/altera/sdram_arria10.c b/drivers/ddr/altera/sdram_arria10.c index 4a8f8dea1c..8ef5fa4c48 100644 --- a/drivers/ddr/altera/sdram_arria10.c +++ b/drivers/ddr/altera/sdram_arria10.c @@ -671,7 +671,7 @@ static int of_sdram_firewall_setup(const void *blob) int ddr_calibration_sequence(void) { - WATCHDOG_RESET(); + schedule(); /* Check to see if SDRAM cal was success */ if (sdram_startup()) { @@ -681,7 +681,7 @@ int ddr_calibration_sequence(void) puts("DDRCAL: Success\n"); - WATCHDOG_RESET(); + schedule(); /* initialize the MMR register */ sdram_mmr_init(); diff --git a/drivers/ddr/altera/sdram_n5x.c b/drivers/ddr/altera/sdram_n5x.c index 737a4e2ff1..d9039443b9 100644 --- a/drivers/ddr/altera/sdram_n5x.c +++ b/drivers/ddr/altera/sdram_n5x.c @@ -517,7 +517,7 @@ static int ensure_retry_procedure_complete(phys_addr_t umctl2_base) DDR4_CRCPARSTAT_CMD_IN_ERR_WINDOW; udelay(1); - WATCHDOG_RESET(); + schedule(); } return 0; @@ -1349,7 +1349,7 @@ static int ddr_post_handoff_config(phys_addr_t umctl2_base, } udelay(1); - WATCHDOG_RESET(); + schedule(); /* Polling until SDRAM entered normal operating mode */ value = readl(umctl2_base + DDR4_STAT_OFFSET) & diff --git a/drivers/ddr/altera/sdram_soc64.c b/drivers/ddr/altera/sdram_soc64.c index 9b1710c135..4716abfc9a 100644 --- a/drivers/ddr/altera/sdram_soc64.c +++ b/drivers/ddr/altera/sdram_soc64.c @@ -161,7 +161,7 @@ void sdram_init_ecc_bits(struct bd_info *bd) sdram_clear_mem(start_addr, size_init); size -= size_init; start_addr += size_init; - WATCHDOG_RESET(); + schedule(); } bank++; diff --git a/drivers/fpga/intel_sdm_mb.c b/drivers/fpga/intel_sdm_mb.c index f5fd9a14c2..903d143a36 100644 --- a/drivers/fpga/intel_sdm_mb.c +++ b/drivers/fpga/intel_sdm_mb.c @@ -44,7 +44,7 @@ static int reconfig_status_polling_resp(void) puts("."); udelay(RECONFIG_STATUS_INTERVAL_DELAY_US); - WATCHDOG_RESET(); + schedule(); } return -ETIMEDOUT; @@ -104,7 +104,7 @@ static int send_bitstream(const void *rbf_data, size_t rbf_size) udelay(20000); } - WATCHDOG_RESET(); + schedule(); } return 0; @@ -252,7 +252,7 @@ static int reconfig_status_polling_resp(void) puts("."); udelay(RECONFIG_STATUS_INTERVAL_DELAY_US); - WATCHDOG_RESET(); + schedule(); } return -ETIMEDOUT; @@ -378,7 +378,7 @@ static int send_reconfig_data(const void *rbf_data, size_t rbf_size, if (resp_err && !xfer_count) return resp_err; } - WATCHDOG_RESET(); + schedule(); } return 0; diff --git a/drivers/fpga/socfpga_arria10.c b/drivers/fpga/socfpga_arria10.c index d8089122af..e86e3b7431 100644 --- a/drivers/fpga/socfpga_arria10.c +++ b/drivers/fpga/socfpga_arria10.c @@ -383,7 +383,7 @@ static int fpgamgr_program_poll_cd(void) printf("nstatus == 0 while waiting for condone\n"); return -EPERM; } - WATCHDOG_RESET(); + schedule(); } if (i == FPGA_TIMEOUT_CNT) @@ -534,7 +534,7 @@ static void get_rbf_image_info(struct rbf_info *rbf, u16 *buffer) rbf->section = unknown; break; - WATCHDOG_RESET(); + schedule(); } } @@ -635,7 +635,7 @@ static int first_loading_rbf_to_buffer(struct udevice *dev, break; } } - WATCHDOG_RESET(); + schedule(); } if (!fpga_node_name) { @@ -879,7 +879,7 @@ int socfpga_loadfs(fpga_fs_info *fpga_fsinfo, const void *buf, size_t bsize, total_sizeof_image += buffer_sizebytes_ori; - WATCHDOG_RESET(); + schedule(); } wait_for_fifo_empty(); diff --git a/drivers/i2c/mxc_i2c.c b/drivers/i2c/mxc_i2c.c index aa13af3ae1..f80ff5383b 100644 --- a/drivers/i2c/mxc_i2c.c +++ b/drivers/i2c/mxc_i2c.c @@ -199,7 +199,7 @@ static int wait_for_sr_state(struct mxc_i2c_bus *i2c_bus, unsigned state) } if ((sr & (state >> 8)) == (unsigned char)state) return sr; - WATCHDOG_RESET(); + schedule(); elapsed = get_timer(start_time); if (elapsed > (CONFIG_SYS_HZ / 10)) /* .1 seconds */ break; @@ -447,7 +447,7 @@ int i2c_idle_bus(struct mxc_i2c_bus *i2c_bus) sda = dm_gpio_get_value(sda_gpio); if ((sda & scl) == 1) break; - WATCHDOG_RESET(); + schedule(); elapsed = get_timer(start_time); if (elapsed > (CONFIG_SYS_HZ / 5)) { /* .2 seconds */ ret = -EBUSY; diff --git a/drivers/mmc/octeontx_hsmmc.c b/drivers/mmc/octeontx_hsmmc.c index 6e9acf7310..4ee62df9d4 100644 --- a/drivers/mmc/octeontx_hsmmc.c +++ b/drivers/mmc/octeontx_hsmmc.c @@ -1023,7 +1023,7 @@ static void octeontx_mmc_cleanup_dma(struct mmc *mmc, start = get_timer(0); do { rsp_sts.u = read_csr(mmc, MIO_EMM_RSP_STS()); - WATCHDOG_RESET(); + schedule(); } while (get_timer(start) < 100 && (rsp_sts.s.dma_val || rsp_sts.s.dma_pend)); } while (retries-- >= 0 && rsp_sts.s.dma_pend); @@ -1107,7 +1107,7 @@ static int octeontx_mmc_wait_dma(struct mmc *mmc, bool write, ulong timeout, } else if (!rsp_sts.s.dma_val && emm_dma_int.s.done) { break; } - WATCHDOG_RESET(); + schedule(); timed_out = (get_timer(start_time) > timeout); } while (!timed_out); @@ -1219,7 +1219,7 @@ static int octeontx_mmc_read_blocks(struct mmc *mmc, struct mmc_cmd *cmd, } return blkcnt - count; } - WATCHDOG_RESET(); + schedule(); } while (--count); } #ifdef DEBUG @@ -1253,7 +1253,7 @@ static int octeontx_mmc_poll_ready(struct mmc *mmc, ulong timeout) } else if (cmd.response[0] & R1_READY_FOR_DATA) { return 0; } - WATCHDOG_RESET(); + schedule(); } while (get_timer(start) < timeout); if (not_ready) @@ -1328,7 +1328,7 @@ static ulong octeontx_mmc_write_blocks(struct mmc *mmc, struct mmc_cmd *cmd, read_csr(mmc, MIO_EMM_DMA())); return blkcnt - count; } - WATCHDOG_RESET(); + schedule(); } while (--count); } @@ -1491,7 +1491,7 @@ static int octeontx_mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, start = get_timer(0); do { rsp_sts.u = read_csr(mmc, MIO_EMM_RSP_STS()); - WATCHDOG_RESET(); + schedule(); } while (!rsp_sts.s.cmd_done && !rsp_sts.s.rsp_timeout && (get_timer(start) < timeout + 10)); octeontx_mmc_print_rsp_errors(mmc, rsp_sts); diff --git a/drivers/mmc/sh_mmcif.c b/drivers/mmc/sh_mmcif.c index 830e29cdd4..76dc1c68b8 100644 --- a/drivers/mmc/sh_mmcif.c +++ b/drivers/mmc/sh_mmcif.c @@ -242,7 +242,7 @@ static int sh_mmcif_multi_read(struct sh_mmcif_host *host, for (i = 0; i < blocksize / 4; i++) *p++ = sh_mmcif_read(&host->regs->ce_data); - WATCHDOG_RESET(); + schedule(); } return 0; } @@ -309,7 +309,7 @@ static int sh_mmcif_multi_write(struct sh_mmcif_host *host, for (i = 0; i < blocksize / 4; i++) sh_mmcif_write(*p++, &host->regs->ce_data); - WATCHDOG_RESET(); + schedule(); } return 0; } @@ -523,7 +523,7 @@ static int sh_mmcif_send_cmd_common(struct sh_mmcif_host *host, { int ret; - WATCHDOG_RESET(); + schedule(); switch (cmd->cmdidx) { case MMC_CMD_APP_CMD: diff --git a/drivers/mmc/stm32_sdmmc2.c b/drivers/mmc/stm32_sdmmc2.c index bfce8a2e4a..7ab4d949e7 100644 --- a/drivers/mmc/stm32_sdmmc2.c +++ b/drivers/mmc/stm32_sdmmc2.c @@ -445,7 +445,7 @@ static int stm32_sdmmc2_send_cmd(struct udevice *dev, struct mmc_cmd *cmd, u32 cmdat = data ? SDMMC_CMD_CMDTRANS : 0; int ret, retry = 3; - WATCHDOG_RESET(); + schedule(); retry_cmd: ctx.data_length = 0; diff --git a/drivers/mtd/cfi_flash.c b/drivers/mtd/cfi_flash.c index 4950410706..d34d8ee976 100644 --- a/drivers/mtd/cfi_flash.c +++ b/drivers/mtd/cfi_flash.c @@ -584,7 +584,7 @@ static int flash_status_check(flash_info_t *info, flash_sect_t sector, reset_timer(); #endif start = get_timer(0); - WATCHDOG_RESET(); + schedule(); while (flash_is_busy(info, sector)) { if (get_timer(start) > tout) { printf("Flash %s timeout at address %lx data %lx\n", @@ -677,7 +677,7 @@ static int flash_status_poll(flash_info_t *info, void *src, void *dst, reset_timer(); #endif start = get_timer(0); - WATCHDOG_RESET(); + schedule(); while (1) { switch (info->portwidth) { case FLASH_CFI_8BIT: diff --git a/drivers/mtd/nand/core.c b/drivers/mtd/nand/core.c index 090834a495..99c29670c7 100644 --- a/drivers/mtd/nand/core.c +++ b/drivers/mtd/nand/core.c @@ -173,7 +173,7 @@ int nanddev_mtd_erase(struct mtd_info *mtd, struct erase_info *einfo) nanddev_offs_to_pos(nand, einfo->addr, &pos); nanddev_offs_to_pos(nand, einfo->addr + einfo->len - 1, &last); while (nanddev_pos_cmp(&pos, &last) <= 0) { - WATCHDOG_RESET(); + schedule(); ret = nanddev_erase(nand, &pos); if (ret) { einfo->fail_addr = nanddev_pos_to_offs(nand, &pos); diff --git a/drivers/mtd/nand/raw/atmel_nand.c b/drivers/mtd/nand/raw/atmel_nand.c index 06bf5ac18f..61bfd175be 100644 --- a/drivers/mtd/nand/raw/atmel_nand.c +++ b/drivers/mtd/nand/raw/atmel_nand.c @@ -420,7 +420,7 @@ static int pmecc_err_location(struct mtd_info *mtd) while (--timeout) { if (pmecc_readl(host->pmerrloc, elisr) & PMERRLOC_CALC_DONE) break; - WATCHDOG_RESET(); + schedule(); udelay(1); } @@ -558,7 +558,7 @@ static int atmel_nand_pmecc_read_page(struct mtd_info *mtd, while (--timeout) { if (!(pmecc_readl(host->pmecc, sr) & PMECC_SR_BUSY)) break; - WATCHDOG_RESET(); + schedule(); udelay(1); } @@ -598,7 +598,7 @@ static int atmel_nand_pmecc_write_page(struct mtd_info *mtd, while (--timeout) { if (!(pmecc_readl(host->pmecc, sr) & PMECC_SR_BUSY)) break; - WATCHDOG_RESET(); + schedule(); udelay(1); } diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c index 1a1a757932..215b9ba84f 100644 --- a/drivers/mtd/nand/raw/nand_base.c +++ b/drivers/mtd/nand/raw/nand_base.c @@ -595,7 +595,7 @@ static void nand_wait_status_ready(struct mtd_info *mtd, unsigned long timeo) if (status & NAND_STATUS_READY) break; - WATCHDOG_RESET(); + schedule(); } }; @@ -2342,7 +2342,7 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from, while (1) { unsigned int ecc_failures = mtd->ecc_stats.failed; - WATCHDOG_RESET(); + schedule(); bytes = min(mtd->writesize - col, readlen); aligned = (bytes == mtd->writesize); @@ -2695,7 +2695,7 @@ static int nand_do_read_oob(struct mtd_info *mtd, loff_t from, page = realpage & chip->pagemask; while (1) { - WATCHDOG_RESET(); + schedule(); if (ops->mode == MTD_OPS_RAW) ret = chip->ecc.read_oob_raw(mtd, chip, page); @@ -3263,7 +3263,7 @@ static int nand_do_write_ops(struct mtd_info *mtd, loff_t to, else use_bufpoi = 0; - WATCHDOG_RESET(); + schedule(); /* Partial page write?, or need to use bounce buffer */ if (use_bufpoi) { pr_debug("%s: using write bounce buffer for buf@%p\n", @@ -3556,7 +3556,7 @@ int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr, instr->state = MTD_ERASING; while (len) { - WATCHDOG_RESET(); + schedule(); /* Check if we have a bad block, we do not erase bad blocks! */ if (!instr->scrub && nand_block_checkbad(mtd, ((loff_t) page) << diff --git a/drivers/mtd/nand/raw/nand_util.c b/drivers/mtd/nand/raw/nand_util.c index 5150607d8a..b2345dca7f 100644 --- a/drivers/mtd/nand/raw/nand_util.c +++ b/drivers/mtd/nand/raw/nand_util.c @@ -103,7 +103,7 @@ int nand_erase_opts(struct mtd_info *mtd, erased_length < erase_length; erase.addr += mtd->erasesize) { - WATCHDOG_RESET(); + schedule(); if (opts->lim && (erase.addr >= (opts->offset + opts->lim))) { puts("Size of erase exceeds limit\n"); @@ -638,7 +638,7 @@ int nand_write_skip_bad(struct mtd_info *mtd, loff_t offset, size_t *length, size_t block_offset = offset & (mtd->erasesize - 1); size_t write_size, truncated_write_size; - WATCHDOG_RESET(); + schedule(); if (nand_block_isbad(mtd, block_start)) { printf("Skip bad block 0x%08llx\n", block_start); @@ -753,7 +753,7 @@ int nand_read_skip_bad(struct mtd_info *mtd, loff_t offset, size_t *length, size_t block_offset = offset & (mtd->erasesize - 1); size_t read_length; - WATCHDOG_RESET(); + schedule(); if (nand_block_isbad(mtd, offset & ~(mtd->erasesize - 1))) { printf("Skipping bad block 0x%08llx\n", diff --git a/drivers/mtd/nand/spi/core.c b/drivers/mtd/nand/spi/core.c index e5330958c7..134bf22c80 100644 --- a/drivers/mtd/nand/spi/core.c +++ b/drivers/mtd/nand/spi/core.c @@ -579,7 +579,7 @@ static int spinand_mtd_read(struct mtd_info *mtd, loff_t from, #endif nanddev_io_for_each_page(nand, from, ops, &iter) { - WATCHDOG_RESET(); + schedule(); ret = spinand_select_target(spinand, iter.req.pos.target); if (ret) break; @@ -631,7 +631,7 @@ static int spinand_mtd_write(struct mtd_info *mtd, loff_t to, #endif nanddev_io_for_each_page(nand, to, ops, &iter) { - WATCHDOG_RESET(); + schedule(); ret = spinand_select_target(spinand, iter.req.pos.target); if (ret) break; diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c index f94597c061..08fe7d427a 100644 --- a/drivers/mtd/onenand/onenand_base.c +++ b/drivers/mtd/onenand/onenand_base.c @@ -478,7 +478,7 @@ static int onenand_wait(struct mtd_info *mtd, int state) u32 timeo = (CONFIG_SYS_HZ * 20) / 1000; u32 time_start = get_timer(0); do { - WATCHDOG_RESET(); + schedule(); if (get_timer(time_start) > timeo) return -EIO; interrupt = this->read_word(this->base + ONENAND_REG_INTERRUPT); @@ -1170,7 +1170,7 @@ static int onenand_bbt_wait(struct mtd_info *mtd, int state) u32 timeo = (CONFIG_SYS_HZ * 20) / 1000; u32 time_start = get_timer(0); do { - WATCHDOG_RESET(); + schedule(); if (get_timer(time_start) > timeo) return ONENAND_BBT_READ_FATAL_ERROR; interrupt = this->read_word(this->base + ONENAND_REG_INTERRUPT); diff --git a/drivers/mtd/spi/spi-nor-core.c b/drivers/mtd/spi/spi-nor-core.c index f236e87510..c73636d7d1 100644 --- a/drivers/mtd/spi/spi-nor-core.c +++ b/drivers/mtd/spi/spi-nor-core.c @@ -958,7 +958,7 @@ static int spi_nor_erase(struct mtd_info *mtd, struct erase_info *instr) addr_known = true; while (len) { - WATCHDOG_RESET(); + schedule(); if (!IS_ENABLED(CONFIG_SPL_BUILD) && ctrlc()) { addr_known = false; ret = -EINTR; @@ -1721,7 +1721,7 @@ static int spi_nor_write(struct mtd_info *mtd, loff_t to, size_t len, for (i = 0; i < len; ) { ssize_t written; loff_t addr = to + i; - WATCHDOG_RESET(); + schedule(); /* * If page_size is a power of two, the offset can be quickly diff --git a/drivers/net/octeontx2/nix.c b/drivers/net/octeontx2/nix.c index a5665a25f2..f596b6bca8 100644 --- a/drivers/net/octeontx2/nix.c +++ b/drivers/net/octeontx2/nix.c @@ -580,7 +580,7 @@ int nix_lf_xmit(struct udevice *dev, void *pkt, int pkt_len) __iowmb(); result = lmt_submit((u64)(nix->nix_base + NIXX_LF_OP_SENDX(0))); - WATCHDOG_RESET(); + schedule(); } while (result == 0); return 0; diff --git a/drivers/net/octeontx2/nix_af.c b/drivers/net/octeontx2/nix_af.c index cd098d6cd6..c945ea0f5f 100644 --- a/drivers/net/octeontx2/nix_af.c +++ b/drivers/net/octeontx2/nix_af.c @@ -65,7 +65,7 @@ int npa_attach_aura(struct nix_af *nix_af, int lf, start = get_timer(0); while ((res->s.compcode == NPA_AQ_COMP_E_NOTDONE) && (get_timer(start) < 1000)) - WATCHDOG_RESET(); + schedule(); if (res->s.compcode != NPA_AQ_COMP_E_GOOD) { printf("%s: Error: result 0x%x not good\n", __func__, res->s.compcode); @@ -111,7 +111,7 @@ int npa_attach_pool(struct nix_af *nix_af, int lf, start = get_timer(0); while ((res->s.compcode == NPA_AQ_COMP_E_NOTDONE) && (get_timer(start) < 1000)) - WATCHDOG_RESET(); + schedule(); if (res->s.compcode != NPA_AQ_COMP_E_GOOD) { printf("%s: Error: result 0x%x not good\n", @@ -136,7 +136,7 @@ int npa_lf_admin_setup(struct npa *npa, int lf, dma_addr_t aura_base) do { lf_rst.u = npa_af_reg_read(npa_af, NPA_AF_LF_RST()); - WATCHDOG_RESET(); + schedule(); } while (lf_rst.s.exec); /* Set Aura size and enable caching of contexts */ @@ -199,7 +199,7 @@ int npa_lf_admin_shutdown(struct nix_af *nix_af, int lf, u32 pool_count) start = get_timer(0); while ((res->s.compcode == NPA_AQ_COMP_E_NOTDONE) && (get_timer(start) < 1000)) - WATCHDOG_RESET(); + schedule(); if (res->s.compcode != NPA_AQ_COMP_E_GOOD) { printf("%s: Error: result 0x%x not good for lf %d\n" @@ -235,7 +235,7 @@ int npa_lf_admin_shutdown(struct nix_af *nix_af, int lf, u32 pool_count) start = get_timer(0); while ((res->s.compcode == NPA_AQ_COMP_E_NOTDONE) && (get_timer(start) < 1000)) - WATCHDOG_RESET(); + schedule(); if (res->s.compcode != NPA_AQ_COMP_E_GOOD) { printf("%s: Error: result 0x%x not good for lf %d\n" @@ -255,7 +255,7 @@ int npa_lf_admin_shutdown(struct nix_af *nix_af, int lf, u32 pool_count) do { lf_rst.u = npa_af_reg_read(npa, NPA_AF_LF_RST()); - WATCHDOG_RESET(); + schedule(); } while (lf_rst.s.exec); return 0; @@ -286,7 +286,7 @@ int npa_af_setup(struct npa_af *npa_af) /* Wait for reset to complete */ do { blk_rst.u = npa_af_reg_read(npa_af, NPA_AF_BLK_RST()); - WATCHDOG_RESET(); + schedule(); } while (blk_rst.s.busy); /* Set little Endian */ @@ -318,7 +318,7 @@ int npa_af_shutdown(struct npa_af *npa_af) /* Wait for reset to complete */ do { blk_rst.u = npa_af_reg_read(npa_af, NPA_AF_BLK_RST()); - WATCHDOG_RESET(); + schedule(); } while (blk_rst.s.busy); rvu_aq_free(&npa_af->aq); @@ -481,7 +481,7 @@ static int nix_aq_issue_command(struct nix_af *nix_af, start = get_timer(0); /* Wait for completion */ do { - WATCHDOG_RESET(); + schedule(); dsb(); } while (result->s.compcode == 0 && get_timer(start) < 2); @@ -645,7 +645,7 @@ int nix_lf_admin_setup(struct nix *nix) do { lf_rst.u = nix_af_reg_read(nix_af, NIXX_AF_LF_RST()); - WATCHDOG_RESET(); + schedule(); } while (lf_rst.s.exec); /* Config NIX RQ HW context and base*/ @@ -767,7 +767,7 @@ int nix_lf_admin_shutdown(struct nix_af *nix_af, int lf, do { sw_sync.u = nix_af_reg_read(nix_af, NIXX_AF_RX_SW_SYNC()); - WATCHDOG_RESET(); + schedule(); } while (sw_sync.s.ena); for (index = 0; index < rq_count; index++) { @@ -832,7 +832,7 @@ int nix_lf_admin_shutdown(struct nix_af *nix_af, int lf, do { lf_rst.u = nix_af_reg_read(nix_af, NIXX_AF_LF_RST()); - WATCHDOG_RESET(); + schedule(); } while (lf_rst.s.exec); return 0; @@ -972,7 +972,7 @@ int npc_af_shutdown(struct nix_af *nix_af) /* Wait for reset to complete */ do { blk_rst.u = npc_af_reg_read(nix_af, NPC_AF_BLK_RST()); - WATCHDOG_RESET(); + schedule(); } while (blk_rst.s.busy); debug("%s: npc af reset --\n", __func__); @@ -1008,7 +1008,7 @@ int nix_af_setup(struct nix_af *nix_af) /* Wait for reset to complete */ do { blk_rst.u = nix_af_reg_read(nix_af, NIXX_AF_BLK_RST()); - WATCHDOG_RESET(); + schedule(); } while (blk_rst.s.busy); /* Put in LE mode */ @@ -1031,7 +1031,7 @@ int nix_af_setup(struct nix_af *nix_af) /* Wait for calibration to complete */ do { af_status.u = nix_af_reg_read(nix_af, NIXX_AF_STATUS()); - WATCHDOG_RESET(); + schedule(); } while (af_status.s.calibrate_done == 0); af_cfg.u = nix_af_reg_read(nix_af, NIXX_AF_CFG()); @@ -1091,7 +1091,7 @@ int nix_af_shutdown(struct nix_af *nix_af) /* Wait for reset to complete */ do { blk_rst.u = nix_af_reg_read(nix_af, NIXX_AF_BLK_RST()); - WATCHDOG_RESET(); + schedule(); } while (blk_rst.s.busy); rvu_aq_free(&nix_af->aq); diff --git a/drivers/ram/stm32mp1/stm32mp1_tests.c b/drivers/ram/stm32mp1/stm32mp1_tests.c index 64262f1aa9..c5f3354414 100644 --- a/drivers/ram/stm32mp1/stm32mp1_tests.c +++ b/drivers/ram/stm32mp1/stm32mp1_tests.c @@ -169,7 +169,7 @@ static int test_loop_end(u32 *loop, u32 nb_loop, u32 progress) return 1; } printf("loop #%d\n", *loop); - WATCHDOG_RESET(); + schedule(); return 0; } diff --git a/drivers/serial/atmel_usart.c b/drivers/serial/atmel_usart.c index 1fb9ee5cc9..90ccdf6b29 100644 --- a/drivers/serial/atmel_usart.c +++ b/drivers/serial/atmel_usart.c @@ -103,7 +103,7 @@ static int atmel_serial_getc(void) atmel_usart3_t *usart = (atmel_usart3_t *)CONFIG_USART_BASE; while (!(readl(&usart->csr) & USART3_BIT(RXRDY))) - WATCHDOG_RESET(); + schedule(); return readl(&usart->rhr); } diff --git a/drivers/serial/ns16550.c b/drivers/serial/ns16550.c index 47bad6f8e2..7592979cab 100644 --- a/drivers/serial/ns16550.c +++ b/drivers/serial/ns16550.c @@ -296,7 +296,7 @@ void ns16550_putc(struct ns16550 *com_port, char c) * in puts(). */ if (c == '\n') - WATCHDOG_RESET(); + schedule(); } #ifndef CONFIG_NS16550_MIN_FUNCTIONS @@ -307,7 +307,7 @@ char ns16550_getc(struct ns16550 *com_port) extern void usbtty_poll(void); usbtty_poll(); #endif - WATCHDOG_RESET(); + schedule(); } return serial_in(&com_port->rbr); } @@ -395,7 +395,7 @@ static int ns16550_serial_putc(struct udevice *dev, const char ch) * in puts(). */ if (ch == '\n') - WATCHDOG_RESET(); + schedule(); return 0; } diff --git a/drivers/serial/serial-uclass.c b/drivers/serial/serial-uclass.c index 30650e37b0..0d43e9b625 100644 --- a/drivers/serial/serial-uclass.c +++ b/drivers/serial/serial-uclass.c @@ -246,7 +246,7 @@ static int __serial_getc(struct udevice *dev) do { err = ops->getc(dev); if (err == -EAGAIN) - WATCHDOG_RESET(); + schedule(); } while (err == -EAGAIN); return err >= 0 ? err : 0; diff --git a/drivers/serial/serial_bcm283x_mu.c b/drivers/serial/serial_bcm283x_mu.c index f0756c37c8..493a42b4cc 100644 --- a/drivers/serial/serial_bcm283x_mu.c +++ b/drivers/serial/serial_bcm283x_mu.c @@ -114,7 +114,7 @@ static int bcm283x_mu_serial_pending(struct udevice *dev, bool input) lsr = readl(®s->lsr); if (input) { - WATCHDOG_RESET(); + schedule(); return (lsr & BCM283X_MU_LSR_RX_READY) ? 1 : 0; } else { return (lsr & BCM283X_MU_LSR_TX_IDLE) ? 0 : 1; diff --git a/drivers/serial/serial_lpuart.c b/drivers/serial/serial_lpuart.c index ca49ef7372..ff576da516 100644 --- a/drivers/serial/serial_lpuart.c +++ b/drivers/serial/serial_lpuart.c @@ -169,7 +169,7 @@ static int _lpuart_serial_getc(struct lpuart_serial_plat *plat) { struct lpuart_fsl *base = plat->reg; while (!(__raw_readb(&base->us1) & (US1_RDRF | US1_OR))) - WATCHDOG_RESET(); + schedule(); barrier(); @@ -182,7 +182,7 @@ static void _lpuart_serial_putc(struct lpuart_serial_plat *plat, struct lpuart_fsl *base = plat->reg; while (!(__raw_readb(&base->us1) & US1_TDRE)) - WATCHDOG_RESET(); + schedule(); __raw_writeb(c, &base->ud); } @@ -330,7 +330,7 @@ static int _lpuart32_serial_getc(struct lpuart_serial_plat *plat) lpuart_read32(plat->flags, &base->stat, &stat); while ((stat & STAT_RDRF) == 0) { lpuart_write32(plat->flags, &base->stat, STAT_FLAGS); - WATCHDOG_RESET(); + schedule(); lpuart_read32(plat->flags, &base->stat, &stat); } @@ -358,7 +358,7 @@ static void _lpuart32_serial_putc(struct lpuart_serial_plat *plat, if ((stat & STAT_TDRE)) break; - WATCHDOG_RESET(); + schedule(); } lpuart_write32(plat->flags, &base->data, c); diff --git a/drivers/serial/serial_mpc8xx.c b/drivers/serial/serial_mpc8xx.c index 0978930dcd..aeae6ae6cd 100644 --- a/drivers/serial/serial_mpc8xx.c +++ b/drivers/serial/serial_mpc8xx.c @@ -187,7 +187,7 @@ static int serial_mpc8xx_putc(struct udevice *dev, const char c) setbits_be16(&rtx->txbd.cbd_sc, BD_SC_READY); while (in_be16(&rtx->txbd.cbd_sc) & BD_SC_READY) - WATCHDOG_RESET(); + schedule(); return 0; } @@ -204,7 +204,7 @@ static int serial_mpc8xx_getc(struct udevice *dev) /* Wait for character to show up. */ while (in_be16(&rtx->rxbd.cbd_sc) & BD_SC_EMPTY) - WATCHDOG_RESET(); + schedule(); /* the characters are read one by one, * use the rxindex to know the next char to deliver diff --git a/drivers/serial/serial_mt7620.c b/drivers/serial/serial_mt7620.c index 5c5264bc96..b00e2f2c36 100644 --- a/drivers/serial/serial_mt7620.c +++ b/drivers/serial/serial_mt7620.c @@ -102,7 +102,7 @@ static int mt7620_serial_putc(struct udevice *dev, const char ch) writel(ch, &plat->regs->thr); if (ch == '\n') - WATCHDOG_RESET(); + schedule(); return 0; } diff --git a/drivers/serial/serial_mtk.c b/drivers/serial/serial_mtk.c index a84f39b3fa..22251c5f4c 100644 --- a/drivers/serial/serial_mtk.c +++ b/drivers/serial/serial_mtk.c @@ -141,7 +141,7 @@ static int _mtk_serial_putc(struct mtk_serial_priv *priv, const char ch) writel(ch, &priv->regs->thr); if (ch == '\n') - WATCHDOG_RESET(); + schedule(); return 0; } @@ -295,7 +295,7 @@ DECLARE_GLOBAL_DATA_PTR; do { \ err = _mtk_serial_getc(&mtk_hsuart##port); \ if (err == -EAGAIN) \ - WATCHDOG_RESET(); \ + schedule(); \ } while (err == -EAGAIN); \ return err >= 0 ? err : 0; \ } \ diff --git a/drivers/serial/serial_mxc.c b/drivers/serial/serial_mxc.c index 70a0e5e919..315c136ef8 100644 --- a/drivers/serial/serial_mxc.c +++ b/drivers/serial/serial_mxc.c @@ -200,7 +200,7 @@ static void mxc_serial_setbrg(void) static int mxc_serial_getc(void) { while (readl(&mxc_base->ts) & UTS_RXEMPTY) - WATCHDOG_RESET(); + schedule(); return (readl(&mxc_base->rxd) & URXD_RX_DATA); /* mask out status from upper word */ } @@ -214,7 +214,7 @@ static void mxc_serial_putc(const char c) /* wait for transmitter to be ready */ while (!(readl(&mxc_base->ts) & UTS_TXEMPTY)) - WATCHDOG_RESET(); + schedule(); } /* Test whether a character is in the RX buffer */ @@ -384,7 +384,7 @@ static inline void _debug_uart_putc(int ch) struct mxc_uart *base = (struct mxc_uart *)CONFIG_VAL(DEBUG_UART_BASE); while (!(readl(&base->ts) & UTS_TXEMPTY)) - WATCHDOG_RESET(); + schedule(); writel(ch, &base->txd); } diff --git a/drivers/serial/serial_octeon_bootcmd.c b/drivers/serial/serial_octeon_bootcmd.c index 4bcff77eb8..eff5c43e2a 100644 --- a/drivers/serial/serial_octeon_bootcmd.c +++ b/drivers/serial/serial_octeon_bootcmd.c @@ -98,7 +98,7 @@ static int octeon_bootcmd_getc(struct udevice *dev) } while (!octeon_bootcmd_pending(dev, true)) { - WATCHDOG_RESET(); + schedule(); /* * ToDo: * The original code calls octeon_board_poll() here. We may diff --git a/drivers/serial/serial_octeon_pcie_console.c b/drivers/serial/serial_octeon_pcie_console.c index c76e787d03..b0eafe7ad8 100644 --- a/drivers/serial/serial_octeon_pcie_console.c +++ b/drivers/serial/serial_octeon_pcie_console.c @@ -134,7 +134,7 @@ static int octeon_pcie_console_read(struct udevice *dev, cons_ptr->input_write_index, cons_ptr->input_read_index))) { mdelay(10); - WATCHDOG_RESET(); + schedule(); } } @@ -210,7 +210,7 @@ static int octeon_pcie_console_write(struct udevice *dev, if (flags & OCT_PCI_CON_FLAG_NONBLOCK) goto done; - WATCHDOG_RESET(); + schedule(); mdelay(10); /* Delay if we are spinning */ } else { bytes_written = -1; diff --git a/drivers/serial/serial_pl01x.c b/drivers/serial/serial_pl01x.c index 9b0d16f164..d3c3d3e2d1 100644 --- a/drivers/serial/serial_pl01x.c +++ b/drivers/serial/serial_pl01x.c @@ -70,7 +70,7 @@ static int pl01x_getc(struct pl01x_regs *regs) static int pl01x_tstc(struct pl01x_regs *regs) { - WATCHDOG_RESET(); + schedule(); return !(readl(®s->fr) & UART_PL01x_FR_RXFE); } @@ -227,7 +227,7 @@ static int pl01x_serial_getc(void) int ch = pl01x_getc(base_regs); if (ch == -EAGAIN) { - WATCHDOG_RESET(); + schedule(); continue; } @@ -247,9 +247,9 @@ static void pl01x_serial_setbrg(void) * crap in console */ while (!(readl(&base_regs->fr) & UART_PL01x_FR_TXFE)) - WATCHDOG_RESET(); + schedule(); while (readl(&base_regs->fr) & UART_PL01x_FR_BUSY) - WATCHDOG_RESET(); + schedule(); pl01x_serial_init_baud(gd->baudrate); } diff --git a/drivers/serial/serial_sifive.c b/drivers/serial/serial_sifive.c index 4af1ff5060..c449f3fd02 100644 --- a/drivers/serial/serial_sifive.c +++ b/drivers/serial/serial_sifive.c @@ -225,7 +225,7 @@ static inline void _debug_uart_putc(int ch) (struct uart_sifive *)CONFIG_VAL(DEBUG_UART_BASE); while (_sifive_serial_putc(regs, ch) == -EAGAIN) - WATCHDOG_RESET(); + schedule(); } DEBUG_UART_FUNCS diff --git a/drivers/serial/serial_zynq.c b/drivers/serial/serial_zynq.c index 295337a817..4b1818313a 100644 --- a/drivers/serial/serial_zynq.c +++ b/drivers/serial/serial_zynq.c @@ -307,7 +307,7 @@ static inline void _debug_uart_putc(int ch) struct uart_zynq *regs = (struct uart_zynq *)CONFIG_VAL(DEBUG_UART_BASE); while (_uart_zynq_serial_putc(regs, ch) == -EAGAIN) - WATCHDOG_RESET(); + schedule(); } DEBUG_UART_FUNCS diff --git a/drivers/spi/mtk_snfi_spi.c b/drivers/spi/mtk_snfi_spi.c index 65d0ce0981..5ea62776b4 100644 --- a/drivers/spi/mtk_snfi_spi.c +++ b/drivers/spi/mtk_snfi_spi.c @@ -202,7 +202,7 @@ static int mtk_snfi_exec_op(struct spi_slave *slave, int addr_sh; int ret; - WATCHDOG_RESET(); + schedule(); ret = mtk_snfi_mac_reset(priv); if (ret) diff --git a/drivers/spi/octeon_spi.c b/drivers/spi/octeon_spi.c index c2a7ee232b..4bc38beaa6 100644 --- a/drivers/spi/octeon_spi.c +++ b/drivers/spi/octeon_spi.c @@ -126,7 +126,7 @@ static void octeon_spi_wait_ready(struct udevice *dev) do { mpi_sts = readq(base + MPI_STS); - WATCHDOG_RESET(); + schedule(); } while (mpi_sts & MPI_STS_BUSY); debug("%s(%s)\n", __func__, dev->name); diff --git a/drivers/spi/stm32_qspi.c b/drivers/spi/stm32_qspi.c index ceba413727..90c207d518 100644 --- a/drivers/spi/stm32_qspi.c +++ b/drivers/spi/stm32_qspi.c @@ -172,7 +172,7 @@ static int _stm32_qspi_wait_cmd(struct stm32_qspi_priv *priv, static void _stm32_qspi_read_fifo(u8 *val, void __iomem *addr) { *val = readb(addr); - WATCHDOG_RESET(); + schedule(); } static void _stm32_qspi_write_fifo(u8 *val, void __iomem *addr) diff --git a/drivers/timer/mpc83xx_timer.c b/drivers/timer/mpc83xx_timer.c index 952293195f..410bf723d6 100644 --- a/drivers/timer/mpc83xx_timer.c +++ b/drivers/timer/mpc83xx_timer.c @@ -176,7 +176,7 @@ void timer_interrupt(struct pt_regs *regs) #if defined(CONFIG_WATCHDOG) || defined(CONFIG_HW_WATCHDOG) if (CONFIG_SYS_WATCHDOG_FREQ && (priv->timestamp % (CONFIG_SYS_WATCHDOG_FREQ)) == 0) - WATCHDOG_RESET(); + schedule(); #endif /* CONFIG_WATCHDOG || CONFIG_HW_WATCHDOG */ #ifdef CONFIG_LED_STATUS @@ -189,7 +189,7 @@ void wait_ticks(ulong ticks) ulong end = get_ticks() + ticks; while (end > get_ticks()) - WATCHDOG_RESET(); + schedule(); } static u64 mpc83xx_timer_get_count(struct udevice *dev) diff --git a/drivers/usb/eth/lan7x.h b/drivers/usb/eth/lan7x.h index f71e8c7268..9480f4f6d1 100644 --- a/drivers/usb/eth/lan7x.h +++ b/drivers/usb/eth/lan7x.h @@ -157,7 +157,7 @@ static inline int lan7x_wait_for_bit(struct usb_device *udev, } udelay(1); - WATCHDOG_RESET(); + schedule(); } debug("%s: Timeout (reg=0x%x mask=%08x wait_set=%i)\n", prefix, reg, @@ -199,7 +199,7 @@ static inline int lan7x_mdio_wait_for_bit(struct usb_device *udev, } udelay(1); - WATCHDOG_RESET(); + schedule(); } debug("%s: Timeout (reg=0x%x mask=%08x wait_set=%i)\n", prefix, reg, diff --git a/drivers/usb/gadget/f_acm.c b/drivers/usb/gadget/f_acm.c index 388f73d1bc..b2ddd1ada8 100644 --- a/drivers/usb/gadget/f_acm.c +++ b/drivers/usb/gadget/f_acm.c @@ -579,7 +579,7 @@ static int acm_stdio_getc(struct stdio_dev *dev) /* Wait for a character to arrive. */ while (!acm_stdio_tstc(dev)) - WATCHDOG_RESET(); + schedule(); buf_pop(&f_acm->rx_buf, &c, 1); @@ -639,7 +639,7 @@ static int acm_stdio_start(struct stdio_dev *dev) if (ctrlc()) return -ECANCELED; - WATCHDOG_RESET(); + schedule(); } return 0; diff --git a/drivers/usb/gadget/f_sdp.c b/drivers/usb/gadget/f_sdp.c index 0fa7230b99..74548ab603 100644 --- a/drivers/usb/gadget/f_sdp.c +++ b/drivers/usb/gadget/f_sdp.c @@ -711,7 +711,7 @@ int sdp_init(int controller_index) return 1; } - WATCHDOG_RESET(); + schedule(); usb_gadget_handle_interrupts(controller_index); } @@ -927,7 +927,7 @@ int spl_sdp_handle(int controller_index, struct spl_image_info *spl_image, if (flag == SDP_EXIT) return 0; - WATCHDOG_RESET(); + schedule(); usb_gadget_handle_interrupts(controller_index); #ifdef CONFIG_SPL_BUILD diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index f033198a7c..d30f2a0d13 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -641,7 +641,7 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer, token = hc32_to_cpu(vtd->qt_token); if (!(QT_TOKEN_GET_STATUS(token) & QT_TOKEN_STATUS_ACTIVE)) break; - WATCHDOG_RESET(); + schedule(); } while (get_timer(ts) < timeout); qhtoken = hc32_to_cpu(qh->qh_overlay.qt_token); diff --git a/drivers/usb/musb-new/musb_uboot.c b/drivers/usb/musb-new/musb_uboot.c index d186facc7e..62c5e8e5fa 100644 --- a/drivers/usb/musb-new/musb_uboot.c +++ b/drivers/usb/musb-new/musb_uboot.c @@ -378,7 +378,7 @@ static struct musb *gadget; int usb_gadget_handle_interrupts(int index) { - WATCHDOG_RESET(); + schedule(); if (!gadget || !gadget->isr) return -EINVAL; diff --git a/drivers/video/video_bmp.c b/drivers/video/video_bmp.c index 4d2d961696..082895a50e 100644 --- a/drivers/video/video_bmp.c +++ b/drivers/video/video_bmp.c @@ -329,7 +329,7 @@ int video_bmp_display(struct udevice *dev, ulong bmp_image, int x, int y, byte_width = width; for (i = 0; i < height; ++i) { - WATCHDOG_RESET(); + schedule(); for (j = 0; j < width; j++) { write_pix8(fb, bpix, eformat, palette, bmap); bmap++; @@ -342,7 +342,7 @@ int video_bmp_display(struct udevice *dev, ulong bmp_image, int x, int y, case 16: if (IS_ENABLED(CONFIG_BMP_16BPP)) { for (i = 0; i < height; ++i) { - WATCHDOG_RESET(); + schedule(); for (j = 0; j < width; j++) { *fb++ = *bmap++; *fb++ = *bmap++; diff --git a/env/common.c b/env/common.c index f9226e0690..8dd05ff76d 100644 --- a/env/common.c +++ b/env/common.c @@ -115,7 +115,7 @@ char *env_get(const char *name) if (gd->flags & GD_FLG_ENV_READY) { /* after import into hashtable */ struct env_entry e, *ep; - WATCHDOG_RESET(); + schedule(); e.key = name; e.data = NULL; diff --git a/fs/cramfs/uncompress.c b/fs/cramfs/uncompress.c index 38e10e2e44..0d071b69f4 100644 --- a/fs/cramfs/uncompress.c +++ b/fs/cramfs/uncompress.c @@ -21,6 +21,7 @@ */ #include +#include #include #include #include @@ -62,7 +63,7 @@ int cramfs_uncompress_init (void) stream.avail_in = 0; #if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG) - stream.outcb = (cb_func)watchdog_reset_func; + stream.outcb = (cb_func)cyclic_run; #else stream.outcb = Z_NULL; #endif /* CONFIG_HW_WATCHDOG */ diff --git a/fs/jffs2/jffs2_1pass.c b/fs/jffs2/jffs2_1pass.c index ef7b302725..49ba82ef95 100644 --- a/fs/jffs2/jffs2_1pass.c +++ b/fs/jffs2/jffs2_1pass.c @@ -1523,7 +1523,7 @@ jffs2_1pass_build_lists(struct part_info * part) /* Set buf_size to maximum length */ buf_size = DEFAULT_EMPTY_SCAN_SIZE; - WATCHDOG_RESET(); + schedule(); #ifdef CONFIG_JFFS2_SUMMARY buf_len = sizeof(*sm); diff --git a/include/linux/compat.h b/include/linux/compat.h index 3d0acbd582..921e698f40 100644 --- a/include/linux/compat.h +++ b/include/linux/compat.h @@ -2,6 +2,7 @@ #define _LINUX_COMPAT_H_ #include +#include #include #include @@ -230,7 +231,6 @@ typedef unsigned long blkcnt_t; #define try_to_freeze(...) 0 #define set_current_state(...) do { } while (0) #define kthread_should_stop(...) 0 -#define schedule() do { } while (0) #define setup_timer(timer, func, data) do {} while (0) #define del_timer_sync(timer) do {} while (0) diff --git a/include/wait_bit.h b/include/wait_bit.h index dcc5c4fd39..f1d70aef87 100644 --- a/include/wait_bit.h +++ b/include/wait_bit.h @@ -63,7 +63,7 @@ static inline int wait_for_bit_##sfx(const void *reg, \ } \ \ udelay(1); \ - WATCHDOG_RESET(); \ + schedule(); \ } \ \ debug("%s: Timeout (reg=%p mask=%x wait_set=%i)\n", __func__, \ diff --git a/include/watchdog.h b/include/watchdog.h index 0a9777edcb..7a09346a09 100644 --- a/include/watchdog.h +++ b/include/watchdog.h @@ -88,14 +88,6 @@ int init_func_watchdog_reset(void); #endif /* CONFIG_WATCHDOG && !__ASSEMBLY__ */ #endif /* CONFIG_HW_WATCHDOG */ -#if !defined(__ASSEMBLY__) -/* Currently only needed for fs/cramfs/uncompress.c */ -static inline void watchdog_reset_func(void) -{ - WATCHDOG_RESET(); -} -#endif - /* * Prototypes from $(CPU)/cpu.c. */ diff --git a/lib/bzip2/bzlib.c b/lib/bzip2/bzlib.c index 377b269b06..bd589aa810 100644 --- a/lib/bzip2/bzlib.c +++ b/lib/bzip2/bzlib.c @@ -844,7 +844,7 @@ int BZ_API(BZ2_bzDecompress) ( bz_stream *strm ) while (True) { #if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG) - WATCHDOG_RESET(); + schedule(); #endif if (s->state == BZ_X_IDLE) return BZ_SEQUENCE_ERROR; if (s->state == BZ_X_OUTPUT) { diff --git a/lib/bzip2/bzlib_decompress.c b/lib/bzip2/bzlib_decompress.c index 4412b8a23e..3b417d57b2 100644 --- a/lib/bzip2/bzlib_decompress.c +++ b/lib/bzip2/bzlib_decompress.c @@ -418,7 +418,7 @@ Int32 BZ2_decompress ( DState* s ) while (True) { #if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG) - WATCHDOG_RESET(); + schedule(); #endif if (nextSym == EOB) break; @@ -503,7 +503,7 @@ Int32 BZ2_decompress ( DState* s ) kk = MTFA_SIZE-1; for (ii = 256 / MTFL_SIZE-1; ii >= 0; ii--) { #if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG) - WATCHDOG_RESET(); + schedule(); #endif for (jj = MTFL_SIZE-1; jj >= 0; jj--) { s->mtfa[kk] = s->mtfa[s->mtfbase[ii] + jj]; @@ -568,7 +568,7 @@ Int32 BZ2_decompress ( DState* s ) while (i != s->origPtr); #if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG) - WATCHDOG_RESET(); + schedule(); #endif s->tPos = s->origPtr; s->nblock_used = 0; @@ -583,7 +583,7 @@ Int32 BZ2_decompress ( DState* s ) } else { #if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG) - WATCHDOG_RESET(); + schedule(); #endif /*-- compute the T^(-1) vector --*/ for (i = 0; i < nblock; i++) { diff --git a/lib/crc32.c b/lib/crc32.c index 5a3127e03a..aa94d70ef3 100644 --- a/lib/crc32.c +++ b/lib/crc32.c @@ -255,7 +255,7 @@ uint32_t crc32_wd(uint32_t crc, const unsigned char *buf, uInt len, chunk = chunk_sz; crc = crc32(crc, curr, chunk); curr += chunk; - WATCHDOG_RESET (); + schedule(); } #else crc = crc32(crc, buf, len); diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c index 1233418e77..8da3bb29aa 100644 --- a/lib/efi_loader/efi_boottime.c +++ b/lib/efi_loader/efi_boottime.c @@ -828,7 +828,7 @@ void efi_timer_check(void) efi_signal_event(evt); } efi_process_event_queue(); - WATCHDOG_RESET(); + schedule(); } /** @@ -2193,7 +2193,7 @@ static efi_status_t EFIAPI efi_exit_boot_services(efi_handle_t image_handle, /* Give the payload some time to boot */ efi_set_watchdog(0); - WATCHDOG_RESET(); + schedule(); out: if (IS_ENABLED(CONFIG_EFI_TCG2_PROTOCOL)) { if (ret != EFI_SUCCESS) diff --git a/lib/gunzip.c b/lib/gunzip.c index a8e498d98d..932e3e8036 100644 --- a/lib/gunzip.c +++ b/lib/gunzip.c @@ -251,7 +251,7 @@ int gzwrite(unsigned char *src, int len, puts("abort\n"); goto out; } - WATCHDOG_RESET(); + schedule(); } while (s.avail_out == 0); /* done when inflate() says it's done */ } while (r != Z_STREAM_END); diff --git a/lib/lzma/LzmaDec.c b/lib/lzma/LzmaDec.c index 4f45f80fe2..341149f766 100644 --- a/lib/lzma/LzmaDec.c +++ b/lib/lzma/LzmaDec.c @@ -153,7 +153,7 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte UInt32 range = p->range; UInt32 code = p->code; - WATCHDOG_RESET(); + schedule(); do { @@ -177,7 +177,7 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte state -= (state < 4) ? state : 3; symbol = 1; - WATCHDOG_RESET(); + schedule(); do { GET_BIT(prob + symbol, symbol) } while (symbol < 0x100); } @@ -188,7 +188,7 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte state -= (state < 10) ? 3 : 6; symbol = 1; - WATCHDOG_RESET(); + schedule(); do { @@ -321,7 +321,7 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte UInt32 mask = 1; unsigned i = 1; - WATCHDOG_RESET(); + schedule(); do { @@ -335,7 +335,7 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte { numDirectBits -= kNumAlignBits; - WATCHDOG_RESET(); + schedule(); do { @@ -409,7 +409,7 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte const Byte *lim = dest + curLen; dicPos += curLen; - WATCHDOG_RESET(); + schedule(); do *(dest) = (Byte)*(dest + src); @@ -418,7 +418,7 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte else { - WATCHDOG_RESET(); + schedule(); do { @@ -433,7 +433,7 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte } while (dicPos < limit && buf < bufLimit); - WATCHDOG_RESET(); + schedule(); NORMALIZE; p->buf = buf; diff --git a/lib/lzma/LzmaTools.c b/lib/lzma/LzmaTools.c index af88900d31..55f64cd289 100644 --- a/lib/lzma/LzmaTools.c +++ b/lib/lzma/LzmaTools.c @@ -104,7 +104,7 @@ int lzmaBuffToBuffDecompress(unsigned char *outStream, SizeT *uncompressedSize, /* Decompress */ outProcessed = min(outSizeFull, *uncompressedSize); - WATCHDOG_RESET(); + schedule(); res = LzmaDecode( outStream, &outProcessed, diff --git a/lib/md5.c b/lib/md5.c index 9d34465564..1636ab9366 100644 --- a/lib/md5.c +++ b/lib/md5.c @@ -304,7 +304,7 @@ md5_wd(const unsigned char *input, unsigned int len, unsigned char output[16], chunk = chunk_sz; MD5Update(&context, curr, chunk); curr += chunk; - WATCHDOG_RESET (); + schedule(); } #else MD5Update(&context, input, len); diff --git a/lib/sha1.c b/lib/sha1.c index e5e42bc9fe..8d07407893 100644 --- a/lib/sha1.c +++ b/lib/sha1.c @@ -344,7 +344,7 @@ void sha1_csum_wd(const unsigned char *input, unsigned int ilen, chunk = chunk_sz; sha1_update (&ctx, curr, chunk); curr += chunk; - WATCHDOG_RESET (); + schedule(); } #else sha1_update (&ctx, input, ilen); diff --git a/lib/sha256.c b/lib/sha256.c index 50b0b51183..4d26aea1c8 100644 --- a/lib/sha256.c +++ b/lib/sha256.c @@ -293,7 +293,7 @@ void sha256_csum_wd(const unsigned char *input, unsigned int ilen, chunk = chunk_sz; sha256_update(&ctx, curr, chunk); curr += chunk; - WATCHDOG_RESET(); + schedule(); } #else sha256_update(&ctx, input, ilen); diff --git a/lib/sha512.c b/lib/sha512.c index a421f249ba..fbe8d5f5bf 100644 --- a/lib/sha512.c +++ b/lib/sha512.c @@ -309,7 +309,7 @@ void sha384_csum_wd(const unsigned char *input, unsigned int ilen, chunk = chunk_sz; sha384_update(&ctx, curr, chunk); curr += chunk; - WATCHDOG_RESET(); + schedule(); } #else sha384_update(&ctx, input, ilen); @@ -372,7 +372,7 @@ void sha512_csum_wd(const unsigned char *input, unsigned int ilen, chunk = chunk_sz; sha512_update(&ctx, curr, chunk); curr += chunk; - WATCHDOG_RESET(); + schedule(); } #else sha512_update(&ctx, input, ilen); diff --git a/lib/time.c b/lib/time.c index bbf191f673..f3aaf472d1 100644 --- a/lib/time.c +++ b/lib/time.c @@ -198,7 +198,7 @@ void udelay(unsigned long usec) ulong kv; do { - WATCHDOG_RESET(); + schedule(); kv = usec > CONFIG_WD_PERIOD ? CONFIG_WD_PERIOD : usec; __udelay(kv); usec -= kv; diff --git a/lib/zlib/inflate.c b/lib/zlib/inflate.c index 6411c47932..30dfe15599 100644 --- a/lib/zlib/inflate.c +++ b/lib/zlib/inflate.c @@ -25,7 +25,7 @@ int ZEXPORT inflateReset(z_streamp strm) state->hold = 0; state->bits = 0; state->lencode = state->distcode = state->next = state->codes; - WATCHDOG_RESET(); + schedule(); Tracev((stderr, "inflate: reset\n")); return Z_OK; } @@ -543,7 +543,7 @@ int ZEXPORT inflate(z_streamp strm, int flush) strm->adler = state->check = adler32(0L, Z_NULL, 0); state->mode = TYPE; case TYPE: - WATCHDOG_RESET(); + schedule(); if (flush == Z_BLOCK) goto inf_leave; case TYPEDO: if (state->last) { @@ -721,7 +721,7 @@ int ZEXPORT inflate(z_streamp strm, int flush) Tracev((stderr, "inflate: codes ok\n")); state->mode = LEN; case LEN: - WATCHDOG_RESET(); + schedule(); if (have >= 6 && left >= 258) { RESTORE(); inflate_fast(strm, out); @@ -933,7 +933,7 @@ int ZEXPORT inflateEnd(z_streamp strm) return Z_STREAM_ERROR; state = (struct inflate_state FAR *)strm->state; if (state->window != Z_NULL) { - WATCHDOG_RESET(); + schedule(); ZFREE(strm, state->window); } ZFREE(strm, strm->state); diff --git a/net/net.c b/net/net.c index 81905f6315..f9d11c08d2 100644 --- a/net/net.c +++ b/net/net.c @@ -559,7 +559,7 @@ restart: * someone sets `net_state' to a state that terminates. */ for (;;) { - WATCHDOG_RESET(); + schedule(); if (arp_timeout_check() > 0) time_start = get_timer(0); diff --git a/post/cpu/mpc83xx/ecc.c b/post/cpu/mpc83xx/ecc.c index f88eff8998..edd7411567 100644 --- a/post/cpu/mpc83xx/ecc.c +++ b/post/cpu/mpc83xx/ecc.c @@ -73,7 +73,7 @@ int ecc_post_test(int flags) for (addr = (u64*)CONFIG_SYS_POST_ECC_START_ADDR, errbit=0; addr < (u64*)CONFIG_SYS_POST_ECC_STOP_ADDR; addr++, errbit++ ) { - WATCHDOG_RESET(); + schedule(); ecc_clear(ddr); diff --git a/post/drivers/memory.c b/post/drivers/memory.c index 4fb9355d60..d249942af0 100644 --- a/post/drivers/memory.c +++ b/post/drivers/memory.c @@ -279,7 +279,7 @@ static int memory_post_test1(unsigned long start, for (i = 0; i < size / sizeof (ulong); i++) { mem[i] = val; if (i % 1024 == 0) - WATCHDOG_RESET(); + schedule(); } for (i = 0; i < size / sizeof (ulong) && !ret; i++) { @@ -292,7 +292,7 @@ static int memory_post_test1(unsigned long start, break; } if (i % 1024 == 0) - WATCHDOG_RESET(); + schedule(); } return ret; @@ -308,7 +308,7 @@ static int memory_post_test2(unsigned long start, unsigned long size) for (i = 0; i < size / sizeof (ulong); i++) { mem[i] = 1 << (i % 32); if (i % 1024 == 0) - WATCHDOG_RESET(); + schedule(); } for (i = 0; i < size / sizeof (ulong) && !ret; i++) { @@ -321,7 +321,7 @@ static int memory_post_test2(unsigned long start, unsigned long size) break; } if (i % 1024 == 0) - WATCHDOG_RESET(); + schedule(); } return ret; @@ -337,7 +337,7 @@ static int memory_post_test3(unsigned long start, unsigned long size) for (i = 0; i < size / sizeof (ulong); i++) { mem[i] = i; if (i % 1024 == 0) - WATCHDOG_RESET(); + schedule(); } for (i = 0; i < size / sizeof (ulong) && !ret; i++) { @@ -350,7 +350,7 @@ static int memory_post_test3(unsigned long start, unsigned long size) break; } if (i % 1024 == 0) - WATCHDOG_RESET(); + schedule(); } return ret; @@ -366,7 +366,7 @@ static int memory_post_test4(unsigned long start, unsigned long size) for (i = 0; i < size / sizeof (ulong); i++) { mem[i] = ~i; if (i % 1024 == 0) - WATCHDOG_RESET(); + schedule(); } for (i = 0; i < size / sizeof (ulong) && !ret; i++) { @@ -379,7 +379,7 @@ static int memory_post_test4(unsigned long start, unsigned long size) break; } if (i % 1024 == 0) - WATCHDOG_RESET(); + schedule(); } return ret; @@ -390,15 +390,15 @@ static int memory_post_test_lines(unsigned long start, unsigned long size) int ret = 0; ret = memory_post_dataline((unsigned long long *)start); - WATCHDOG_RESET(); + schedule(); if (!ret) ret = memory_post_addrline((ulong *)start, (ulong *)start, size); - WATCHDOG_RESET(); + schedule(); if (!ret) ret = memory_post_addrline((ulong *)(start+size-8), (ulong *)start, size); - WATCHDOG_RESET(); + schedule(); return ret; } @@ -408,25 +408,25 @@ static int memory_post_test_patterns(unsigned long start, unsigned long size) int ret = 0; ret = memory_post_test1(start, size, 0x00000000); - WATCHDOG_RESET(); + schedule(); if (!ret) ret = memory_post_test1(start, size, 0xffffffff); - WATCHDOG_RESET(); + schedule(); if (!ret) ret = memory_post_test1(start, size, 0x55555555); - WATCHDOG_RESET(); + schedule(); if (!ret) ret = memory_post_test1(start, size, 0xaaaaaaaa); - WATCHDOG_RESET(); + schedule(); if (!ret) ret = memory_post_test2(start, size); - WATCHDOG_RESET(); + schedule(); if (!ret) ret = memory_post_test3(start, size); - WATCHDOG_RESET(); + schedule(); if (!ret) ret = memory_post_test4(start, size); - WATCHDOG_RESET(); + schedule(); return ret; } diff --git a/post/lib_powerpc/cpu.c b/post/lib_powerpc/cpu.c index 8506fd6b71..1d47107342 100644 --- a/post/lib_powerpc/cpu.c +++ b/post/lib_powerpc/cpu.c @@ -61,7 +61,7 @@ int cpu_post_test (int flags) int ic = icache_status(); int ret = 0; - WATCHDOG_RESET(); + schedule(); if (ic) icache_disable(); @@ -73,7 +73,7 @@ int cpu_post_test (int flags) ret = cpu_post_test_two (); if (ret == 0) ret = cpu_post_test_twox (); - WATCHDOG_RESET(); + schedule(); if (ret == 0) ret = cpu_post_test_three (); if (ret == 0) @@ -82,7 +82,7 @@ int cpu_post_test (int flags) ret = cpu_post_test_threei (); if (ret == 0) ret = cpu_post_test_andi (); - WATCHDOG_RESET(); + schedule(); if (ret == 0) ret = cpu_post_test_srawi (); if (ret == 0) @@ -91,7 +91,7 @@ int cpu_post_test (int flags) ret = cpu_post_test_rlwinm (); if (ret == 0) ret = cpu_post_test_rlwimi (); - WATCHDOG_RESET(); + schedule(); if (ret == 0) ret = cpu_post_test_store (); if (ret == 0) @@ -100,20 +100,20 @@ int cpu_post_test (int flags) ret = cpu_post_test_cr (); if (ret == 0) ret = cpu_post_test_b (); - WATCHDOG_RESET(); + schedule(); if (ret == 0) ret = cpu_post_test_multi (); - WATCHDOG_RESET(); + schedule(); if (ret == 0) ret = cpu_post_test_string (); if (ret == 0) ret = cpu_post_test_complex (); - WATCHDOG_RESET(); + schedule(); if (ic) icache_enable(); - WATCHDOG_RESET(); + schedule(); return ret; } diff --git a/post/lib_powerpc/fpu/fpu.c b/post/lib_powerpc/fpu/fpu.c index 0de76ce051..bd65f623d5 100644 --- a/post/lib_powerpc/fpu/fpu.c +++ b/post/lib_powerpc/fpu/fpu.c @@ -43,7 +43,7 @@ int fpu_post_test (int flags) int ret = 0; - WATCHDOG_RESET (); + schedule(); if (!fpu) fpu_enable (); @@ -66,7 +66,7 @@ int fpu_post_test (int flags) if (!fpu) fpu_disable (); - WATCHDOG_RESET (); + schedule(); return ret; } diff --git a/post/post.c b/post/post.c index d67c43ed8a..b81425d8cf 100644 --- a/post/post.c +++ b/post/post.c @@ -245,7 +245,7 @@ static int post_run_single(struct post_test *test, { if ((flags & test_flags & POST_ALWAYS) && (flags & test_flags & POST_MEM)) { - WATCHDOG_RESET(); + schedule(); if (!(flags & POST_REBOOT)) { if ((test_flags & POST_REBOOT) && @@ -350,7 +350,7 @@ int post_run(char *name, int flags) } if (i < post_list_size) { - WATCHDOG_RESET(); + schedule(); return post_run_single(post_list + i, test_flags[i], flags, i); diff --git a/test/common/cyclic.c b/test/common/cyclic.c index a5c4e78989..6e758e89db 100644 --- a/test/common/cyclic.c +++ b/test/common/cyclic.c @@ -27,7 +27,7 @@ static int dm_test_cyclic_running(struct unit_test_state *uts) NULL)); /* Execute all registered cyclic functions */ - WATCHDOG_RESET(); + schedule(); ut_asserteq(true, cyclic_active); return 0; diff --git a/test/dm/wdt.c b/test/dm/wdt.c index 535f00a874..653d7b1c8b 100644 --- a/test/dm/wdt.c +++ b/test/dm/wdt.c @@ -4,6 +4,7 @@ */ #include +#include #include #include #include @@ -130,7 +131,7 @@ static int dm_test_wdt_watchdog_reset(struct unit_test_state *uts) /* Neither device should be "started", so watchdog_reset() should be a no-op. */ reset_count = state->wdt.reset_count; val = sandbox_gpio_get_value(gpio, offset); - watchdog_reset(); + cyclic_run(); ut_asserteq(reset_count, state->wdt.reset_count); ut_asserteq(val, sandbox_gpio_get_value(gpio, offset)); @@ -140,19 +141,19 @@ static int dm_test_wdt_watchdog_reset(struct unit_test_state *uts) /* Make sure both devices have just been pinged. */ timer_test_add_offset(100); - watchdog_reset(); + cyclic_run(); reset_count = state->wdt.reset_count; val = sandbox_gpio_get_value(gpio, offset); /* The gpio watchdog should be pinged, the sandbox one not. */ timer_test_add_offset(30); - watchdog_reset(); + cyclic_run(); ut_asserteq(reset_count, state->wdt.reset_count); ut_asserteq(!val, sandbox_gpio_get_value(gpio, offset)); /* After another ~30ms, both devices should get pinged. */ timer_test_add_offset(30); - watchdog_reset(); + cyclic_run(); ut_asserteq(reset_count + 1, state->wdt.reset_count); ut_asserteq(val, sandbox_gpio_get_value(gpio, offset)); From ff3fdfe89b29a4561afe4756b9c7df886e70e0d7 Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Fri, 2 Sep 2022 14:10:47 +0200 Subject: [PATCH 201/374] watchdog: Get rid of ASSEMBLY hacks Only one occurance of WATCHDOG_RESET is left in one assembler file. This patch changes this occurance to a direct call to watchdog_reset and then removes all the ASSEMBLY ifdef'ery in watchdog.h, as it's not needed any more to clean this mess a bit up. Signed-off-by: Stefan Roese Tested-by: Tom Rini [am335x_evm, mx6cuboxi, rpi_3,dra7xx_evm, pine64_plus, am65x_evm, j721e_evm] --- arch/powerpc/lib/ticks.S | 5 ++-- include/watchdog.h | 50 +++++++++++++--------------------------- 2 files changed, 19 insertions(+), 36 deletions(-) diff --git a/arch/powerpc/lib/ticks.S b/arch/powerpc/lib/ticks.S index c487f938fa..8647d77cc9 100644 --- a/arch/powerpc/lib/ticks.S +++ b/arch/powerpc/lib/ticks.S @@ -9,7 +9,6 @@ #include #include #include -#include /* * unsigned long long get_ticks(void); @@ -42,7 +41,9 @@ wait_ticks: addc r14, r4, r14 /* Compute end time lower */ addze r15, r3 /* and end time upper */ - WATCHDOG_RESET /* Trigger watchdog, if needed */ +#if defined(CONFIG_WATCHDOG) || defined(CONFIG_HW_WATCHDOG) + bl schedule /* Trigger watchdog, if needed */ +#endif 1: bl get_ticks /* Get current time */ subfc r4, r4, r14 /* Subtract current time from end time */ subfe. r3, r3, r15 diff --git a/include/watchdog.h b/include/watchdog.h index 7a09346a09..1365b154a2 100644 --- a/include/watchdog.h +++ b/include/watchdog.h @@ -38,54 +38,36 @@ int init_func_watchdog_reset(void); * Hardware watchdog */ #ifdef CONFIG_HW_WATCHDOG - #if defined(__ASSEMBLY__) - #define WATCHDOG_RESET bl hw_watchdog_reset - #else - extern void hw_watchdog_reset(void); + extern void hw_watchdog_reset(void); - #define WATCHDOG_RESET hw_watchdog_reset - #endif /* __ASSEMBLY__ */ + #define WATCHDOG_RESET hw_watchdog_reset #else /* * Maybe a software watchdog? */ #if defined(CONFIG_WATCHDOG) - #if defined(__ASSEMBLY__) - /* Don't require the watchdog to be enabled in SPL */ - #if defined(CONFIG_SPL_BUILD) && \ - !defined(CONFIG_SPL_WATCHDOG) - #define WATCHDOG_RESET /*XXX DO_NOT_DEL_THIS_COMMENT*/ - #else - #define WATCHDOG_RESET bl watchdog_reset - #endif + /* Don't require the watchdog to be enabled in SPL */ + #if defined(CONFIG_SPL_BUILD) && \ + !defined(CONFIG_SPL_WATCHDOG) + #define WATCHDOG_RESET() { \ + cyclic_run(); \ + } #else - /* Don't require the watchdog to be enabled in SPL */ - #if defined(CONFIG_SPL_BUILD) && \ - !defined(CONFIG_SPL_WATCHDOG) - #define WATCHDOG_RESET() { \ - cyclic_run(); \ - } - #else - extern void watchdog_reset(void); + extern void watchdog_reset(void); - #define WATCHDOG_RESET() { \ - watchdog_reset(); \ - cyclic_run(); \ - } - #endif + #define WATCHDOG_RESET() { \ + watchdog_reset(); \ + cyclic_run(); \ + } #endif #else /* * No hardware or software watchdog. */ - #if defined(__ASSEMBLY__) - #define WATCHDOG_RESET /*XXX DO_NOT_DEL_THIS_COMMENT*/ - #else - #define WATCHDOG_RESET() { \ - cyclic_run(); \ + #define WATCHDOG_RESET() { \ + cyclic_run(); \ } - #endif /* __ASSEMBLY__ */ - #endif /* CONFIG_WATCHDOG && !__ASSEMBLY__ */ + #endif /* CONFIG_WATCHDOG */ #endif /* CONFIG_HW_WATCHDOG */ /* From 942d07df0e7915fd9e83539a11fb160381072453 Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Fri, 2 Sep 2022 14:10:48 +0200 Subject: [PATCH 202/374] watchdog: Remove WATCHDOG_RESET macro Now that we've globally replaced all WATCHDOG_RESET occurances, let's remove the ugly macro itself in the header. Signed-off-by: Stefan Roese Reviewed-by: Simon Glass Tested-by: Tom Rini [am335x_evm, mx6cuboxi, rpi_3,dra7xx_evm, pine64_plus, am65x_evm, j721e_evm] --- include/watchdog.h | 36 ------------------------------------ 1 file changed, 36 deletions(-) diff --git a/include/watchdog.h b/include/watchdog.h index 1365b154a2..91506d3327 100644 --- a/include/watchdog.h +++ b/include/watchdog.h @@ -34,42 +34,6 @@ int init_func_watchdog_reset(void); # error "Configuration error: CONFIG_HW_WATCHDOG and CONFIG_WATCHDOG can't be used together." #endif -/* - * Hardware watchdog - */ -#ifdef CONFIG_HW_WATCHDOG - extern void hw_watchdog_reset(void); - - #define WATCHDOG_RESET hw_watchdog_reset -#else - /* - * Maybe a software watchdog? - */ - #if defined(CONFIG_WATCHDOG) - /* Don't require the watchdog to be enabled in SPL */ - #if defined(CONFIG_SPL_BUILD) && \ - !defined(CONFIG_SPL_WATCHDOG) - #define WATCHDOG_RESET() { \ - cyclic_run(); \ - } - #else - extern void watchdog_reset(void); - - #define WATCHDOG_RESET() { \ - watchdog_reset(); \ - cyclic_run(); \ - } - #endif - #else - /* - * No hardware or software watchdog. - */ - #define WATCHDOG_RESET() { \ - cyclic_run(); \ - } - #endif /* CONFIG_WATCHDOG */ -#endif /* CONFIG_HW_WATCHDOG */ - /* * Prototypes from $(CPU)/cpu.c. */ From 8695fbb3a7ff3640eff62f7123323b16546d5b35 Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Fri, 2 Sep 2022 14:10:49 +0200 Subject: [PATCH 203/374] watchdog: Further cleanup Remove some now unused macros and #ifdef's. Signed-off-by: Stefan Roese Reviewed-by: Simon Glass Tested-by: Tom Rini [am335x_evm, mx6cuboxi, rpi_3,dra7xx_evm, pine64_plus, am65x_evm, j721e_evm] --- include/watchdog.h | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/include/watchdog.h b/include/watchdog.h index 91506d3327..ac5f11e376 100644 --- a/include/watchdog.h +++ b/include/watchdog.h @@ -10,7 +10,6 @@ #ifndef _WATCHDOG_H_ #define _WATCHDOG_H_ -#if !defined(__ASSEMBLY__) #include /* @@ -20,7 +19,6 @@ * and the legacy arch//board.c code. */ int init_func_watchdog_reset(void); -#endif #if defined(CONFIG_WATCHDOG) || defined(CONFIG_HW_WATCHDOG) #define INIT_FUNC_WATCHDOG_INIT init_func_watchdog_init, @@ -38,11 +36,11 @@ int init_func_watchdog_reset(void); * Prototypes from $(CPU)/cpu.c. */ -#if (defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)) && !defined(__ASSEMBLY__) +#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG) void hw_watchdog_init(void); #endif -#if defined(CONFIG_MPC85xx) && !defined(__ASSEMBLY__) +#if defined(CONFIG_MPC85xx) void init_85xx_watchdog(void); #endif #endif /* _WATCHDOG_H_ */ From 222a1f490722c60d73efaa3387e617ff5b730eb6 Mon Sep 17 00:00:00 2001 From: Sergiu Moga Date: Wed, 22 Jun 2022 16:30:47 +0300 Subject: [PATCH 204/374] mmc: atmel_sdhci: re-enable sdhci after SD Card re-insertion Whenever the SD Card would be removed and then re-inserted while in the U-Boot command line, the `SDBPWR` bit of the `SDMMC_PCR` register would remain unset afterwards. In order for the bit to be set again after re-insertion, register an additional `deferred_probe` method that the DM would then transparently call. This method will call the generic `sdhci_probe` which will, during its execution flow, set this bit to 1. Signed-off-by: Sergiu Moga Reported-by: Mihai Sain Reviewed-by: Eugen Hristev --- drivers/mmc/atmel_sdhci.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/mmc/atmel_sdhci.c b/drivers/mmc/atmel_sdhci.c index 2b5ceeab94..37b0beeed4 100644 --- a/drivers/mmc/atmel_sdhci.c +++ b/drivers/mmc/atmel_sdhci.c @@ -52,6 +52,17 @@ struct atmel_sdhci_plat { struct mmc mmc; }; +static int atmel_sdhci_deferred_probe(struct sdhci_host *host) +{ + struct udevice *dev = host->mmc->dev; + + return sdhci_probe(dev); +} + +static const struct sdhci_ops atmel_sdhci_ops = { + .deferred_probe = atmel_sdhci_deferred_probe, +}; + static int atmel_sdhci_probe(struct udevice *dev) { struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev); @@ -104,6 +115,7 @@ static int atmel_sdhci_probe(struct udevice *dev) return ret; host->mmc->priv = host; + host->ops = &atmel_sdhci_ops; upriv->mmc = host->mmc; clk_free(&clk); From 63aee5491b6d13052b44c9f4c3d855f4d7aa5b1e Mon Sep 17 00:00:00 2001 From: Durai Manickam KR Date: Thu, 7 Jul 2022 16:40:54 +0530 Subject: [PATCH 205/374] configs: sama9x60_curiosity: add onewire and eeprom drivers SAM9X60 SoC can have extra clip boards (PDAs) connected, which have an EEPROM memory for identification. A special GPIO can be used to read this memory over 1wire protocol. Enabling one wire and eeprom drivers for this memory. Signed-off-by: Durai Manickam KR --- configs/sam9x60_curiosity_mmc_defconfig | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/configs/sam9x60_curiosity_mmc_defconfig b/configs/sam9x60_curiosity_mmc_defconfig index 99f61d732a..c8dffa85d1 100644 --- a/configs/sam9x60_curiosity_mmc_defconfig +++ b/configs/sam9x60_curiosity_mmc_defconfig @@ -72,4 +72,8 @@ CONFIG_DEBUG_UART_ANNOUNCE=y CONFIG_ATMEL_USART=y CONFIG_TIMER=y CONFIG_MCHP_PIT64B_TIMER=y +CONFIG_W1=y +CONFIG_W1_GPIO=y +CONFIG_W1_EEPROM=y +CONFIG_W1_EEPROM_DS24XXX=y CONFIG_OF_LIBFDT_OVERLAY=y From af64b436b15120da177b2c42c6860d3b361f065a Mon Sep 17 00:00:00 2001 From: Durai Manickam KR Date: Thu, 7 Jul 2022 16:40:55 +0530 Subject: [PATCH 206/374] board: sam9x60_curiosity: add pda detect call at init time Call the PDA detection mechanism at boot time so that we can have the pda environment variable ready for use. Signed-off-by: Durai Manickam KR --- board/atmel/sam9x60_curiosity/sam9x60_curiosity.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/board/atmel/sam9x60_curiosity/sam9x60_curiosity.c b/board/atmel/sam9x60_curiosity/sam9x60_curiosity.c index d8f32c93b5..8cf67d148d 100644 --- a/board/atmel/sam9x60_curiosity/sam9x60_curiosity.c +++ b/board/atmel/sam9x60_curiosity/sam9x60_curiosity.c @@ -19,6 +19,8 @@ #include #include +extern void at91_pda_detect(void); + DECLARE_GLOBAL_DATA_PTR; void at91_prepare_cpu_var(void); @@ -27,6 +29,8 @@ int board_late_init(void) { at91_prepare_cpu_var(); + at91_pda_detect(); + return 0; } From 353467220079932d8e62e9e2d462e382b83a4598 Mon Sep 17 00:00:00 2001 From: Durai Manickam KR Date: Thu, 7 Jul 2022 16:40:56 +0530 Subject: [PATCH 207/374] ARM: dts: at91: sam9x60_curiosity: add onewire support Add support for onewire memory. Signed-off-by: Durai Manickam KR --- arch/arm/dts/at91-sam9x60_curiosity.dts | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/arch/arm/dts/at91-sam9x60_curiosity.dts b/arch/arm/dts/at91-sam9x60_curiosity.dts index 2e7ccb0ffb..7c5b6ae2b8 100644 --- a/arch/arm/dts/at91-sam9x60_curiosity.dts +++ b/arch/arm/dts/at91-sam9x60_curiosity.dts @@ -44,6 +44,11 @@ ; }; + + pinctrl_onewire_tm_default: onewire_tm_default { + atmel,pins = + ; + }; }; }; }; @@ -66,6 +71,18 @@ memory { reg = <0x20000000 0x8000000>; }; + + onewire_tm: onewire { + gpios = <&pioD 14 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_onewire_tm_default>; + status = "okay"; + + w1_eeprom: w1_eeprom@0 { + compatible = "maxim,ds24b33"; + status = "okay"; + }; + }; }; &macb0 { From 56ce54a97c464df2dec2189b6a12e012d8894815 Mon Sep 17 00:00:00 2001 From: Mihai Sain Date: Tue, 19 Jul 2022 16:51:59 +0300 Subject: [PATCH 208/374] clk: at91: sam9x60: change parent clock from mck_pres to mck_div ddrck and qspick should have mck_div as parent clocks to be in sync with linux driver. Signed-off-by: Mihai Sain Reviewed-by: Claudiu Beznea --- drivers/clk/at91/sam9x60.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/clk/at91/sam9x60.c b/drivers/clk/at91/sam9x60.c index 4d00ee2ddc..6b5486c6c9 100644 --- a/drivers/clk/at91/sam9x60.c +++ b/drivers/clk/at91/sam9x60.c @@ -265,10 +265,10 @@ static const struct { u8 id; u8 cid; } sam9x60_systemck[] = { - { .n = "ddrck", .p = "mck_pres", .id = 2, .cid = ID_DDR, }, + { .n = "ddrck", .p = "mck_div", .id = 2, .cid = ID_DDR, }, { .n = "pck0", .p = "prog0", .id = 8, .cid = ID_PCK0, }, { .n = "pck1", .p = "prog1", .id = 9, .cid = ID_PCK1, }, - { .n = "qspick", .p = "mck_pres", .id = 19, .cid = ID_QSPI, }, + { .n = "qspick", .p = "mck_div", .id = 19, .cid = ID_QSPI, }, }; /** From 2df729e96d72ddeec9c7ef0cf98b483e71c644d3 Mon Sep 17 00:00:00 2001 From: Sergiu Moga Date: Thu, 1 Sep 2022 17:22:39 +0300 Subject: [PATCH 209/374] ARM: dts: at91: sama5: Align with Linux Devicetree This patch makes sure that the Devicetree for the sama5 boards are aligned with the Devicetree from Linux. This implies removing the GPIO compatible and replacing it with the PINCTRL one, as well as unifying the SDMMC pinctrl related subnodes under one single subnode. Signed-off-by: Sergiu Moga --- arch/arm/dts/at91-sama5d27_giantboard.dts | 59 +++-- arch/arm/dts/at91-sama5d27_som1_ek.dts | 78 +++---- .../dts/at91-sama5d27_wlsom1_ek-u-boot.dtsi | 6 +- arch/arm/dts/at91-sama5d27_wlsom1_ek.dts | 92 ++++---- arch/arm/dts/at91-sama5d2_icp.dts | 120 +++++------ arch/arm/dts/at91-sama5d2_ptc_ek.dts | 98 ++++----- arch/arm/dts/at91-sama5d2_xplained.dts | 204 +++++++++--------- arch/arm/dts/sama5d2.dtsi | 9 +- arch/arm/dts/sama5d27_som1.dtsi | 84 ++++---- arch/arm/dts/sama5d27_wlsom1.dtsi | 54 +++-- 10 files changed, 398 insertions(+), 406 deletions(-) diff --git a/arch/arm/dts/at91-sama5d27_giantboard.dts b/arch/arm/dts/at91-sama5d27_giantboard.dts index e81ca60ca0..2625f81c8b 100644 --- a/arch/arm/dts/at91-sama5d27_giantboard.dts +++ b/arch/arm/dts/at91-sama5d27_giantboard.dts @@ -30,7 +30,7 @@ sdmmc1: sdio-host@b0000000 { bus-width = <4>; pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_sdmmc1_cmd_dat_default &pinctrl_sdmmc1_ck_cd_default>; + pinctrl-0 = <&pinctrl_sdmmc1_default>; status = "okay"; u-boot,dm-pre-reloc; }; @@ -73,10 +73,9 @@ u-boot,dm-pre-reloc; }; - pioA: gpio@fc038000 { - pinctrl { - - pinctrl_sdmmc1_cmd_dat_default: sdmmc1_cmd_dat_default { + pioA: pinctrl@fc038000 { + pinctrl_sdmmc1_default: sdmmc1_default { + cmd_data { pinmux = , , , @@ -86,41 +85,41 @@ u-boot,dm-pre-reloc; }; - pinctrl_sdmmc1_ck_cd_default: sdmmc1_ck_cd_default { + ck_cd { pinmux = , ; bias-disable; u-boot,dm-pre-reloc; }; + }; - pinctrl_uart1_default: uart1_default { - pinmux = , - ; - bias-disable; - u-boot,dm-pre-reloc; - }; + pinctrl_uart1_default: uart1_default { + pinmux = , + ; + bias-disable; + u-boot,dm-pre-reloc; + }; - pinctrl_i2c0_default: i2c0_default { - pinmux = , - ; - bias-disable; - }; + pinctrl_i2c0_default: i2c0_default { + pinmux = , + ; + bias-disable; + }; - pinctrl_i2c1_default: i2c1_default { - pinmux = , - ; - bias-disable; - }; + pinctrl_i2c1_default: i2c1_default { + pinmux = , + ; + bias-disable; + }; - pinctrl_usb_default: usb_default { - pinmux = ; - bias-disable; - }; + pinctrl_usb_default: usb_default { + pinmux = ; + bias-disable; + }; - pinctrl_usba_vbus: usba_vbus { - pinmux = ; - bias-disable; - }; + pinctrl_usba_vbus: usba_vbus { + pinmux = ; + bias-disable; }; }; }; diff --git a/arch/arm/dts/at91-sama5d27_som1_ek.dts b/arch/arm/dts/at91-sama5d27_som1_ek.dts index efd1a5d197..70d15c8a62 100644 --- a/arch/arm/dts/at91-sama5d27_som1_ek.dts +++ b/arch/arm/dts/at91-sama5d27_som1_ek.dts @@ -83,7 +83,7 @@ sdmmc0: sdio-host@a0000000 { bus-width = <8>; pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_sdmmc0_cmd_dat_default &pinctrl_sdmmc0_ck_cd_default>; + pinctrl-0 = <&pinctrl_sdmmc0_default>; status = "okay"; u-boot,dm-pre-reloc; }; @@ -91,7 +91,7 @@ sdmmc1: sdio-host@b0000000 { bus-width = <4>; pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_sdmmc1_cmd_dat_default &pinctrl_sdmmc1_ck_cd_default>; + pinctrl-0 = <&pinctrl_sdmmc1_default>; status = "okay"; /* conflict with qspi0 */ u-boot,dm-pre-reloc; }; @@ -129,7 +129,7 @@ u-boot,dm-pre-reloc; }; - pioA: gpio@fc038000 { + pioA: pinctrl@fc038000 { pinctrl { pinctrl_lcd_base: pinctrl_lcd_base { pinmux = , @@ -166,43 +166,47 @@ bias-disable; }; - pinctrl_sdmmc0_cmd_dat_default: sdmmc0_cmd_dat_default { - pinmux = , - , - , - , - , - , - , - , - ; - bias-pull-up; - u-boot,dm-pre-reloc; + pinctrl_sdmmc0_default: sdmmc0_default { + cmd_dat { + pinmux = , + , + , + , + , + , + , + , + ; + bias-pull-up; + u-boot,dm-pre-reloc; + }; + + ck_cd { + pinmux = , + , + ; + bias-disable; + u-boot,dm-pre-reloc; + }; }; - pinctrl_sdmmc0_ck_cd_default: sdmmc0_ck_cd_default { - pinmux = , - , - ; - bias-disable; - u-boot,dm-pre-reloc; - }; + pinctrl_sdmmc1_default: sdmmc1_default { + cmd_dat { + pinmux = , + , + , + , + ; + bias-pull-up; + u-boot,dm-pre-reloc; + }; - pinctrl_sdmmc1_cmd_dat_default: sdmmc1_cmd_dat_default { - pinmux = , - , - , - , - ; - bias-pull-up; - u-boot,dm-pre-reloc; - }; - - pinctrl_sdmmc1_ck_cd_default: sdmmc1_ck_cd_default { - pinmux = , - ; - bias-disable; - u-boot,dm-pre-reloc; + ck_cd { + pinmux = , + ; + bias-disable; + u-boot,dm-pre-reloc; + }; }; pinctrl_uart1_default: uart1_default { diff --git a/arch/arm/dts/at91-sama5d27_wlsom1_ek-u-boot.dtsi b/arch/arm/dts/at91-sama5d27_wlsom1_ek-u-boot.dtsi index 8c84dd08fd..41cf9061a1 100644 --- a/arch/arm/dts/at91-sama5d27_wlsom1_ek-u-boot.dtsi +++ b/arch/arm/dts/at91-sama5d27_wlsom1_ek-u-boot.dtsi @@ -37,11 +37,7 @@ u-boot,dm-pre-reloc; }; -&pinctrl_sdmmc0_cmd_dat_default { - u-boot,dm-pre-reloc; -}; - -&pinctrl_sdmmc0_ck_cd_default { +&pinctrl_sdmmc0_default { u-boot,dm-pre-reloc; }; diff --git a/arch/arm/dts/at91-sama5d27_wlsom1_ek.dts b/arch/arm/dts/at91-sama5d27_wlsom1_ek.dts index f3f6942143..eec183d5de 100644 --- a/arch/arm/dts/at91-sama5d27_wlsom1_ek.dts +++ b/arch/arm/dts/at91-sama5d27_wlsom1_ek.dts @@ -34,7 +34,7 @@ sdmmc0: sdio-host@a0000000 { bus-width = <4>; pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_sdmmc0_cmd_dat_default &pinctrl_sdmmc0_ck_cd_default>; + pinctrl-0 = <&pinctrl_sdmmc0_default>; status = "okay"; }; @@ -78,44 +78,44 @@ status = "okay"; }; - pioA: gpio@fc038000 { - pinctrl { - pinctrl_lcd_base: pinctrl_lcd_base { - pinmux = , - , - , - ; - bias-disable; - }; + pioA: pinctrl@fc038000 { + pinctrl_lcd_base: pinctrl_lcd_base { + pinmux = , + , + , + ; + bias-disable; + }; - pinctrl_lcd_pwm: pinctrl_lcd_pwm { - pinmux = ; - bias-disable; - }; + pinctrl_lcd_pwm: pinctrl_lcd_pwm { + pinmux = ; + bias-disable; + }; - pinctrl_lcd_rgb666: pinctrl_lcd_rgb666 { - pinmux = , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - ; - bias-disable; - }; + pinctrl_lcd_rgb666: pinctrl_lcd_rgb666 { + pinmux = , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + ; + bias-disable; + }; - pinctrl_sdmmc0_cmd_dat_default: sdmmc0_cmd_dat_default { + pinctrl_sdmmc0_default: sdmmc0_default { + cmd_data { pinmux = , , , @@ -124,24 +124,24 @@ bias-disable; }; - pinctrl_sdmmc0_ck_cd_default: sdmmc0_ck_cd_default { + ck_cd_vddsel { pinmux = , , , ; bias-disable; }; + }; - pinctrl_uart0_default: uart0_default { - pinmux = , - ; - bias-disable; - }; + pinctrl_uart0_default: uart0_default { + pinmux = , + ; + bias-disable; + }; - pinctrl_onewire_tm_default: onewire_tm_default { - pinmux = ; - bias-pull-up; - }; + pinctrl_onewire_tm_default: onewire_tm_default { + pinmux = ; + bias-pull-up; }; }; }; diff --git a/arch/arm/dts/at91-sama5d2_icp.dts b/arch/arm/dts/at91-sama5d2_icp.dts index 0b0db1b2be..2dffae9c5c 100644 --- a/arch/arm/dts/at91-sama5d2_icp.dts +++ b/arch/arm/dts/at91-sama5d2_icp.dts @@ -86,75 +86,73 @@ }; }; - pioA: gpio@fc038000 { + pioA: pinctrl@fc038000 { status = "okay"; - pinctrl { - pinctrl_i2c1_default: i2c1_default { - pinmux = , - ; - bias-disable; - }; + pinctrl_i2c1_default: i2c1_default { + pinmux = , + ; + bias-disable; + }; - pinctrl_macb0_rmii: macb0_rmii { - pinmux = , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - ; - bias-disable; - }; + pinctrl_macb0_rmii: macb0_rmii { + pinmux = , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + ; + bias-disable; + }; - pinctrl_macb0_phy_irq: macb0_phy_irq { - pinmux = ; - bias-disable; - }; + pinctrl_macb0_phy_irq: macb0_phy_irq { + pinmux = ; + bias-disable; + }; - pinctrl_macb0_rst: macb0_sw_rst { - pinmux = ; - bias-pull-up; - }; + pinctrl_macb0_rst: macb0_sw_rst { + pinmux = ; + bias-pull-up; + }; - pinctrl_mikrobus1_uart: mikrobus1_uart { - pinmux = , - ; - bias-disable; - }; + pinctrl_mikrobus1_uart: mikrobus1_uart { + pinmux = , + ; + bias-disable; + }; - pinctrl_qspi1_sck_cs_default: qspi1_sck_cs_default { - pinmux = , - ; - bias-disable; - }; + pinctrl_qspi1_sck_cs_default: qspi1_sck_cs_default { + pinmux = , + ; + bias-disable; + }; - pinctrl_qspi1_dat_default: qspi1_dat_default { - pinmux = , - , - , - ; - bias-pull-up; - }; + pinctrl_qspi1_dat_default: qspi1_dat_default { + pinmux = , + , + , + ; + bias-pull-up; + }; - pinctrl_sdmmc0_default: sdmmc0_default { - pinmux = , - , - , - , - , - , - ; - bias-disable; - }; + pinctrl_sdmmc0_default: sdmmc0_default { + pinmux = , + , + , + , + , + , + ; + bias-disable; }; }; }; diff --git a/arch/arm/dts/at91-sama5d2_ptc_ek.dts b/arch/arm/dts/at91-sama5d2_ptc_ek.dts index f45fb1ef26..36d52c2c5e 100644 --- a/arch/arm/dts/at91-sama5d2_ptc_ek.dts +++ b/arch/arm/dts/at91-sama5d2_ptc_ek.dts @@ -94,7 +94,7 @@ sdmmc0: sdio-host@a0000000 { bus-width = <8>; pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_sdmmc0_cmd_dat_default &pinctrl_sdmmc0_ck_cd_default>; + pinctrl-0 = <&pinctrl_sdmmc0_default>; status = "okay"; u-boot,dm-pre-reloc; }; @@ -102,7 +102,7 @@ sdmmc1: sdio-host@b0000000 { bus-width = <4>; pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_sdmmc1_cmd_dat_default &pinctrl_sdmmc1_ck_cd_default>; + pinctrl-0 = <&pinctrl_sdmmc1_default>; status = "disabled"; /* conflicts with nand and qspi0*/ u-boot,dm-pre-reloc; }; @@ -137,34 +137,34 @@ }; }; - pioA: gpio@fc038000 { - pinctrl { - pinctrl_i2c1_default: i2c1_default { - pinmux = , - ; - bias-disable; - }; + pioA: pinctrl@fc038000 { + pinctrl_i2c1_default: i2c1_default { + pinmux = , + ; + bias-disable; + }; - pinctrl_macb0_phy_irq: macb0_phy_irq { - pinmux = ; - bias-disable; - }; + pinctrl_macb0_phy_irq: macb0_phy_irq { + pinmux = ; + bias-disable; + }; - pinctrl_macb0_rmii: macb0_rmii { - pinmux = , - , - , - , - , - , - , - , - , - ; - bias-disable; - }; + pinctrl_macb0_rmii: macb0_rmii { + pinmux = , + , + , + , + , + , + , + , + , + ; + bias-disable; + }; - pinctrl_sdmmc0_cmd_dat_default: sdmmc0_cmd_dat_default { + pinctrl_sdmmc0_default: sdmmc0_default { + cmd_dat { pinmux = , , , @@ -178,7 +178,7 @@ u-boot,dm-pre-reloc; }; - pinctrl_sdmmc0_ck_cd_default: sdmmc0_ck_cd_default { + ck_cd { pinmux = , , , @@ -186,8 +186,10 @@ bias-disable; u-boot,dm-pre-reloc; }; + }; - pinctrl_sdmmc1_cmd_dat_default: sdmmc1_cmd_dat_default { + pinctrl_sdmmc1_default: sdmmc1_default { + cmd_dat { pinmux = , , , @@ -197,34 +199,34 @@ u-boot,dm-pre-reloc; }; - pinctrl_sdmmc1_ck_cd_default: sdmmc1_ck_cd_default { + ck_cd { pinmux = , ; bias-disable; u-boot,dm-pre-reloc; }; + }; - pinctrl_uart0_default: uart0_default { - pinmux = , - ; - bias-disable; - u-boot,dm-pre-reloc; - }; + pinctrl_uart0_default: uart0_default { + pinmux = , + ; + bias-disable; + u-boot,dm-pre-reloc; + }; - pinctrl_usb_default: usb_default { - pinmux = ; - bias-disable; - }; + pinctrl_usb_default: usb_default { + pinmux = ; + bias-disable; + }; - pinctrl_usba_vbus: usba_vbus { - pinmux = ; - bias-disable; - }; + pinctrl_usba_vbus: usba_vbus { + pinmux = ; + bias-disable; + }; - pinctrl_onewire_tm_default: onewire_tm_default { - pinmux = ; - bias-pull-up; - }; + pinctrl_onewire_tm_default: onewire_tm_default { + pinmux = ; + bias-pull-up; }; }; }; diff --git a/arch/arm/dts/at91-sama5d2_xplained.dts b/arch/arm/dts/at91-sama5d2_xplained.dts index 34b64a22af..78a3a851bb 100644 --- a/arch/arm/dts/at91-sama5d2_xplained.dts +++ b/arch/arm/dts/at91-sama5d2_xplained.dts @@ -44,7 +44,7 @@ sdmmc0: sdio-host@a0000000 { bus-width = <8>; pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_sdmmc0_cmd_dat_default &pinctrl_sdmmc0_ck_cd_default>; + pinctrl-0 = <&pinctrl_sdmmc0_default>; status = "okay"; u-boot,dm-pre-reloc; }; @@ -52,7 +52,7 @@ sdmmc1: sdio-host@b0000000 { bus-width = <4>; pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_sdmmc1_cmd_dat_default &pinctrl_sdmmc1_ck_cd_default>; + pinctrl-0 = <&pinctrl_sdmmc1_default>; status = "okay"; /* conflict with qspi0 */ u-boot,dm-pre-reloc; }; @@ -143,85 +143,85 @@ }; }; - pioA: gpio@fc038000 { - pinctrl { - pinctrl_i2c1_default: i2c1_default { - pinmux = , - ; - bias-disable; - }; + pioA: pinctrl@fc038000 { + pinctrl_i2c1_default: i2c1_default { + pinmux = , + ; + bias-disable; + }; - pinctrl_lcd_base: pinctrl_lcd_base { - pinmux = , - , - , - ; - bias-disable; - }; + pinctrl_lcd_base: pinctrl_lcd_base { + pinmux = , + , + , + ; + bias-disable; + }; - pinctrl_lcd_pwm: pinctrl_lcd_pwm { - pinmux = ; - bias-disable; - }; + pinctrl_lcd_pwm: pinctrl_lcd_pwm { + pinmux = ; + bias-disable; + }; - pinctrl_lcd_rgb666: pinctrl_lcd_rgb666 { - pinmux = , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - , - ; - bias-disable; - }; + pinctrl_lcd_rgb666: pinctrl_lcd_rgb666 { + pinmux = , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + ; + bias-disable; + }; - pinctrl_macb0_phy_irq: macb0_phy_irq { - pinmux = ; - bias-disable; - }; + pinctrl_macb0_phy_irq: macb0_phy_irq { + pinmux = ; + bias-disable; + }; - pinctrl_macb0_rmii: macb0_rmii { - pinmux = , - , - , - , - , - , - , - , - , - ; - bias-disable; - }; + pinctrl_macb0_rmii: macb0_rmii { + pinmux = , + , + , + , + , + , + , + , + , + ; + bias-disable; + }; - pinctrl_qspi0_sck_cs_default: qspi0_sck_cs_default { - pinmux = , - ; - bias-disable; - u-boot,dm-pre-reloc; - }; + pinctrl_qspi0_sck_cs_default: qspi0_sck_cs_default { + pinmux = , + ; + bias-disable; + u-boot,dm-pre-reloc; + }; - pinctrl_qspi0_dat_default: qspi0_dat_default { - pinmux = , - , - , - ; - bias-pull-up; - u-boot,dm-pre-reloc; - }; + pinctrl_qspi0_dat_default: qspi0_dat_default { + pinmux = , + , + , + ; + bias-pull-up; + u-boot,dm-pre-reloc; + }; - pinctrl_sdmmc0_cmd_dat_default: sdmmc0_cmd_dat_default { + pinctrl_sdmmc0_default: sdmmc0_default { + cmd_dat { pinmux = , , , @@ -235,7 +235,7 @@ u-boot,dm-pre-reloc; }; - pinctrl_sdmmc0_ck_cd_default: sdmmc0_ck_cd_default { + ck_cd_default { pinmux = , , , @@ -243,8 +243,10 @@ bias-disable; u-boot,dm-pre-reloc; }; + }; - pinctrl_sdmmc1_cmd_dat_default: sdmmc1_cmd_dat_default { + pinctrl_sdmmc1_default: sdmmc1_default { + cmd_dat { pinmux = , , , @@ -254,42 +256,42 @@ u-boot,dm-pre-reloc; }; - pinctrl_sdmmc1_ck_cd_default: sdmmc1_ck_cd_default { + ck_cd { pinmux = , ; bias-disable; u-boot,dm-pre-reloc; }; + }; - pinctrl_spi0_default: spi0_default { - pinmux = , - , - ; - bias-disable; - u-boot,dm-pre-reloc; - }; + pinctrl_spi0_default: spi0_default { + pinmux = , + , + ; + bias-disable; + u-boot,dm-pre-reloc; + }; - pinctrl_uart1_default: uart1_default { - pinmux = , - ; - bias-disable; - u-boot,dm-pre-reloc; - }; + pinctrl_uart1_default: uart1_default { + pinmux = , + ; + bias-disable; + u-boot,dm-pre-reloc; + }; - pinctrl_usb_default: usb_default { - pinmux = ; - bias-disable; - }; + pinctrl_usb_default: usb_default { + pinmux = ; + bias-disable; + }; - pinctrl_usba_vbus: usba_vbus { - pinmux = ; - bias-disable; - }; + pinctrl_usba_vbus: usba_vbus { + pinmux = ; + bias-disable; + }; - pinctrl_onewire_tm_default: onewire_tm_default { - pinmux = ; - bias-pull-up; - }; + pinctrl_onewire_tm_default: onewire_tm_default { + pinmux = ; + bias-pull-up; }; }; }; diff --git a/arch/arm/dts/sama5d2.dtsi b/arch/arm/dts/sama5d2.dtsi index d92bdd5588..790b746ed1 100644 --- a/arch/arm/dts/sama5d2.dtsi +++ b/arch/arm/dts/sama5d2.dtsi @@ -799,18 +799,13 @@ status = "disabled"; }; - pioA: gpio@fc038000 { - compatible = "atmel,sama5d2-gpio"; + pioA: pinctrl@fc038000 { + compatible = "atmel,sama5d2-pinctrl"; reg = <0xfc038000 0x600>; clocks = <&pioA_clk>; gpio-controller; #gpio-cells = <2>; u-boot,dm-pre-reloc; - - pinctrl { - compatible = "atmel,sama5d2-pinctrl"; - u-boot,dm-pre-reloc; - }; }; }; }; diff --git a/arch/arm/dts/sama5d27_som1.dtsi b/arch/arm/dts/sama5d27_som1.dtsi index db4fefadcd..f920077449 100644 --- a/arch/arm/dts/sama5d27_som1.dtsi +++ b/arch/arm/dts/sama5d27_som1.dtsi @@ -103,54 +103,52 @@ status = "okay"; }; - pioA: gpio@fc038000 { - pinctrl { - pinctrl_i2c0_default: i2c0_default { - pinmux = , - ; - bias-disable; - }; + pioA: pinctrl@fc038000 { + pinctrl_i2c0_default: i2c0_default { + pinmux = , + ; + bias-disable; + }; - pinctrl_i2c1_default: i2c1_default { - pinmux = , - ; - bias-disable; - }; + pinctrl_i2c1_default: i2c1_default { + pinmux = , + ; + bias-disable; + }; - pinctrl_macb0_phy_irq: macb0_phy_irq { - pinmux = ; - bias-disable; - }; + pinctrl_macb0_phy_irq: macb0_phy_irq { + pinmux = ; + bias-disable; + }; - pinctrl_macb0_rmii: macb0_rmii { - pinmux = , - , - , - , - , - , - , - , - , - ; - bias-disable; - }; + pinctrl_macb0_rmii: macb0_rmii { + pinmux = , + , + , + , + , + , + , + , + , + ; + bias-disable; + }; - pinctrl_qspi1_sck_cs_default: qspi1_sck_cs_default { - pinmux = , - ; - bias-disable; - u-boot,dm-pre-reloc; - }; + pinctrl_qspi1_sck_cs_default: qspi1_sck_cs_default { + pinmux = , + ; + bias-disable; + u-boot,dm-pre-reloc; + }; - pinctrl_qspi1_dat_default: qspi1_dat_default { - pinmux = , - , - , - ; - bias-pull-up; - u-boot,dm-pre-reloc; - }; + pinctrl_qspi1_dat_default: qspi1_dat_default { + pinmux = , + , + , + ; + bias-pull-up; + u-boot,dm-pre-reloc; }; }; }; diff --git a/arch/arm/dts/sama5d27_wlsom1.dtsi b/arch/arm/dts/sama5d27_wlsom1.dtsi index 889a0034d1..1c23b8c737 100644 --- a/arch/arm/dts/sama5d27_wlsom1.dtsi +++ b/arch/arm/dts/sama5d27_wlsom1.dtsi @@ -41,36 +41,34 @@ }; }; - pioA: gpio@fc038000 { - pinctrl { - pinctrl_macb0_phy_irq: macb0_phy_irq { - pinmux = ; - bias-disable; - }; + pioA: pinctrl@fc038000 { + pinctrl_macb0_phy_irq: macb0_phy_irq { + pinmux = ; + bias-disable; + }; - pinctrl_macb0_rmii: macb0_rmii { - pinmux = , - , - , - , - , - , - , - , - , - ; - bias-disable; - }; + pinctrl_macb0_rmii: macb0_rmii { + pinmux = , + , + , + , + , + , + , + , + , + ; + bias-disable; + }; - pinctrl_qspi1_default: qspi1_default { - pinmux = , - , - , - , - , - ; - bias-pull-up; - }; + pinctrl_qspi1_default: qspi1_default { + pinmux = , + , + , + , + , + ; + bias-pull-up; }; }; }; From f02e52b7e68eeebca1d9e2c4bfccff9bd647e393 Mon Sep 17 00:00:00 2001 From: Sergiu Moga Date: Thu, 1 Sep 2022 17:22:40 +0300 Subject: [PATCH 210/374] ARM: dts: at91: sama7: Align with Linux Devicetree This patch makes sure that the Devicetree for the sama7 boards are aligned with the Devicetree from Linux. This implies removing the GPIO compatible and replacing it with the PINCTRL one, as well as unifying the SDMMC pinctrl related subnodes under one single subnode. Signed-off-by: Sergiu Moga --- arch/arm/dts/at91-sama7g5ek-u-boot.dtsi | 2 +- arch/arm/dts/at91-sama7g5ek.dts | 85 +++++++++++++++---------- arch/arm/dts/sama7g5.dtsi | 16 ++--- 3 files changed, 60 insertions(+), 43 deletions(-) diff --git a/arch/arm/dts/at91-sama7g5ek-u-boot.dtsi b/arch/arm/dts/at91-sama7g5ek-u-boot.dtsi index 601386788f..d294ddb54a 100644 --- a/arch/arm/dts/at91-sama7g5ek-u-boot.dtsi +++ b/arch/arm/dts/at91-sama7g5ek-u-boot.dtsi @@ -28,7 +28,7 @@ u-boot,dm-pre-reloc; }; -&pinctrl { +&pioA { u-boot,dm-pre-reloc; }; diff --git a/arch/arm/dts/at91-sama7g5ek.dts b/arch/arm/dts/at91-sama7g5ek.dts index eaba0de3f7..aed84f15a1 100644 --- a/arch/arm/dts/at91-sama7g5ek.dts +++ b/arch/arm/dts/at91-sama7g5ek.dts @@ -690,46 +690,67 @@ }; pinctrl_sdmmc0_default: sdmmc0_default { - pinmux = , - , - , - , - , - , - , - , - , - , - , - , - ; + cmd_data { + pinmux = , + , + , + , + , + , + , + , + ; slew-rate = <0>; bias-pull-up; + }; + + ck_cd_rstn_vddsel { + pinmux = , + , + , + ; + slew-rate = <0>; + bias-pull-up; + }; }; pinctrl_sdmmc1_default: sdmmc1_default { - pinmux = , - , - , - , - , - , - , - , - ; - slew-rate = <0>; - bias-pull-up; + cmd_data { + pinmux = , + , + , + , + ; + slew-rate = <0>; + bias-pull-up; + }; + + ck_cd_rstn_vddsel { + pinmux = , + , + , + ; + slew-rate = <0>; + bias-pull-up; + }; }; pinctrl_sdmmc2_default: sdmmc2_default { - pinmux = , - , - , - , - , - ; - slew-rate = <0>; - bias-pull-up; + cmd_data { + pinmux = , + , + , + , + ; + slew-rate = <0>; + bias-pull-up; + }; + + ck { + pinmux = ; + slew-rate = <0>; + bias-pull-up; + }; }; pinctrl_spdifrx_default: spdifrx_default { diff --git a/arch/arm/dts/sama7g5.dtsi b/arch/arm/dts/sama7g5.dtsi index 97400dc18e..d38090d7dd 100644 --- a/arch/arm/dts/sama7g5.dtsi +++ b/arch/arm/dts/sama7g5.dtsi @@ -187,8 +187,8 @@ reg = <0xe0008000 0x20>; }; - pinctrl: pinctrl@e0014000 { - compatible = "microchip,sama7g5-gpio"; + pioA: pinctrl@e0014000 { + compatible = "microchip,sama7g5-pinctrl"; reg = <0xe0014000 0x800>; interrupts = , , @@ -196,14 +196,10 @@ , ; clocks = <&pmc PMC_TYPE_PERIPHERAL 11>; - - pioA: pinctrl_default { - interrupt-controller; - #interrupt-cells = <2>; - gpio-controller; - #gpio-cells = <2>; - compatible = "microchip,sama7g5-pinctrl"; - }; + interrupt-controller; + #interrupt-cells = <2>; + gpio-controller; + #gpio-cells = <2>; }; pmc: pmc@e0018000 { From 2ed96a87d2c7f22fe2649f6e041cc3884a0dbea7 Mon Sep 17 00:00:00 2001 From: Sergiu Moga Date: Thu, 1 Sep 2022 17:22:41 +0300 Subject: [PATCH 211/374] pinctrl: at91-pio4: Bind GPIO driver to the pinctrl DT node This has been done in order to align the DT of U-Boot with the DT of Linux. In Linux, a phandle from a '-gpio' DT property is linked to the pinctrl driver, a single driver that handles both pinctrl settings and offers GPIO API to callers. On the other hand, U-Boot redirects such phandle to a corresponding UCLASS_GPIO driver, because U-Boot offers two different types of drivers in this case: UCLASS_PINCTRL which handles pin functions and UCLASS_GPIO which handles gpio requests as a gpio provider. Due to this, we have two drivers in Uboot, but the Devicetree has a single node. Thus, just one of the drivers can be probed for the DT node during platform initialization, before relocation. Our previous solution in U-Boot was to have a different devicetree: the gpio node has a subnode for the pinctrl driver, which is not compliant with Linux ABI. Furthermore, our documentation for this type of nodes mentions no such gpio compatible. After this patch, we can no longer add nodes with a gpio compatible in the DT. Thus, in order to link the pinctrl driver to the gpio one, a hook to the bind method of the former in U-Boot has been added and the GPIO related compatibles have been removed to avoid conflict when compatibles are enumerated and bound to drivers during platform start before relocation. The bind method will attach the GPIO driver to the pinctrl DT node so that every phandle coming from '-gpio' DT properties will be redirected to a valid driver attached to the pinctrl DT node. Signed-off-by: Sergiu Moga --- drivers/gpio/atmel_pio4.c | 2 - drivers/pinctrl/pinctrl-at91-pio4.c | 65 ++++++++++++++++++++++++++--- 2 files changed, 60 insertions(+), 7 deletions(-) diff --git a/drivers/gpio/atmel_pio4.c b/drivers/gpio/atmel_pio4.c index 77a76c1d50..47ed297981 100644 --- a/drivers/gpio/atmel_pio4.c +++ b/drivers/gpio/atmel_pio4.c @@ -350,10 +350,8 @@ static const struct atmel_pioctrl_data microchip_sama7g5_pioctrl_data = { static const struct udevice_id atmel_pio4_ids[] = { { - .compatible = "atmel,sama5d2-gpio", .data = (ulong)&atmel_sama5d2_pioctrl_data, }, { - .compatible = "microchip,sama7g5-gpio", .data = (ulong)µchip_sama7g5_pioctrl_data, }, {} diff --git a/drivers/pinctrl/pinctrl-at91-pio4.c b/drivers/pinctrl/pinctrl-at91-pio4.c index 26fb5d61d5..e434a38f1f 100644 --- a/drivers/pinctrl/pinctrl-at91-pio4.c +++ b/drivers/pinctrl/pinctrl-at91-pio4.c @@ -9,6 +9,8 @@ #include #include #include +#include +#include #include #include #include @@ -28,6 +30,25 @@ struct atmel_pio4_plat { unsigned int slew_rate_support; }; +/* + * Table keeping track of the pinctrl driver's slew rate support and the + * corresponding index into the struct udevice_id of the gpio_atmel_pio4 GPIO + * driver. This has been done in order to align the DT of U-Boot with the DT of + * Linux. In Linux, a phandle from a '-gpio' DT property is linked to the + * pinctrl driver, unlike U-Boot which redirects this phandle to a corresponding + * UCLASS_GPIO driver. Thus, in order to link the two, a hook to the bind method + * of the pinctrl driver in U-Boot has been added. This bind method will attach + * the GPIO driver to the pinctrl DT node using this table. + * @slew_rate_support pinctrl driver's slew rate support + * @gdidx index into the GPIO driver's struct udevide_id + * (needed in order to properly bind with driver_data) + */ + +struct atmel_pinctrl_data { + unsigned int slew_rate_support; + int gdidx; +}; + static const struct pinconf_param conf_params[] = { { "bias-disable", PIN_CONFIG_BIAS_DISABLE, 0 }, { "bias-pull-up", PIN_CONFIG_BIAS_PULL_UP, 1 }, @@ -181,24 +202,57 @@ const struct pinctrl_ops atmel_pinctrl_ops = { static int atmel_pinctrl_probe(struct udevice *dev) { struct atmel_pio4_plat *plat = dev_get_plat(dev); - ulong priv = dev_get_driver_data(dev); + struct atmel_pinctrl_data *priv = (struct atmel_pinctrl_data *)dev_get_driver_data(dev); fdt_addr_t addr_base; - dev = dev_get_parent(dev); addr_base = dev_read_addr(dev); if (addr_base == FDT_ADDR_T_NONE) return -EINVAL; plat->reg_base = (struct atmel_pio4_port *)addr_base; - plat->slew_rate_support = priv; + plat->slew_rate_support = priv->slew_rate_support; return 0; } +static int atmel_pinctrl_bind(struct udevice *dev) +{ + struct udevice *g; + struct driver *drv; + ofnode node = dev_ofnode(dev); + struct atmel_pinctrl_data *priv = (struct atmel_pinctrl_data *)dev_get_driver_data(dev); + + if (!CONFIG_IS_ENABLED(ATMEL_PIO4)) + return 0; + + /* Obtain a handle to the GPIO driver */ + drv = lists_driver_lookup_name("gpio_atmel_pio4"); + if (!drv) + return -ENOENT; + + /* + * Bind the GPIO driver to the pinctrl DT node, together + * with its corresponding driver_data. + */ + return device_bind_with_driver_data(dev, drv, drv->name, + drv->of_match[priv->gdidx].data, + node, &g); +} + +static const struct atmel_pinctrl_data atmel_sama5d2_pinctrl_data = { + .gdidx = 0, +}; + +static const struct atmel_pinctrl_data microchip_sama7g5_pinctrl_data = { + .slew_rate_support = 1, + .gdidx = 1, +}; + static const struct udevice_id atmel_pinctrl_match[] = { - { .compatible = "atmel,sama5d2-pinctrl" }, + { .compatible = "atmel,sama5d2-pinctrl", + .data = (ulong)&atmel_sama5d2_pinctrl_data, }, { .compatible = "microchip,sama7g5-pinctrl", - .data = (ulong)1, }, + .data = (ulong)µchip_sama7g5_pinctrl_data, }, {} }; @@ -206,6 +260,7 @@ U_BOOT_DRIVER(atmel_pinctrl) = { .name = "pinctrl_atmel_pio4", .id = UCLASS_PINCTRL, .of_match = atmel_pinctrl_match, + .bind = atmel_pinctrl_bind, .probe = atmel_pinctrl_probe, .plat_auto = sizeof(struct atmel_pio4_plat), .ops = &atmel_pinctrl_ops, From 7086defa048cc5303291b592192a18d69c6510cf Mon Sep 17 00:00:00 2001 From: Sergiu Moga Date: Thu, 1 Sep 2022 17:22:42 +0300 Subject: [PATCH 212/374] pinctrl: at91-pio4: Add support for pinctrl config subnodes Previously, in order for the `pinctrl-*` DT node properties to be properly processed, the pinctrl's subnodes were limited to only having the `pinmux` property as well as other additional properties (slew-rate, bias-disable, etc.). Now, with this patch the pinctrl driver is made to work similarly to the one from Linux. It can now distinguish between one subnode and a subnode with multiple subnodes. Signed-off-by: Sergiu Moga --- drivers/pinctrl/pinctrl-at91-pio4.c | 73 ++++++++++++++++++++++++----- 1 file changed, 61 insertions(+), 12 deletions(-) diff --git a/drivers/pinctrl/pinctrl-at91-pio4.c b/drivers/pinctrl/pinctrl-at91-pio4.c index e434a38f1f..50e3dd449a 100644 --- a/drivers/pinctrl/pinctrl-at91-pio4.c +++ b/drivers/pinctrl/pinctrl-at91-pio4.c @@ -15,6 +15,7 @@ #include #include #include +#include #include DECLARE_GLOBAL_DATA_PTR; @@ -151,12 +152,11 @@ static inline struct atmel_pio4_port *atmel_pio4_bank_base(struct udevice *dev, #define MAX_PINMUX_ENTRIES 40 -static int atmel_pinctrl_set_state(struct udevice *dev, struct udevice *config) +static int atmel_process_config_dev(struct udevice *dev, struct udevice *config) { struct atmel_pio4_plat *plat = dev_get_plat(dev); - struct atmel_pio4_port *bank_base; - const void *blob = gd->fdt_blob; int node = dev_of_offset(config); + struct atmel_pio4_port *bank_base; u32 offset, func, bank, line; u32 cells[MAX_PINMUX_ENTRIES]; u32 i, conf; @@ -164,18 +164,17 @@ static int atmel_pinctrl_set_state(struct udevice *dev, struct udevice *config) conf = atmel_pinctrl_get_pinconf(config, plat); - count = fdtdec_get_int_array_count(blob, node, "pinmux", + /* + * The only case where this function returns a negative error value + * is when there is no "pinmux" property attached to this node + */ + count = fdtdec_get_int_array_count(gd->fdt_blob, node, "pinmux", cells, ARRAY_SIZE(cells)); - if (count < 0) { - printf("%s: bad pinmux array %d\n", __func__, count); - return -EINVAL; - } + if (count < 0) + return count; - if (count > MAX_PINMUX_ENTRIES) { - printf("%s: unsupported pinmux array count %d\n", - __func__, count); + if (count > MAX_PINMUX_ENTRIES) return -EINVAL; - } for (i = 0 ; i < count; i++) { offset = ATMEL_GET_PIN_NO(cells[i]); @@ -195,6 +194,56 @@ static int atmel_pinctrl_set_state(struct udevice *dev, struct udevice *config) return 0; } +static int atmel_pinctrl_set_state(struct udevice *dev, struct udevice *config) +{ + int node = dev_of_offset(config); + struct udevice *subconfig; + int subnode, subnode_count = 0, ret; + + /* + * If this function returns a negative error code then that means + * that either the "pinmux" property of the node is missing, which is + * the case for pinctrl nodes that do not have all the pins with the + * same configuration and are split in multiple subnodes, or something + * else went wrong and we have to stop. For the latter case, it would + * mean that the node failed even though it has no subnodes. + */ + ret = atmel_process_config_dev(dev, config); + if (!ret) + return ret; + + /* + * If we reach here, it means that the subnode pinctrl's DT has multiple + * subnodes. If it does not, then something else went wrong in the + * previous call to atmel_process_config_dev. + */ + fdt_for_each_subnode(subnode, gd->fdt_blob, node) { + /* Get subnode as an udevice */ + ret = uclass_find_device_by_of_offset(UCLASS_PINCONFIG, subnode, + &subconfig); + if (ret) + return ret; + + /* + * If this time the function returns an error code on a subnode + * then something is totally wrong so abort. + */ + ret = atmel_process_config_dev(dev, subconfig); + if (ret) + return ret; + + subnode_count++; + } + + /* + * If we somehow got here and we do not have any subnodes, abort. + */ + if (!subnode_count) + return -EINVAL; + + return 0; +} + const struct pinctrl_ops atmel_pinctrl_ops = { .set_state = atmel_pinctrl_set_state, }; From d285e4b0807a63330b57cd6c97ffd66122f046a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Wed, 14 Sep 2022 15:06:14 +0200 Subject: [PATCH 213/374] Makefile: Add missing CONFIG_BOARD_SIZE_LIMIT check for u-boot-spl.kwb MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently CONFIG_BOARD_SIZE_LIMIT check is ignored for u-boot-spl.kwb target. Fix it by adding missing $(BOARD_SIZE_CHECK) macro. Signed-off-by: Pali Rohár Reviewed-by: Marek Behún Reviewed-by: Stefan Roese --- Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile b/Makefile index b421296da2..c80b32198d 100644 --- a/Makefile +++ b/Makefile @@ -1474,6 +1474,7 @@ endif u-boot-spl.kwb: u-boot.bin spl/u-boot-spl.bin FORCE $(call if_changed,mkimage) + $(BOARD_SIZE_CHECK) u-boot.sha1: u-boot.bin tools/ubsha1 u-boot.bin From 5138c8fa5626d097cd6d136b14bdef06652effd9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Wed, 14 Sep 2022 15:06:46 +0200 Subject: [PATCH 214/374] arm: mvebu: turris_omnia: Add CONFIG_BOARD_SIZE_LIMIT MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Maximal size of u-boot kwb image binary is $CONFIG_ENV_OFFSET which is 0xF0000 = 983040 bytes. So add missing CONFIG_BOARD_SIZE_LIMIT definition to ensure that u-boot binary does not overflow to the u-boot env storage. Signed-off-by: Pali Rohár Reviewed-by: Marek Behún Reviewed-by: Stefan Roese --- configs/turris_omnia_defconfig | 2 ++ 1 file changed, 2 insertions(+) diff --git a/configs/turris_omnia_defconfig b/configs/turris_omnia_defconfig index ba635feb44..6698f23135 100644 --- a/configs/turris_omnia_defconfig +++ b/configs/turris_omnia_defconfig @@ -28,6 +28,8 @@ CONFIG_SYS_MEMTEST_END=0x00ffffff CONFIG_DISTRO_DEFAULTS=y CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0xff0000 +CONFIG_HAS_BOARD_SIZE_LIMIT=y +CONFIG_BOARD_SIZE_LIMIT=983040 CONFIG_FIT=y CONFIG_FIT_VERBOSE=y CONFIG_OF_BOARD_SETUP=y From 4a08c26647cf1f5aeaf4cc573020d976d19f810a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Wed, 14 Sep 2022 18:48:16 +0200 Subject: [PATCH 215/374] arm: mvebu: Add default SPL_SIZE_LIMIT for 32-bit SoCs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 32-bit Marvell Armada BootROMs limit maximal size of SPL image to 192 kB. So define 192 kB (= 0x30000) limit as default value for SPL_SIZE_LIMIT. Signed-off-by: Pali Rohár Reviewed-by: Marek Behún Reviewed-by: Stefan Roese --- common/spl/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/common/spl/Kconfig b/common/spl/Kconfig index e1b2a421cd..f2422d28f9 100644 --- a/common/spl/Kconfig +++ b/common/spl/Kconfig @@ -40,6 +40,7 @@ config SPL_SIZE_LIMIT hex "Maximum size of SPL image" default 0x11000 if ARCH_MX6 && !MX6_OCRAM_256KB default 0x31000 if ARCH_MX6 && MX6_OCRAM_256KB + default 0x30000 if ARCH_MVEBU && ARMADA_32BIT default 0x0 help Specifies the maximum length of the U-Boot SPL image. From c686d35b4377a7cd47f0bf27308908cfdeb6bec3 Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Thu, 15 Sep 2022 15:21:21 +0200 Subject: [PATCH 216/374] arm: mvebu: theadorable: Misc defconfig changes - Remove EFI support as it's not used on this board - Disable CONFIG_FIT_PRINT to reduce the serial output (minimal speedup) Signed-off-by: Stefan Roese --- configs/theadorable_debug_defconfig | 3 +++ 1 file changed, 3 insertions(+) diff --git a/configs/theadorable_debug_defconfig b/configs/theadorable_debug_defconfig index 9074ca1620..3d84bf9d57 100644 --- a/configs/theadorable_debug_defconfig +++ b/configs/theadorable_debug_defconfig @@ -22,6 +22,7 @@ CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0xff0000 # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set CONFIG_FIT=y +# CONFIG_FIT_PRINT is not set CONFIG_BOOTDELAY=3 CONFIG_USE_PREBOOT=y # CONFIG_CONSOLE_MUX is not set @@ -98,3 +99,5 @@ CONFIG_VIDEO_MVEBU=y CONFIG_BMP_16BPP=y CONFIG_BMP_24BPP=y CONFIG_BMP_32BPP=y +CONFIG_FAT_WRITE=y +# CONFIG_EFI_LOADER is not set From 50e4d8511df61b57e6ed7f7043b157229bc71375 Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Thu, 15 Sep 2022 15:21:22 +0200 Subject: [PATCH 217/374] arm: mvebu: theadorable: Update eth & mdio DT nodes With the recent changes in the Marvel mvneta network driver, the MDIO bus is not connected any more. This patch updates the DT nodes to use the nodes from the dtsi files instead of creating ad-hoc nodes. Signed-off-by: Stefan Roese --- arch/arm/dts/armada-xp-theadorable.dts | 27 ++++++++++++-------------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/arch/arm/dts/armada-xp-theadorable.dts b/arch/arm/dts/armada-xp-theadorable.dts index ba73386d4f..7d833640b6 100644 --- a/arch/arm/dts/armada-xp-theadorable.dts +++ b/arch/arm/dts/armada-xp-theadorable.dts @@ -107,20 +107,6 @@ status = "okay"; }; - mdio { - #address-cells = <1>; - #size-cells = <0>; - phy0: ethernet-phy@0 { - reg = <0>; - }; - }; - - ethernet@70000 { - status = "okay"; - phy = <&phy0>; - phy-mode = "sgmii"; - }; - usb@50000 { status = "okay"; }; @@ -166,6 +152,18 @@ clock-frequency = <100000>; }; +&mdio { + phy0: ethernet-phy@0 { + reg = <0>; + }; +}; + +ð0 { + status = "okay"; + phy = <&phy0>; + phy-mode = "sgmii"; +}; + &spi0 { status = "okay"; @@ -198,7 +196,6 @@ }; }; - &pciec { status = "okay"; From 89fd0cccf9cff1537567b63eaa7a33110bd43a2c Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Thu, 15 Sep 2022 16:20:37 +0200 Subject: [PATCH 218/374] timer: orion-timer: Add support for other Armada SoC's This patch adds support for other Marvell Armada SoC's, supporting the 25MHz fixed clock operation, like the Armada XP etc. Signed-off-by: Stefan Roese Tested-by: Tony Dinh --- drivers/timer/Kconfig | 5 ++++- drivers/timer/orion-timer.c | 42 ++++++++++++++++++++++++++++++++++--- 2 files changed, 43 insertions(+), 4 deletions(-) diff --git a/drivers/timer/Kconfig b/drivers/timer/Kconfig index 1b49236039..fd8745ffc2 100644 --- a/drivers/timer/Kconfig +++ b/drivers/timer/Kconfig @@ -203,8 +203,11 @@ config OMAP_TIMER config ORION_TIMER bool "Orion timer support" depends on TIMER + default y if ARCH_KIRKWOOD || (ARCH_MVEBU && ARMADA_32BIT) + select TIMER_EARLY if ARCH_MVEBU help - Select this to enable an timer for Orion devices. + Select this to enable an timer for Orion and Armada devices + like Armada XP etc. config RISCV_TIMER bool "RISC-V timer support" diff --git a/drivers/timer/orion-timer.c b/drivers/timer/orion-timer.c index d7d1a1b244..14f318e57d 100644 --- a/drivers/timer/orion-timer.c +++ b/drivers/timer/orion-timer.c @@ -11,10 +11,34 @@ #define TIMER0_RELOAD 0x10 #define TIMER0_VAL 0x14 +enum input_clock_type { + INPUT_CLOCK_NON_FIXED, + INPUT_CLOCK_25MHZ, /* input clock rate is fixed to 25MHz */ +}; + struct orion_timer_priv { void *base; }; +#define MVEBU_TIMER_FIXED_RATE_25MHZ 25000000 + +/** + * timer_early_get_rate() - Get the timer rate before driver model + */ +unsigned long notrace timer_early_get_rate(void) +{ + return MVEBU_TIMER_FIXED_RATE_25MHZ; +} + +/** + * timer_early_get_count() - Get the timer count before driver model + * + */ +u64 notrace timer_early_get_count(void) +{ + return timer_conv_64(~readl(MVEBU_TIMER_BASE + TIMER0_VAL)); +} + static uint64_t orion_timer_get_count(struct udevice *dev) { struct orion_timer_priv *priv = dev_get_priv(dev); @@ -25,6 +49,7 @@ static uint64_t orion_timer_get_count(struct udevice *dev) static int orion_timer_probe(struct udevice *dev) { struct timer_dev_priv *uc_priv = dev_get_uclass_priv(dev); + enum input_clock_type type = dev_get_driver_data(dev); struct orion_timer_priv *priv = dev_get_priv(dev); priv->base = devfdt_remap_addr_index(dev, 0); @@ -33,11 +58,20 @@ static int orion_timer_probe(struct udevice *dev) return -ENOMEM; } - uc_priv->clock_rate = CONFIG_SYS_TCLK; - writel(~0, priv->base + TIMER0_VAL); writel(~0, priv->base + TIMER0_RELOAD); + if (type == INPUT_CLOCK_25MHZ) { + /* + * On Armada XP / 38x ..., the 25MHz clock source needs to + * be enabled + */ + setbits_le32(priv->base + TIMER_CTRL, BIT(11)); + uc_priv->clock_rate = MVEBU_TIMER_FIXED_RATE_25MHZ; + } else { + uc_priv->clock_rate = CONFIG_SYS_TCLK; + } + /* enable timer */ setbits_le32(priv->base + TIMER_CTRL, TIMER0_EN | TIMER0_RELOAD_EN); @@ -49,7 +83,9 @@ static const struct timer_ops orion_timer_ops = { }; static const struct udevice_id orion_timer_ids[] = { - { .compatible = "marvell,orion-timer" }, + { .compatible = "marvell,orion-timer", .data = INPUT_CLOCK_NON_FIXED }, + { .compatible = "marvell,armada-370-timer", .data = INPUT_CLOCK_25MHZ }, + { .compatible = "marvell,armada-xp-timer", .data = INPUT_CLOCK_25MHZ }, {} }; From a68f13a3b6b4995ba5d0ad929eb9b79dc2a0a8c3 Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Thu, 15 Sep 2022 16:20:38 +0200 Subject: [PATCH 219/374] timer: orion-timer: Add timer_get_boot_us() for BOOTSTAGE support Add timer_get_boot_us() to support boards, that have CONFIG_BOOTSTAGE enabled, like pogo_v4. Signed-off-by: Stefan Roese Tested-by: Tony Dinh --- drivers/timer/orion-timer.c | 83 ++++++++++++++++++++++++++++--------- 1 file changed, 64 insertions(+), 19 deletions(-) diff --git a/drivers/timer/orion-timer.c b/drivers/timer/orion-timer.c index 14f318e57d..cd63ea9162 100644 --- a/drivers/timer/orion-timer.c +++ b/drivers/timer/orion-timer.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0+ #include #include +#include #include #include #include @@ -22,12 +23,56 @@ struct orion_timer_priv { #define MVEBU_TIMER_FIXED_RATE_25MHZ 25000000 +static bool early_init_done __section(".data") = false; + +/* Common functions for early (boot) and DM based timer */ +static void orion_timer_init(void *base, enum input_clock_type type) +{ + writel(~0, base + TIMER0_VAL); + writel(~0, base + TIMER0_RELOAD); + + if (type == INPUT_CLOCK_25MHZ) { + /* + * On Armada XP / 38x ..., the 25MHz clock source needs to + * be enabled + */ + setbits_le32(base + TIMER_CTRL, BIT(11)); + } + + /* enable timer */ + setbits_le32(base + TIMER_CTRL, TIMER0_EN | TIMER0_RELOAD_EN); +} + +static uint64_t orion_timer_get_count(void *base) +{ + return timer_conv_64(~readl(base + TIMER0_VAL)); +} + +/* Early (e.g. bootstage etc) timer functions */ +static void notrace timer_early_init(void) +{ + /* Only init the timer once */ + if (early_init_done) + return; + early_init_done = true; + + if (IS_ENABLED(CONFIG_ARCH_MVEBU)) + orion_timer_init((void *)MVEBU_TIMER_BASE, INPUT_CLOCK_25MHZ); + else + orion_timer_init((void *)MVEBU_TIMER_BASE, INPUT_CLOCK_NON_FIXED); +} + /** * timer_early_get_rate() - Get the timer rate before driver model */ unsigned long notrace timer_early_get_rate(void) { - return MVEBU_TIMER_FIXED_RATE_25MHZ; + timer_early_init(); + + if (IS_ENABLED(CONFIG_ARCH_MVEBU)) + return MVEBU_TIMER_FIXED_RATE_25MHZ; + else + return CONFIG_SYS_TCLK; } /** @@ -36,14 +81,25 @@ unsigned long notrace timer_early_get_rate(void) */ u64 notrace timer_early_get_count(void) { - return timer_conv_64(~readl(MVEBU_TIMER_BASE + TIMER0_VAL)); + timer_early_init(); + + return orion_timer_get_count((void *)MVEBU_TIMER_BASE); } -static uint64_t orion_timer_get_count(struct udevice *dev) +ulong timer_get_boot_us(void) +{ + u64 ticks; + + ticks = timer_early_get_count(); + return lldiv(ticks * 1000, timer_early_get_rate()); +} + +/* DM timer functions */ +static uint64_t dm_orion_timer_get_count(struct udevice *dev) { struct orion_timer_priv *priv = dev_get_priv(dev); - return timer_conv_64(~readl(priv->base + TIMER0_VAL)); + return orion_timer_get_count(priv->base); } static int orion_timer_probe(struct udevice *dev) @@ -58,28 +114,17 @@ static int orion_timer_probe(struct udevice *dev) return -ENOMEM; } - writel(~0, priv->base + TIMER0_VAL); - writel(~0, priv->base + TIMER0_RELOAD); - - if (type == INPUT_CLOCK_25MHZ) { - /* - * On Armada XP / 38x ..., the 25MHz clock source needs to - * be enabled - */ - setbits_le32(priv->base + TIMER_CTRL, BIT(11)); + if (type == INPUT_CLOCK_25MHZ) uc_priv->clock_rate = MVEBU_TIMER_FIXED_RATE_25MHZ; - } else { + else uc_priv->clock_rate = CONFIG_SYS_TCLK; - } - - /* enable timer */ - setbits_le32(priv->base + TIMER_CTRL, TIMER0_EN | TIMER0_RELOAD_EN); + orion_timer_init(priv->base, type); return 0; } static const struct timer_ops orion_timer_ops = { - .get_count = orion_timer_get_count, + .get_count = dm_orion_timer_get_count, }; static const struct udevice_id orion_timer_ids[] = { From 7b530bb19e367107113c523c541a4c79235b7e01 Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Thu, 15 Sep 2022 16:20:39 +0200 Subject: [PATCH 220/374] arm: mvebu: Use CONFIG_TIMER on all MVEBU & KIRKWOOD platforms Now that the new timer support is available for these platforms, let's select this IF for all these platforms. This way it's not necessary that each board changes it's config header. Signed-off-by: Stefan Roese Tested-by: Tony Dinh --- arch/arm/Kconfig | 4 ++++ arch/arm/mach-mvebu/include/mach/config.h | 5 ----- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index f3a3c0f9a9..9a6c2e8101 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -627,6 +627,7 @@ config ARCH_KIRKWOOD select BOARD_EARLY_INIT_F select CPU_ARM926EJS select GPIO_EXTRA_HEADER + select TIMER config ARCH_MVEBU bool "Marvell MVEBU family (Armada XP/375/38x/3700/7K/8K)" @@ -638,6 +639,8 @@ config ARCH_MVEBU select GPIO_EXTRA_HEADER select SPL_DM_SPI if SPL select SPL_DM_SPI_FLASH if SPL + select SPL_TIMER if SPL + select TIMER select OF_CONTROL select OF_SEPARATE select SPI @@ -648,6 +651,7 @@ config ARCH_ORION5X select CPU_ARM926EJS select GPIO_EXTRA_HEADER select SPL_SEPARATE_BSS if SPL + select TIMER config TARGET_STV0991 bool "Support stv0991" diff --git a/arch/arm/mach-mvebu/include/mach/config.h b/arch/arm/mach-mvebu/include/mach/config.h index 0bba0a4cf9..2e06f2bdae 100644 --- a/arch/arm/mach-mvebu/include/mach/config.h +++ b/arch/arm/mach-mvebu/include/mach/config.h @@ -39,9 +39,4 @@ #endif #endif -/* Use common timer */ -#define CONFIG_SYS_TIMER_COUNTS_DOWN -#define CONFIG_SYS_TIMER_COUNTER (MVEBU_TIMER_BASE + 0x14) -#define CONFIG_SYS_TIMER_RATE 25000000 - #endif /* __MVEBU_CONFIG_H */ From 0cc5d2321f64d9ca08f3079051f217eb0ffeb9d3 Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Thu, 15 Sep 2022 16:20:40 +0200 Subject: [PATCH 221/374] arm: mvebu: dts: Makefile: Compile Armada 375 dtb in a separate step This patch changes the compilation, so that the Armada 375 board(s) are compiled in a separate step. This is necessary for the timer dts conversion, as A375 has a different / timer description in the dts. Signed-off-by: Stefan Roese Tested-by: Tony Dinh --- arch/arm/dts/Makefile | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index 7c40714450..5a42d5061c 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -233,8 +233,11 @@ dtb-$(CONFIG_ARCH_TEGRA) += tegra20-harmony.dtb \ tegra210-p3450-0000.dtb ifdef CONFIG_ARMADA_32BIT +ifdef CONFIG_ARMADA_375 +dtb-$(CONFIG_ARCH_MVEBU) += \ + armada-375-db.dtb +else dtb-$(CONFIG_ARCH_MVEBU) += \ - armada-375-db.dtb \ armada-385-atl-x530.dtb \ armada-385-atl-x530DP.dtb \ armada-385-db-88f6820-amc.dtb \ @@ -254,6 +257,7 @@ dtb-$(CONFIG_ARCH_MVEBU) += \ armada-xp-maxbcm.dtb \ armada-xp-synology-ds414.dtb \ armada-xp-theadorable.dtb +endif else dtb-$(CONFIG_ARCH_MVEBU) += \ armada-3720-db.dtb \ From d06ba5cc71ef63233d3dee348a4cdc07d19fe807 Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Thu, 15 Sep 2022 16:20:41 +0200 Subject: [PATCH 222/374] arm: mvebu: dts: armada-375.dtsi: Add timer0 & timer1 Add the DT bindings / descriptions for timer0 & timer1, exactly as done in mainline Linux. Signed-off-by: Stefan Roese Tested-by: Tony Dinh --- arch/arm/dts/armada-375.dtsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/dts/armada-375.dtsi b/arch/arm/dts/armada-375.dtsi index 20a8c352b2..a044b3fc99 100644 --- a/arch/arm/dts/armada-375.dtsi +++ b/arch/arm/dts/armada-375.dtsi @@ -187,7 +187,7 @@ reg = <0xc000 0x58>; }; - timer@c600 { + timer0: timer@c600 { compatible = "arm,cortex-a9-twd-timer"; reg = <0xc600 0x20>; interrupts = ; @@ -416,7 +416,7 @@ interrupts = ; }; - timer@20300 { + timer1: timer@20300 { compatible = "marvell,armada-375-timer", "marvell,armada-370-timer"; reg = <0x20300 0x30>, <0x21040 0x30>; interrupts-extended = <&gic GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>, From b81db4bfdd886b06d980eed8d6c2302682ad3507 Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Thu, 15 Sep 2022 16:20:42 +0200 Subject: [PATCH 223/374] arm: mvebu: dts: mvebu-u-boot.dtsi: Add "u-boot, dm-pre-reloc" to timer DT node Adding the "u-boot,dm-pre-reloc" DT property to the timer node is necesssary to support the timer in the early boot phases (e.g. SPL & pre-reloc). Signed-off-by: Stefan Roese Tested-by: Tony Dinh --- arch/arm/dts/mvebu-u-boot.dtsi | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/arch/arm/dts/mvebu-u-boot.dtsi b/arch/arm/dts/mvebu-u-boot.dtsi index 5538f95148..db4bf39920 100644 --- a/arch/arm/dts/mvebu-u-boot.dtsi +++ b/arch/arm/dts/mvebu-u-boot.dtsi @@ -15,6 +15,17 @@ u-boot,dm-pre-reloc; }; +#ifdef CONFIG_ARMADA_375 +/* Armada 375 has multiple timers, use timer1 here */ +&timer1 { + u-boot,dm-pre-reloc; +}; +#else +&timer { + u-boot,dm-pre-reloc; +}; +#endif + #ifdef CONFIG_SPL_SPI &spi0 { u-boot,dm-pre-reloc; From 7a6102a6133a1f7a368c91626bb1707bed2bac45 Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Thu, 15 Sep 2022 16:20:43 +0200 Subject: [PATCH 224/374] kirkwood: lsxl: Sync defconfigs With the recent changes in the Orion timer driver Kconfig setup, the board specific enabling is not needed any more. This patch sync's these 2 boards with their current defconfig version. Signed-off-by: Stefan Roese Cc: Michael Walle Tested-by: Tony Dinh --- configs/lschlv2_defconfig | 2 -- configs/lsxhl_defconfig | 2 -- 2 files changed, 4 deletions(-) diff --git a/configs/lschlv2_defconfig b/configs/lschlv2_defconfig index cfccfdcfc4..441cd8ef24 100644 --- a/configs/lschlv2_defconfig +++ b/configs/lschlv2_defconfig @@ -70,7 +70,5 @@ CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_DM_SPI=y CONFIG_KIRKWOOD_SPI=y -CONFIG_TIMER=y -CONFIG_ORION_TIMER=y CONFIG_USB=y CONFIG_USB_EHCI_HCD=y diff --git a/configs/lsxhl_defconfig b/configs/lsxhl_defconfig index 1945b72450..f350f8ff42 100644 --- a/configs/lsxhl_defconfig +++ b/configs/lsxhl_defconfig @@ -71,7 +71,5 @@ CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_DM_SPI=y CONFIG_KIRKWOOD_SPI=y -CONFIG_TIMER=y -CONFIG_ORION_TIMER=y CONFIG_USB=y CONFIG_USB_EHCI_HCD=y From 0fb7fd865b1ac0ab4c0546f53484530d866a030b Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Mon, 19 Sep 2022 10:16:53 +0200 Subject: [PATCH 225/374] xilinx: versal: Remove unused comments from xilinx_versal.h Couple of options have been moved to Kconfig but comments stayed in header that's why remove them. Signed-off-by: Michal Simek Link: https://lore.kernel.org/r/ffaee826dcb6853825ac72db91bb3a682c42297d.1663575411.git.michal.simek@amd.com --- include/configs/xilinx_versal.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/include/configs/xilinx_versal.h b/include/configs/xilinx_versal.h index 971bd69dec..8caf5394ed 100644 --- a/include/configs/xilinx_versal.h +++ b/include/configs/xilinx_versal.h @@ -23,10 +23,6 @@ EFI_GUID(0x20c5fba5, 0x0171, 0x457f, 0xb9, 0xcd, \ 0xf5, 0x12, 0x9c, 0xd0, 0x72, 0x28) -/* Miscellaneous configurable options */ - -/* Console I/O Buffer Size */ - #if defined(CONFIG_CMD_DFU) #define DFU_DEFAULT_POLL_TIMEOUT 300 #define CONFIG_THOR_RESET_OFF From 13622c7a9dfabb2dd07e8c125243f47540673ba9 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Fri, 9 Sep 2022 13:05:48 +0200 Subject: [PATCH 226/374] arm64: zynqmp: Describe TI phy as ethernet-phy-id TI DP83867 is using strapping based on MIO pins. Tristate setup can influce PHY address. That's why switch description with ethernet-phy-id compatible string which enable calling reset. PHY itself setups phy address after power up or reset. Reset description will be added in separate commit. Signed-off-by: Michal Simek Link: https://lore.kernel.org/r/52bf9ac0453d4e4896d8edd2618e684bb1ff6012.1662721547.git.michal.simek@amd.com --- arch/arm/dts/zynqmp-zcu102-revA.dts | 20 +++++++++++++------- arch/arm/dts/zynqmp-zcu104-revA.dts | 18 ++++++++++++------ arch/arm/dts/zynqmp-zcu104-revC.dts | 18 ++++++++++++------ arch/arm/dts/zynqmp-zcu111-revA.dts | 18 ++++++++++++------ arch/arm/dts/zynqmp-zcu208-revA.dts | 18 ++++++++++++------ arch/arm/dts/zynqmp-zcu216-revA.dts | 19 ++++++++++++------- 6 files changed, 73 insertions(+), 38 deletions(-) diff --git a/arch/arm/dts/zynqmp-zcu102-revA.dts b/arch/arm/dts/zynqmp-zcu102-revA.dts index a4e92c8bb1..8d8f495714 100644 --- a/arch/arm/dts/zynqmp-zcu102-revA.dts +++ b/arch/arm/dts/zynqmp-zcu102-revA.dts @@ -200,13 +200,19 @@ phy-mode = "rgmii-id"; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_gem3_default>; - phy0: ethernet-phy@21 { - reg = <21>; - ti,rx-internal-delay = <0x8>; - ti,tx-internal-delay = <0xa>; - ti,fifo-depth = <0x1>; - ti,dp83867-rxctrl-strap-quirk; - /* reset-gpios = <&tca6416_u97 6 GPIO_ACTIVE_LOW>; */ + mdio: mdio { + #address-cells = <1>; + #size-cells = <0>; + phy0: ethernet-phy@21 { + #phy-cells = <1>; + compatible = "ethernet-phy-id2000.a231"; + reg = <21>; + ti,rx-internal-delay = <0x8>; + ti,tx-internal-delay = <0xa>; + ti,fifo-depth = <0x1>; + ti,dp83867-rxctrl-strap-quirk; + /* reset-gpios = <&tca6416_u97 6 GPIO_ACTIVE_LOW>; */ + }; }; }; diff --git a/arch/arm/dts/zynqmp-zcu104-revA.dts b/arch/arm/dts/zynqmp-zcu104-revA.dts index 1418cffb20..6df9a13438 100644 --- a/arch/arm/dts/zynqmp-zcu104-revA.dts +++ b/arch/arm/dts/zynqmp-zcu104-revA.dts @@ -109,12 +109,18 @@ phy-mode = "rgmii-id"; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_gem3_default>; - phy0: ethernet-phy@c { - reg = <0xc>; - ti,rx-internal-delay = <0x8>; - ti,tx-internal-delay = <0xa>; - ti,fifo-depth = <0x1>; - ti,dp83867-rxctrl-strap-quirk; + mdio: mdio { + #address-cells = <1>; + #size-cells = <0>; + phy0: ethernet-phy@c { + #phy-cells = <1>; + compatible = "ethernet-phy-id2000.a231"; + reg = <0xc>; + ti,rx-internal-delay = <0x8>; + ti,tx-internal-delay = <0xa>; + ti,fifo-depth = <0x1>; + ti,dp83867-rxctrl-strap-quirk; + }; }; }; diff --git a/arch/arm/dts/zynqmp-zcu104-revC.dts b/arch/arm/dts/zynqmp-zcu104-revC.dts index 7fd19ca3a8..0721516bd1 100644 --- a/arch/arm/dts/zynqmp-zcu104-revC.dts +++ b/arch/arm/dts/zynqmp-zcu104-revC.dts @@ -114,12 +114,18 @@ phy-mode = "rgmii-id"; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_gem3_default>; - phy0: ethernet-phy@c { - reg = <0xc>; - ti,rx-internal-delay = <0x8>; - ti,tx-internal-delay = <0xa>; - ti,fifo-depth = <0x1>; - ti,dp83867-rxctrl-strap-quirk; + mdio: mdio { + #address-cells = <1>; + #size-cells = <0>; + phy0: ethernet-phy@c { + #phy-cells = <1>; + compatible = "ethernet-phy-id2000.a231"; + reg = <0xc>; + ti,rx-internal-delay = <0x8>; + ti,tx-internal-delay = <0xa>; + ti,fifo-depth = <0x1>; + ti,dp83867-rxctrl-strap-quirk; + }; }; }; diff --git a/arch/arm/dts/zynqmp-zcu111-revA.dts b/arch/arm/dts/zynqmp-zcu111-revA.dts index e412992ff1..c37c4b8b61 100644 --- a/arch/arm/dts/zynqmp-zcu111-revA.dts +++ b/arch/arm/dts/zynqmp-zcu111-revA.dts @@ -172,12 +172,18 @@ phy-mode = "rgmii-id"; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_gem3_default>; - phy0: ethernet-phy@c { - reg = <0xc>; - ti,rx-internal-delay = <0x8>; - ti,tx-internal-delay = <0xa>; - ti,fifo-depth = <0x1>; - ti,dp83867-rxctrl-strap-quirk; + mdio: mdio { + #address-cells = <1>; + #size-cells = <0>; + phy0: ethernet-phy@c { + #phy-cells = <1>; + compatible = "ethernet-phy-id2000.a231"; + reg = <0xc>; + ti,rx-internal-delay = <0x8>; + ti,tx-internal-delay = <0xa>; + ti,fifo-depth = <0x1>; + ti,dp83867-rxctrl-strap-quirk; + }; }; }; diff --git a/arch/arm/dts/zynqmp-zcu208-revA.dts b/arch/arm/dts/zynqmp-zcu208-revA.dts index c5cdd58af6..3e8ee429eb 100644 --- a/arch/arm/dts/zynqmp-zcu208-revA.dts +++ b/arch/arm/dts/zynqmp-zcu208-revA.dts @@ -169,12 +169,18 @@ status = "okay"; phy-handle = <&phy0>; phy-mode = "rgmii-id"; - phy0: ethernet-phy@c { - reg = <0xc>; - ti,rx-internal-delay = <0x8>; - ti,tx-internal-delay = <0xa>; - ti,fifo-depth = <0x1>; - ti,dp83867-rxctrl-strap-quirk; + mdio: mdio { + #address-cells = <1>; + #size-cells = <0>; + phy0: ethernet-phy@c { + #phy-cells = <1>; + compatible = "ethernet-phy-id2000.a231"; + reg = <0xc>; + ti,rx-internal-delay = <0x8>; + ti,tx-internal-delay = <0xa>; + ti,fifo-depth = <0x1>; + ti,dp83867-rxctrl-strap-quirk; + }; }; }; diff --git a/arch/arm/dts/zynqmp-zcu216-revA.dts b/arch/arm/dts/zynqmp-zcu216-revA.dts index caae16965d..80e7ddb970 100644 --- a/arch/arm/dts/zynqmp-zcu216-revA.dts +++ b/arch/arm/dts/zynqmp-zcu216-revA.dts @@ -176,15 +176,20 @@ status = "okay"; phy-handle = <&phy0>; phy-mode = "rgmii-id"; - phy0: ethernet-phy@c { - reg = <0xc>; - ti,rx-internal-delay = <0x8>; - ti,tx-internal-delay = <0xa>; - ti,fifo-depth = <0x1>; - ti,dp83867-rxctrl-strap-quirk; + mdio: mdio { + #address-cells = <1>; + #size-cells = <0>; + phy0: ethernet-phy@c { + #phy-cells = <1>; + compatible = "ethernet-phy-id2000.a231"; + reg = <0xc>; + ti,rx-internal-delay = <0x8>; + ti,tx-internal-delay = <0xa>; + ti,fifo-depth = <0x1>; + ti,dp83867-rxctrl-strap-quirk; + }; }; }; - &gpio { status = "okay"; gpio-line-names = "QSPI_LWR_CLK", "QSPI_LWR_DQ1", "QSPI_LWR_DQ2", "QSPI_LWR_DQ3", "QSPI_LWR_DQ0", /* 0 - 4 */ From 2b1db7b18c97432d496f586311511ae230bed0d2 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Fri, 9 Sep 2022 13:05:49 +0200 Subject: [PATCH 227/374] arm64: zynqmp: Wire GEM reset gpio With ethernet-phy-id driver ETH phy reset can be properly handle that's why describe it in DT. Signed-off-by: Michal Simek Link: https://lore.kernel.org/r/5bfd92827033d19617113f4117f37dcf79699a0f.1662721547.git.michal.simek@amd.com --- arch/arm/dts/zynqmp-zcu102-revA.dts | 2 +- arch/arm/dts/zynqmp-zcu104-revA.dts | 1 + arch/arm/dts/zynqmp-zcu104-revC.dts | 1 + arch/arm/dts/zynqmp-zcu111-revA.dts | 1 + arch/arm/dts/zynqmp-zcu208-revA.dts | 1 + arch/arm/dts/zynqmp-zcu216-revA.dts | 1 + 6 files changed, 6 insertions(+), 1 deletion(-) diff --git a/arch/arm/dts/zynqmp-zcu102-revA.dts b/arch/arm/dts/zynqmp-zcu102-revA.dts index 8d8f495714..9d8e551ed2 100644 --- a/arch/arm/dts/zynqmp-zcu102-revA.dts +++ b/arch/arm/dts/zynqmp-zcu102-revA.dts @@ -211,7 +211,7 @@ ti,tx-internal-delay = <0xa>; ti,fifo-depth = <0x1>; ti,dp83867-rxctrl-strap-quirk; - /* reset-gpios = <&tca6416_u97 6 GPIO_ACTIVE_LOW>; */ + reset-gpios = <&tca6416_u97 6 GPIO_ACTIVE_LOW>; }; }; }; diff --git a/arch/arm/dts/zynqmp-zcu104-revA.dts b/arch/arm/dts/zynqmp-zcu104-revA.dts index 6df9a13438..b9d82afc51 100644 --- a/arch/arm/dts/zynqmp-zcu104-revA.dts +++ b/arch/arm/dts/zynqmp-zcu104-revA.dts @@ -120,6 +120,7 @@ ti,tx-internal-delay = <0xa>; ti,fifo-depth = <0x1>; ti,dp83867-rxctrl-strap-quirk; + reset-gpios = <&tca6416_u97 6 GPIO_ACTIVE_LOW>; }; }; }; diff --git a/arch/arm/dts/zynqmp-zcu104-revC.dts b/arch/arm/dts/zynqmp-zcu104-revC.dts index 0721516bd1..6f24e335a1 100644 --- a/arch/arm/dts/zynqmp-zcu104-revC.dts +++ b/arch/arm/dts/zynqmp-zcu104-revC.dts @@ -125,6 +125,7 @@ ti,tx-internal-delay = <0xa>; ti,fifo-depth = <0x1>; ti,dp83867-rxctrl-strap-quirk; + reset-gpios = <&tca6416_u97 6 GPIO_ACTIVE_LOW>; }; }; }; diff --git a/arch/arm/dts/zynqmp-zcu111-revA.dts b/arch/arm/dts/zynqmp-zcu111-revA.dts index c37c4b8b61..2e95f22c3f 100644 --- a/arch/arm/dts/zynqmp-zcu111-revA.dts +++ b/arch/arm/dts/zynqmp-zcu111-revA.dts @@ -183,6 +183,7 @@ ti,tx-internal-delay = <0xa>; ti,fifo-depth = <0x1>; ti,dp83867-rxctrl-strap-quirk; + reset-gpios = <&tca6416_u22 6 GPIO_ACTIVE_LOW>; }; }; }; diff --git a/arch/arm/dts/zynqmp-zcu208-revA.dts b/arch/arm/dts/zynqmp-zcu208-revA.dts index 3e8ee429eb..7e7e1577eb 100644 --- a/arch/arm/dts/zynqmp-zcu208-revA.dts +++ b/arch/arm/dts/zynqmp-zcu208-revA.dts @@ -180,6 +180,7 @@ ti,tx-internal-delay = <0xa>; ti,fifo-depth = <0x1>; ti,dp83867-rxctrl-strap-quirk; + reset-gpios = <&tca6416_u15 6 GPIO_ACTIVE_LOW>; }; }; }; diff --git a/arch/arm/dts/zynqmp-zcu216-revA.dts b/arch/arm/dts/zynqmp-zcu216-revA.dts index 80e7ddb970..35a30971cb 100644 --- a/arch/arm/dts/zynqmp-zcu216-revA.dts +++ b/arch/arm/dts/zynqmp-zcu216-revA.dts @@ -187,6 +187,7 @@ ti,tx-internal-delay = <0xa>; ti,fifo-depth = <0x1>; ti,dp83867-rxctrl-strap-quirk; + reset-gpios = <&tca6416_u15 6 GPIO_ACTIVE_LOW>; }; }; }; From 4d7df7f7666a2bc6b0b8980969b69c8008b90af6 Mon Sep 17 00:00:00 2001 From: Patrick Delaunay Date: Tue, 6 Sep 2022 18:53:17 +0200 Subject: [PATCH 228/374] stm32mp: stm32prog: support empty flashlayout When the STM32CubeProgrammer sent a empty flashlayout.tsv file, the command stm32prog correctly parse the file but data->dev_nb = 0 and the stm32prog_devices_init operations should be skipped. Signed-off-by: Patrick Delaunay Reviewed-by: Patrice Chotard --- arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c index a720d0ba71..7067605d49 100644 --- a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c +++ b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c @@ -1884,6 +1884,10 @@ static void stm32prog_devices_init(struct stm32prog_data *data) if (ret) goto error; + /* empty flashlayout */ + if (!data->dev_nb) + return; + /* initialize the selected device */ for (i = 0; i < data->dev_nb; i++) { ret = init_device(data, &data->dev[i]); From ada8fe0c42da5341989bdf1c11d4adb23f7aae37 Mon Sep 17 00:00:00 2001 From: Patrick Delaunay Date: Tue, 6 Sep 2022 18:53:18 +0200 Subject: [PATCH 229/374] stm32mp: stm32prog: change default flashlayout location to CONFIG_SYS_LOAD_ADDR Change the defaut flashlayout location, hardcoded at STM32_DDR_BASE, to CONFIG_SYS_LOAD_ADDR to avoid issue on board with reserved memory at STM32_DDR_BASE. This patch changes the command behavior for STM32MP13 and STM32MP15 platform, as CONFIG_SYS_LOAD_ADDR(0xc2000000) != STM32_DDR_BASE but without impact for serial boot with STM32CubeProgrammer. Signed-off-by: Patrick Delaunay Reviewed-by: Patrice Chotard --- arch/arm/mach-stm32mp/cmd_stm32prog/cmd_stm32prog.c | 2 +- arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c | 8 ++++---- arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_serial.c | 2 +- arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_usb.c | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/cmd_stm32prog.c b/arch/arm/mach-stm32mp/cmd_stm32prog/cmd_stm32prog.c index f59414e716..cb9e20da13 100644 --- a/arch/arm/mach-stm32mp/cmd_stm32prog/cmd_stm32prog.c +++ b/arch/arm/mach-stm32mp/cmd_stm32prog/cmd_stm32prog.c @@ -61,7 +61,7 @@ static int do_stm32prog(struct cmd_tbl *cmdtp, int flag, int argc, dev = (int)dectoul(argv[2], NULL); - addr = STM32_DDR_BASE; + addr = CONFIG_SYS_LOAD_ADDR; size = 0; if (argc > 3) { addr = hextoul(argv[3], NULL); diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c index 7067605d49..082f7887c4 100644 --- a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c +++ b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c @@ -1388,7 +1388,7 @@ static int dfu_init_entities(struct stm32prog_data *data) char buf[ALT_BUF_LEN]; sprintf(buf, "@FlashLayout/0x%02x/1*256Ke ram %x 40000", - PHASE_FLASHLAYOUT, STM32_DDR_BASE); + PHASE_FLASHLAYOUT, CONFIG_SYS_LOAD_ADDR); ret = dfu_alt_add(dfu, "ram", NULL, buf); log_debug("dfu_alt_add(ram, NULL,%s) result %d\n", buf, ret); } @@ -1699,15 +1699,15 @@ static void stm32prog_end_phase(struct stm32prog_data *data, u64 offset) { if (data->phase == PHASE_FLASHLAYOUT) { #if defined(CONFIG_LEGACY_IMAGE_FORMAT) - if (genimg_get_format((void *)STM32_DDR_BASE) == IMAGE_FORMAT_LEGACY) { - data->script = STM32_DDR_BASE; + if (genimg_get_format((void *)CONFIG_SYS_LOAD_ADDR) == IMAGE_FORMAT_LEGACY) { + data->script = CONFIG_SYS_LOAD_ADDR; data->phase = PHASE_END; log_notice("U-Boot script received\n"); return; } #endif log_notice("\nFlashLayout received, size = %lld\n", offset); - if (parse_flash_layout(data, STM32_DDR_BASE, offset)) + if (parse_flash_layout(data, CONFIG_SYS_LOAD_ADDR, offset)) stm32prog_err("Layout: invalid FlashLayout"); return; } diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_serial.c b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_serial.c index 1a69bc3897..e71956831b 100644 --- a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_serial.c +++ b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_serial.c @@ -462,7 +462,7 @@ static void get_phase_command(struct stm32prog_data *data) length = strlen(err_msg); } if (phase == PHASE_FLASHLAYOUT) - destination = STM32_DDR_BASE; + destination = CONFIG_SYS_LOAD_ADDR; stm32prog_serial_putc(length + 5); /* Total length */ stm32prog_serial_putc(phase & 0xFF); /* partition ID */ diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_usb.c b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_usb.c index a8b57c4d8f..bcb4d373f6 100644 --- a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_usb.c +++ b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_usb.c @@ -90,7 +90,7 @@ static int stm32prog_cmd_read(u64 offset, void *buf, long *len) } phase = stm32prog_data->phase; if (phase == PHASE_FLASHLAYOUT) - destination = STM32_DDR_BASE; + destination = CONFIG_SYS_LOAD_ADDR; dfu_offset = stm32prog_data->offset; /* mandatory header, size = PHASE_MIN_SIZE */ From 3df19b8bec379be01fd6d0db5a9bb4813f8148d3 Mon Sep 17 00:00:00 2001 From: Patrick Delaunay Date: Tue, 6 Sep 2022 18:53:19 +0200 Subject: [PATCH 230/374] stm32mp: stm32prog: solve warning for 64bits compilation Solve many compilation warning when stm32prog is activated on the aarch64. Signed-off-by: Patrick Delaunay Reviewed-by: Patrice Chotard --- .../mach-stm32mp/cmd_stm32prog/cmd_stm32prog.c | 14 +++++++------- arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c | 16 ++++++++-------- arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h | 14 +++++++------- .../cmd_stm32prog/stm32prog_serial.c | 15 +++++++-------- .../mach-stm32mp/cmd_stm32prog/stm32prog_usb.c | 4 ++-- 5 files changed, 31 insertions(+), 32 deletions(-) diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/cmd_stm32prog.c b/arch/arm/mach-stm32mp/cmd_stm32prog/cmd_stm32prog.c index cb9e20da13..d2666b9775 100644 --- a/arch/arm/mach-stm32mp/cmd_stm32prog/cmd_stm32prog.c +++ b/arch/arm/mach-stm32mp/cmd_stm32prog/cmd_stm32prog.c @@ -126,21 +126,21 @@ static int do_stm32prog(struct cmd_tbl *cmdtp, int flag, int argc, char *bootm_argv[5] = { "bootm", boot_addr_start, "-", dtb_addr, NULL }; - u32 uimage = data->uimage; - u32 dtb = data->dtb; - u32 initrd = data->initrd; + const void *uimage = (void *)data->uimage; + const void *dtb = (void *)data->dtb; + const void *initrd = (void *)data->initrd; if (!dtb) bootm_argv[3] = env_get("fdtcontroladdr"); else snprintf(dtb_addr, sizeof(dtb_addr) - 1, - "0x%x", dtb); + "0x%p", dtb); snprintf(boot_addr_start, sizeof(boot_addr_start) - 1, - "0x%x", uimage); + "0x%p", uimage); if (initrd) { - snprintf(initrd_addr, sizeof(initrd_addr) - 1, "0x%x:0x%x", + snprintf(initrd_addr, sizeof(initrd_addr) - 1, "0x%p:0x%zx", initrd, data->initrd_size); bootm_argv[2] = initrd_addr; } @@ -148,7 +148,7 @@ static int do_stm32prog(struct cmd_tbl *cmdtp, int flag, int argc, printf("Booting kernel at %s %s %s...\n\n\n", boot_addr_start, bootm_argv[2], bootm_argv[3]); /* Try bootm for legacy and FIT format image */ - if (genimg_get_format((void *)uimage) != IMAGE_FORMAT_INVALID) + if (genimg_get_format(uimage) != IMAGE_FORMAT_INVALID) do_bootm(cmdtp, 0, 4, bootm_argv); else if (CONFIG_IS_ENABLED(CMD_BOOTZ)) do_bootz(cmdtp, 0, 4, bootm_argv); diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c index 082f7887c4..07632648e1 100644 --- a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c +++ b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c @@ -322,7 +322,7 @@ void stm32prog_header_check(uintptr_t raw_header, struct image_header_s *header) header->image_length = 0x0; } -static u32 stm32prog_header_checksum(u32 addr, struct image_header_s *header) +static u32 stm32prog_header_checksum(uintptr_t addr, struct image_header_s *header) { u32 i, checksum; u8 *payload; @@ -398,7 +398,7 @@ static int parse_name(struct stm32prog_data *data, if (strlen(p) < sizeof(part->name)) { strcpy(part->name, p); } else { - stm32prog_err("Layout line %d: partition name too long [%d]: %s", + stm32prog_err("Layout line %d: partition name too long [%zd]: %s", i, strlen(p), p); result = -EINVAL; } @@ -537,7 +537,7 @@ int (* const parse[COL_NB_STM32])(struct stm32prog_data *data, int i, char *p, }; static int parse_flash_layout(struct stm32prog_data *data, - ulong addr, + uintptr_t addr, ulong size) { int column = 0, part_nb = 0, ret; @@ -1440,7 +1440,7 @@ int stm32prog_otp_write(struct stm32prog_data *data, u32 offset, u8 *buffer, if (offset + *size > otp_size) *size = otp_size - offset; - memcpy((void *)((u32)data->otp_part + offset), buffer, *size); + memcpy((void *)((uintptr_t)data->otp_part + offset), buffer, *size); return 0; } @@ -1479,7 +1479,7 @@ int stm32prog_otp_read(struct stm32prog_data *data, u32 offset, u8 *buffer, data->otp_part, OTP_SIZE_TA); else if (IS_ENABLED(CONFIG_ARM_SMCCC)) result = stm32_smc_exec(STM32_SMC_BSEC, STM32_SMC_READ_ALL, - (u32)data->otp_part, 0); + (unsigned long)data->otp_part, 0); if (result) goto end_otp_read; } @@ -1491,7 +1491,7 @@ int stm32prog_otp_read(struct stm32prog_data *data, u32 offset, u8 *buffer, if (offset + *size > otp_size) *size = otp_size - offset; - memcpy(buffer, (void *)((u32)data->otp_part + offset), *size); + memcpy(buffer, (void *)((uintptr_t)data->otp_part + offset), *size); end_otp_read: log_debug("%s: result %i\n", __func__, result); @@ -1521,7 +1521,7 @@ int stm32prog_otp_start(struct stm32prog_data *data) data->otp_part, OTP_SIZE_TA); } else if (IS_ENABLED(CONFIG_ARM_SMCCC)) { arm_smccc_smc(STM32_SMC_BSEC, STM32_SMC_WRITE_ALL, - (u32)data->otp_part, 0, 0, 0, 0, 0, &res); + (uintptr_t)data->otp_part, 0, 0, 0, 0, 0, &res); if (!res.a0) { switch (res.a1) { @@ -1951,7 +1951,7 @@ int stm32prog_dfu_init(struct stm32prog_data *data) return dfu_init_entities(data); } -int stm32prog_init(struct stm32prog_data *data, ulong addr, ulong size) +int stm32prog_init(struct stm32prog_data *data, uintptr_t addr, ulong size) { memset(data, 0x0, sizeof(*data)); data->read_phase = PHASE_RESET; diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h index ac300768ca..397506ac47 100644 --- a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h +++ b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h @@ -154,7 +154,7 @@ struct stm32prog_data { u32 offset; char error[255]; struct stm32prog_part_t *cur_part; - u32 *otp_part; + void *otp_part; u8 pmic_part[PMIC_SIZE]; /* SERIAL information */ @@ -165,12 +165,12 @@ struct stm32prog_data { u8 read_phase; /* bootm information */ - u32 uimage; - u32 dtb; - u32 initrd; - u32 initrd_size; + uintptr_t uimage; + uintptr_t dtb; + uintptr_t initrd; + size_t initrd_size; - u32 script; + uintptr_t script; /* OPTEE PTA NVMEM */ struct udevice *tee; @@ -209,7 +209,7 @@ char *stm32prog_get_error(struct stm32prog_data *data); } /* Main function */ -int stm32prog_init(struct stm32prog_data *data, ulong addr, ulong size); +int stm32prog_init(struct stm32prog_data *data, uintptr_t addr, ulong size); void stm32prog_clean(struct stm32prog_data *data); #ifdef CONFIG_CMD_STM32PROG_SERIAL diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_serial.c b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_serial.c index e71956831b..f1bed7d1a3 100644 --- a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_serial.c +++ b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_serial.c @@ -300,7 +300,7 @@ static void stm32prog_serial_putc(u8 w_byte) } /* Helper function ************************************************/ -static u8 stm32prog_start(struct stm32prog_data *data, u32 address) +static u8 stm32prog_start(struct stm32prog_data *data, uintptr_t address) { u8 ret = 0; struct dfu_entity *dfu_entity; @@ -353,7 +353,7 @@ static u8 stm32prog_start(struct stm32prog_data *data, u32 address) } else { void (*entry)(void) = (void *)address; - printf("## Starting application at 0x%x ...\n", address); + printf("## Starting application at 0x%p ...\n", (void *)address); (*entry)(); printf("## Application terminated\n"); ret = -ENOEXEC; @@ -368,9 +368,9 @@ static u8 stm32prog_start(struct stm32prog_data *data, u32 address) * @tmp_xor: Current xor value to update * Return: The address area */ -static u32 get_address(u8 *tmp_xor) +static uintptr_t get_address(u8 *tmp_xor) { - u32 address = 0x0; + uintptr_t address = 0x0; u8 data; data = stm32prog_serial_getc(); @@ -487,7 +487,7 @@ static void get_phase_command(struct stm32prog_data *data) */ static void read_memory_command(struct stm32prog_data *data) { - u32 address = 0x0; + uintptr_t address = 0x0; u8 rcv_data = 0x0, tmp_xor = 0x0; u32 counter = 0x0; @@ -532,7 +532,7 @@ static void read_memory_command(struct stm32prog_data *data) */ static void start_command(struct stm32prog_data *data) { - u32 address = 0; + uintptr_t address = 0; u8 tmp_xor = 0x0; u8 ret, rcv_data; @@ -546,8 +546,7 @@ static void start_command(struct stm32prog_data *data) return; } /* validate partition */ - ret = stm32prog_start(data, - address); + ret = stm32prog_start(data, address); if (ret) stm32prog_serial_result(ABORT_BYTE); diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_usb.c b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_usb.c index bcb4d373f6..be38ff239b 100644 --- a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_usb.c +++ b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog_usb.c @@ -41,7 +41,7 @@ static int stm32prog_set_phase(struct stm32prog_data *data, u8 phase, static int stm32prog_cmd_write(u64 offset, void *buf, long *len) { u8 phase; - u32 address; + uintptr_t address; u8 *pt = buf; void (*entry)(void); int ret; @@ -58,7 +58,7 @@ static int stm32prog_cmd_write(u64 offset, void *buf, long *len) address = (pt[1] << 24) | (pt[2] << 16) | (pt[3] << 8) | pt[4]; if (phase == PHASE_RESET) { entry = (void *)address; - printf("## Starting application at 0x%x ...\n", address); + printf("## Starting application at 0x%p ...\n", entry); (*entry)(); printf("## Application terminated\n"); return 0; From 93b2d4d0bda27a73a8825b05a69e8e31bf4232f6 Mon Sep 17 00:00:00 2001 From: Patrick Delaunay Date: Tue, 6 Sep 2022 18:53:20 +0200 Subject: [PATCH 231/374] stm32mp: stm32prog: correctly handle OTP when SMC is not supported As the SMC is only supported in SP-MIN for STM32MP15x, the associated partition should be absent when the TA NVMEM is not available in OPT-TEE in STM32MP13x. Signed-off-by: Patrick Delaunay Reviewed-by: Patrice Chotard --- .../mach-stm32mp/cmd_stm32prog/stm32prog.c | 25 +++++++++++++------ .../mach-stm32mp/cmd_stm32prog/stm32prog.h | 5 ++++ 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c index 07632648e1..c03ad8526d 100644 --- a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c +++ b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c @@ -1342,10 +1342,22 @@ static int dfu_init_entities(struct stm32prog_data *data) struct stm32prog_part_t *part; struct dfu_entity *dfu; int alt_nb; + u32 otp_size = 0; alt_nb = 1; /* number of virtual = CMD*/ - if (IS_ENABLED(CONFIG_CMD_STM32PROG_OTP)) - alt_nb++; /* OTP*/ + + if (IS_ENABLED(CONFIG_CMD_STM32PROG_OTP)) { + /* OTP_SIZE_SMC = 0 if SMC is not supported */ + otp_size = OTP_SIZE_SMC; + /* check if PTA BSEC is supported */ + ret = optee_ta_open(data); + log_debug("optee_ta_open(PTA_NVMEM) result %d\n", ret); + if (!ret && data->tee) + otp_size = OTP_SIZE_TA; + if (otp_size) + alt_nb++; /* OTP*/ + } + if (CONFIG_IS_ENABLED(DM_PMIC)) alt_nb++; /* PMIC NVMEM*/ @@ -1363,6 +1375,7 @@ static int dfu_init_entities(struct stm32prog_data *data) puts("DFU alt info setting: "); if (data->part_nb) { alt_id = 0; + ret = 0; for (phase = 1; (phase <= PHASE_LAST_USER) && (alt_id < alt_nb) && !ret; @@ -1396,12 +1409,8 @@ static int dfu_init_entities(struct stm32prog_data *data) if (!ret) ret = stm32prog_alt_add_virt(dfu, "virtual", PHASE_CMD, CMD_SIZE); - if (!ret && IS_ENABLED(CONFIG_CMD_STM32PROG_OTP)) { - ret = optee_ta_open(data); - log_debug("optee_ta result %d\n", ret); - ret = stm32prog_alt_add_virt(dfu, "OTP", PHASE_OTP, - data->tee ? OTP_SIZE_TA : OTP_SIZE_SMC); - } + if (!ret && IS_ENABLED(CONFIG_CMD_STM32PROG_OTP) && otp_size) + ret = stm32prog_alt_add_virt(dfu, "OTP", PHASE_OTP, otp_size); if (!ret && CONFIG_IS_ENABLED(DM_PMIC)) ret = stm32prog_alt_add_virt(dfu, "PMIC", PHASE_PMIC, PMIC_SIZE); diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h index 397506ac47..58f4b96fa7 100644 --- a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h +++ b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.h @@ -20,7 +20,12 @@ #define DEFAULT_ADDRESS 0xFFFFFFFF #define CMD_SIZE 512 +/* SMC is only supported in SPMIN for STM32MP15x */ +#ifdef CONFIG_STM32MP15x #define OTP_SIZE_SMC 1024 +#else +#define OTP_SIZE_SMC 0 +#endif #define OTP_SIZE_TA 776 #define PMIC_SIZE 8 From 152498d580ad666d23d55603de2e77dd27a30adb Mon Sep 17 00:00:00 2001 From: Patrick Delaunay Date: Wed, 7 Sep 2022 13:42:23 +0200 Subject: [PATCH 232/374] ARM: dts: stm32mp: alignment with v6.0-rc3 Device tree alignment with Linux kernel v6.0-rc3: - ARM: dts: stm32: add support for USB2514B onboard hub on stm32mp15xx-dkx - ARM: dts: stm32: Add alternate pinmux for RCC pin - ARM: dts: stm32: Add alternate pinmux for DCMI pins - ARM: dts: stm32: Add alternate pinmux for SPI2 pins - ARM: dts: stm32: Fix SPI2 pinmux pin comments on stm32mp15 - ARM: dts: stm32: add optee reserved memory on stm32mp135f-dk - ARM: dts: stm32: enable optee firmware and SCMI support on STM32MP13 - ARM: dts: stm32: remove the IPCC "wakeup" IRQ on stm32mp151 Signed-off-by: Patrick Delaunay Reviewed-by: Patrice Chotard --- arch/arm/dts/stm32mp13-u-boot.dtsi | 10 +++-- arch/arm/dts/stm32mp131.dtsi | 28 ++++++------- arch/arm/dts/stm32mp135f-dk.dts | 4 +- arch/arm/dts/stm32mp15-pinctrl.dtsi | 64 ++++++++++++++++++++++++++--- arch/arm/dts/stm32mp151.dtsi | 7 ++-- arch/arm/dts/stm32mp15xx-dkx.dtsi | 8 ++++ 6 files changed, 91 insertions(+), 30 deletions(-) diff --git a/arch/arm/dts/stm32mp13-u-boot.dtsi b/arch/arm/dts/stm32mp13-u-boot.dtsi index 01552adb7c..47a43649bb 100644 --- a/arch/arm/dts/stm32mp13-u-boot.dtsi +++ b/arch/arm/dts/stm32mp13-u-boot.dtsi @@ -17,6 +17,12 @@ pinctrl0 = &pinctrl; }; + firmware { + optee { + u-boot,dm-pre-reloc; + }; + }; + /* need PSCI for sysreset during board_f */ psci { u-boot,dm-pre-proper; @@ -82,10 +88,6 @@ u-boot,dm-pre-reloc; }; -&optee { - u-boot,dm-pre-reloc; -}; - &pinctrl { u-boot,dm-pre-reloc; }; diff --git a/arch/arm/dts/stm32mp131.dtsi b/arch/arm/dts/stm32mp131.dtsi index 84e16bb2f2..a1c6d0d00b 100644 --- a/arch/arm/dts/stm32mp131.dtsi +++ b/arch/arm/dts/stm32mp131.dtsi @@ -27,21 +27,8 @@ interrupt-parent = <&intc>; }; - scmi_sram: sram@2ffff000 { - compatible = "mmio-sram"; - reg = <0x2ffff000 0x1000>; - #address-cells = <1>; - #size-cells = <1>; - ranges = <0 0x2ffff000 0x1000>; - - scmi_shm: scmi_shm@0 { - compatible = "arm,scmi-shmem"; - reg = <0 0x80>; - }; - }; - firmware { - optee: optee { + optee { method = "smc"; compatible = "linaro,optee-tz"; }; @@ -151,6 +138,19 @@ interrupt-parent = <&intc>; ranges; + scmi_sram: sram@2ffff000 { + compatible = "mmio-sram"; + reg = <0x2ffff000 0x1000>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0x2ffff000 0x1000>; + + scmi_shm: scmi-sram@0 { + compatible = "arm,scmi-shmem"; + reg = <0 0x80>; + }; + }; + uart4: serial@40010000 { compatible = "st,stm32h7-uart"; reg = <0x40010000 0x400>; diff --git a/arch/arm/dts/stm32mp135f-dk.dts b/arch/arm/dts/stm32mp135f-dk.dts index f436ffab99..e6b8ffd332 100644 --- a/arch/arm/dts/stm32mp135f-dk.dts +++ b/arch/arm/dts/stm32mp135f-dk.dts @@ -31,8 +31,8 @@ #size-cells = <1>; ranges; - optee@de000000 { - reg = <0xde000000 0x2000000>; + optee@dd000000 { + reg = <0xdd000000 0x3000000>; no-map; }; }; diff --git a/arch/arm/dts/stm32mp15-pinctrl.dtsi b/arch/arm/dts/stm32mp15-pinctrl.dtsi index d3ed10335d..2cc9341d43 100644 --- a/arch/arm/dts/stm32mp15-pinctrl.dtsi +++ b/arch/arm/dts/stm32mp15-pinctrl.dtsi @@ -151,6 +151,43 @@ }; }; + dcmi_pins_c: dcmi-2 { + pins { + pinmux = ,/* DCMI_HSYNC */ + ,/* DCMI_VSYNC */ + ,/* DCMI_PIXCLK */ + ,/* DCMI_D0 */ + ,/* DCMI_D1 */ + ,/* DCMI_D2 */ + ,/* DCMI_D3 */ + ,/* DCMI_D4 */ + ,/* DCMI_D5 */ + ,/* DCMI_D6 */ + ,/* DCMI_D7 */ + ,/* DCMI_D8 */ + ;/* DCMI_D9 */ + bias-pull-up; + }; + }; + + dcmi_sleep_pins_c: dcmi-sleep-2 { + pins { + pinmux = ,/* DCMI_HSYNC */ + ,/* DCMI_VSYNC */ + ,/* DCMI_PIXCLK */ + ,/* DCMI_D0 */ + ,/* DCMI_D1 */ + ,/* DCMI_D2 */ + ,/* DCMI_D3 */ + ,/* DCMI_D4 */ + ,/* DCMI_D5 */ + ,/* DCMI_D6 */ + ,/* DCMI_D7 */ + ,/* DCMI_D8 */ + ;/* DCMI_D9 */ + }; + }; + ethernet0_rgmii_pins_a: rgmii-0 { pins1 { pinmux = , /* ETH_RGMII_CLK125 */ @@ -923,6 +960,21 @@ }; }; + mco1_pins_a: mco1-0 { + pins { + pinmux = ; /* MCO1 */ + bias-disable; + drive-push-pull; + slew-rate = <1>; + }; + }; + + mco1_sleep_pins_a: mco1-sleep-0 { + pins { + pinmux = ; /* MCO1 */ + }; + }; + mco2_pins_a: mco2-0 { pins { pinmux = ; /* MCO2 */ @@ -1814,30 +1866,30 @@ spi2_pins_a: spi2-0 { pins1 { - pinmux = , /* SPI1_SCK */ - ; /* SPI1_MOSI */ + pinmux = , /* SPI2_SCK */ + ; /* SPI2_MOSI */ bias-disable; drive-push-pull; slew-rate = <1>; }; pins2 { - pinmux = ; /* SPI1_MISO */ + pinmux = ; /* SPI2_MISO */ bias-disable; }; }; spi2_pins_b: spi2-1 { pins1 { - pinmux = , /* SPI1_SCK */ - ; /* SPI1_MOSI */ + pinmux = , /* SPI2_SCK */ + ; /* SPI2_MOSI */ bias-disable; drive-push-pull; slew-rate = <1>; }; pins2 { - pinmux = ; /* SPI1_MISO */ + pinmux = ; /* SPI2_MISO */ bias-disable; }; }; diff --git a/arch/arm/dts/stm32mp151.dtsi b/arch/arm/dts/stm32mp151.dtsi index 767a06ef68..f0fb022fc6 100644 --- a/arch/arm/dts/stm32mp151.dtsi +++ b/arch/arm/dts/stm32mp151.dtsi @@ -1143,10 +1143,9 @@ reg = <0x4c001000 0x400>; st,proc-id = <0>; interrupts-extended = - <&intc GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>, - <&intc GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>, - <&exti 61 1>; - interrupt-names = "rx", "tx", "wakeup"; + <&exti 61 1>, + <&intc GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "rx", "tx"; clocks = <&rcc IPCC>; wakeup-source; status = "disabled"; diff --git a/arch/arm/dts/stm32mp15xx-dkx.dtsi b/arch/arm/dts/stm32mp15xx-dkx.dtsi index 3d36cac9ed..5a045d7156 100644 --- a/arch/arm/dts/stm32mp15xx-dkx.dtsi +++ b/arch/arm/dts/stm32mp15xx-dkx.dtsi @@ -685,6 +685,14 @@ &usbh_ehci { phys = <&usbphyc_port0>; status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + /* onboard HUB */ + hub@1 { + compatible = "usb424,2514"; + reg = <1>; + vdd-supply = <&v3v3>; + }; }; &usbotg_hs { From 450036f4eff2f9bccb13355d7d96edf217f91ed9 Mon Sep 17 00:00:00 2001 From: Patrick Delaunay Date: Fri, 9 Sep 2022 17:22:15 +0200 Subject: [PATCH 233/374] stm32mp: stm32prog: improve the partitioning trace Improve the partitioning trace done in command stm32prog: - remove the trace "partition: Done" when the GPT partitioning is not done - indicate the mmc instance used for each 'gpt write' command Signed-off-by: Patrick Delaunay Reviewed-by: Patrice Chotard --- arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c index c03ad8526d..89552d2ad1 100644 --- a/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c +++ b/arch/arm/mach-stm32mp/cmd_stm32prog/stm32prog.c @@ -1090,7 +1090,6 @@ static int create_gpt_partitions(struct stm32prog_data *data) if (!buf) return -ENOMEM; - puts("partitions : "); /* initialize the selected device */ for (i = 0; i < data->dev_nb; i++) { /* create gpt partition support only for full update on MMC */ @@ -1098,6 +1097,7 @@ static int create_gpt_partitions(struct stm32prog_data *data) !data->dev[i].full_update) continue; + printf("partitions on mmc%d: ", data->dev[i].dev_id); offset = 0; rootfs_found = false; memset(buf, 0, buflen); @@ -1197,8 +1197,8 @@ static int create_gpt_partitions(struct stm32prog_data *data) sprintf(buf, "part list mmc %d", data->dev[i].dev_id); run_command(buf, 0); #endif + puts("done\n"); } - puts("done\n"); #ifdef DEBUG run_command("mtd list", 0); From 89f3745152ab1a88eb9b6629a12b4ff0efe8c61b Mon Sep 17 00:00:00 2001 From: Christophe Kerello Date: Mon, 12 Sep 2022 17:40:50 +0200 Subject: [PATCH 234/374] board: st: stm32mp1: use of correct compatible string to add partitions Current compatible string used to update SPI NAND and SPI NOR devices can lead to a wrong partitions update (for example, SPI NAND partitions added to SPI NOR node in the device tree). To avoid this wrong behavior, use jedec,spi-nor compatible string for SPI NOR devices and spi-nand compatible string for SPI NAND devices. Signed-off-by: Christophe Kerello Signed-off-by: Patrick Delaunay Reviewed-by: Patrice Chotard --- board/st/stm32mp1/stm32mp1.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/board/st/stm32mp1/stm32mp1.c b/board/st/stm32mp1/stm32mp1.c index 581a4df1cc..2d98ff41ab 100644 --- a/board/st/stm32mp1/stm32mp1.c +++ b/board/st/stm32mp1/stm32mp1.c @@ -898,8 +898,8 @@ int mmc_get_env_dev(void) int ft_board_setup(void *blob, struct bd_info *bd) { static const struct node_info nodes[] = { - { "st,stm32f469-qspi", MTD_DEV_TYPE_NOR, }, - { "st,stm32f469-qspi", MTD_DEV_TYPE_SPINAND}, + { "jedec,spi-nor", MTD_DEV_TYPE_NOR, }, + { "spi-nand", MTD_DEV_TYPE_SPINAND}, { "st,stm32mp15-fmc2", MTD_DEV_TYPE_NAND, }, { "st,stm32mp1-fmc2-nfc", MTD_DEV_TYPE_NAND, }, }; From c6327ba40f59de42cfac4b6e489f4a7a1539ddf5 Mon Sep 17 00:00:00 2001 From: Patrick Delaunay Date: Thu, 15 Sep 2022 18:11:38 +0200 Subject: [PATCH 235/374] arm: stm32mp: add defines for BSEC_LOCK status in stm32key command Add defines for value used in stm32key for BSEC permanent lock status and error. This patch is a preliminary step to support more lock status in BSEC driver. Signed-off-by: Patrick Delaunay Reviewed-by: Patrice Chotard --- arch/arm/mach-stm32mp/cmd_stm32key.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/arch/arm/mach-stm32mp/cmd_stm32key.c b/arch/arm/mach-stm32mp/cmd_stm32key.c index 68f28922d1..1899d91ecb 100644 --- a/arch/arm/mach-stm32mp/cmd_stm32key.c +++ b/arch/arm/mach-stm32mp/cmd_stm32key.c @@ -19,6 +19,9 @@ #define STM32_OTP_HASH_KEY_START 24 #define STM32_OTP_HASH_KEY_SIZE 8 +#define BSEC_LOCK_ERROR (-1) +#define BSEC_LOCK_PERM BIT(0) + static int get_misc_dev(struct udevice **dev) { int ret; @@ -60,14 +63,14 @@ static int read_hash_otp(bool print, bool *locked, bool *closed) val = ~0x0; ret = misc_read(dev, STM32_BSEC_LOCK(word), &lock, 4); if (ret != 4) - lock = -1; + lock = BSEC_LOCK_ERROR; if (print) - printf("OTP HASH %i: %x lock : %d\n", word, val, lock); + printf("OTP HASH %i: %x lock : %x\n", word, val, lock); if (val == ~0x0) nb_invalid++; else if (val == 0x0) nb_zero++; - if (lock == 1) + if (lock & BSEC_LOCK_PERM) nb_lock++; } @@ -77,13 +80,13 @@ static int read_hash_otp(bool print, bool *locked, bool *closed) val = 0x0; ret = misc_read(dev, STM32_BSEC_LOCK(word), &lock, 4); if (ret != 4) - lock = -1; + lock = BSEC_LOCK_ERROR; status = (val & STM32_OTP_CLOSE_MASK) == STM32_OTP_CLOSE_MASK; if (closed) *closed = status; if (print) - printf("OTP %d: closed status: %d lock : %d\n", word, status, lock); + printf("OTP %d: closed status: %d lock : %x\n", word, status, lock); status = (nb_lock == STM32_OTP_HASH_KEY_SIZE); if (locked) @@ -128,7 +131,7 @@ static int fuse_hash_value(u32 addr, bool print) return ret; } /* on success, lock the OTP for HASH key */ - val = 1; + val = BSEC_LOCK_PERM; ret = misc_write(dev, STM32_BSEC_LOCK(word), &val, 4); if (ret != 4) { log_err("Lock OTP %i failed\n", word); From 8921b3dccd24da7e2d1c7ea6ccb56d065ec588c6 Mon Sep 17 00:00:00 2001 From: Patrick Delaunay Date: Thu, 15 Sep 2022 18:11:39 +0200 Subject: [PATCH 236/374] arm: stm32mp: introduced read_close_status function in stm32key command Split the read_hash_otp function and introduce the helper function read_close_status to read the close status in OTP separately of the PKH. This patch is a preliminary step for STM32MP13 support. Signed-off-by: Patrick Delaunay Reviewed-by: Patrice Chotard --- arch/arm/mach-stm32mp/cmd_stm32key.c | 107 ++++++++++++++++----------- 1 file changed, 65 insertions(+), 42 deletions(-) diff --git a/arch/arm/mach-stm32mp/cmd_stm32key.c b/arch/arm/mach-stm32mp/cmd_stm32key.c index 1899d91ecb..68f9b1a9a5 100644 --- a/arch/arm/mach-stm32mp/cmd_stm32key.c +++ b/arch/arm/mach-stm32mp/cmd_stm32key.c @@ -45,18 +45,13 @@ static void read_hash_value(u32 addr) } } -static int read_hash_otp(bool print, bool *locked, bool *closed) +static int read_hash_otp(struct udevice *dev, bool print, bool *locked) { - struct udevice *dev; int i, word, ret; int nb_invalid = 0, nb_zero = 0, nb_lock = 0; u32 val, lock; bool status; - ret = get_misc_dev(&dev); - if (ret) - return ret; - for (i = 0, word = STM32_OTP_HASH_KEY_START; i < STM32_OTP_HASH_KEY_SIZE; i++, word++) { ret = misc_read(dev, STM32_BSEC_OTP(word), &val, 4); if (ret != 4) @@ -74,20 +69,6 @@ static int read_hash_otp(bool print, bool *locked, bool *closed) nb_lock++; } - word = STM32_OTP_CLOSE_ID; - ret = misc_read(dev, STM32_BSEC_OTP(word), &val, 4); - if (ret != 4) - val = 0x0; - ret = misc_read(dev, STM32_BSEC_LOCK(word), &lock, 4); - if (ret != 4) - lock = BSEC_LOCK_ERROR; - - status = (val & STM32_OTP_CLOSE_MASK) == STM32_OTP_CLOSE_MASK; - if (closed) - *closed = status; - if (print) - printf("OTP %d: closed status: %d lock : %x\n", word, status, lock); - status = (nb_lock == STM32_OTP_HASH_KEY_SIZE); if (locked) *locked = status; @@ -108,16 +89,40 @@ static int read_hash_otp(bool print, bool *locked, bool *closed) return 0; } -static int fuse_hash_value(u32 addr, bool print) +static int read_close_status(struct udevice *dev, bool print, bool *closed) +{ + int word, ret, result; + u32 val, lock; + bool status; + + result = 0; + word = STM32_OTP_CLOSE_ID; + ret = misc_read(dev, STM32_BSEC_OTP(word), &val, 4); + if (ret < 0) + result = ret; + if (ret != 4) + val = 0x0; + + ret = misc_read(dev, STM32_BSEC_LOCK(word), &lock, 4); + if (ret < 0) + result = ret; + if (ret != 4) + lock = BSEC_LOCK_ERROR; + + status = (val & STM32_OTP_CLOSE_MASK) == STM32_OTP_CLOSE_MASK; + if (closed) + *closed = status; + if (print) + printf("OTP %d: closed status: %d lock : %x\n", word, status, lock); + + return result; +} + +static int fuse_hash_value(struct udevice *dev, u32 addr, bool print) { - struct udevice *dev; u32 word, val; int i, ret; - ret = get_misc_dev(&dev); - if (ret) - return ret; - for (i = 0, word = STM32_OTP_HASH_KEY_START; i < STM32_OTP_HASH_KEY_SIZE; i++, word++, addr += 4) { @@ -158,10 +163,20 @@ static int confirm_prog(void) static int do_stm32key_read(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) { + struct udevice *dev; u32 addr; + int ret; + + ret = get_misc_dev(&dev); if (argc == 1) { - read_hash_otp(true, NULL, NULL); + if (ret) + return CMD_RET_FAILURE; + read_hash_otp(dev, true, NULL); + ret = read_close_status(dev, true, NULL); + if (ret) + return CMD_RET_FAILURE; + return CMD_RET_SUCCESS; } @@ -176,8 +191,10 @@ static int do_stm32key_read(struct cmd_tbl *cmdtp, int flag, int argc, char *con static int do_stm32key_fuse(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) { + struct udevice *dev; u32 addr; - bool yes = false, lock, closed; + int ret; + bool yes = false, lock; if (argc < 2) return CMD_RET_USAGE; @@ -192,20 +209,23 @@ static int do_stm32key_fuse(struct cmd_tbl *cmdtp, int flag, int argc, char *con if (!addr) return CMD_RET_USAGE; - if (read_hash_otp(!yes, &lock, &closed) != -ENOENT) { + ret = get_misc_dev(&dev); + if (ret) + return CMD_RET_FAILURE; + + if (read_hash_otp(dev, !yes, &lock) != -ENOENT) { printf("Error: can't fuse again the OTP\n"); return CMD_RET_FAILURE; } - - if (lock || closed) { - printf("Error: invalid OTP configuration (lock=%d, closed=%d)\n", lock, closed); + if (lock) { + printf("Error: PKH is locked\n"); return CMD_RET_FAILURE; } if (!yes && !confirm_prog()) return CMD_RET_FAILURE; - if (fuse_hash_value(addr, !yes)) + if (fuse_hash_value(dev, addr, !yes)) return CMD_RET_FAILURE; printf("Hash key updated !\n"); @@ -227,28 +247,31 @@ static int do_stm32key_close(struct cmd_tbl *cmdtp, int flag, int argc, char *co yes = true; } - ret = read_hash_otp(!yes, &lock, &closed); - if (ret) { - if (ret == -ENOENT) - printf("Error: OTP not programmed!\n"); + ret = get_misc_dev(&dev); + if (ret) + return CMD_RET_FAILURE; + + if (read_close_status(dev, !yes, &closed)) return CMD_RET_FAILURE; - } if (closed) { printf("Error: already closed!\n"); return CMD_RET_FAILURE; } + /* check PKH status before to close */ + ret = read_hash_otp(dev, !yes, &lock); + if (ret) { + if (ret == -ENOENT) + printf("Error: OTP not programmed!\n"); + return CMD_RET_FAILURE; + } if (!lock) printf("Warning: OTP not locked!\n"); if (!yes && !confirm_prog()) return CMD_RET_FAILURE; - ret = get_misc_dev(&dev); - if (ret) - return CMD_RET_FAILURE; - val = STM32_OTP_CLOSE_MASK; ret = misc_write(dev, STM32_BSEC_OTP(STM32_OTP_CLOSE_ID), &val, 4); if (ret != 4) { From fd1f4c9abd8eba06c5ad1169a03bd28b4c2e54a7 Mon Sep 17 00:00:00 2001 From: Patrick Delaunay Date: Thu, 15 Sep 2022 18:11:40 +0200 Subject: [PATCH 237/374] arm: stm32mp: support several key in command stm32key Update the command stm32key to support several keys selected by key name and managed by the new sub-command: stm32key list stm32key select [] stm32key read -a This patch doesn't change the STM32MP15 behavior, only PKH is supported, but it is a preliminary patch for STM32MP13 support. Signed-off-by: Patrick Delaunay Reviewed-by: Patrice Chotard --- arch/arm/mach-stm32mp/cmd_stm32key.c | 193 ++++++++++++++++++++------- 1 file changed, 148 insertions(+), 45 deletions(-) diff --git a/arch/arm/mach-stm32mp/cmd_stm32key.c b/arch/arm/mach-stm32mp/cmd_stm32key.c index 68f9b1a9a5..4eac56082d 100644 --- a/arch/arm/mach-stm32mp/cmd_stm32key.c +++ b/arch/arm/mach-stm32mp/cmd_stm32key.c @@ -15,9 +15,37 @@ #define STM32_OTP_CLOSE_ID 0 #define STM32_OTP_CLOSE_MASK BIT(6) -/* HASH of key: 8 OTPs, starting with OTP24) */ -#define STM32_OTP_HASH_KEY_START 24 -#define STM32_OTP_HASH_KEY_SIZE 8 +/* PKH is the first element of the key list */ +#define STM32KEY_PKH 0 + +struct stm32key { + char *name; + char *desc; + u8 start; + u8 size; +}; + +const struct stm32key stm32mp15_list[] = { + [STM32KEY_PKH] = { + .name = "PKH", + .desc = "Hash of the ECC Public Key (ECDSA is the authentication algorithm)", + .start = 24, + .size = 8, + } +}; + +/* index of current selected key in stm32key list, 0 = PKH by default */ +static u8 stm32key_index; + +static u8 get_key_nb(void) +{ + return ARRAY_SIZE(stm32mp15_list); +} + +static const struct stm32key *get_key(u8 index) +{ + return &stm32mp15_list[index]; +} #define BSEC_LOCK_ERROR (-1) #define BSEC_LOCK_PERM BIT(0) @@ -33,26 +61,25 @@ static int get_misc_dev(struct udevice **dev) return ret; } -static void read_hash_value(u32 addr) +static void read_key_value(const struct stm32key *key, u32 addr) { int i; - printf("Read KEY at 0x%x\n", addr); - for (i = 0; i < STM32_OTP_HASH_KEY_SIZE; i++) { - printf("OTP value %i: %x\n", STM32_OTP_HASH_KEY_START + i, - __be32_to_cpu(*(u32 *)addr)); + for (i = 0; i < key->size; i++) { + printf("%s OTP %i: [%08x] %08x\n", key->name, key->start + i, + addr, __be32_to_cpu(*(u32 *)addr)); addr += 4; } } -static int read_hash_otp(struct udevice *dev, bool print, bool *locked) +static int read_key_otp(struct udevice *dev, const struct stm32key *key, bool print, bool *locked) { int i, word, ret; - int nb_invalid = 0, nb_zero = 0, nb_lock = 0; + int nb_invalid = 0, nb_zero = 0, nb_lock = 0, nb_lock_err = 0; u32 val, lock; bool status; - for (i = 0, word = STM32_OTP_HASH_KEY_START; i < STM32_OTP_HASH_KEY_SIZE; i++, word++) { + for (i = 0, word = key->start; i < key->size; i++, word++) { ret = misc_read(dev, STM32_BSEC_OTP(word), &val, 4); if (ret != 4) val = ~0x0; @@ -60,29 +87,33 @@ static int read_hash_otp(struct udevice *dev, bool print, bool *locked) if (ret != 4) lock = BSEC_LOCK_ERROR; if (print) - printf("OTP HASH %i: %x lock : %x\n", word, val, lock); + printf("%s OTP %i: %08x lock : %08x\n", key->name, word, val, lock); if (val == ~0x0) nb_invalid++; else if (val == 0x0) nb_zero++; if (lock & BSEC_LOCK_PERM) nb_lock++; + if (lock & BSEC_LOCK_ERROR) + nb_lock_err++; } - status = (nb_lock == STM32_OTP_HASH_KEY_SIZE); + status = nb_lock_err || (nb_lock == key->size); if (locked) *locked = status; - if (!status && print) - printf("Hash of key is not locked!\n"); + if (nb_lock_err && print) + printf("%s lock is invalid!\n", key->name); + else if (!status && print) + printf("%s is not locked!\n", key->name); - if (nb_invalid == STM32_OTP_HASH_KEY_SIZE) { + if (nb_invalid == key->size) { if (print) - printf("Hash of key is invalid!\n"); + printf("%s is invalid!\n", key->name); return -EINVAL; } - if (nb_zero == STM32_OTP_HASH_KEY_SIZE) { + if (nb_zero == key->size) { if (print) - printf("Hash of key is free!\n"); + printf("%s is free!\n", key->name); return -ENOENT; } @@ -113,33 +144,31 @@ static int read_close_status(struct udevice *dev, bool print, bool *closed) if (closed) *closed = status; if (print) - printf("OTP %d: closed status: %d lock : %x\n", word, status, lock); + printf("OTP %d: closed status: %d lock : %08x\n", word, status, lock); return result; } -static int fuse_hash_value(struct udevice *dev, u32 addr, bool print) +static int fuse_key_value(struct udevice *dev, const struct stm32key *key, u32 addr, bool print) { u32 word, val; int i, ret; - for (i = 0, word = STM32_OTP_HASH_KEY_START; - i < STM32_OTP_HASH_KEY_SIZE; - i++, word++, addr += 4) { + for (i = 0, word = key->start; i < key->size; i++, word++, addr += 4) { val = __be32_to_cpu(*(u32 *)addr); if (print) - printf("Fuse OTP %i : %x\n", word, val); + printf("Fuse %s OTP %i : %08x\n", key->name, word, val); ret = misc_write(dev, STM32_BSEC_OTP(word), &val, 4); if (ret != 4) { - log_err("Fuse OTP %i failed\n", word); + log_err("Fuse %s OTP %i failed\n", key->name, word); return ret; } - /* on success, lock the OTP for HASH key */ + /* on success, lock the OTP for the key */ val = BSEC_LOCK_PERM; ret = misc_write(dev, STM32_BSEC_LOCK(word), &val, 4); if (ret != 4) { - log_err("Lock OTP %i failed\n", word); + log_err("Lock %s OTP %i failed\n", key->name, word); return ret; } } @@ -161,36 +190,99 @@ static int confirm_prog(void) return 0; } +static void display_key_info(const struct stm32key *key) +{ + printf("%s : %s\n", key->name, key->desc); + printf("\tOTP%d..%d\n", key->start, key->start + key->size); +} + +static int do_stm32key_list(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) +{ + int i; + + for (i = 0; i < get_key_nb(); i++) + display_key_info(get_key(i)); + + return CMD_RET_SUCCESS; +} + +static int do_stm32key_select(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) +{ + const struct stm32key *key; + int i; + + if (argc == 1) { + printf("Selected key:\n"); + key = get_key(stm32key_index); + display_key_info(key); + return CMD_RET_SUCCESS; + } + + for (i = 0; i < get_key_nb(); i++) { + key = get_key(i); + if (!strcmp(key->name, argv[1])) { + printf("%s selected\n", key->name); + stm32key_index = i; + return CMD_RET_SUCCESS; + } + } + + printf("Unknown key %s\n", argv[1]); + + return CMD_RET_FAILURE; +} + static int do_stm32key_read(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) { + const struct stm32key *key; struct udevice *dev; u32 addr; - int ret; + int ret, i; + int result; ret = get_misc_dev(&dev); if (argc == 1) { if (ret) return CMD_RET_FAILURE; - read_hash_otp(dev, true, NULL); - ret = read_close_status(dev, true, NULL); + key = get_key(stm32key_index); + ret = read_key_otp(dev, key, true, NULL); + if (ret != -ENOENT) + return CMD_RET_FAILURE; + return CMD_RET_SUCCESS; + } + + if (!strcmp("-a", argv[1])) { if (ret) return CMD_RET_FAILURE; + result = CMD_RET_SUCCESS; + for (i = 0; i < get_key_nb(); i++) { + key = get_key(i); + ret = read_key_otp(dev, key, true, NULL); + if (ret != -ENOENT) + result = CMD_RET_FAILURE; + } + ret = read_close_status(dev, true, NULL); + if (ret) + result = CMD_RET_FAILURE; - return CMD_RET_SUCCESS; + return result; } addr = hextoul(argv[1], NULL); if (!addr) return CMD_RET_USAGE; - read_hash_value(addr); + key = get_key(stm32key_index); + printf("Read %s at 0x%08x\n", key->name, addr); + read_key_value(key, addr); return CMD_RET_SUCCESS; } static int do_stm32key_fuse(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) { + const struct stm32key *key = get_key(stm32key_index); struct udevice *dev; u32 addr; int ret; @@ -213,28 +305,34 @@ static int do_stm32key_fuse(struct cmd_tbl *cmdtp, int flag, int argc, char *con if (ret) return CMD_RET_FAILURE; - if (read_hash_otp(dev, !yes, &lock) != -ENOENT) { + if (read_key_otp(dev, key, !yes, &lock) != -ENOENT) { printf("Error: can't fuse again the OTP\n"); return CMD_RET_FAILURE; } if (lock) { - printf("Error: PKH is locked\n"); + printf("Error: %s is locked\n", key->name); return CMD_RET_FAILURE; } + if (!yes) { + printf("Writing %s with\n", key->name); + read_key_value(key, addr); + } + if (!yes && !confirm_prog()) return CMD_RET_FAILURE; - if (fuse_hash_value(dev, addr, !yes)) + if (fuse_key_value(dev, key, addr, !yes)) return CMD_RET_FAILURE; - printf("Hash key updated !\n"); + printf("%s updated !\n", key->name); return CMD_RET_SUCCESS; } static int do_stm32key_close(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) { + const struct stm32key *key; bool yes, lock, closed; struct udevice *dev; u32 val; @@ -260,14 +358,15 @@ static int do_stm32key_close(struct cmd_tbl *cmdtp, int flag, int argc, char *co } /* check PKH status before to close */ - ret = read_hash_otp(dev, !yes, &lock); + key = get_key(STM32KEY_PKH); + ret = read_key_otp(dev, key, !yes, &lock); if (ret) { if (ret == -ENOENT) - printf("Error: OTP not programmed!\n"); + printf("Error: %s not programmed!\n", key->name); return CMD_RET_FAILURE; } if (!lock) - printf("Warning: OTP not locked!\n"); + printf("Warning: %s not locked!\n", key->name); if (!yes && !confirm_prog()) return CMD_RET_FAILURE; @@ -275,7 +374,7 @@ static int do_stm32key_close(struct cmd_tbl *cmdtp, int flag, int argc, char *co val = STM32_OTP_CLOSE_MASK; ret = misc_write(dev, STM32_BSEC_OTP(STM32_OTP_CLOSE_ID), &val, 4); if (ret != 4) { - printf("Error: can't update OTP\n"); + printf("Error: can't update OTP %d\n", STM32_OTP_CLOSE_ID); return CMD_RET_FAILURE; } @@ -285,11 +384,15 @@ static int do_stm32key_close(struct cmd_tbl *cmdtp, int flag, int argc, char *co } static char stm32key_help_text[] = - "read []: Read the hash stored at addr in memory or in OTP\n" - "stm32key fuse [-y] : Fuse hash stored at addr in OTP\n" - "stm32key close [-y] : Close the device, the hash stored in OTP\n"; + "list : list the supported key with description\n" + "stm32key select [] : Select the key identified by or display the key used for read/fuse command\n" + "stm32key read [ | -a ] : Read the curent key at or current / all (-a) key in OTP\n" + "stm32key fuse [-y] : Fuse the current key at addr in OTP\n" + "stm32key close [-y] : Close the device\n"; -U_BOOT_CMD_WITH_SUBCMDS(stm32key, "Fuse ST Hash key", stm32key_help_text, +U_BOOT_CMD_WITH_SUBCMDS(stm32key, "Manage key on STM32", stm32key_help_text, + U_BOOT_SUBCMD_MKENT(list, 1, 0, do_stm32key_list), + U_BOOT_SUBCMD_MKENT(select, 2, 0, do_stm32key_select), U_BOOT_SUBCMD_MKENT(read, 2, 0, do_stm32key_read), U_BOOT_SUBCMD_MKENT(fuse, 3, 0, do_stm32key_fuse), U_BOOT_SUBCMD_MKENT(close, 2, 0, do_stm32key_close)); From e83cef87a847d10aa2c46308bd8ac870bf56deee Mon Sep 17 00:00:00 2001 From: Patrick Delaunay Date: Thu, 15 Sep 2022 18:11:41 +0200 Subject: [PATCH 238/374] arm: stm32mp: adapt the command stm32key for STM32MP13x Change the mask of OTP0 used to close the device on STM32MP - STM32MP15x: bit 6 of OPT0 - STM32MP13x: 0b111111 = 0x3F for OTP_SECURED closed device And support the 2 keys for STM32MP13x - PKHTH : Hash of the 8 ECC Public Keys Hashes Table (ECDSA is the authentication algorithm) - EDMK : Encryption/Decryption Master Key Signed-off-by: Patrick Delaunay Reviewed-by: Patrice Chotard --- arch/arm/mach-stm32mp/cmd_stm32key.c | 52 ++++++++++++++++++++++++---- 1 file changed, 45 insertions(+), 7 deletions(-) diff --git a/arch/arm/mach-stm32mp/cmd_stm32key.c b/arch/arm/mach-stm32mp/cmd_stm32key.c index 4eac56082d..278253e472 100644 --- a/arch/arm/mach-stm32mp/cmd_stm32key.c +++ b/arch/arm/mach-stm32mp/cmd_stm32key.c @@ -11,9 +11,14 @@ #include #include -/* Closed device : bit 6 of OPT0*/ +/* + * Closed device: OTP0 + * STM32MP15x: bit 6 of OPT0 + * STM32MP13x: 0b111111 = 0x3F for OTP_SECURED closed device + */ #define STM32_OTP_CLOSE_ID 0 -#define STM32_OTP_CLOSE_MASK BIT(6) +#define STM32_OTP_STM32MP13x_CLOSE_MASK 0x3F +#define STM32_OTP_STM32MP15x_CLOSE_MASK BIT(6) /* PKH is the first element of the key list */ #define STM32KEY_PKH 0 @@ -25,6 +30,21 @@ struct stm32key { u8 size; }; +const struct stm32key stm32mp13_list[] = { + [STM32KEY_PKH] = { + .name = "PKHTH", + .desc = "Hash of the 8 ECC Public Keys Hashes Table (ECDSA is the authentication algorithm)", + .start = 24, + .size = 8, + }, + { + .name = "EDMK", + .desc = "Encryption/Decryption Master Key", + .start = 92, + .size = 4, + } +}; + const struct stm32key stm32mp15_list[] = { [STM32KEY_PKH] = { .name = "PKH", @@ -39,12 +59,29 @@ static u8 stm32key_index; static u8 get_key_nb(void) { - return ARRAY_SIZE(stm32mp15_list); + if (IS_ENABLED(CONFIG_STM32MP13x)) + return ARRAY_SIZE(stm32mp13_list); + + if (IS_ENABLED(CONFIG_STM32MP15x)) + return ARRAY_SIZE(stm32mp15_list); } static const struct stm32key *get_key(u8 index) { - return &stm32mp15_list[index]; + if (IS_ENABLED(CONFIG_STM32MP13x)) + return &stm32mp13_list[index]; + + if (IS_ENABLED(CONFIG_STM32MP15x)) + return &stm32mp15_list[index]; +} + +static u32 get_otp_close_mask(void) +{ + if (IS_ENABLED(CONFIG_STM32MP13x)) + return STM32_OTP_STM32MP13x_CLOSE_MASK; + + if (IS_ENABLED(CONFIG_STM32MP15x)) + return STM32_OTP_STM32MP15x_CLOSE_MASK; } #define BSEC_LOCK_ERROR (-1) @@ -123,7 +160,7 @@ static int read_key_otp(struct udevice *dev, const struct stm32key *key, bool pr static int read_close_status(struct udevice *dev, bool print, bool *closed) { int word, ret, result; - u32 val, lock; + u32 val, lock, mask; bool status; result = 0; @@ -140,7 +177,8 @@ static int read_close_status(struct udevice *dev, bool print, bool *closed) if (ret != 4) lock = BSEC_LOCK_ERROR; - status = (val & STM32_OTP_CLOSE_MASK) == STM32_OTP_CLOSE_MASK; + mask = get_otp_close_mask(); + status = (val & mask) == mask; if (closed) *closed = status; if (print) @@ -371,7 +409,7 @@ static int do_stm32key_close(struct cmd_tbl *cmdtp, int flag, int argc, char *co if (!yes && !confirm_prog()) return CMD_RET_FAILURE; - val = STM32_OTP_CLOSE_MASK; + val = get_otp_close_mask(); ret = misc_write(dev, STM32_BSEC_OTP(STM32_OTP_CLOSE_ID), &val, 4); if (ret != 4) { printf("Error: can't update OTP %d\n", STM32_OTP_CLOSE_ID); From 86d5a06ae3b826bf7b4627e926afd5378d88c574 Mon Sep 17 00:00:00 2001 From: Patrick Delaunay Date: Fri, 16 Sep 2022 16:52:57 +0200 Subject: [PATCH 239/374] configs: stm32mp1: cleanup config file Remove the unnecessary comment after the CONFIG_SYS_BOOTM_LEN migration to Kconfig. Fixes: c45568cc4e51 ("Convert CONFIG_SYS_BOOTM_LEN to Kconfig") Signed-off-by: Patrick Delaunay Reviewed-by: Patrice Chotard --- include/configs/stm32mp13_common.h | 2 -- include/configs/stm32mp15_common.h | 2 -- 2 files changed, 4 deletions(-) diff --git a/include/configs/stm32mp13_common.h b/include/configs/stm32mp13_common.h index 3ca65ea2a3..78089b965a 100644 --- a/include/configs/stm32mp13_common.h +++ b/include/configs/stm32mp13_common.h @@ -21,8 +21,6 @@ */ #define CONFIG_SYS_BOOTMAPSZ SZ_256M -/* Extend size of kernel image for uncompression */ - /*MMC SD*/ #define CONFIG_SYS_MMC_MAX_DEVICE 2 diff --git a/include/configs/stm32mp15_common.h b/include/configs/stm32mp15_common.h index c5412ffeb3..bd8e16bc1b 100644 --- a/include/configs/stm32mp15_common.h +++ b/include/configs/stm32mp15_common.h @@ -21,8 +21,6 @@ */ #define CONFIG_SYS_BOOTMAPSZ SZ_256M -/* Extend size of kernel image for uncompression */ - /*MMC SD*/ #define CONFIG_SYS_MMC_MAX_DEVICE 3 From 9f7c58dc0deacd6c453ac628953741f1a6a68126 Mon Sep 17 00:00:00 2001 From: Patrick Delaunay Date: Wed, 21 Sep 2022 09:37:13 +0200 Subject: [PATCH 240/374] ARM: dts: stm32mp15: update DDR node Remove the unnecessary nodes for TFABOOT and keep the mandatory part in SOC dtsi, only the DDRCTRL and DDRPHY addresses. This patch allows to manage the DDR configuration setting in U-Boot device tree only if it is needed, when CONFIG_SPL is defined. With TFABOOT, the DDR configuration is done in TF-A BL2 and the DDR size is dynamically computed in U-Boot since commit d72e7bbe7c28 ("ram: stm32mp1: compute DDR size from DDRCTL registers"). Signed-off-by: Patrick Delaunay Reviewed-by: Patrice Chotard --- arch/arm/dts/stm32mp15-ddr.dtsi | 16 ++++++++++++++++ arch/arm/dts/stm32mp15-u-boot.dtsi | 14 -------------- arch/arm/dts/stm32mp157a-dk1-scmi-u-boot.dtsi | 1 - arch/arm/dts/stm32mp157c-ed1-scmi-u-boot.dtsi | 1 - 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/arch/arm/dts/stm32mp15-ddr.dtsi b/arch/arm/dts/stm32mp15-ddr.dtsi index 0aac9131a6..d02f79dac6 100644 --- a/arch/arm/dts/stm32mp15-ddr.dtsi +++ b/arch/arm/dts/stm32mp15-ddr.dtsi @@ -4,7 +4,22 @@ */ #include +#ifdef CONFIG_SPL &ddr { + clocks = <&rcc AXIDCG>, + <&rcc DDRC1>, + <&rcc DDRC2>, + <&rcc DDRPHYC>, + <&rcc DDRCAPB>, + <&rcc DDRPHYCAPB>; + + clock-names = "axidcg", + "ddrc1", + "ddrc2", + "ddrphyc", + "ddrcapb", + "ddrphycapb"; + config-DDR_MEM_COMPATIBLE { u-boot,dm-pre-reloc; @@ -119,6 +134,7 @@ status = "okay"; }; }; +#endif #undef DDR_MEM_COMPATIBLE #undef DDR_MEM_NAME diff --git a/arch/arm/dts/stm32mp15-u-boot.dtsi b/arch/arm/dts/stm32mp15-u-boot.dtsi index d9d04743ac..d5c87d29d8 100644 --- a/arch/arm/dts/stm32mp15-u-boot.dtsi +++ b/arch/arm/dts/stm32mp15-u-boot.dtsi @@ -53,20 +53,6 @@ reg = <0x5a003000 0x550 0x5a004000 0x234>; - clocks = <&rcc AXIDCG>, - <&rcc DDRC1>, - <&rcc DDRC2>, - <&rcc DDRPHYC>, - <&rcc DDRCAPB>, - <&rcc DDRPHYCAPB>; - - clock-names = "axidcg", - "ddrc1", - "ddrc2", - "ddrphyc", - "ddrcapb", - "ddrphycapb"; - status = "okay"; }; }; diff --git a/arch/arm/dts/stm32mp157a-dk1-scmi-u-boot.dtsi b/arch/arm/dts/stm32mp157a-dk1-scmi-u-boot.dtsi index 2db045e7ce..1209dfe009 100644 --- a/arch/arm/dts/stm32mp157a-dk1-scmi-u-boot.dtsi +++ b/arch/arm/dts/stm32mp157a-dk1-scmi-u-boot.dtsi @@ -5,7 +5,6 @@ #include #include "stm32mp15-scmi-u-boot.dtsi" -#include "stm32mp15-ddr3-1x4Gb-1066-binG.dtsi" / { aliases { diff --git a/arch/arm/dts/stm32mp157c-ed1-scmi-u-boot.dtsi b/arch/arm/dts/stm32mp157c-ed1-scmi-u-boot.dtsi index 54662f7e29..c265745ff1 100644 --- a/arch/arm/dts/stm32mp157c-ed1-scmi-u-boot.dtsi +++ b/arch/arm/dts/stm32mp157c-ed1-scmi-u-boot.dtsi @@ -5,7 +5,6 @@ #include #include "stm32mp15-scmi-u-boot.dtsi" -#include "stm32mp15-ddr3-2x4Gb-1066-binG.dtsi" / { aliases { From 10c62336968ab99d673319541c0c246dd6a525fb Mon Sep 17 00:00:00 2001 From: Weijie Gao Date: Fri, 9 Sep 2022 19:59:09 +0800 Subject: [PATCH 241/374] arm: mediatek: add support for MediaTek MT7986 SoC This patch adds basic support for MediaTek MT7986 SoC. This include the file that will initialize the SoC after boot and its device tree. Reviewed-by: Simon Glass Tested-by: Daniel Golle Signed-off-by: Weijie Gao --- arch/arm/dts/mt7986-u-boot.dtsi | 33 ++ arch/arm/dts/mt7986.dtsi | 350 ++++++++++++++++++ arch/arm/mach-mediatek/Kconfig | 12 + arch/arm/mach-mediatek/Makefile | 1 + arch/arm/mach-mediatek/mt7986/Makefile | 4 + arch/arm/mach-mediatek/mt7986/init.c | 45 +++ arch/arm/mach-mediatek/mt7986/lowlevel_init.S | 32 ++ 7 files changed, 477 insertions(+) create mode 100644 arch/arm/dts/mt7986-u-boot.dtsi create mode 100644 arch/arm/dts/mt7986.dtsi create mode 100644 arch/arm/mach-mediatek/mt7986/Makefile create mode 100644 arch/arm/mach-mediatek/mt7986/init.c create mode 100644 arch/arm/mach-mediatek/mt7986/lowlevel_init.S diff --git a/arch/arm/dts/mt7986-u-boot.dtsi b/arch/arm/dts/mt7986-u-boot.dtsi new file mode 100644 index 0000000000..95671f8afa --- /dev/null +++ b/arch/arm/dts/mt7986-u-boot.dtsi @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2022 MediaTek Inc. + * Author: Sam Shih + */ + +&topckgen { + u-boot,dm-pre-reloc; +}; + +&pericfg { + u-boot,dm-pre-reloc; +}; + +&apmixedsys { + u-boot,dm-pre-reloc; +}; + +&timer0 { + u-boot,dm-pre-reloc; +}; + +&uart0 { + u-boot,dm-pre-reloc; +}; + +&snand { + u-boot,dm-pre-reloc; +}; + +&pinctrl { + u-boot,dm-pre-reloc; +}; diff --git a/arch/arm/dts/mt7986.dtsi b/arch/arm/dts/mt7986.dtsi new file mode 100644 index 0000000000..794ab1f4bd --- /dev/null +++ b/arch/arm/dts/mt7986.dtsi @@ -0,0 +1,350 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2022 MediaTek Inc. + * Author: Sam Shih + */ + +#include +#include +#include +#include +#include +#include + +/ { + compatible = "mediatek,mt7986"; + interrupt-parent = <&gic>; + #address-cells = <1>; + #size-cells = <1>; + + config { + u-boot,mmc-env-partition = "u-boot-env"; + }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + cpu0: cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a53"; + reg = <0x0>; + mediatek,hwver = <&hwver>; + }; + cpu1: cpu@1 { + device_type = "cpu"; + compatible = "arm,cortex-a53"; + reg = <0x1>; + mediatek,hwver = <&hwver>; + }; + cpu2: cpu@2 { + device_type = "cpu"; + compatible = "arm,cortex-a53"; + reg = <0x2>; + mediatek,hwver = <&hwver>; + }; + cpu3: cpu@3 { + device_type = "cpu"; + compatible = "arm,cortex-a53"; + reg = <0x3>; + mediatek,hwver = <&hwver>; + }; + }; + + dummy_clk: dummy12m { + compatible = "fixed-clock"; + clock-frequency = <12000000>; + #clock-cells = <0>; + /* must need this line, or uart uanable to get dummy_clk */ + u-boot,dm-pre-reloc; + }; + + hwver: hwver { + compatible = "mediatek,hwver", "syscon"; + reg = <0x8000000 0x1000>; + }; + + timer { + compatible = "arm,armv8-timer"; + interrupt-parent = <&gic>; + clock-frequency = <13000000>; + interrupts = , + , + , + ; + arm,cpu-registers-not-fw-configured; + }; + + timer0: timer@10008000 { + compatible = "mediatek,mt7986-timer"; + reg = <0x10008000 0x1000>; + interrupts = ; + clocks = <&infracfg CK_INFRA_CK_F26M>; + clock-names = "gpt-clk"; + u-boot,dm-pre-reloc; + }; + + watchdog: watchdog@1001c000 { + compatible = "mediatek,mt7986-wdt"; + reg = <0x1001c000 0x1000>; + interrupts = ; + #reset-cells = <1>; + status = "disabled"; + }; + + gic: interrupt-controller@c000000 { + compatible = "arm,gic-v3"; + #interrupt-cells = <3>; + interrupt-parent = <&gic>; + interrupt-controller; + reg = <0x0c000000 0x40000>, /* GICD */ + <0x0c080000 0x200000>; /* GICR */ + + interrupts = ; + }; + + fixed_plls: apmixedsys@1001E000 { + compatible = "mediatek,mt7986-fixed-plls"; + reg = <0x1001E000 0x1000>; + #clock-cells = <1>; + }; + + topckgen: topckgen@1001B000 { + compatible = "mediatek,mt7986-topckgen"; + reg = <0x1001B000 0x1000>; + clock-parent = <&fixed_plls>; + #clock-cells = <1>; + }; + + infracfg_ao: infracfg_ao@10001000 { + compatible = "mediatek,mt7986-infracfg_ao"; + reg = <0x10001000 0x68>; + clock-parent = <&infracfg>; + #clock-cells = <1>; + }; + + infracfg: infracfg@10001040 { + compatible = "mediatek,mt7986-infracfg"; + reg = <0x10001000 0x1000>; + clock-parent = <&topckgen>; + #clock-cells = <1>; + }; + + pinctrl: pinctrl@1001f000 { + compatible = "mediatek,mt7986-pinctrl"; + reg = <0x1001f000 0x1000>, + <0x11c30000 0x1000>, + <0x11c40000 0x1000>, + <0x11e20000 0x1000>, + <0x11e30000 0x1000>, + <0x11f00000 0x1000>, + <0x11f10000 0x1000>, + <0x1000b000 0x1000>; + reg-names = "gpio_base", "iocfg_rt_base", "iocfg_rb_base", + "iocfg_lt_base", "iocfg_lb_base", "iocfg_tr_base", + "iocfg_tl_base", "eint"; + gpio: gpio-controller { + gpio-controller; + #gpio-cells = <2>; + }; + }; + + pwm: pwm@10048000 { + compatible = "mediatek,mt7986-pwm"; + reg = <0x10048000 0x1000>; + #clock-cells = <1>; + #pwm-cells = <2>; + interrupts = ; + clocks = <&infracfg CK_INFRA_PWM>, + <&infracfg_ao CK_INFRA_PWM_BSEL>, + <&infracfg_ao CK_INFRA_PWM1_CK>, + <&infracfg_ao CK_INFRA_PWM2_CK>; + assigned-clocks = <&topckgen CK_TOP_PWM_SEL>, + <&infracfg CK_INFRA_PWM_BSEL>, + <&infracfg CK_INFRA_PWM1_SEL>, + <&infracfg CK_INFRA_PWM2_SEL>; + assigned-clock-parents = <&topckgen CK_TOP_CB_M_D4>, + <&infracfg CK_INFRA_PWM>, + <&infracfg CK_INFRA_PWM>, + <&infracfg CK_INFRA_PWM>; + clock-names = "top", "main", "pwm1", "pwm2"; + status = "disabled"; + u-boot,dm-pre-reloc; + }; + + uart0: serial@11002000 { + compatible = "mediatek,hsuart"; + reg = <0x11002000 0x400>; + interrupts = ; + clocks = <&infracfg_ao CK_INFRA_UART0_CK>; + assigned-clocks = <&topckgen CK_TOP_UART_SEL>, + <&infracfg_ao CK_INFRA_UART0_SEL>; + assigned-clock-parents = <&topckgen CK_TOP_CB_CKSQ_40M>, + <&infracfg CK_INFRA_UART>; + mediatek,force-highspeed; + status = "disabled"; + u-boot,dm-pre-reloc; + }; + + uart1: serial@11003000 { + compatible = "mediatek,hsuart"; + reg = <0x11003000 0x400>; + interrupts = ; + clocks = <&infracfg_ao CK_INFRA_UART1_CK>; + assigned-clocks = <&infracfg CK_INFRA_UART1_SEL>; + assigned-clock-parents = <&infracfg CK_INFRA_CK_F26M>; + mediatek,force-highspeed; + status = "disabled"; + }; + + uart2: serial@11004000 { + compatible = "mediatek,hsuart"; + reg = <0x11004000 0x400>; + interrupts = ; + clocks = <&infracfg_ao CK_INFRA_UART2_CK>; + assigned-clocks = <&infracfg CK_INFRA_UART2_SEL>; + assigned-clock-parents = <&infracfg CK_INFRA_CK_F26M>; + mediatek,force-highspeed; + status = "disabled"; + }; + + snand: snand@11005000 { + compatible = "mediatek,mt7986-snand"; + reg = <0x11005000 0x1000>, + <0x11006000 0x1000>; + reg-names = "nfi", "ecc"; + clocks = <&infracfg_ao CK_INFRA_SPINFI1_CK>, + <&infracfg_ao CK_INFRA_NFI1_CK>, + <&infracfg_ao CK_INFRA_NFI_HCK_CK>; + clock-names = "pad_clk", "nfi_clk", "nfi_hclk"; + assigned-clocks = <&topckgen CK_TOP_SPINFI_SEL>, + <&topckgen CK_TOP_NFI1X_SEL>; + assigned-clock-parents = <&topckgen CK_TOP_CB_M_D8>, + <&topckgen CK_TOP_CB_M_D8>; + status = "disabled"; + }; + + ethsys: syscon@15000000 { + compatible = "mediatek,mt7986-ethsys", "syscon"; + reg = <0x15000000 0x1000>; + clock-parent = <&topckgen>; + #clock-cells = <1>; + #reset-cells = <1>; + }; + + eth: ethernet@15100000 { + compatible = "mediatek,mt7986-eth", "syscon"; + reg = <0x15100000 0x20000>; + resets = <ðsys ETHSYS_FE_RST>; + reset-names = "fe"; + mediatek,ethsys = <ðsys>; + mediatek,sgmiisys = <&sgmiisys0>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + sgmiisys0: syscon@10060000 { + compatible = "mediatek,mt7986-sgmiisys", "syscon"; + reg = <0x10060000 0x1000>; + #clock-cells = <1>; + }; + + sgmiisys1: syscon@10070000 { + compatible = "mediatek,mt7986-sgmiisys", "syscon"; + reg = <0x10070000 0x1000>; + #clock-cells = <1>; + }; + + spi0: spi@1100a000 { + compatible = "mediatek,ipm-spi"; + reg = <0x1100a000 0x100>; + clocks = <&infracfg_ao CK_INFRA_SPI0_CK>, + <&topckgen CK_TOP_SPI_SEL>; + assigned-clocks = <&topckgen CK_TOP_SPI_SEL>, + <&infracfg CK_INFRA_SPI0_SEL>; + assigned-clock-parents = <&topckgen CK_TOP_CB_M_D2>, + <&topckgen CK_INFRA_ISPI0>; + clock-names = "sel-clk", "spi-clk"; + interrupts = ; + status = "disabled"; + }; + + spi1: spi@1100b000 { + compatible = "mediatek,ipm-spi"; + reg = <0x1100b000 0x100>; + interrupts = ; + status = "disabled"; + }; + + mmc0: mmc@11230000 { + compatible = "mediatek,mt7986-mmc"; + reg = <0x11230000 0x1000>, + <0x11C20000 0x1000>; + interrupts = ; + clocks = <&topckgen CK_TOP_EMMC_416M>, + <&topckgen CK_TOP_EMMC_250M>, + <&infracfg_ao CK_INFRA_MSDC_CK>; + assigned-clocks = <&topckgen CK_TOP_EMMC_416M_SEL>, + <&topckgen CK_TOP_EMMC_250M_SEL>; + assigned-clock-parents = <&topckgen CK_TOP_CB_M_416M>, + <&topckgen CK_TOP_NET1_D5_D2>; + clock-names = "source", "hclk", "source_cg"; + status = "disabled"; + }; + + xhci: xhci@11200000 { + compatible = "mediatek,mt7986-xhci", + "mediatek,mtk-xhci"; + reg = <0x11200000 0x2e00>, + <0x11203e00 0x0100>; + reg-names = "mac", "ippc"; + interrupts = ; + phys = <&u2port0 PHY_TYPE_USB2>, + <&u3port0 PHY_TYPE_USB3>, + <&u2port1 PHY_TYPE_USB2>; + clocks = <&dummy_clk>, + <&dummy_clk>, + <&dummy_clk>, + <&dummy_clk>, + <&dummy_clk>; + clock-names = "sys_ck", + "xhci_ck", + "ref_ck", + "mcu_ck", + "dma_ck"; + tpl-support; + status = "okay"; + }; + + usbtphy: usb-phy@11e10000 { + compatible = "mediatek,mt7986", + "mediatek,generic-tphy-v2"; + #address-cells = <1>; + #size-cells = <1>; + status = "okay"; + + u2port0: usb-phy@11e10000 { + reg = <0x11e10000 0x700>; + clocks = <&dummy_clk>; + clock-names = "ref"; + #phy-cells = <1>; + status = "okay"; + }; + + u3port0: usb-phy@11e10700 { + reg = <0x11e10700 0x900>; + clocks = <&dummy_clk>; + clock-names = "ref"; + #phy-cells = <1>; + status = "okay"; + }; + + u2port1: usb-phy@11e11000 { + reg = <0x11e11000 0x700>; + clocks = <&dummy_clk>; + clock-names = "ref"; + #phy-cells = <1>; + status = "okay"; + }; + }; +}; diff --git a/arch/arm/mach-mediatek/Kconfig b/arch/arm/mach-mediatek/Kconfig index f79a5c62cd..82fadeba8a 100644 --- a/arch/arm/mach-mediatek/Kconfig +++ b/arch/arm/mach-mediatek/Kconfig @@ -40,6 +40,15 @@ config TARGET_MT7629 including DDR3, crypto engine, 3x3 11n/ac Wi-Fi, Gigabit Ethernet, switch, USB3.0, PCIe, UART, SPI, I2C and PWM. +config TARGET_MT7986 + bool "MediaTek MT7986 SoC" + select ARM64 + select CPU + help + The MediaTek MT7986 is a ARM64-based SoC with a quad-core Cortex-A53. + including UART, SPI, SPI flash, USB3.0, MMC, NAND, SNFI, PWM, PCIe, + Gigabit Ethernet, I2C, built-in 4x4 Wi-Fi, and PCIe. + config TARGET_MT8183 bool "MediaTek MT8183 SoC" select ARM64 @@ -84,6 +93,7 @@ config SYS_BOARD default "mt7622" if TARGET_MT7622 default "mt7623" if TARGET_MT7623 default "mt7629" if TARGET_MT7629 + default "mt7986" if TARGET_MT7986 default "mt8183" if TARGET_MT8183 default "mt8512" if TARGET_MT8512 default "mt8516" if TARGET_MT8516 @@ -99,6 +109,7 @@ config SYS_CONFIG_NAME default "mt7622" if TARGET_MT7622 default "mt7623" if TARGET_MT7623 default "mt7629" if TARGET_MT7629 + default "mt7986" if TARGET_MT7986 default "mt8183" if TARGET_MT8183 default "mt8512" if TARGET_MT8512 default "mt8516" if TARGET_MT8516 @@ -113,6 +124,7 @@ config MTK_BROM_HEADER_INFO string default "media=nor" if TARGET_MT8518 || TARGET_MT8512 || TARGET_MT7629 || TARGET_MT7622 default "media=emmc" if TARGET_MT8516 || TARGET_MT8365 || TARGET_MT8183 + default "media=snand;nandinfo=2k+64" if TARGET_MT7986 default "lk=1" if TARGET_MT7623 endif diff --git a/arch/arm/mach-mediatek/Makefile b/arch/arm/mach-mediatek/Makefile index 0f5b0c16d2..fe5c3a837c 100644 --- a/arch/arm/mach-mediatek/Makefile +++ b/arch/arm/mach-mediatek/Makefile @@ -7,6 +7,7 @@ obj-$(CONFIG_MT8512) += mt8512/ obj-$(CONFIG_TARGET_MT7622) += mt7622/ obj-$(CONFIG_TARGET_MT7623) += mt7623/ obj-$(CONFIG_TARGET_MT7629) += mt7629/ +obj-$(CONFIG_TARGET_MT7986) += mt7986/ obj-$(CONFIG_TARGET_MT8183) += mt8183/ obj-$(CONFIG_TARGET_MT8516) += mt8516/ obj-$(CONFIG_TARGET_MT8518) += mt8518/ diff --git a/arch/arm/mach-mediatek/mt7986/Makefile b/arch/arm/mach-mediatek/mt7986/Makefile new file mode 100644 index 0000000000..007eb4a367 --- /dev/null +++ b/arch/arm/mach-mediatek/mt7986/Makefile @@ -0,0 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 + +obj-y += init.o +obj-y += lowlevel_init.o diff --git a/arch/arm/mach-mediatek/mt7986/init.c b/arch/arm/mach-mediatek/mt7986/init.c new file mode 100644 index 0000000000..0fd459657d --- /dev/null +++ b/arch/arm/mach-mediatek/mt7986/init.c @@ -0,0 +1,45 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2022 MediaTek Inc. + * Author: Sam Shih + */ + +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +int dram_init(void) +{ + gd->ram_size = get_ram_size((void *)CONFIG_SYS_SDRAM_BASE, SZ_2G); + + return 0; +} + +void reset_cpu(ulong addr) +{ + psci_system_reset(); +} + +static struct mm_region mt7986_mem_map[] = { + { + /* DDR */ + .virt = 0x40000000UL, + .phys = 0x40000000UL, + .size = 0x80000000UL, + .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_OUTER_SHARE, + }, { + .virt = 0x00000000UL, + .phys = 0x00000000UL, + .size = 0x40000000UL, + .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | + PTE_BLOCK_NON_SHARE | + PTE_BLOCK_PXN | PTE_BLOCK_UXN + }, { + 0, + } +}; + +struct mm_region *mem_map = mt7986_mem_map; diff --git a/arch/arm/mach-mediatek/mt7986/lowlevel_init.S b/arch/arm/mach-mediatek/mt7986/lowlevel_init.S new file mode 100644 index 0000000000..85a1cea359 --- /dev/null +++ b/arch/arm/mach-mediatek/mt7986/lowlevel_init.S @@ -0,0 +1,32 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2022 MediaTek Inc. + * Author: Sam Shih + */ + +/* + * Switch from AArch64 EL2 to AArch32 EL2 + * @param inputs: + * x0: argument, zero + * x1: machine nr + * x2: fdt address + * x3: input argument + * x4: kernel entry point + * @param outputs for secure firmware: + * x0: function id + * x1: kernel entry point + * x2: machine nr + * x3: fdt address + * + * [1] https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git/tree/plat/mediatek/common/mtk_sip_svc.c +*/ + +.global armv8_el2_to_aarch32 +armv8_el2_to_aarch32: + mov x3, x2 + mov x2, x1 + mov x1, x4 + mov x4, #0 + ldr x0, =0x82000200 /* MTK_SIP_KERNEL_BOOT_AARCH32 */ + SMC #0 + ret From ed86e4fba10d8dcb9f65bef7a3535d17cefc9cf8 Mon Sep 17 00:00:00 2001 From: Weijie Gao Date: Fri, 9 Sep 2022 19:59:11 +0800 Subject: [PATCH 242/374] arm: mediatek: add support for MediaTek MT7981 SoC This patch adds basic support for MediaTek MT7981 SoC. This include the file that will initialize the SoC after boot and its device tree. Reviewed-by: Simon Glass Signed-off-by: Weijie Gao --- arch/arm/dts/mt7981.dtsi | 295 ++++++++++++++++++ arch/arm/mach-mediatek/Kconfig | 13 +- arch/arm/mach-mediatek/Makefile | 1 + arch/arm/mach-mediatek/mt7981/Makefile | 4 + arch/arm/mach-mediatek/mt7981/init.c | 45 +++ arch/arm/mach-mediatek/mt7981/lowlevel_init.S | 32 ++ 6 files changed, 389 insertions(+), 1 deletion(-) create mode 100644 arch/arm/dts/mt7981.dtsi create mode 100644 arch/arm/mach-mediatek/mt7981/Makefile create mode 100644 arch/arm/mach-mediatek/mt7981/init.c create mode 100644 arch/arm/mach-mediatek/mt7981/lowlevel_init.S diff --git a/arch/arm/dts/mt7981.dtsi b/arch/arm/dts/mt7981.dtsi new file mode 100644 index 0000000000..3089371805 --- /dev/null +++ b/arch/arm/dts/mt7981.dtsi @@ -0,0 +1,295 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2022 MediaTek Inc. + * Author: Sam Shih + */ + +#include +#include +#include +#include +#include + +/ { + compatible = "mediatek,mt7981"; + interrupt-parent = <&gic>; + #address-cells = <1>; + #size-cells = <1>; + cpus { + #address-cells = <1>; + #size-cells = <0>; + cpu0: cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a53"; + reg = <0x0>; + mediatek,hwver = <&hwver>; + }; + cpu1: cpu@1 { + device_type = "cpu"; + compatible = "arm,cortex-a53"; + reg = <0x1>; + mediatek,hwver = <&hwver>; + }; + }; + + gpt_clk: gpt_dummy20m { + compatible = "fixed-clock"; + clock-frequency = <13000000>; + #clock-cells = <0>; + u-boot,dm-pre-reloc; + }; + + hwver: hwver { + compatible = "mediatek,hwver", "syscon"; + reg = <0x8000000 0x1000>; + }; + + timer { + compatible = "arm,armv8-timer"; + interrupt-parent = <&gic>; + clock-frequency = <13000000>; + interrupts = , + , + , + ; + arm,cpu-registers-not-fw-configured; + }; + + timer0: timer@10008000 { + compatible = "mediatek,mt7986-timer"; + reg = <0x10008000 0x1000>; + interrupts = ; + clocks = <&gpt_clk>; + clock-names = "gpt-clk"; + u-boot,dm-pre-reloc; + }; + + watchdog: watchdog@1001c000 { + compatible = "mediatek,mt7986-wdt"; + reg = <0x1001c000 0x1000>; + interrupts = ; + #reset-cells = <1>; + status = "disabled"; + }; + + gic: interrupt-controller@c000000 { + compatible = "arm,gic-v3"; + #interrupt-cells = <3>; + interrupt-parent = <&gic>; + interrupt-controller; + reg = <0x0c000000 0x40000>, /* GICD */ + <0x0c080000 0x200000>; /* GICR */ + + interrupts = ; + }; + + fixed_plls: apmixedsys@1001e000 { + compatible = "mediatek,mt7981-fixed-plls"; + reg = <0x1001e000 0x1000>; + #clock-cells = <1>; + u-boot,dm-pre-reloc; + }; + + topckgen: topckgen@1001b000 { + compatible = "mediatek,mt7981-topckgen"; + reg = <0x1001b000 0x1000>; + clock-parent = <&fixed_plls>; + #clock-cells = <1>; + u-boot,dm-pre-reloc; + }; + + infracfg_ao: infracfg_ao@10001000 { + compatible = "mediatek,mt7981-infracfg_ao"; + reg = <0x10001000 0x80>; + clock-parent = <&infracfg>; + #clock-cells = <1>; + u-boot,dm-pre-reloc; + }; + + infracfg: infracfg@10001000 { + compatible = "mediatek,mt7981-infracfg"; + reg = <0x10001000 0x30>; + clock-parent = <&topckgen>; + #clock-cells = <1>; + u-boot,dm-pre-reloc; + }; + + pinctrl: pinctrl@11d00000 { + compatible = "mediatek,mt7981-pinctrl"; + reg = <0x11d00000 0x1000>, + <0x11c00000 0x1000>, + <0x11c10000 0x1000>, + <0x11d20000 0x1000>, + <0x11e00000 0x1000>, + <0x11e20000 0x1000>, + <0x11f00000 0x1000>, + <0x11f10000 0x1000>, + <0x1000b000 0x1000>; + reg-names = "gpio_base", "iocfg_rt_base", "iocfg_rm_base", + "iocfg_rb_base", "iocfg_lb_base", "iocfg_bl_base", + "iocfg_tm_base", "iocfg_tl_base", "eint"; + gpio: gpio-controller { + gpio-controller; + #gpio-cells = <2>; + }; + }; + + pwm: pwm@10048000 { + compatible = "mediatek,mt7981-pwm"; + reg = <0x10048000 0x1000>; + #clock-cells = <1>; + #pwm-cells = <2>; + interrupts = ; + clocks = <&infracfg CK_INFRA_PWM>, + <&infracfg_ao CK_INFRA_PWM_BSEL>, + <&infracfg_ao CK_INFRA_PWM1_CK>, + <&infracfg_ao CK_INFRA_PWM2_CK>, + /* FIXME */ + <&infracfg_ao CK_INFRA_PWM2_CK>; + assigned-clocks = <&topckgen CK_TOP_PWM_SEL>; + assigned-clock-parents = <&topckgen CK_TOP_CB_CKSQ_40M>; + clock-names = "top", "main", "pwm1", "pwm2", "pwm3"; + status = "disabled"; + }; + + uart0: serial@11002000 { + compatible = "mediatek,hsuart"; + reg = <0x11002000 0x400>; + interrupts = ; + clocks = <&infracfg_ao CK_INFRA_UART0_CK>; + assigned-clocks = <&topckgen CK_TOP_UART_SEL>, + <&infracfg_ao CK_INFRA_UART0_SEL>; + assigned-clock-parents = <&topckgen CK_TOP_CB_CKSQ_40M>, + <&infracfg CK_INFRA_UART>; + mediatek,force-highspeed; + status = "disabled"; + u-boot,dm-pre-reloc; + }; + + uart1: serial@11003000 { + compatible = "mediatek,hsuart"; + reg = <0x11003000 0x400>; + interrupts = ; + clocks = <&infracfg_ao CK_INFRA_UART1_CK>; + assigned-clocks = <&topckgen CK_TOP_UART_SEL>, + <&infracfg_ao CK_INFRA_UART1_SEL>; + assigned-clock-parents = <&topckgen CK_TOP_CB_CKSQ_40M>, + <&infracfg CK_INFRA_UART>; + mediatek,force-highspeed; + status = "disabled"; + }; + + uart2: serial@11004000 { + compatible = "mediatek,hsuart"; + reg = <0x11004000 0x400>; + interrupts = ; + clocks = <&infracfg_ao CK_INFRA_UART2_CK>; + assigned-clocks = <&topckgen CK_TOP_UART_SEL>, + <&infracfg_ao CK_INFRA_UART2_SEL>; + assigned-clock-parents = <&topckgen CK_TOP_CB_CKSQ_40M>, + <&infracfg CK_INFRA_UART>; + mediatek,force-highspeed; + status = "disabled"; + }; + + snand: snand@11005000 { + compatible = "mediatek,mt7986-snand"; + reg = <0x11005000 0x1000>, + <0x11006000 0x1000>; + reg-names = "nfi", "ecc"; + clocks = <&infracfg_ao CK_INFRA_SPINFI1_CK>, + <&infracfg_ao CK_INFRA_NFI1_CK>, + <&infracfg_ao CK_INFRA_NFI_HCK_CK>; + clock-names = "pad_clk", "nfi_clk", "nfi_hclk"; + assigned-clocks = <&topckgen CK_TOP_SPINFI_SEL>, + <&topckgen CK_TOP_NFI1X_SEL>; + assigned-clock-parents = <&topckgen CK_TOP_CB_M_D8>, + <&topckgen CK_TOP_CB_M_D8>; + status = "disabled"; + }; + + ethsys: syscon@15000000 { + compatible = "mediatek,mt7981-ethsys", "syscon"; + reg = <0x15000000 0x1000>; + clock-parent = <&topckgen>; + #clock-cells = <1>; + #reset-cells = <1>; + }; + + eth: ethernet@15100000 { + compatible = "mediatek,mt7981-eth", "syscon"; + reg = <0x15100000 0x20000>; + resets = <ðsys ETHSYS_FE_RST>; + reset-names = "fe"; + mediatek,ethsys = <ðsys>; + mediatek,sgmiisys = <&sgmiisys0>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + sgmiisys0: syscon@10060000 { + compatible = "mediatek,mt7986-sgmiisys", "syscon"; + reg = <0x10060000 0x1000>; + pn_swap; + #clock-cells = <1>; + }; + + sgmiisys1: syscon@10070000 { + compatible = "mediatek,mt7986-sgmiisys", "syscon"; + reg = <0x10070000 0x1000>; + #clock-cells = <1>; + }; + + spi0: spi@1100a000 { + compatible = "mediatek,ipm-spi"; + reg = <0x1100a000 0x100>; + clocks = <&infracfg_ao CK_INFRA_SPI0_CK>, + <&topckgen CK_TOP_SPI_SEL>; + assigned-clocks = <&topckgen CK_TOP_SPI_SEL>, + <&infracfg CK_INFRA_SPI0_SEL>; + assigned-clock-parents = <&topckgen CK_TOP_CB_M_D2>, + <&topckgen CK_INFRA_ISPI0>; + clock-names = "sel-clk", "spi-clk"; + interrupts = ; + status = "disabled"; + }; + + spi1: spi@1100b000 { + compatible = "mediatek,ipm-spi"; + reg = <0x1100b000 0x100>; + interrupts = ; + status = "disabled"; + }; + + spi2: spi@11009000 { + compatible = "mediatek,ipm-spi"; + reg = <0x11009000 0x100>; + clocks = <&infracfg_ao CK_INFRA_SPI0_CK>, + <&topckgen CK_TOP_SPI_SEL>; + assigned-clocks = <&topckgen CK_TOP_SPI_SEL>, + <&infracfg CK_INFRA_SPI0_SEL>; + assigned-clock-parents = <&topckgen CK_TOP_CB_M_D2>, + <&topckgen CK_INFRA_ISPI0>; + clock-names = "sel-clk", "spi-clk"; + interrupts = ; + status = "disabled"; + }; + + mmc0: mmc@11230000 { + compatible = "mediatek,mt7981-mmc"; + reg = <0x11230000 0x1000>, + <0x11C20000 0x1000>; + interrupts = ; + clocks = <&topckgen CK_TOP_EMMC_400M>, + <&topckgen CK_TOP_EMMC_208M>, + <&infracfg_ao CK_INFRA_MSDC_CK>; + assigned-clocks = <&topckgen CK_TOP_EMMC_400M_SEL>, + <&topckgen CK_TOP_EMMC_208M_SEL>; + assigned-clock-parents = <&topckgen CK_TOP_CB_NET2_D2>, + <&topckgen CK_TOP_CB_M_D2>; + clock-names = "source", "hclk", "source_cg"; + status = "disabled"; + }; + +}; diff --git a/arch/arm/mach-mediatek/Kconfig b/arch/arm/mach-mediatek/Kconfig index 82fadeba8a..04aa2fd97f 100644 --- a/arch/arm/mach-mediatek/Kconfig +++ b/arch/arm/mach-mediatek/Kconfig @@ -40,6 +40,15 @@ config TARGET_MT7629 including DDR3, crypto engine, 3x3 11n/ac Wi-Fi, Gigabit Ethernet, switch, USB3.0, PCIe, UART, SPI, I2C and PWM. +config TARGET_MT7981 + bool "MediaTek MT7981 SoC" + select ARM64 + select CPU + help + The MediaTek MT7981 is a ARM64-based SoC with a dual-core Cortex-A53. + including UART, SPI, USB, NAND, SNFI, PWM, Gigabit Ethernet, I2C, + built-in Wi-Fi, and PCIe. + config TARGET_MT7986 bool "MediaTek MT7986 SoC" select ARM64 @@ -93,6 +102,7 @@ config SYS_BOARD default "mt7622" if TARGET_MT7622 default "mt7623" if TARGET_MT7623 default "mt7629" if TARGET_MT7629 + default "mt7981" if TARGET_MT7981 default "mt7986" if TARGET_MT7986 default "mt8183" if TARGET_MT8183 default "mt8512" if TARGET_MT8512 @@ -109,6 +119,7 @@ config SYS_CONFIG_NAME default "mt7622" if TARGET_MT7622 default "mt7623" if TARGET_MT7623 default "mt7629" if TARGET_MT7629 + default "mt7981" if TARGET_MT7981 default "mt7986" if TARGET_MT7986 default "mt8183" if TARGET_MT8183 default "mt8512" if TARGET_MT8512 @@ -124,7 +135,7 @@ config MTK_BROM_HEADER_INFO string default "media=nor" if TARGET_MT8518 || TARGET_MT8512 || TARGET_MT7629 || TARGET_MT7622 default "media=emmc" if TARGET_MT8516 || TARGET_MT8365 || TARGET_MT8183 - default "media=snand;nandinfo=2k+64" if TARGET_MT7986 + default "media=snand;nandinfo=2k+64" if TARGET_MT7981 || TARGET_MT7986 default "lk=1" if TARGET_MT7623 endif diff --git a/arch/arm/mach-mediatek/Makefile b/arch/arm/mach-mediatek/Makefile index fe5c3a837c..fc85293f71 100644 --- a/arch/arm/mach-mediatek/Makefile +++ b/arch/arm/mach-mediatek/Makefile @@ -7,6 +7,7 @@ obj-$(CONFIG_MT8512) += mt8512/ obj-$(CONFIG_TARGET_MT7622) += mt7622/ obj-$(CONFIG_TARGET_MT7623) += mt7623/ obj-$(CONFIG_TARGET_MT7629) += mt7629/ +obj-$(CONFIG_TARGET_MT7981) += mt7981/ obj-$(CONFIG_TARGET_MT7986) += mt7986/ obj-$(CONFIG_TARGET_MT8183) += mt8183/ obj-$(CONFIG_TARGET_MT8516) += mt8516/ diff --git a/arch/arm/mach-mediatek/mt7981/Makefile b/arch/arm/mach-mediatek/mt7981/Makefile new file mode 100644 index 0000000000..007eb4a367 --- /dev/null +++ b/arch/arm/mach-mediatek/mt7981/Makefile @@ -0,0 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 + +obj-y += init.o +obj-y += lowlevel_init.o diff --git a/arch/arm/mach-mediatek/mt7981/init.c b/arch/arm/mach-mediatek/mt7981/init.c new file mode 100644 index 0000000000..4f77a3defb --- /dev/null +++ b/arch/arm/mach-mediatek/mt7981/init.c @@ -0,0 +1,45 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2022 MediaTek Inc. + * Author: Sam Shih + */ + +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +int dram_init(void) +{ + gd->ram_size = get_ram_size((void *)CONFIG_SYS_SDRAM_BASE, SZ_2G); + + return 0; +} + +void reset_cpu(ulong addr) +{ + psci_system_reset(); +} + +static struct mm_region mt7981_mem_map[] = { + { + /* DDR */ + .virt = 0x40000000UL, + .phys = 0x40000000UL, + .size = 0x80000000UL, + .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_OUTER_SHARE, + }, { + .virt = 0x00000000UL, + .phys = 0x00000000UL, + .size = 0x40000000UL, + .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | + PTE_BLOCK_NON_SHARE | + PTE_BLOCK_PXN | PTE_BLOCK_UXN + }, { + 0, + } +}; + +struct mm_region *mem_map = mt7981_mem_map; diff --git a/arch/arm/mach-mediatek/mt7981/lowlevel_init.S b/arch/arm/mach-mediatek/mt7981/lowlevel_init.S new file mode 100644 index 0000000000..85a1cea359 --- /dev/null +++ b/arch/arm/mach-mediatek/mt7981/lowlevel_init.S @@ -0,0 +1,32 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2022 MediaTek Inc. + * Author: Sam Shih + */ + +/* + * Switch from AArch64 EL2 to AArch32 EL2 + * @param inputs: + * x0: argument, zero + * x1: machine nr + * x2: fdt address + * x3: input argument + * x4: kernel entry point + * @param outputs for secure firmware: + * x0: function id + * x1: kernel entry point + * x2: machine nr + * x3: fdt address + * + * [1] https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git/tree/plat/mediatek/common/mtk_sip_svc.c +*/ + +.global armv8_el2_to_aarch32 +armv8_el2_to_aarch32: + mov x3, x2 + mov x2, x1 + mov x1, x4 + mov x4, #0 + ldr x0, =0x82000200 /* MTK_SIP_KERNEL_BOOT_AARCH32 */ + SMC #0 + ret From 389ba6986bf3559d26564e4a770cab0a7503fd2f Mon Sep 17 00:00:00 2001 From: Weijie Gao Date: Fri, 9 Sep 2022 19:59:13 +0800 Subject: [PATCH 243/374] board: mediatek: add MT7986 reference boards Add general board files based on MT7986 SoCs. MT7986 uses one mmc controller for booting from both SD and eMMC. Both MT7986A and MT7986B use the same pins for spi controller. Configs for various boot types: 1. mt7986_rfb_defconfig - SPI-NOR and SPI-NAND for MT7986A/B 2. mt7986a_bpir3_emmc_defconfig - eMMC for MT7986A only 3. mt7986a_bpir3_sd_defconfig - SD for MT7986A only Reviewed-by: Simon Glass Signed-off-by: Weijie Gao --- arch/arm/dts/Makefile | 6 + arch/arm/dts/mt7986a-emmc-rfb.dts | 16 ++ arch/arm/dts/mt7986a-rfb.dts | 218 +++++++++++++++++++++++++++ arch/arm/dts/mt7986a-sd-rfb.dts | 177 ++++++++++++++++++++++ arch/arm/dts/mt7986b-emmc-rfb.dts | 16 ++ arch/arm/dts/mt7986b-rfb.dts | 204 +++++++++++++++++++++++++ arch/arm/dts/mt7986b-sd-rfb.dts | 173 +++++++++++++++++++++ board/mediatek/mt7986/MAINTAINERS | 12 ++ board/mediatek/mt7986/Makefile | 3 + board/mediatek/mt7986/mt7986_rfb.c | 10 ++ configs/mt7986_rfb_defconfig | 66 ++++++++ configs/mt7986a_bpir3_emmc_defconfig | 64 ++++++++ configs/mt7986a_bpir3_sd_defconfig | 64 ++++++++ include/configs/mt7986.h | 25 +++ 14 files changed, 1054 insertions(+) create mode 100644 arch/arm/dts/mt7986a-emmc-rfb.dts create mode 100644 arch/arm/dts/mt7986a-rfb.dts create mode 100644 arch/arm/dts/mt7986a-sd-rfb.dts create mode 100644 arch/arm/dts/mt7986b-emmc-rfb.dts create mode 100644 arch/arm/dts/mt7986b-rfb.dts create mode 100644 arch/arm/dts/mt7986b-sd-rfb.dts create mode 100644 board/mediatek/mt7986/MAINTAINERS create mode 100644 board/mediatek/mt7986/Makefile create mode 100644 board/mediatek/mt7986/mt7986_rfb.c create mode 100644 configs/mt7986_rfb_defconfig create mode 100644 configs/mt7986a_bpir3_emmc_defconfig create mode 100644 configs/mt7986a_bpir3_sd_defconfig create mode 100644 include/configs/mt7986.h diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index 5a42d5061c..138c7edf0a 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -1235,6 +1235,12 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += \ mt7622-bananapi-bpi-r64.dtb \ mt7623n-bananapi-bpi-r2.dtb \ mt7629-rfb.dtb \ + mt7986a-rfb.dtb \ + mt7986b-rfb.dtb \ + mt7986a-sd-rfb.dtb \ + mt7986b-sd-rfb.dtb \ + mt7986a-emmc-rfb.dtb \ + mt7986b-emmc-rfb.dtb \ mt8183-pumpkin.dtb \ mt8512-bm1-emmc.dtb \ mt8516-pumpkin.dtb \ diff --git a/arch/arm/dts/mt7986a-emmc-rfb.dts b/arch/arm/dts/mt7986a-emmc-rfb.dts new file mode 100644 index 0000000000..315bdd0b14 --- /dev/null +++ b/arch/arm/dts/mt7986a-emmc-rfb.dts @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2022 MediaTek Inc. + * Author: Sam Shih + */ + +/dts-v1/; +#include "mt7986a-rfb.dts" + +/ { + compatible = "mediatek,mt7986", "mediatek,mt7986-rfb", + "mediatek,mt7986-emmc-rfb"; + bl2_verify { + bl2_compatible = "emmc"; + }; +}; diff --git a/arch/arm/dts/mt7986a-rfb.dts b/arch/arm/dts/mt7986a-rfb.dts new file mode 100644 index 0000000000..80def57e1a --- /dev/null +++ b/arch/arm/dts/mt7986a-rfb.dts @@ -0,0 +1,218 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2022 MediaTek Inc. + * Author: Sam Shih + */ + +/dts-v1/; +#include "mt7986.dtsi" +#include + +/ { + #address-cells = <1>; + #size-cells = <1>; + model = "mt7986-rfb"; + compatible = "mediatek,mt7986", "mediatek,mt7986-rfb"; + chosen { + stdout-path = &uart0; + tick-timer = &timer0; + }; + + reg_1p8v: regulator-1p8v { + compatible = "regulator-fixed"; + regulator-name = "fixed-1.8V"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-boot-on; + regulator-always-on; + }; + + reg_3p3v: regulator-3p3v { + compatible = "regulator-fixed"; + regulator-name = "fixed-3.3V"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + regulator-always-on; + }; +}; + +&uart0 { + status = "okay"; +}; + +&uart1 { + pinctrl-names = "default"; + pinctrl-0 = <&uart1_pins>; + status = "disabled"; +}; + +ð { + status = "okay"; + mediatek,gmac-id = <0>; + phy-mode = "sgmii"; + mediatek,switch = "mt7531"; + reset-gpios = <&gpio 5 GPIO_ACTIVE_HIGH>; + + fixed-link { + speed = <1000>; + full-duplex; + }; +}; + +&pinctrl { + spi_flash_pins: spi0-pins-func-1 { + mux { + function = "flash"; + groups = "spi0", "spi0_wp_hold"; + }; + + conf-pu { + pins = "SPI2_CS", "SPI2_HOLD", "SPI2_WP"; + drive-strength = ; + bias-pull-up = ; + }; + + conf-pd { + pins = "SPI2_CLK", "SPI2_MOSI", "SPI2_MISO"; + drive-strength = ; + bias-pull-down = ; + }; + }; + + snfi_pins: snfi-pins-func-1 { + mux { + function = "flash"; + groups = "snfi"; + }; + + clk { + pins = "SPI0_CLK"; + drive-strength = ; + bias-pull-down = ; + }; + + conf-pu { + pins = "SPI0_CS", "SPI0_HOLD", "SPI0_WP"; + drive-strength = ; + bias-pull-up = ; + }; + + conf-pd { + pins = "SPI0_MOSI", "SPI0_MISO"; + drive-strength = ; + bias-pull-down = ; + }; + }; + + spic_pins: spi1-pins-func-1 { + mux { + function = "spi"; + groups = "spi1_2"; + }; + }; + + uart1_pins: spi1-pins-func-3 { + mux { + function = "uart"; + groups = "uart1_2"; + }; + }; + + pwm_pins: pwm0-pins-func-1 { + mux { + function = "pwm"; + groups = "pwm0"; + }; + }; + + mmc0_pins_default: mmc0default { + mux { + function = "flash"; + groups = "emmc_51"; + }; + + conf-cmd-dat { + pins = "EMMC_DATA_0", "EMMC_DATA_1", "EMMC_DATA_2", + "EMMC_DATA_3", "EMMC_DATA_4", "EMMC_DATA_5", + "EMMC_DATA_6", "EMMC_DATA_7", "EMMC_CMD"; + input-enable; + drive-strength = ; + bias-pull-up = ; + }; + + conf-clk { + pins = "EMMC_CK"; + drive-strength = ; + bias-pull-down = ; + }; + + conf-dsl { + pins = "EMMC_DSL"; + bias-pull-down = ; + }; + + conf-rst { + pins = "EMMC_RSTB"; + drive-strength = ; + bias-pull-up = ; + }; + }; +}; + +&snand { + pinctrl-names = "default"; + pinctrl-0 = <&snfi_pins>; + status = "okay"; + quad-spi; +}; + +&spi0 { + #address-cells = <1>; + #size-cells = <0>; + pinctrl-names = "default"; + pinctrl-0 = <&spi_flash_pins>; + status = "okay"; + must_tx; + enhance_timing; + dma_ext; + ipm_design; + support_quad; + tick_dly = <2>; + sample_sel = <0>; + + spi_nor@0 { + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <52000000>; + }; + + spi_nand@1 { + compatible = "spi-nand"; + reg = <1>; + spi-max-frequency = <52000000>; + }; +}; + +&pwm { + pinctrl-names = "default"; + pinctrl-0 = <&pwm_pins>; + status = "okay"; +}; + +&watchdog { + status = "disabled"; +}; + +&mmc0 { + pinctrl-names = "default"; + pinctrl-0 = <&mmc0_pins_default>; + bus-width = <8>; + max-frequency = <52000000>; + cap-mmc-highspeed; + cap-mmc-hw-reset; + vmmc-supply = <®_3p3v>; + vqmmc-supply = <®_1p8v>; + non-removable; + status = "okay"; +}; diff --git a/arch/arm/dts/mt7986a-sd-rfb.dts b/arch/arm/dts/mt7986a-sd-rfb.dts new file mode 100644 index 0000000000..5807c5d5cc --- /dev/null +++ b/arch/arm/dts/mt7986a-sd-rfb.dts @@ -0,0 +1,177 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2022 MediaTek Inc. + * Author: Sam Shih + */ + +/dts-v1/; +#include "mt7986.dtsi" +#include + +/ { + #address-cells = <1>; + #size-cells = <1>; + model = "mt7986-rfb"; + compatible = "mediatek,mt7986", "mediatek,mt7986-rfb", + "mediatek,mt7986-sd-rfb"; + chosen { + stdout-path = &uart0; + tick-timer = &timer0; + }; + + reg_3p3v: regulator-3p3v { + compatible = "regulator-fixed"; + regulator-name = "fixed-3.3V"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + regulator-always-on; + }; +}; + +&uart0 { + status = "okay"; +}; + +&uart1 { + pinctrl-names = "default"; + pinctrl-0 = <&uart1_pins>; + status = "disabled"; +}; + +ð { + status = "okay"; + mediatek,gmac-id = <0>; + phy-mode = "sgmii"; + mediatek,switch = "mt7531"; + reset-gpios = <&gpio 5 GPIO_ACTIVE_HIGH>; + + fixed-link { + speed = <1000>; + full-duplex; + }; +}; + +&pinctrl { + spi_flash_pins: spi0-pins-func-1 { + mux { + function = "flash"; + groups = "spi0", "spi0_wp_hold"; + }; + + conf-pu { + pins = "SPI2_CS", "SPI2_HOLD", "SPI2_WP"; + drive-strength = ; + bias-pull-up = ; + }; + + conf-pd { + pins = "SPI2_CLK", "SPI2_MOSI", "SPI2_MISO"; + drive-strength = ; + bias-pull-down = ; + }; + }; + + spic_pins: spi1-pins-func-1 { + mux { + function = "spi"; + groups = "spi1_2"; + }; + }; + + uart1_pins: spi1-pins-func-3 { + mux { + function = "uart"; + groups = "uart1_2"; + }; + }; + + pwm_pins: pwm0-pins-func-1 { + mux { + function = "pwm"; + groups = "pwm0"; + }; + }; + + mmc0_pins_default: mmc0default { + mux { + function = "flash"; + groups = "emmc_51"; + }; + + conf-cmd-dat { + pins = "EMMC_DATA_0", "EMMC_DATA_1", "EMMC_DATA_2", + "EMMC_DATA_3", "EMMC_DATA_4", "EMMC_DATA_5", + "EMMC_DATA_6", "EMMC_DATA_7", "EMMC_CMD"; + input-enable; + drive-strength = ; + bias-pull-up = ; + }; + + conf-clk { + pins = "EMMC_CK"; + drive-strength = ; + bias-pull-down = ; + }; + + conf-dsl { + pins = "EMMC_DSL"; + bias-pull-down = ; + }; + + conf-rst { + pins = "EMMC_RSTB"; + drive-strength = ; + bias-pull-up = ; + }; + }; +}; + +&spi0 { + #address-cells = <1>; + #size-cells = <0>; + pinctrl-names = "default"; + pinctrl-0 = <&spi_flash_pins>; + status = "okay"; + must_tx; + enhance_timing; + dma_ext; + ipm_design; + support_quad; + tick_dly = <2>; + sample_sel = <0>; + + spi_nor@0 { + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <52000000>; + }; + + spi_nand@1 { + compatible = "spi-nand"; + reg = <1>; + spi-max-frequency = <52000000>; + }; +}; + +&pwm { + pinctrl-names = "default"; + pinctrl-0 = <&pwm_pins>; + status = "okay"; +}; + +&watchdog { + status = "disabled"; +}; + +&mmc0 { + pinctrl-names = "default"; + pinctrl-0 = <&mmc0_pins_default>; + bus-width = <4>; + max-frequency = <52000000>; + cap-sd-highspeed; + r_smpl = <1>; + vmmc-supply = <®_3p3v>; + vqmmc-supply = <®_3p3v>; + status = "okay"; +}; diff --git a/arch/arm/dts/mt7986b-emmc-rfb.dts b/arch/arm/dts/mt7986b-emmc-rfb.dts new file mode 100644 index 0000000000..315bdd0b14 --- /dev/null +++ b/arch/arm/dts/mt7986b-emmc-rfb.dts @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2022 MediaTek Inc. + * Author: Sam Shih + */ + +/dts-v1/; +#include "mt7986a-rfb.dts" + +/ { + compatible = "mediatek,mt7986", "mediatek,mt7986-rfb", + "mediatek,mt7986-emmc-rfb"; + bl2_verify { + bl2_compatible = "emmc"; + }; +}; diff --git a/arch/arm/dts/mt7986b-rfb.dts b/arch/arm/dts/mt7986b-rfb.dts new file mode 100644 index 0000000000..0c4e3e878f --- /dev/null +++ b/arch/arm/dts/mt7986b-rfb.dts @@ -0,0 +1,204 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2022 MediaTek Inc. + * Author: Sam Shih + */ + +/dts-v1/; +#include "mt7986.dtsi" +#include + +/ { + #address-cells = <1>; + #size-cells = <1>; + model = "mt7986-rfb"; + compatible = "mediatek,mt7986", "mediatek,mt7986-rfb"; + chosen { + stdout-path = &uart0; + tick-timer = &timer0; + }; + + reg_3p3v: regulator-3p3v { + compatible = "regulator-fixed"; + regulator-name = "fixed-3.3V"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + regulator-always-on; + }; +}; + +&uart0 { + status = "okay"; +}; + +&uart1 { + pinctrl-names = "default"; + pinctrl-0 = <&uart1_pins>; + status = "disabled"; +}; + +ð { + status = "okay"; + mediatek,gmac-id = <0>; + phy-mode = "sgmii"; + mediatek,switch = "mt7531"; + reset-gpios = <&gpio 5 GPIO_ACTIVE_HIGH>; + + fixed-link { + speed = <1000>; + full-duplex; + }; +}; + +&pinctrl { + spi_flash_pins: spi0-pins-func-1 { + mux { + function = "flash"; + groups = "spi0", "spi0_wp_hold"; + }; + + conf-pu { + pins = "SPI2_CS", "SPI2_HOLD", "SPI2_WP"; + drive-strength = ; + bias-pull-up = ; + }; + + conf-pd { + pins = "SPI2_CLK", "SPI2_MOSI", "SPI2_MISO"; + drive-strength = ; + bias-pull-down = ; + }; + }; + + snfi_pins: snfi-pins-func-1 { + mux { + function = "flash"; + groups = "snfi"; + }; + + clk { + pins = "SPI0_CLK"; + drive-strength = ; + bias-pull-down = ; + }; + + conf-pu { + pins = "SPI0_CS", "SPI0_HOLD", "SPI0_WP"; + drive-strength = ; + bias-pull-up = ; + }; + + conf-pd { + pins = "SPI0_MOSI", "SPI0_MISO"; + drive-strength = ; + bias-pull-down = ; + }; + }; + + spic_pins: spi1-pins-func-1 { + mux { + function = "spi"; + groups = "spi1_2"; + }; + }; + + uart1_pins: spi1-pins-func-3 { + mux { + function = "uart"; + groups = "uart1_2"; + }; + }; + + pwm_pins: pwm0-pins-func-1 { + mux { + function = "pwm"; + groups = "pwm0"; + }; + }; + + mmc0_pins_default: mmc0default { + mux { + function = "flash"; + groups = "emmc_45"; + input-schmitt-enable; + }; + + conf-cmd-dat { + pins = "SPI0_CLK", "SPI0_MOSI", "SPI0_MISO", + "SPI0_CS", "SPI0_HOLD", "SPI0_WP", + "SPI1_CLK", "SPI1_MOSI", "SPI1_MISO"; + input-enable; + drive-strength = ; + bias-pull-up = ; + }; + + conf-clk { + pins = "SPI1_CS"; + drive-strength = ; + bias-pull-down = ; + }; + + conf-rst { + pins = "PWM1"; + drive-strength = ; + bias-pull-up = ; + }; + }; +}; + +&snand { + pinctrl-names = "default"; + pinctrl-0 = <&snfi_pins>; + status = "okay"; + quad-spi; +}; + +&spi0 { + #address-cells = <1>; + #size-cells = <0>; + pinctrl-names = "default"; + pinctrl-0 = <&spi_flash_pins>; + status = "okay"; + must_tx; + enhance_timing; + dma_ext; + ipm_design; + support_quad; + tick_dly = <2>; + sample_sel = <0>; + + spi_nor@0 { + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <52000000>; + }; + + spi_nand@1 { + compatible = "spi-nand"; + reg = <1>; + spi-max-frequency = <52000000>; + }; +}; + +&pwm { + pinctrl-names = "default"; + pinctrl-0 = <&pwm_pins>; + status = "okay"; +}; + +&watchdog { + status = "disabled"; +}; + +&mmc0 { + pinctrl-names = "default"; + pinctrl-0 = <&mmc0_pins_default>; + bus-width = <8>; + max-frequency = <52000000>; + cap-mmc-highspeed; + cap-mmc-hw-reset; + vmmc-supply = <®_3p3v>; + non-removable; + status = "okay"; +}; diff --git a/arch/arm/dts/mt7986b-sd-rfb.dts b/arch/arm/dts/mt7986b-sd-rfb.dts new file mode 100644 index 0000000000..48f9320e7a --- /dev/null +++ b/arch/arm/dts/mt7986b-sd-rfb.dts @@ -0,0 +1,173 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2022 MediaTek Inc. + * Author: Sam Shih + */ + +/dts-v1/; +#include "mt7986.dtsi" +#include + +/ { + #address-cells = <1>; + #size-cells = <1>; + model = "mt7986-rfb"; + compatible = "mediatek,mt7986", "mediatek,mt7986-rfb", + "mediatek,mt7986-sd-rfb"; + chosen { + stdout-path = &uart0; + tick-timer = &timer0; + }; + + reg_3p3v: regulator-3p3v { + compatible = "regulator-fixed"; + regulator-name = "fixed-3.3V"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + regulator-always-on; + }; +}; + +&uart0 { + status = "okay"; +}; + +&uart1 { + pinctrl-names = "default"; + pinctrl-0 = <&uart1_pins>; + status = "disabled"; +}; + +ð { + status = "okay"; + mediatek,gmac-id = <0>; + phy-mode = "sgmii"; + mediatek,switch = "mt7531"; + reset-gpios = <&gpio 5 GPIO_ACTIVE_HIGH>; + + fixed-link { + speed = <1000>; + full-duplex; + }; +}; + +&pinctrl { + spi_flash_pins: spi0-pins-func-1 { + mux { + function = "flash"; + groups = "spi0", "spi0_wp_hold"; + }; + + conf-pu { + pins = "SPI2_CS", "SPI2_HOLD", "SPI2_WP"; + drive-strength = ; + bias-pull-up = ; + }; + + conf-pd { + pins = "SPI2_CLK", "SPI2_MOSI", "SPI2_MISO"; + drive-strength = ; + bias-pull-down = ; + }; + }; + + spic_pins: spi1-pins-func-1 { + mux { + function = "spi"; + groups = "spi1_2"; + }; + }; + + uart1_pins: spi1-pins-func-3 { + mux { + function = "uart"; + groups = "uart1_2"; + }; + }; + + pwm_pins: pwm0-pins-func-1 { + mux { + function = "pwm"; + groups = "pwm0"; + }; + }; + + mmc0_pins_default: mmc0default { + mux { + function = "flash"; + groups = "emmc_45"; + input-schmitt-enable; + }; + + conf-cmd-dat { + pins = "SPI0_CLK", "SPI0_MOSI", "SPI0_MISO", + "SPI0_CS", "SPI0_HOLD", "SPI0_WP", + "SPI1_CLK", "SPI1_MOSI", "SPI1_MISO"; + input-enable; + drive-strength = ; + bias-pull-up = ; + }; + + conf-clk { + pins = "SPI1_CS"; + drive-strength = ; + bias-pull-down = ; + }; + + conf-rst { + pins = "PWM1"; + drive-strength = ; + bias-pull-up = ; + }; + }; +}; + +&spi0 { + #address-cells = <1>; + #size-cells = <0>; + pinctrl-names = "default"; + pinctrl-0 = <&spi_flash_pins>; + status = "okay"; + must_tx; + enhance_timing; + dma_ext; + ipm_design; + support_quad; + tick_dly = <2>; + sample_sel = <0>; + + spi_nor@0 { + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <52000000>; + }; + + spi_nand@1 { + compatible = "spi-nand"; + reg = <1>; + spi-max-frequency = <52000000>; + }; +}; + +&pwm { + pinctrl-names = "default"; + pinctrl-0 = <&pwm_pins>; + status = "okay"; +}; + +&watchdog { + status = "disabled"; +}; + +&mmc0 { + pinctrl-names = "default"; + pinctrl-0 = <&mmc0_pins_default>; + bus-width = <4>; + max-frequency = <52000000>; + cap-sd-highspeed; + r_smpl = <1>; + vmmc-supply = <®_3p3v>; + vqmmc-supply = <®_3p3v>; + status = "okay"; +}; diff --git a/board/mediatek/mt7986/MAINTAINERS b/board/mediatek/mt7986/MAINTAINERS new file mode 100644 index 0000000000..ddc078a567 --- /dev/null +++ b/board/mediatek/mt7986/MAINTAINERS @@ -0,0 +1,12 @@ +MT7986 +M: Sam Shih +S: Maintained +F: board/mediatek/mt7986 +F: include/configs/mt7986.h +F: configs/mt7986_rfb_defconfig +F: configs/mt7986a_bpir3_emmc_defconfig +F: configs/mt7986a_bpir3_sd_defconfig +F: configs/mt7986a_emmc_rfb_defconfig +F: configs/mt7986a_sd_rfb_defconfig +F: configs/mt7986b_emmc_rfb_defconfig +F: configs/mt7986b_sd_rfb_defconfig diff --git a/board/mediatek/mt7986/Makefile b/board/mediatek/mt7986/Makefile new file mode 100644 index 0000000000..7bb84fa2f4 --- /dev/null +++ b/board/mediatek/mt7986/Makefile @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0 + +obj-y += mt7986_rfb.o diff --git a/board/mediatek/mt7986/mt7986_rfb.c b/board/mediatek/mt7986/mt7986_rfb.c new file mode 100644 index 0000000000..846c715ca0 --- /dev/null +++ b/board/mediatek/mt7986/mt7986_rfb.c @@ -0,0 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2022 MediaTek Inc. + * Author: Sam Shih + */ + +int board_init(void) +{ + return 0; +} diff --git a/configs/mt7986_rfb_defconfig b/configs/mt7986_rfb_defconfig new file mode 100644 index 0000000000..ff1e63b6bd --- /dev/null +++ b/configs/mt7986_rfb_defconfig @@ -0,0 +1,66 @@ +CONFIG_ARM=y +CONFIG_POSITION_INDEPENDENT=y +CONFIG_ARCH_MEDIATEK=y +CONFIG_SYS_TEXT_BASE=0x41e00000 +CONFIG_SYS_MALLOC_F_LEN=0x4000 +CONFIG_NR_DRAM_BANKS=1 +CONFIG_DEFAULT_DEVICE_TREE="mt7986a-rfb" +CONFIG_TARGET_MT7986=y +CONFIG_DEBUG_UART_BASE=0x11002000 +CONFIG_DEBUG_UART_CLOCK=40000000 +CONFIG_SYS_LOAD_ADDR=0x46000000 +CONFIG_DEBUG_UART=y +# CONFIG_AUTOBOOT is not set +CONFIG_DEFAULT_FDT_FILE="mt7986a-rfb" +CONFIG_LOGLEVEL=7 +CONFIG_LOG=y +CONFIG_SYS_PROMPT="MT7986> " +CONFIG_SYS_CBSIZE=512 +CONFIG_SYS_PBSIZE=1049 +# CONFIG_BOOTM_NETBSD is not set +# CONFIG_BOOTM_PLAN9 is not set +# CONFIG_BOOTM_RTEMS is not set +# CONFIG_BOOTM_VXWORKS is not set +# CONFIG_CMD_ELF is not set +# CONFIG_CMD_UNLZ4 is not set +# CONFIG_CMD_UNZIP is not set +CONFIG_CMD_GPIO=y +CONFIG_CMD_MTD=y +CONFIG_CMD_SF_TEST=y +CONFIG_CMD_PING=y +CONFIG_CMD_SMC=y +CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y +CONFIG_NET_RANDOM_ETHADDR=y +CONFIG_REGMAP=y +CONFIG_SYSCON=y +CONFIG_CLK=y +# CONFIG_MMC is not set +CONFIG_MTD=y +CONFIG_DM_MTD=y +CONFIG_MTD_SPI_NAND=y +CONFIG_DM_SPI_FLASH=y +CONFIG_SPI_FLASH_SFDP_SUPPORT=y +CONFIG_SPI_FLASH_EON=y +CONFIG_SPI_FLASH_GIGADEVICE=y +CONFIG_SPI_FLASH_ISSI=y +CONFIG_SPI_FLASH_MACRONIX=y +CONFIG_SPI_FLASH_SPANSION=y +CONFIG_SPI_FLASH_STMICRO=y +CONFIG_SPI_FLASH_WINBOND=y +CONFIG_SPI_FLASH_XMC=y +CONFIG_SPI_FLASH_XTX=y +CONFIG_SPI_FLASH_MTD=y +CONFIG_PHY_FIXED=y +CONFIG_DM_ETH=y +CONFIG_MEDIATEK_ETH=y +CONFIG_PINCTRL=y +CONFIG_PINCONF=y +CONFIG_PINCTRL_MT7986=y +CONFIG_POWER_DOMAIN=y +CONFIG_MTK_POWER_DOMAIN=y +CONFIG_DM_SERIAL=y +CONFIG_MTK_SERIAL=y +CONFIG_SPI=y +CONFIG_DM_SPI=y +CONFIG_MTK_SPIM=y +CONFIG_HEXDUMP=y diff --git a/configs/mt7986a_bpir3_emmc_defconfig b/configs/mt7986a_bpir3_emmc_defconfig new file mode 100644 index 0000000000..3e368b68de --- /dev/null +++ b/configs/mt7986a_bpir3_emmc_defconfig @@ -0,0 +1,64 @@ +CONFIG_ARM=y +CONFIG_POSITION_INDEPENDENT=y +CONFIG_ARCH_MEDIATEK=y +CONFIG_SYS_TEXT_BASE=0x41e00000 +CONFIG_SYS_MALLOC_F_LEN=0x4000 +CONFIG_NR_DRAM_BANKS=1 +CONFIG_ENV_SIZE=0x80000 +CONFIG_ENV_OFFSET=0x300000 +CONFIG_DEFAULT_DEVICE_TREE="mt7986a-emmc-rfb" +CONFIG_TARGET_MT7986=y +CONFIG_DEBUG_UART_BASE=0x11002000 +CONFIG_DEBUG_UART_CLOCK=40000000 +CONFIG_SYS_LOAD_ADDR=0x46000000 +CONFIG_DEBUG_UART=y +# CONFIG_AUTOBOOT is not set +CONFIG_DEFAULT_FDT_FILE="mt7986a-emmc-rfb" +CONFIG_LOGLEVEL=7 +CONFIG_LOG=y +CONFIG_SYS_PROMPT="MT7986> " +CONFIG_SYS_CBSIZE=512 +CONFIG_SYS_PBSIZE=1049 +# CONFIG_BOOTM_NETBSD is not set +# CONFIG_BOOTM_PLAN9 is not set +# CONFIG_BOOTM_RTEMS is not set +# CONFIG_BOOTM_VXWORKS is not set +# CONFIG_CMD_ELF is not set +# CONFIG_CMD_UNLZ4 is not set +# CONFIG_CMD_UNZIP is not set +CONFIG_CMD_GPIO=y +CONFIG_CMD_GPT=y +CONFIG_CMD_GPT_RENAME=y +CONFIG_CMD_LSBLK=y +CONFIG_CMD_MMC=y +CONFIG_CMD_PART=y +CONFIG_CMD_READ=y +CONFIG_CMD_PING=y +CONFIG_CMD_SMC=y +CONFIG_CMD_FAT=y +CONFIG_CMD_FS_GENERIC=y +CONFIG_PARTITION_TYPE_GUID=y +CONFIG_ENV_OVERWRITE=y +CONFIG_ENV_IS_IN_MMC=y +CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y +CONFIG_NET_RANDOM_ETHADDR=y +CONFIG_REGMAP=y +CONFIG_SYSCON=y +CONFIG_CLK=y +CONFIG_MMC_HS200_SUPPORT=y +CONFIG_MMC_MTK=y +CONFIG_PHY_FIXED=y +CONFIG_DM_ETH=y +CONFIG_MEDIATEK_ETH=y +CONFIG_PINCTRL=y +CONFIG_PINCONF=y +CONFIG_PINCTRL_MT7986=y +CONFIG_POWER_DOMAIN=y +CONFIG_MTK_POWER_DOMAIN=y +CONFIG_DM_REGULATOR=y +CONFIG_DM_REGULATOR_FIXED=y +CONFIG_DM_SERIAL=y +CONFIG_MTK_SERIAL=y +CONFIG_FAT_WRITE=y +CONFIG_HEXDUMP=y +# CONFIG_EFI_LOADER is not set diff --git a/configs/mt7986a_bpir3_sd_defconfig b/configs/mt7986a_bpir3_sd_defconfig new file mode 100644 index 0000000000..b9a69a3d3d --- /dev/null +++ b/configs/mt7986a_bpir3_sd_defconfig @@ -0,0 +1,64 @@ +CONFIG_ARM=y +CONFIG_POSITION_INDEPENDENT=y +CONFIG_ARCH_MEDIATEK=y +CONFIG_SYS_TEXT_BASE=0x41e00000 +CONFIG_SYS_MALLOC_F_LEN=0x4000 +CONFIG_NR_DRAM_BANKS=1 +CONFIG_ENV_SIZE=0x80000 +CONFIG_ENV_OFFSET=0x300000 +CONFIG_DEFAULT_DEVICE_TREE="mt7986a-sd-rfb" +CONFIG_TARGET_MT7986=y +CONFIG_DEBUG_UART_BASE=0x11002000 +CONFIG_DEBUG_UART_CLOCK=40000000 +CONFIG_SYS_LOAD_ADDR=0x46000000 +CONFIG_DEBUG_UART=y +# CONFIG_AUTOBOOT is not set +CONFIG_DEFAULT_FDT_FILE="mt7986a-sd-rfb" +CONFIG_LOGLEVEL=7 +CONFIG_LOG=y +CONFIG_SYS_PROMPT="MT7986> " +CONFIG_SYS_CBSIZE=512 +CONFIG_SYS_PBSIZE=1049 +# CONFIG_BOOTM_NETBSD is not set +# CONFIG_BOOTM_PLAN9 is not set +# CONFIG_BOOTM_RTEMS is not set +# CONFIG_BOOTM_VXWORKS is not set +# CONFIG_CMD_ELF is not set +# CONFIG_CMD_UNLZ4 is not set +# CONFIG_CMD_UNZIP is not set +CONFIG_CMD_GPIO=y +CONFIG_CMD_GPT=y +CONFIG_CMD_GPT_RENAME=y +CONFIG_CMD_LSBLK=y +CONFIG_CMD_MMC=y +CONFIG_CMD_PART=y +CONFIG_CMD_READ=y +CONFIG_CMD_PING=y +CONFIG_CMD_SMC=y +CONFIG_CMD_FAT=y +CONFIG_CMD_FS_GENERIC=y +CONFIG_PARTITION_TYPE_GUID=y +CONFIG_ENV_OVERWRITE=y +CONFIG_ENV_IS_IN_MMC=y +CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y +CONFIG_NET_RANDOM_ETHADDR=y +CONFIG_REGMAP=y +CONFIG_SYSCON=y +CONFIG_CLK=y +CONFIG_MMC_HS200_SUPPORT=y +CONFIG_MMC_MTK=y +CONFIG_PHY_FIXED=y +CONFIG_DM_ETH=y +CONFIG_MEDIATEK_ETH=y +CONFIG_PINCTRL=y +CONFIG_PINCONF=y +CONFIG_PINCTRL_MT7986=y +CONFIG_POWER_DOMAIN=y +CONFIG_MTK_POWER_DOMAIN=y +CONFIG_DM_REGULATOR=y +CONFIG_DM_REGULATOR_FIXED=y +CONFIG_DM_SERIAL=y +CONFIG_MTK_SERIAL=y +CONFIG_FAT_WRITE=y +CONFIG_HEXDUMP=y +# CONFIG_EFI_LOADER is not set diff --git a/include/configs/mt7986.h b/include/configs/mt7986.h new file mode 100644 index 0000000000..ccdd6abdb1 --- /dev/null +++ b/include/configs/mt7986.h @@ -0,0 +1,25 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Configuration for MediaTek MT7986 SoC + * + * Copyright (C) 2022 MediaTek Inc. + * Author: Sam Shih + */ + +#ifndef __MT7986_H +#define __MT7986_H + +#include + +#define CONFIG_SYS_NONCACHED_MEMORY SZ_1M + +/* Uboot definition */ +#define CONFIG_SYS_UBOOT_BASE CONFIG_SYS_TEXT_BASE + +/* SPL -> Uboot */ +#define CONFIG_SYS_UBOOT_START CONFIG_SYS_TEXT_BASE + +/* DRAM */ +#define CONFIG_SYS_SDRAM_BASE 0x40000000 + +#endif From e053ccf6ef45c0d803d4435d1f3e7fca6e14981e Mon Sep 17 00:00:00 2001 From: Weijie Gao Date: Fri, 9 Sep 2022 19:59:16 +0800 Subject: [PATCH 244/374] board: mediatek: add MT7981 reference boards This patch adds general board files based on MT7981 SoCs. MT7981 uses one mmc controller for booting from both SD and eMMC, and the pins of mmc controller are also shared with spi controller. So three configs are need for these boot types: 1. mt7981_rfb_defconfig - SPI-NOR and SPI-NAND 2. mt7981_emmc_rfb_defconfig - eMMC only 3. mt7981_sd_rfb_defconfig - SD only Reviewed-by: Simon Glass Signed-off-by: Weijie Gao --- arch/arm/dts/Makefile | 3 + arch/arm/dts/mt7981-emmc-rfb.dts | 139 +++++++++++++++++++++++ arch/arm/dts/mt7981-rfb.dts | 173 +++++++++++++++++++++++++++++ arch/arm/dts/mt7981-sd-rfb.dts | 139 +++++++++++++++++++++++ board/mediatek/mt7981/MAINTAINERS | 10 ++ board/mediatek/mt7981/Makefile | 3 + board/mediatek/mt7981/mt7981_rfb.c | 10 ++ configs/mt7981_emmc_rfb_defconfig | 64 +++++++++++ configs/mt7981_rfb_defconfig | 69 ++++++++++++ configs/mt7981_sd_rfb_defconfig | 64 +++++++++++ include/configs/mt7981.h | 25 +++++ 11 files changed, 699 insertions(+) create mode 100644 arch/arm/dts/mt7981-emmc-rfb.dts create mode 100644 arch/arm/dts/mt7981-rfb.dts create mode 100644 arch/arm/dts/mt7981-sd-rfb.dts create mode 100644 board/mediatek/mt7981/MAINTAINERS create mode 100644 board/mediatek/mt7981/Makefile create mode 100644 board/mediatek/mt7981/mt7981_rfb.c create mode 100644 configs/mt7981_emmc_rfb_defconfig create mode 100644 configs/mt7981_rfb_defconfig create mode 100644 configs/mt7981_sd_rfb_defconfig create mode 100644 include/configs/mt7981.h diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index 138c7edf0a..885ed5ef6f 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -1235,6 +1235,9 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += \ mt7622-bananapi-bpi-r64.dtb \ mt7623n-bananapi-bpi-r2.dtb \ mt7629-rfb.dtb \ + mt7981-rfb.dtb \ + mt7981-emmc-rfb.dtb \ + mt7981-sd-rfb.dtb \ mt7986a-rfb.dtb \ mt7986b-rfb.dtb \ mt7986a-sd-rfb.dtb \ diff --git a/arch/arm/dts/mt7981-emmc-rfb.dts b/arch/arm/dts/mt7981-emmc-rfb.dts new file mode 100644 index 0000000000..2b7eae99ce --- /dev/null +++ b/arch/arm/dts/mt7981-emmc-rfb.dts @@ -0,0 +1,139 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2022 MediaTek Inc. + * Author: Sam Shih + */ + +/dts-v1/; +#include "mt7981.dtsi" +#include + +/ { + #address-cells = <1>; + #size-cells = <1>; + model = "mt7981-rfb"; + compatible = "mediatek,mt7981", "mediatek,mt7981-rfb"; + chosen { + stdout-path = &uart0; + tick-timer = &timer0; + }; + + reg_3p3v: regulator-3p3v { + compatible = "regulator-fixed"; + regulator-name = "fixed-3.3V"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + regulator-always-on; + }; +}; + +&uart0 { + status = "okay"; +}; + +&uart1 { + pinctrl-names = "default"; + pinctrl-0 = <&uart1_pins>; + status = "disabled"; +}; + +ð { + status = "okay"; + mediatek,gmac-id = <0>; + phy-mode = "sgmii"; + mediatek,switch = "mt7531"; + reset-gpios = <&gpio 39 GPIO_ACTIVE_HIGH>; + + fixed-link { + speed = <1000>; + full-duplex; + }; +}; + +&pinctrl { + spic_pins: spi1-pins-func-1 { + mux { + function = "spi"; + groups = "spi1_1"; + }; + }; + + uart1_pins: spi1-pins-func-3 { + mux { + function = "uart"; + groups = "uart1_2"; + }; + }; + + /* pin15 as pwm0 */ + one_pwm_pins: one-pwm-pins { + mux { + function = "pwm"; + groups = "pwm0_1"; + }; + }; + + /* pin15 as pwm0 and pin14 as pwm1 */ + two_pwm_pins: two-pwm-pins { + mux { + function = "pwm"; + groups = "pwm0_1", "pwm1_0"; + }; + }; + + /* pin15 as pwm0, pin14 as pwm1, pin7 as pwm2 */ + three_pwm_pins: three-pwm-pins { + mux { + function = "pwm"; + groups = "pwm0_1", "pwm1_0", "pwm2"; + }; + }; + + mmc0_pins_default: mmc0default { + mux { + function = "flash"; + groups = "emmc_45"; + }; + conf-cmd-dat { + pins = "SPI0_CLK", "SPI0_MOSI", "SPI0_MISO", + "SPI0_CS", "SPI0_HOLD", "SPI0_WP", + "SPI1_CLK", "SPI1_MOSI", "SPI1_MISO"; + input-enable; + drive-strength = ; + bias-pull-up = ; + }; + conf-clk { + pins = "SPI1_CS"; + drive-strength = ; + bias-pull-down = ; + }; + conf-rst { + pins = "PWM0"; + drive-strength = ; + bias-pull-up = ; + }; + }; +}; + +&pwm { + pinctrl-names = "default"; + pinctrl-0 = <&two_pwm_pins>; + status = "okay"; +}; + +&watchdog { + status = "disabled"; +}; + +&mmc0 { + pinctrl-names = "default"; + pinctrl-0 = <&mmc0_pins_default>; + bus-width = <8>; + max-frequency = <52000000>; + cap-mmc-highspeed; + cap-mmc-hw-reset; + vmmc-supply = <®_3p3v>; + non-removable; + status = "okay"; +}; diff --git a/arch/arm/dts/mt7981-rfb.dts b/arch/arm/dts/mt7981-rfb.dts new file mode 100644 index 0000000000..5559ace953 --- /dev/null +++ b/arch/arm/dts/mt7981-rfb.dts @@ -0,0 +1,173 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2022 MediaTek Inc. + * Author: Sam Shih + */ + +/dts-v1/; +#include "mt7981.dtsi" +#include + +/ { + #address-cells = <1>; + #size-cells = <1>; + model = "mt7981-rfb"; + compatible = "mediatek,mt7981", "mediatek,mt7981-rfb"; + chosen { + stdout-path = &uart0; + tick-timer = &timer0; + }; +}; + +&uart0 { + status = "okay"; +}; + +&uart1 { + pinctrl-names = "default"; + pinctrl-0 = <&uart1_pins>; + status = "disabled"; +}; + +ð { + status = "okay"; + mediatek,gmac-id = <0>; + phy-mode = "sgmii"; + mediatek,switch = "mt7531"; + reset-gpios = <&gpio 39 GPIO_ACTIVE_HIGH>; + + fixed-link { + speed = <1000>; + full-duplex; + }; +}; + +&pinctrl { + spi_flash_pins: spi0-pins-func-1 { + mux { + function = "flash"; + groups = "spi0", "spi0_wp_hold"; + }; + + conf-pu { + pins = "SPI0_CS", "SPI0_HOLD", "SPI0_WP"; + drive-strength = ; + bias-pull-up = ; + }; + + conf-pd { + pins = "SPI0_CLK", "SPI0_MOSI", "SPI0_MISO"; + drive-strength = ; + bias-pull-down = ; + }; + }; + + spi2_flash_pins: spi2-spi2-pins { + mux { + function = "spi"; + groups = "spi2", "spi2_wp_hold"; + }; + + conf-pu { + pins = "SPI2_CS", "SPI2_HOLD", "SPI2_WP"; + drive-strength = ; + bias-pull-down = ; + }; + + conf-pd { + pins = "SPI2_CLK", "SPI2_MOSI", "SPI2_MISO"; + drive-strength = ; + bias-pull-down = ; + }; + }; + + spic_pins: spi1-pins-func-1 { + mux { + function = "spi"; + groups = "spi1_1"; + }; + }; + + uart1_pins: spi1-pins-func-3 { + mux { + function = "uart"; + groups = "uart1_2"; + }; + }; + + /* pin15 as pwm0 */ + one_pwm_pins: one-pwm-pins { + mux { + function = "pwm"; + groups = "pwm0_1"; + }; + }; + + /* pin15 as pwm0 and pin14 as pwm1 */ + two_pwm_pins: two-pwm-pins { + mux { + function = "pwm"; + groups = "pwm0_1", "pwm1_0"; + }; + }; + + /* pin15 as pwm0, pin14 as pwm1, pin7 as pwm2 */ + three_pwm_pins: three-pwm-pins { + mux { + function = "pwm"; + groups = "pwm0_1", "pwm1_0", "pwm2"; + }; + }; +}; + +&spi0 { + #address-cells = <1>; + #size-cells = <0>; + pinctrl-names = "default"; + pinctrl-0 = <&spi_flash_pins>; + status = "okay"; + must_tx; + enhance_timing; + dma_ext; + ipm_design; + support_quad; + tick_dly = <2>; + sample_sel = <0>; + + spi_nand@0 { + compatible = "spi-nand"; + reg = <0>; + spi-max-frequency = <52000000>; + }; +}; + +&spi2 { + #address-cells = <1>; + #size-cells = <0>; + pinctrl-names = "default"; + pinctrl-0 = <&spi2_flash_pins>; + status = "okay"; + must_tx; + enhance_timing; + dma_ext; + ipm_design; + support_quad; + tick_dly = <2>; + sample_sel = <0>; + + spi_nor@0 { + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <52000000>; + }; +}; + +&pwm { + pinctrl-names = "default"; + pinctrl-0 = <&two_pwm_pins>; + status = "okay"; +}; + +&watchdog { + status = "disabled"; +}; diff --git a/arch/arm/dts/mt7981-sd-rfb.dts b/arch/arm/dts/mt7981-sd-rfb.dts new file mode 100644 index 0000000000..34ac227ecf --- /dev/null +++ b/arch/arm/dts/mt7981-sd-rfb.dts @@ -0,0 +1,139 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2022 MediaTek Inc. + * Author: Sam Shih + */ + +/dts-v1/; +#include "mt7981.dtsi" +#include + +/ { + #address-cells = <1>; + #size-cells = <1>; + model = "mt7981-rfb"; + compatible = "mediatek,mt7981", "mediatek,mt7981-sd-rfb"; + chosen { + stdout-path = &uart0; + tick-timer = &timer0; + }; + + reg_3p3v: regulator-3p3v { + compatible = "regulator-fixed"; + regulator-name = "fixed-3.3V"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + regulator-always-on; + }; +}; + +&uart0 { + status = "okay"; +}; + +&uart1 { + pinctrl-names = "default"; + pinctrl-0 = <&uart1_pins>; + status = "disabled"; +}; + +ð { + status = "okay"; + mediatek,gmac-id = <0>; + phy-mode = "sgmii"; + mediatek,switch = "mt7531"; + reset-gpios = <&gpio 39 GPIO_ACTIVE_HIGH>; + + fixed-link { + speed = <1000>; + full-duplex; + }; +}; + +&pinctrl { + spic_pins: spi1-pins-func-1 { + mux { + function = "spi"; + groups = "spi1_1"; + }; + }; + + uart1_pins: spi1-pins-func-3 { + mux { + function = "uart"; + groups = "uart1_2"; + }; + }; + + /* pin15 as pwm0 */ + one_pwm_pins: one-pwm-pins { + mux { + function = "pwm"; + groups = "pwm0_1"; + }; + }; + + /* pin15 as pwm0 and pin14 as pwm1 */ + two_pwm_pins: two-pwm-pins { + mux { + function = "pwm"; + groups = "pwm0_1", "pwm1_0"; + }; + }; + + /* pin15 as pwm0, pin14 as pwm1, pin7 as pwm2 */ + three_pwm_pins: three-pwm-pins { + mux { + function = "pwm"; + groups = "pwm0_1", "pwm1_0", "pwm2"; + }; + }; + + mmc0_pins_default: mmc0default { + mux { + function = "flash"; + groups = "emmc_45"; + }; + conf-cmd-dat { + pins = "SPI0_CLK", "SPI0_MOSI", "SPI0_MISO", + "SPI0_CS", "SPI0_HOLD", "SPI0_WP", + "SPI1_CLK", "SPI1_MOSI", "SPI1_MISO"; + input-enable; + drive-strength = ; + bias-pull-up = ; + }; + conf-clk { + pins = "SPI1_CS"; + drive-strength = ; + bias-pull-down = ; + }; + conf-rst { + pins = "PWM0"; + drive-strength = ; + bias-pull-up = ; + }; + }; +}; + +&pwm { + pinctrl-names = "default"; + pinctrl-0 = <&two_pwm_pins>; + status = "okay"; +}; + +&watchdog { + status = "disabled"; +}; + +&mmc0 { + pinctrl-names = "default"; + pinctrl-0 = <&mmc0_pins_default>; + bus-width = <4>; + max-frequency = <52000000>; + cap-sd-highspeed; + r_smpl = <0>; + vmmc-supply = <®_3p3v>; + vqmmc-supply = <®_3p3v>; + status = "okay"; +}; diff --git a/board/mediatek/mt7981/MAINTAINERS b/board/mediatek/mt7981/MAINTAINERS new file mode 100644 index 0000000000..e7592a7a54 --- /dev/null +++ b/board/mediatek/mt7981/MAINTAINERS @@ -0,0 +1,10 @@ +MT7981 +M: Sam Shih +S: Maintained +F: board/mediatek/mt7981 +F: include/configs/mt7981.h +F: configs/mt7981_emmc_rfb_defconfig +F: configs/mt7981_rfb_defconfig +F: configs/mt7981_sd_rfb_defconfig +F: configs/mt7981_spim_nand_rfb_defconfig +F: configs/mt7981_spim_nor_rfb_defconfig diff --git a/board/mediatek/mt7981/Makefile b/board/mediatek/mt7981/Makefile new file mode 100644 index 0000000000..fa5990ffb2 --- /dev/null +++ b/board/mediatek/mt7981/Makefile @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0 + +obj-y += mt7981_rfb.o diff --git a/board/mediatek/mt7981/mt7981_rfb.c b/board/mediatek/mt7981/mt7981_rfb.c new file mode 100644 index 0000000000..846c715ca0 --- /dev/null +++ b/board/mediatek/mt7981/mt7981_rfb.c @@ -0,0 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2022 MediaTek Inc. + * Author: Sam Shih + */ + +int board_init(void) +{ + return 0; +} diff --git a/configs/mt7981_emmc_rfb_defconfig b/configs/mt7981_emmc_rfb_defconfig new file mode 100644 index 0000000000..5f9f6d8582 --- /dev/null +++ b/configs/mt7981_emmc_rfb_defconfig @@ -0,0 +1,64 @@ +CONFIG_ARM=y +CONFIG_POSITION_INDEPENDENT=y +CONFIG_ARCH_MEDIATEK=y +CONFIG_SYS_TEXT_BASE=0x41e00000 +CONFIG_SYS_MALLOC_F_LEN=0x4000 +CONFIG_NR_DRAM_BANKS=1 +CONFIG_ENV_SIZE=0x80000 +CONFIG_ENV_OFFSET=0x300000 +CONFIG_DEFAULT_DEVICE_TREE="mt7981-emmc-rfb" +CONFIG_TARGET_MT7981=y +CONFIG_DEBUG_UART_BASE=0x11002000 +CONFIG_DEBUG_UART_CLOCK=40000000 +CONFIG_SYS_LOAD_ADDR=0x46000000 +CONFIG_DEBUG_UART=y +# CONFIG_AUTOBOOT is not set +CONFIG_DEFAULT_FDT_FILE="mt7981-emmc-rfb" +CONFIG_LOGLEVEL=7 +CONFIG_LOG=y +CONFIG_SYS_PROMPT="MT7981> " +CONFIG_SYS_CBSIZE=512 +CONFIG_SYS_PBSIZE=1049 +# CONFIG_BOOTM_NETBSD is not set +# CONFIG_BOOTM_PLAN9 is not set +# CONFIG_BOOTM_RTEMS is not set +# CONFIG_BOOTM_VXWORKS is not set +# CONFIG_CMD_ELF is not set +# CONFIG_CMD_UNLZ4 is not set +# CONFIG_CMD_UNZIP is not set +CONFIG_CMD_GPIO=y +CONFIG_CMD_GPT=y +CONFIG_CMD_GPT_RENAME=y +CONFIG_CMD_LSBLK=y +CONFIG_CMD_MMC=y +CONFIG_CMD_PART=y +CONFIG_CMD_READ=y +CONFIG_CMD_PING=y +CONFIG_CMD_SMC=y +CONFIG_CMD_FAT=y +CONFIG_CMD_FS_GENERIC=y +CONFIG_PARTITION_TYPE_GUID=y +CONFIG_ENV_OVERWRITE=y +CONFIG_ENV_IS_IN_MMC=y +CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y +CONFIG_NET_RANDOM_ETHADDR=y +CONFIG_REGMAP=y +CONFIG_SYSCON=y +CONFIG_CLK=y +CONFIG_MMC_HS200_SUPPORT=y +CONFIG_MMC_MTK=y +CONFIG_PHY_FIXED=y +CONFIG_DM_ETH=y +CONFIG_MEDIATEK_ETH=y +CONFIG_PINCTRL=y +CONFIG_PINCONF=y +CONFIG_PINCTRL_MT7981=y +CONFIG_POWER_DOMAIN=y +CONFIG_MTK_POWER_DOMAIN=y +CONFIG_DM_REGULATOR=y +CONFIG_DM_REGULATOR_FIXED=y +CONFIG_DM_SERIAL=y +CONFIG_MTK_SERIAL=y +CONFIG_FAT_WRITE=y +CONFIG_HEXDUMP=y +# CONFIG_EFI_LOADER is not set diff --git a/configs/mt7981_rfb_defconfig b/configs/mt7981_rfb_defconfig new file mode 100644 index 0000000000..88299e3e51 --- /dev/null +++ b/configs/mt7981_rfb_defconfig @@ -0,0 +1,69 @@ +CONFIG_ARM=y +CONFIG_POSITION_INDEPENDENT=y +CONFIG_ARCH_MEDIATEK=y +CONFIG_SYS_TEXT_BASE=0x41e00000 +CONFIG_SYS_MALLOC_F_LEN=0x4000 +CONFIG_NR_DRAM_BANKS=1 +CONFIG_DEFAULT_DEVICE_TREE="mt7981-rfb" +CONFIG_TARGET_MT7981=y +CONFIG_DEBUG_UART_BASE=0x11002000 +CONFIG_DEBUG_UART_CLOCK=40000000 +CONFIG_SYS_LOAD_ADDR=0x46000000 +CONFIG_DEBUG_UART=y +# CONFIG_AUTOBOOT is not set +CONFIG_DEFAULT_FDT_FILE="mt7981-rfb" +CONFIG_LOGLEVEL=7 +CONFIG_LOG=y +CONFIG_SYS_PROMPT="MT7981> " +CONFIG_SYS_CBSIZE=512 +CONFIG_SYS_PBSIZE=1049 +# CONFIG_BOOTM_NETBSD is not set +# CONFIG_BOOTM_PLAN9 is not set +# CONFIG_BOOTM_RTEMS is not set +# CONFIG_BOOTM_VXWORKS is not set +# CONFIG_CMD_ELF is not set +# CONFIG_CMD_UNLZ4 is not set +# CONFIG_CMD_UNZIP is not set +CONFIG_CMD_GPIO=y +CONFIG_CMD_MTD=y +CONFIG_CMD_SF_TEST=y +CONFIG_CMD_PING=y +CONFIG_CMD_SMC=y +CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y +CONFIG_NET_RANDOM_ETHADDR=y +CONFIG_REGMAP=y +CONFIG_SYSCON=y +CONFIG_BLK=y +CONFIG_HAVE_BLOCK_DEVICE=y +CONFIG_CLK=y +# CONFIG_MMC is not set +CONFIG_MTD=y +CONFIG_DM_MTD=y +CONFIG_MTD_SPI_NAND=y +CONFIG_DM_SPI_FLASH=y +CONFIG_SPI_FLASH_SFDP_SUPPORT=y +CONFIG_SPI_FLASH_EON=y +CONFIG_SPI_FLASH_GIGADEVICE=y +CONFIG_SPI_FLASH_ISSI=y +CONFIG_SPI_FLASH_MACRONIX=y +CONFIG_SPI_FLASH_SPANSION=y +CONFIG_SPI_FLASH_STMICRO=y +CONFIG_SPI_FLASH_WINBOND=y +CONFIG_SPI_FLASH_XMC=y +CONFIG_SPI_FLASH_XTX=y +CONFIG_SPI_FLASH_MTD=y +CONFIG_PHY_FIXED=y +CONFIG_DM_ETH=y +CONFIG_MEDIATEK_ETH=y +CONFIG_PINCTRL=y +CONFIG_PINCONF=y +CONFIG_PINCTRL_MT7981=y +CONFIG_POWER_DOMAIN=y +CONFIG_MTK_POWER_DOMAIN=y +CONFIG_DM_SERIAL=y +CONFIG_MTK_SERIAL=y +CONFIG_SPI=y +CONFIG_DM_SPI=y +CONFIG_MTK_SPIM=y +CONFIG_HEXDUMP=y +# CONFIG_EFI_LOADER is not set diff --git a/configs/mt7981_sd_rfb_defconfig b/configs/mt7981_sd_rfb_defconfig new file mode 100644 index 0000000000..b5c765bd7c --- /dev/null +++ b/configs/mt7981_sd_rfb_defconfig @@ -0,0 +1,64 @@ +CONFIG_ARM=y +CONFIG_POSITION_INDEPENDENT=y +CONFIG_ARCH_MEDIATEK=y +CONFIG_SYS_TEXT_BASE=0x41e00000 +CONFIG_SYS_MALLOC_F_LEN=0x4000 +CONFIG_NR_DRAM_BANKS=1 +CONFIG_ENV_SIZE=0x80000 +CONFIG_ENV_OFFSET=0x300000 +CONFIG_DEFAULT_DEVICE_TREE="mt7981-sd-rfb" +CONFIG_TARGET_MT7981=y +CONFIG_DEBUG_UART_BASE=0x11002000 +CONFIG_DEBUG_UART_CLOCK=40000000 +CONFIG_SYS_LOAD_ADDR=0x46000000 +CONFIG_DEBUG_UART=y +# CONFIG_AUTOBOOT is not set +CONFIG_DEFAULT_FDT_FILE="mt7981-sd-rfb" +CONFIG_LOGLEVEL=7 +CONFIG_LOG=y +CONFIG_SYS_PROMPT="MT7981> " +CONFIG_SYS_CBSIZE=512 +CONFIG_SYS_PBSIZE=1049 +# CONFIG_BOOTM_NETBSD is not set +# CONFIG_BOOTM_PLAN9 is not set +# CONFIG_BOOTM_RTEMS is not set +# CONFIG_BOOTM_VXWORKS is not set +# CONFIG_CMD_ELF is not set +# CONFIG_CMD_UNLZ4 is not set +# CONFIG_CMD_UNZIP is not set +CONFIG_CMD_GPIO=y +CONFIG_CMD_GPT=y +CONFIG_CMD_GPT_RENAME=y +CONFIG_CMD_LSBLK=y +CONFIG_CMD_MMC=y +CONFIG_CMD_PART=y +CONFIG_CMD_READ=y +CONFIG_CMD_PING=y +CONFIG_CMD_SMC=y +CONFIG_CMD_FAT=y +CONFIG_CMD_FS_GENERIC=y +CONFIG_PARTITION_TYPE_GUID=y +CONFIG_ENV_OVERWRITE=y +CONFIG_ENV_IS_IN_MMC=y +CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y +CONFIG_NET_RANDOM_ETHADDR=y +CONFIG_REGMAP=y +CONFIG_SYSCON=y +CONFIG_CLK=y +CONFIG_MMC_HS200_SUPPORT=y +CONFIG_MMC_MTK=y +CONFIG_PHY_FIXED=y +CONFIG_DM_ETH=y +CONFIG_MEDIATEK_ETH=y +CONFIG_PINCTRL=y +CONFIG_PINCONF=y +CONFIG_PINCTRL_MT7981=y +CONFIG_POWER_DOMAIN=y +CONFIG_MTK_POWER_DOMAIN=y +CONFIG_DM_REGULATOR=y +CONFIG_DM_REGULATOR_FIXED=y +CONFIG_DM_SERIAL=y +CONFIG_MTK_SERIAL=y +CONFIG_FAT_WRITE=y +CONFIG_HEXDUMP=y +# CONFIG_EFI_LOADER is not set diff --git a/include/configs/mt7981.h b/include/configs/mt7981.h new file mode 100644 index 0000000000..01ad309608 --- /dev/null +++ b/include/configs/mt7981.h @@ -0,0 +1,25 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Configuration for MediaTek MT7981 SoC + * + * Copyright (C) 2022 MediaTek Inc. + * Author: Sam Shih + */ + +#ifndef __MT7981_H +#define __MT7981_H + +#include + +#define CONFIG_SYS_NONCACHED_MEMORY SZ_1M + +/* Uboot definition */ +#define CONFIG_SYS_UBOOT_BASE CONFIG_SYS_TEXT_BASE + +/* SPL -> Uboot */ +#define CONFIG_SYS_UBOOT_START CONFIG_SYS_TEXT_BASE + +/* DRAM */ +#define CONFIG_SYS_SDRAM_BASE 0x40000000 + +#endif From fccf960e1c5e31c1430f756e3a5db9c21f195dd2 Mon Sep 17 00:00:00 2001 From: Weijie Gao Date: Fri, 9 Sep 2022 19:59:19 +0800 Subject: [PATCH 245/374] mmc: mediatek: add support for MediaTek MT7891/MT7986 SoCs Add eMMC and SDXC support for MediaTek MT7981/MT7986 SoCs Both chips support SDXC and eMMC 4.5. MT7986A supports eMMC 5.1. Reviewed-by: Jaehoon Chung Reviewed-by: Simon Glass Tested-by: Daniel Golle Signed-off-by: Weijie Gao --- drivers/mmc/mtk-sd.c | 68 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 53 insertions(+), 15 deletions(-) diff --git a/drivers/mmc/mtk-sd.c b/drivers/mmc/mtk-sd.c index e61e8cf4b9..b206b0a085 100644 --- a/drivers/mmc/mtk-sd.c +++ b/drivers/mmc/mtk-sd.c @@ -1496,7 +1496,12 @@ static void msdc_init_hw(struct msdc_host *host) /* Enable data & cmd interrupts */ writel(DATA_INTS_MASK | CMD_INTS_MASK, &host->base->msdc_inten); - writel(0, tune_reg); + if (host->top_base) { + writel(0, &host->top_base->emmc_top_control); + writel(0, &host->top_base->emmc_top_cmd); + } else { + writel(0, tune_reg); + } writel(0, &host->base->msdc_iocon); if (host->r_smpl) @@ -1507,9 +1512,14 @@ static void msdc_init_hw(struct msdc_host *host) writel(0x403c0046, &host->base->patch_bit0); writel(0xffff4089, &host->base->patch_bit1); - if (host->dev_comp->stop_clk_fix) + if (host->dev_comp->stop_clk_fix) { clrsetbits_le32(&host->base->patch_bit1, MSDC_PB1_STOP_DLY_M, 3 << MSDC_PB1_STOP_DLY_S); + clrbits_le32(&host->base->sdc_fifo_cfg, + SDC_FIFO_CFG_WRVALIDSEL); + clrbits_le32(&host->base->sdc_fifo_cfg, + SDC_FIFO_CFG_RDVALIDSEL); + } if (host->dev_comp->busy_check) clrbits_le32(&host->base->patch_bit1, (1 << 7)); @@ -1544,15 +1554,28 @@ static void msdc_init_hw(struct msdc_host *host) } if (host->dev_comp->data_tune) { - setbits_le32(tune_reg, - MSDC_PAD_TUNE_RD_SEL | MSDC_PAD_TUNE_CMD_SEL); - clrsetbits_le32(&host->base->patch_bit0, - MSDC_INT_DAT_LATCH_CK_SEL_M, - host->latch_ck << - MSDC_INT_DAT_LATCH_CK_SEL_S); + if (host->top_base) { + setbits_le32(&host->top_base->emmc_top_control, + PAD_DAT_RD_RXDLY_SEL); + clrbits_le32(&host->top_base->emmc_top_control, + DATA_K_VALUE_SEL); + setbits_le32(&host->top_base->emmc_top_cmd, + PAD_CMD_RD_RXDLY_SEL); + } else { + setbits_le32(tune_reg, + MSDC_PAD_TUNE_RD_SEL | MSDC_PAD_TUNE_CMD_SEL); + clrsetbits_le32(&host->base->patch_bit0, + MSDC_INT_DAT_LATCH_CK_SEL_M, + host->latch_ck << + MSDC_INT_DAT_LATCH_CK_SEL_S); + } } else { /* choose clock tune */ - setbits_le32(tune_reg, MSDC_PAD_TUNE_RXDLYSEL); + if (host->top_base) + setbits_le32(&host->top_base->emmc_top_control, + PAD_RXDLY_SEL); + else + setbits_le32(tune_reg, MSDC_PAD_TUNE_RXDLYSEL); } if (host->dev_comp->builtin_pad_ctrl) { @@ -1604,12 +1627,6 @@ static void msdc_init_hw(struct msdc_host *host) clrsetbits_le32(&host->base->sdc_cfg, SDC_CFG_DTOC_M, 3 << SDC_CFG_DTOC_S); - if (host->dev_comp->stop_clk_fix) { - clrbits_le32(&host->base->sdc_fifo_cfg, - SDC_FIFO_CFG_WRVALIDSEL); - clrbits_le32(&host->base->sdc_fifo_cfg, - SDC_FIFO_CFG_RDVALIDSEL); - } host->def_tune_para.iocon = readl(&host->base->msdc_iocon); host->def_tune_para.pad_tune = readl(&host->base->pad_tune); @@ -1792,6 +1809,25 @@ static const struct msdc_compatible mt7623_compat = { .enhance_rx = false }; +static const struct msdc_compatible mt7986_compat = { + .clk_div_bits = 12, + .pad_tune0 = true, + .async_fifo = true, + .data_tune = true, + .busy_check = true, + .stop_clk_fix = true, + .enhance_rx = true, +}; + +static const struct msdc_compatible mt7981_compat = { + .clk_div_bits = 12, + .pad_tune0 = true, + .async_fifo = true, + .data_tune = true, + .busy_check = true, + .stop_clk_fix = true, +}; + static const struct msdc_compatible mt8512_compat = { .clk_div_bits = 12, .pad_tune0 = true, @@ -1824,6 +1860,8 @@ static const struct udevice_id msdc_ids[] = { { .compatible = "mediatek,mt7621-mmc", .data = (ulong)&mt7621_compat }, { .compatible = "mediatek,mt7622-mmc", .data = (ulong)&mt7622_compat }, { .compatible = "mediatek,mt7623-mmc", .data = (ulong)&mt7623_compat }, + { .compatible = "mediatek,mt7986-mmc", .data = (ulong)&mt7986_compat }, + { .compatible = "mediatek,mt7981-mmc", .data = (ulong)&mt7981_compat }, { .compatible = "mediatek,mt8512-mmc", .data = (ulong)&mt8512_compat }, { .compatible = "mediatek,mt8516-mmc", .data = (ulong)&mt8516_compat }, { .compatible = "mediatek,mt8183-mmc", .data = (ulong)&mt8183_compat }, From 625967254c3983730e998b5f302b70390bb9e770 Mon Sep 17 00:00:00 2001 From: Weijie Gao Date: Fri, 9 Sep 2022 19:59:21 +0800 Subject: [PATCH 246/374] net: mediatek: use a struct to cover variations of all SoCs Using a single soc id to control different initialization and TX/RX flow for all SoCs is not extensible if more hardware variations are added in the future. This patch introduces a struct to replace the original mtk_soc to allow the driver be able handle newer hardwares. Reviewed-by: Simon Glass Tested-by: Daniel Golle Signed-off-by: Weijie Gao Reviewed-by: Ramon Fried --- drivers/net/mtk_eth.c | 56 ++++++++++++++++++++++++++++++------------- drivers/net/mtk_eth.h | 25 ++++++++++++++++++- 2 files changed, 64 insertions(+), 17 deletions(-) diff --git a/drivers/net/mtk_eth.c b/drivers/net/mtk_eth.c index 4fe7ee0d36..ce4aa6e065 100644 --- a/drivers/net/mtk_eth.c +++ b/drivers/net/mtk_eth.c @@ -142,11 +142,15 @@ enum mtk_switch { SW_MT7531 }; -enum mtk_soc { - SOC_MT7623, - SOC_MT7629, - SOC_MT7622, - SOC_MT7621 +/* struct mtk_soc_data - This is the structure holding all differences + * among various plaforms + * @caps Flags shown the extra capability for the SoC + * @ana_rgc3: The offset for register ANA_RGC3 related to + * sgmiisys syscon + */ +struct mtk_soc_data { + u32 caps; + u32 ana_rgc3; }; struct mtk_eth_priv { @@ -171,7 +175,7 @@ struct mtk_eth_priv { int (*mmd_write)(struct mtk_eth_priv *priv, u8 addr, u8 devad, u16 reg, u16 val); - enum mtk_soc soc; + const struct mtk_soc_data *soc; int gmac_id; int force_mode; int speed; @@ -679,7 +683,7 @@ static int mt7530_setup(struct mtk_eth_priv *priv) u32 val, txdrv; int i; - if (priv->soc != SOC_MT7621) { + if (!MTK_HAS_CAPS(priv->soc->caps, MTK_TRGMII_MT7621_CLK)) { /* Select 250MHz clk for RGMII mode */ mtk_ethsys_rmw(priv, ETHSYS_CLKCFG0_REG, ETHSYS_TRGMII_CLK_SEL362_5, 0); @@ -1108,9 +1112,8 @@ static int mtk_phy_probe(struct udevice *dev) static void mtk_sgmii_init(struct mtk_eth_priv *priv) { /* Set SGMII GEN2 speed(2.5G) */ - clrsetbits_le32(priv->sgmii_base + ((priv->soc == SOC_MT7622) ? - SGMSYS_GEN2_SPEED : SGMSYS_GEN2_SPEED_V2), - SGMSYS_SPEED_2500, SGMSYS_SPEED_2500); + setbits_le32(priv->sgmii_base + priv->soc->ana_rgc3, + SGMSYS_SPEED_2500); /* Disable SGMII AN */ clrsetbits_le32(priv->sgmii_base + SGMSYS_PCS_CONTROL_1, @@ -1182,7 +1185,8 @@ static void mtk_mac_init(struct mtk_eth_priv *priv) mtk_gmac_write(priv, GMAC_PORT_MCR(priv->gmac_id), mcr); } - if (priv->soc == SOC_MT7623) { + if (MTK_HAS_CAPS(priv->soc->caps, MTK_GMAC1_TRGMII) && + !MTK_HAS_CAPS(priv->soc->caps, MTK_TRGMII_MT7621_CLK)) { /* Lower Tx Driving for TRGMII path */ for (i = 0 ; i < NUM_TRGMII_CTRL; i++) mtk_gmac_write(priv, GMAC_TRGMII_TD_ODT(i), @@ -1431,7 +1435,11 @@ static int mtk_eth_of_to_plat(struct udevice *dev) ofnode subnode; int ret; - priv->soc = dev_get_driver_data(dev); + priv->soc = (const struct mtk_soc_data *)dev_get_driver_data(dev); + if (!priv->soc) { + dev_err(dev, "missing soc compatible data\n"); + return -EINVAL; + } pdata->iobase = (phys_addr_t)dev_remap_addr(dev); @@ -1544,11 +1552,27 @@ static int mtk_eth_of_to_plat(struct udevice *dev) return 0; } +static const struct mtk_soc_data mt7629_data = { + .ana_rgc3 = 0x128, +}; + +static const struct mtk_soc_data mt7623_data = { + .caps = MT7623_CAPS, +}; + +static const struct mtk_soc_data mt7622_data = { + .ana_rgc3 = 0x2028, +}; + +static const struct mtk_soc_data mt7621_data = { + .caps = MT7621_CAPS, +}; + static const struct udevice_id mtk_eth_ids[] = { - { .compatible = "mediatek,mt7629-eth", .data = SOC_MT7629 }, - { .compatible = "mediatek,mt7623-eth", .data = SOC_MT7623 }, - { .compatible = "mediatek,mt7622-eth", .data = SOC_MT7622 }, - { .compatible = "mediatek,mt7621-eth", .data = SOC_MT7621 }, + { .compatible = "mediatek,mt7629-eth", .data = (ulong)&mt7629_data }, + { .compatible = "mediatek,mt7623-eth", .data = (ulong)&mt7623_data }, + { .compatible = "mediatek,mt7622-eth", .data = (ulong)&mt7622_data }, + { .compatible = "mediatek,mt7621-eth", .data = (ulong)&mt7621_data }, {} }; diff --git a/drivers/net/mtk_eth.h b/drivers/net/mtk_eth.h index 057ecfaabf..15c2030617 100644 --- a/drivers/net/mtk_eth.h +++ b/drivers/net/mtk_eth.h @@ -9,8 +9,31 @@ #ifndef _MTK_ETH_H_ #define _MTK_ETH_H_ -/* Frame Engine Register Bases */ #include + +enum mkt_eth_capabilities { + MTK_TRGMII_BIT, + MTK_TRGMII_MT7621_CLK_BIT, + + /* PATH BITS */ + MTK_ETH_PATH_GMAC1_TRGMII_BIT, +}; + +#define MTK_TRGMII BIT(MTK_TRGMII_BIT) +#define MTK_TRGMII_MT7621_CLK BIT(MTK_TRGMII_MT7621_CLK_BIT) + +/* Supported path present on SoCs */ +#define MTK_ETH_PATH_GMAC1_TRGMII BIT(MTK_ETH_PATH_GMAC1_TRGMII_BIT) + +#define MTK_GMAC1_TRGMII (MTK_ETH_PATH_GMAC1_TRGMII | MTK_TRGMII) + +#define MTK_HAS_CAPS(caps, _x) (((caps) & (_x)) == (_x)) + +#define MT7621_CAPS (MTK_GMAC1_TRGMII | MTK_TRGMII_MT7621_CLK) + +#define MT7623_CAPS (MTK_GMAC1_TRGMII) + +/* Frame Engine Register Bases */ #define PDMA_BASE 0x0800 #define GDMA1_BASE 0x0500 #define GDMA2_BASE 0x1500 From 7d928c3f2798fc2602e3c320b533fa721a92df38 Mon Sep 17 00:00:00 2001 From: Weijie Gao Date: Fri, 9 Sep 2022 19:59:24 +0800 Subject: [PATCH 247/374] net: mediatek: stop using bitfileds for DMA descriptors This patch is a preparation for adding a new version of PDMA of which the DMA descriptor fields has changed. Using bitfields will result in a complex modification. Convert bitfields to u32 units can solve this problem easily. Reviewed-by: Simon Glass Tested-by: Daniel Golle Signed-off-by: Weijie Gao Reviewed-by: Ramon Fried --- drivers/net/mtk_eth.c | 144 ++++++++++++++---------------------------- drivers/net/mtk_eth.h | 32 ++++++++++ 2 files changed, 80 insertions(+), 96 deletions(-) diff --git a/drivers/net/mtk_eth.c b/drivers/net/mtk_eth.c index ce4aa6e065..e3738b9277 100644 --- a/drivers/net/mtk_eth.c +++ b/drivers/net/mtk_eth.c @@ -65,77 +65,6 @@ (DP_DISCARD << MC_DP_S) | \ (DP_DISCARD << UN_DP_S)) -struct pdma_rxd_info1 { - u32 PDP0; -}; - -struct pdma_rxd_info2 { - u32 PLEN1 : 14; - u32 LS1 : 1; - u32 UN_USED : 1; - u32 PLEN0 : 14; - u32 LS0 : 1; - u32 DDONE : 1; -}; - -struct pdma_rxd_info3 { - u32 PDP1; -}; - -struct pdma_rxd_info4 { - u32 FOE_ENTRY : 14; - u32 CRSN : 5; - u32 SP : 3; - u32 L4F : 1; - u32 L4VLD : 1; - u32 TACK : 1; - u32 IP4F : 1; - u32 IP4 : 1; - u32 IP6 : 1; - u32 UN_USED : 4; -}; - -struct pdma_rxdesc { - struct pdma_rxd_info1 rxd_info1; - struct pdma_rxd_info2 rxd_info2; - struct pdma_rxd_info3 rxd_info3; - struct pdma_rxd_info4 rxd_info4; -}; - -struct pdma_txd_info1 { - u32 SDP0; -}; - -struct pdma_txd_info2 { - u32 SDL1 : 14; - u32 LS1 : 1; - u32 BURST : 1; - u32 SDL0 : 14; - u32 LS0 : 1; - u32 DDONE : 1; -}; - -struct pdma_txd_info3 { - u32 SDP1; -}; - -struct pdma_txd_info4 { - u32 VLAN_TAG : 16; - u32 INS : 1; - u32 RESV : 2; - u32 UDF : 6; - u32 FPORT : 3; - u32 TSO : 1; - u32 TUI_CO : 3; -}; - -struct pdma_txdesc { - struct pdma_txd_info1 txd_info1; - struct pdma_txd_info2 txd_info2; - struct pdma_txd_info3 txd_info3; - struct pdma_txd_info4 txd_info4; -}; - enum mtk_switch { SW_NONE, SW_MT7530, @@ -151,13 +80,15 @@ enum mtk_switch { struct mtk_soc_data { u32 caps; u32 ana_rgc3; + u32 txd_size; + u32 rxd_size; }; struct mtk_eth_priv { char pkt_pool[TOTAL_PKT_BUF_SIZE] __aligned(ARCH_DMA_MINALIGN); - struct pdma_txdesc *tx_ring_noc; - struct pdma_rxdesc *rx_ring_noc; + void *tx_ring_noc; + void *rx_ring_noc; int rx_dma_owner_idx0; int tx_cpu_owner_idx0; @@ -1202,14 +1133,16 @@ static void mtk_mac_init(struct mtk_eth_priv *priv) static void mtk_eth_fifo_init(struct mtk_eth_priv *priv) { char *pkt_base = priv->pkt_pool; + struct mtk_tx_dma *txd; + struct mtk_rx_dma *rxd; int i; mtk_pdma_rmw(priv, PDMA_GLO_CFG_REG, 0xffff0000, 0); udelay(500); - memset(priv->tx_ring_noc, 0, NUM_TX_DESC * sizeof(struct pdma_txdesc)); - memset(priv->rx_ring_noc, 0, NUM_RX_DESC * sizeof(struct pdma_rxdesc)); - memset(priv->pkt_pool, 0, TOTAL_PKT_BUF_SIZE); + memset(priv->tx_ring_noc, 0, NUM_TX_DESC * priv->soc->txd_size); + memset(priv->rx_ring_noc, 0, NUM_RX_DESC * priv->soc->rxd_size); + memset(priv->pkt_pool, 0xff, TOTAL_PKT_BUF_SIZE); flush_dcache_range((ulong)pkt_base, (ulong)(pkt_base + TOTAL_PKT_BUF_SIZE)); @@ -1218,17 +1151,21 @@ static void mtk_eth_fifo_init(struct mtk_eth_priv *priv) priv->tx_cpu_owner_idx0 = 0; for (i = 0; i < NUM_TX_DESC; i++) { - priv->tx_ring_noc[i].txd_info2.LS0 = 1; - priv->tx_ring_noc[i].txd_info2.DDONE = 1; - priv->tx_ring_noc[i].txd_info4.FPORT = priv->gmac_id + 1; + txd = priv->tx_ring_noc + i * priv->soc->txd_size; + + txd->txd1 = virt_to_phys(pkt_base); + txd->txd2 = PDMA_TXD2_DDONE | PDMA_TXD2_LS0; + txd->txd4 = PDMA_TXD4_FPORT_SET(priv->gmac_id + 1); - priv->tx_ring_noc[i].txd_info1.SDP0 = virt_to_phys(pkt_base); pkt_base += PKTSIZE_ALIGN; } for (i = 0; i < NUM_RX_DESC; i++) { - priv->rx_ring_noc[i].rxd_info2.PLEN0 = PKTSIZE_ALIGN; - priv->rx_ring_noc[i].rxd_info1.PDP0 = virt_to_phys(pkt_base); + rxd = priv->rx_ring_noc + i * priv->soc->rxd_size; + + rxd->rxd1 = virt_to_phys(pkt_base); + rxd->rxd2 = PDMA_RXD2_PLEN0_SET(PKTSIZE_ALIGN); + pkt_base += PKTSIZE_ALIGN; } @@ -1315,20 +1252,22 @@ static int mtk_eth_send(struct udevice *dev, void *packet, int length) { struct mtk_eth_priv *priv = dev_get_priv(dev); u32 idx = priv->tx_cpu_owner_idx0; + struct mtk_tx_dma *txd; void *pkt_base; - if (!priv->tx_ring_noc[idx].txd_info2.DDONE) { + txd = priv->tx_ring_noc + idx * priv->soc->txd_size; + + if (!(txd->txd2 & PDMA_TXD2_DDONE)) { debug("mtk-eth: TX DMA descriptor ring is full\n"); return -EPERM; } - pkt_base = (void *)phys_to_virt(priv->tx_ring_noc[idx].txd_info1.SDP0); + pkt_base = (void *)phys_to_virt(txd->txd1); memcpy(pkt_base, packet, length); flush_dcache_range((ulong)pkt_base, (ulong)pkt_base + roundup(length, ARCH_DMA_MINALIGN)); - priv->tx_ring_noc[idx].txd_info2.SDL0 = length; - priv->tx_ring_noc[idx].txd_info2.DDONE = 0; + txd->txd2 = PDMA_TXD2_LS0 | PDMA_TXD2_SDL0_SET(length); priv->tx_cpu_owner_idx0 = (priv->tx_cpu_owner_idx0 + 1) % NUM_TX_DESC; mtk_pdma_write(priv, TX_CTX_IDX_REG(0), priv->tx_cpu_owner_idx0); @@ -1340,16 +1279,20 @@ static int mtk_eth_recv(struct udevice *dev, int flags, uchar **packetp) { struct mtk_eth_priv *priv = dev_get_priv(dev); u32 idx = priv->rx_dma_owner_idx0; + struct mtk_rx_dma *rxd; uchar *pkt_base; u32 length; - if (!priv->rx_ring_noc[idx].rxd_info2.DDONE) { + rxd = priv->rx_ring_noc + idx * priv->soc->rxd_size; + + if (!(rxd->rxd2 & PDMA_RXD2_DDONE)) { debug("mtk-eth: RX DMA descriptor ring is empty\n"); return -EAGAIN; } - length = priv->rx_ring_noc[idx].rxd_info2.PLEN0; - pkt_base = (void *)phys_to_virt(priv->rx_ring_noc[idx].rxd_info1.PDP0); + length = PDMA_RXD2_PLEN0_GET(rxd->rxd2); + + pkt_base = (void *)phys_to_virt(rxd->rxd1); invalidate_dcache_range((ulong)pkt_base, (ulong)pkt_base + roundup(length, ARCH_DMA_MINALIGN)); @@ -1363,10 +1306,11 @@ static int mtk_eth_free_pkt(struct udevice *dev, uchar *packet, int length) { struct mtk_eth_priv *priv = dev_get_priv(dev); u32 idx = priv->rx_dma_owner_idx0; + struct mtk_rx_dma *rxd; - priv->rx_ring_noc[idx].rxd_info2.DDONE = 0; - priv->rx_ring_noc[idx].rxd_info2.LS0 = 0; - priv->rx_ring_noc[idx].rxd_info2.PLEN0 = PKTSIZE_ALIGN; + rxd = priv->rx_ring_noc + idx * priv->soc->rxd_size; + + rxd->rxd2 = PDMA_RXD2_PLEN0_SET(PKTSIZE_ALIGN); mtk_pdma_write(priv, RX_CRX_IDX_REG(0), idx); priv->rx_dma_owner_idx0 = (priv->rx_dma_owner_idx0 + 1) % NUM_RX_DESC; @@ -1393,11 +1337,11 @@ static int mtk_eth_probe(struct udevice *dev) return ret; /* Prepare for tx/rx rings */ - priv->tx_ring_noc = (struct pdma_txdesc *) - noncached_alloc(sizeof(struct pdma_txdesc) * NUM_TX_DESC, + priv->tx_ring_noc = (void *) + noncached_alloc(priv->soc->txd_size * NUM_TX_DESC, ARCH_DMA_MINALIGN); - priv->rx_ring_noc = (struct pdma_rxdesc *) - noncached_alloc(sizeof(struct pdma_rxdesc) * NUM_RX_DESC, + priv->rx_ring_noc = (void *) + noncached_alloc(priv->soc->rxd_size * NUM_RX_DESC, ARCH_DMA_MINALIGN); /* Set MAC mode */ @@ -1554,18 +1498,26 @@ static int mtk_eth_of_to_plat(struct udevice *dev) static const struct mtk_soc_data mt7629_data = { .ana_rgc3 = 0x128, + .txd_size = sizeof(struct mtk_tx_dma), + .rxd_size = sizeof(struct mtk_rx_dma), }; static const struct mtk_soc_data mt7623_data = { .caps = MT7623_CAPS, + .txd_size = sizeof(struct mtk_tx_dma), + .rxd_size = sizeof(struct mtk_rx_dma), }; static const struct mtk_soc_data mt7622_data = { .ana_rgc3 = 0x2028, + .txd_size = sizeof(struct mtk_tx_dma), + .rxd_size = sizeof(struct mtk_rx_dma), }; static const struct mtk_soc_data mt7621_data = { .caps = MT7621_CAPS, + .txd_size = sizeof(struct mtk_tx_dma), + .rxd_size = sizeof(struct mtk_rx_dma), }; static const struct udevice_id mtk_eth_ids[] = { diff --git a/drivers/net/mtk_eth.h b/drivers/net/mtk_eth.h index 15c2030617..65bc9fcc04 100644 --- a/drivers/net/mtk_eth.h +++ b/drivers/net/mtk_eth.h @@ -10,6 +10,7 @@ #define _MTK_ETH_H_ #include +#include enum mkt_eth_capabilities { MTK_TRGMII_BIT, @@ -435,4 +436,35 @@ enum mkt_eth_capabilities { #define PHY_POWER_SAVING_M 0x300 #define PHY_POWER_SAVING_TX 0x0 +/* PDMA descriptors */ +struct mtk_rx_dma { + unsigned int rxd1; + unsigned int rxd2; + unsigned int rxd3; + unsigned int rxd4; +} __packed __aligned(4); + +struct mtk_tx_dma { + unsigned int txd1; + unsigned int txd2; + unsigned int txd3; + unsigned int txd4; +} __packed __aligned(4); + +/* PDMA TXD fields */ +#define PDMA_TXD2_DDONE BIT(31) +#define PDMA_TXD2_LS0 BIT(30) +#define PDMA_TXD2_SDL0_M GENMASK(29, 16) +#define PDMA_TXD2_SDL0_SET(_v) FIELD_PREP(PDMA_TXD2_SDL0_M, (_v)) + +#define PDMA_TXD4_FPORT_M GENMASK(27, 25) +#define PDMA_TXD4_FPORT_SET(_v) FIELD_PREP(PDMA_TXD4_FPORT_M, (_v)) + +/* PDMA RXD fields */ +#define PDMA_RXD2_DDONE BIT(31) +#define PDMA_RXD2_LS0 BIT(30) +#define PDMA_RXD2_PLEN0_M GENMASK(29, 16) +#define PDMA_RXD2_PLEN0_GET(_v) FIELD_GET(PDMA_RXD2_PLEN0_M, (_v)) +#define PDMA_RXD2_PLEN0_SET(_v) FIELD_PREP(PDMA_RXD2_PLEN0_M, (_v)) + #endif /* _MTK_ETH_H_ */ From e7ad046b64cf7d745e32c2e223d24c4f7f867521 Mon Sep 17 00:00:00 2001 From: Weijie Gao Date: Fri, 9 Sep 2022 19:59:26 +0800 Subject: [PATCH 248/374] net: mediatek: add support for PDMA v2 This patch adds support for PDMA v2 hardware. The PDMA v2 has extended the DMA descriptor to 8-words, and some of its fields have changed comparing to the v1 hardware. Reviewed-by: Ramon Fried Reviewed-by: Simon Glass Tested-by: Daniel Golle Signed-off-by: Weijie Gao --- drivers/net/mtk_eth.c | 54 ++++++++++++++++++++++++++++++++----------- drivers/net/mtk_eth.h | 53 +++++++++++++++++++++++++++++++++++------- 2 files changed, 86 insertions(+), 21 deletions(-) diff --git a/drivers/net/mtk_eth.c b/drivers/net/mtk_eth.c index e3738b9277..fb72baae68 100644 --- a/drivers/net/mtk_eth.c +++ b/drivers/net/mtk_eth.c @@ -76,10 +76,14 @@ enum mtk_switch { * @caps Flags shown the extra capability for the SoC * @ana_rgc3: The offset for register ANA_RGC3 related to * sgmiisys syscon + * @pdma_base: Register base of PDMA block + * @txd_size: Tx DMA descriptor size. + * @rxd_size: Rx DMA descriptor size. */ struct mtk_soc_data { u32 caps; u32 ana_rgc3; + u32 pdma_base; u32 txd_size; u32 rxd_size; }; @@ -130,13 +134,13 @@ struct mtk_eth_priv { static void mtk_pdma_write(struct mtk_eth_priv *priv, u32 reg, u32 val) { - writel(val, priv->fe_base + PDMA_BASE + reg); + writel(val, priv->fe_base + priv->soc->pdma_base + reg); } static void mtk_pdma_rmw(struct mtk_eth_priv *priv, u32 reg, u32 clr, u32 set) { - clrsetbits_le32(priv->fe_base + PDMA_BASE + reg, clr, set); + clrsetbits_le32(priv->fe_base + priv->soc->pdma_base + reg, clr, set); } static void mtk_gdma_write(struct mtk_eth_priv *priv, int no, u32 reg, @@ -1133,8 +1137,8 @@ static void mtk_mac_init(struct mtk_eth_priv *priv) static void mtk_eth_fifo_init(struct mtk_eth_priv *priv) { char *pkt_base = priv->pkt_pool; - struct mtk_tx_dma *txd; - struct mtk_rx_dma *rxd; + struct mtk_tx_dma_v2 *txd; + struct mtk_rx_dma_v2 *rxd; int i; mtk_pdma_rmw(priv, PDMA_GLO_CFG_REG, 0xffff0000, 0); @@ -1155,7 +1159,11 @@ static void mtk_eth_fifo_init(struct mtk_eth_priv *priv) txd->txd1 = virt_to_phys(pkt_base); txd->txd2 = PDMA_TXD2_DDONE | PDMA_TXD2_LS0; - txd->txd4 = PDMA_TXD4_FPORT_SET(priv->gmac_id + 1); + + if (MTK_HAS_CAPS(priv->soc->caps, MTK_NETSYS_V2)) + txd->txd5 = PDMA_V2_TXD5_FPORT_SET(priv->gmac_id + 1); + else + txd->txd4 = PDMA_V1_TXD4_FPORT_SET(priv->gmac_id + 1); pkt_base += PKTSIZE_ALIGN; } @@ -1164,7 +1172,11 @@ static void mtk_eth_fifo_init(struct mtk_eth_priv *priv) rxd = priv->rx_ring_noc + i * priv->soc->rxd_size; rxd->rxd1 = virt_to_phys(pkt_base); - rxd->rxd2 = PDMA_RXD2_PLEN0_SET(PKTSIZE_ALIGN); + + if (MTK_HAS_CAPS(priv->soc->caps, MTK_NETSYS_V2)) + rxd->rxd2 = PDMA_V2_RXD2_PLEN0_SET(PKTSIZE_ALIGN); + else + rxd->rxd2 = PDMA_V1_RXD2_PLEN0_SET(PKTSIZE_ALIGN); pkt_base += PKTSIZE_ALIGN; } @@ -1193,6 +1205,9 @@ static int mtk_eth_start(struct udevice *dev) reset_deassert(&priv->rst_fe); mdelay(10); + if (MTK_HAS_CAPS(priv->soc->caps, MTK_NETSYS_V2)) + setbits_le32(priv->fe_base + FE_GLO_MISC_REG, PDMA_VER_V2); + /* Packets forward to PDMA */ mtk_gdma_write(priv, priv->gmac_id, GDMA_IG_CTRL_REG, GDMA_FWD_TO_CPU); @@ -1227,7 +1242,7 @@ static void mtk_eth_stop(struct udevice *dev) TX_WB_DDONE | RX_DMA_EN | TX_DMA_EN, 0); udelay(500); - wait_for_bit_le32(priv->fe_base + PDMA_BASE + PDMA_GLO_CFG_REG, + wait_for_bit_le32(priv->fe_base + priv->soc->pdma_base + PDMA_GLO_CFG_REG, RX_DMA_BUSY | TX_DMA_BUSY, 0, 5000, 0); } @@ -1252,7 +1267,7 @@ static int mtk_eth_send(struct udevice *dev, void *packet, int length) { struct mtk_eth_priv *priv = dev_get_priv(dev); u32 idx = priv->tx_cpu_owner_idx0; - struct mtk_tx_dma *txd; + struct mtk_tx_dma_v2 *txd; void *pkt_base; txd = priv->tx_ring_noc + idx * priv->soc->txd_size; @@ -1267,7 +1282,10 @@ static int mtk_eth_send(struct udevice *dev, void *packet, int length) flush_dcache_range((ulong)pkt_base, (ulong)pkt_base + roundup(length, ARCH_DMA_MINALIGN)); - txd->txd2 = PDMA_TXD2_LS0 | PDMA_TXD2_SDL0_SET(length); + if (MTK_HAS_CAPS(priv->soc->caps, MTK_NETSYS_V2)) + txd->txd2 = PDMA_TXD2_LS0 | PDMA_V2_TXD2_SDL0_SET(length); + else + txd->txd2 = PDMA_TXD2_LS0 | PDMA_V1_TXD2_SDL0_SET(length); priv->tx_cpu_owner_idx0 = (priv->tx_cpu_owner_idx0 + 1) % NUM_TX_DESC; mtk_pdma_write(priv, TX_CTX_IDX_REG(0), priv->tx_cpu_owner_idx0); @@ -1279,7 +1297,7 @@ static int mtk_eth_recv(struct udevice *dev, int flags, uchar **packetp) { struct mtk_eth_priv *priv = dev_get_priv(dev); u32 idx = priv->rx_dma_owner_idx0; - struct mtk_rx_dma *rxd; + struct mtk_rx_dma_v2 *rxd; uchar *pkt_base; u32 length; @@ -1290,7 +1308,10 @@ static int mtk_eth_recv(struct udevice *dev, int flags, uchar **packetp) return -EAGAIN; } - length = PDMA_RXD2_PLEN0_GET(rxd->rxd2); + if (MTK_HAS_CAPS(priv->soc->caps, MTK_NETSYS_V2)) + length = PDMA_V2_RXD2_PLEN0_GET(rxd->rxd2); + else + length = PDMA_V1_RXD2_PLEN0_GET(rxd->rxd2); pkt_base = (void *)phys_to_virt(rxd->rxd1); invalidate_dcache_range((ulong)pkt_base, (ulong)pkt_base + @@ -1306,11 +1327,14 @@ static int mtk_eth_free_pkt(struct udevice *dev, uchar *packet, int length) { struct mtk_eth_priv *priv = dev_get_priv(dev); u32 idx = priv->rx_dma_owner_idx0; - struct mtk_rx_dma *rxd; + struct mtk_rx_dma_v2 *rxd; rxd = priv->rx_ring_noc + idx * priv->soc->rxd_size; - rxd->rxd2 = PDMA_RXD2_PLEN0_SET(PKTSIZE_ALIGN); + if (MTK_HAS_CAPS(priv->soc->caps, MTK_NETSYS_V2)) + rxd->rxd2 = PDMA_V2_RXD2_PLEN0_SET(PKTSIZE_ALIGN); + else + rxd->rxd2 = PDMA_V1_RXD2_PLEN0_SET(PKTSIZE_ALIGN); mtk_pdma_write(priv, RX_CRX_IDX_REG(0), idx); priv->rx_dma_owner_idx0 = (priv->rx_dma_owner_idx0 + 1) % NUM_RX_DESC; @@ -1498,24 +1522,28 @@ static int mtk_eth_of_to_plat(struct udevice *dev) static const struct mtk_soc_data mt7629_data = { .ana_rgc3 = 0x128, + .pdma_base = PDMA_V1_BASE, .txd_size = sizeof(struct mtk_tx_dma), .rxd_size = sizeof(struct mtk_rx_dma), }; static const struct mtk_soc_data mt7623_data = { .caps = MT7623_CAPS, + .pdma_base = PDMA_V1_BASE, .txd_size = sizeof(struct mtk_tx_dma), .rxd_size = sizeof(struct mtk_rx_dma), }; static const struct mtk_soc_data mt7622_data = { .ana_rgc3 = 0x2028, + .pdma_base = PDMA_V1_BASE, .txd_size = sizeof(struct mtk_tx_dma), .rxd_size = sizeof(struct mtk_rx_dma), }; static const struct mtk_soc_data mt7621_data = { .caps = MT7621_CAPS, + .pdma_base = PDMA_V1_BASE, .txd_size = sizeof(struct mtk_tx_dma), .rxd_size = sizeof(struct mtk_rx_dma), }; diff --git a/drivers/net/mtk_eth.h b/drivers/net/mtk_eth.h index 65bc9fcc04..236c498a1b 100644 --- a/drivers/net/mtk_eth.h +++ b/drivers/net/mtk_eth.h @@ -15,6 +15,7 @@ enum mkt_eth_capabilities { MTK_TRGMII_BIT, MTK_TRGMII_MT7621_CLK_BIT, + MTK_NETSYS_V2_BIT, /* PATH BITS */ MTK_ETH_PATH_GMAC1_TRGMII_BIT, @@ -22,6 +23,7 @@ enum mkt_eth_capabilities { #define MTK_TRGMII BIT(MTK_TRGMII_BIT) #define MTK_TRGMII_MT7621_CLK BIT(MTK_TRGMII_MT7621_CLK_BIT) +#define MTK_NETSYS_V2 BIT(MTK_NETSYS_V2_BIT) /* Supported path present on SoCs */ #define MTK_ETH_PATH_GMAC1_TRGMII BIT(MTK_ETH_PATH_GMAC1_TRGMII_BIT) @@ -35,7 +37,8 @@ enum mkt_eth_capabilities { #define MT7623_CAPS (MTK_GMAC1_TRGMII) /* Frame Engine Register Bases */ -#define PDMA_BASE 0x0800 +#define PDMA_V1_BASE 0x0800 +#define PDMA_V2_BASE 0x6000 #define GDMA1_BASE 0x0500 #define GDMA2_BASE 0x1500 #define GMAC_BASE 0x10000 @@ -74,6 +77,8 @@ enum mkt_eth_capabilities { #define SGMSYS_SPEED_2500 BIT(2) /* Frame Engine Registers */ +#define FE_GLO_MISC_REG 0x124 +#define PDMA_VER_V2 BIT(4) /* PDMA */ #define TX_BASE_PTR_REG(n) (0x000 + (n) * 0x10) @@ -444,6 +449,17 @@ struct mtk_rx_dma { unsigned int rxd4; } __packed __aligned(4); +struct mtk_rx_dma_v2 { + unsigned int rxd1; + unsigned int rxd2; + unsigned int rxd3; + unsigned int rxd4; + unsigned int rxd5; + unsigned int rxd6; + unsigned int rxd7; + unsigned int rxd8; +} __packed __aligned(4); + struct mtk_tx_dma { unsigned int txd1; unsigned int txd2; @@ -451,20 +467,41 @@ struct mtk_tx_dma { unsigned int txd4; } __packed __aligned(4); +struct mtk_tx_dma_v2 { + unsigned int txd1; + unsigned int txd2; + unsigned int txd3; + unsigned int txd4; + unsigned int txd5; + unsigned int txd6; + unsigned int txd7; + unsigned int txd8; +} __packed __aligned(4); + /* PDMA TXD fields */ #define PDMA_TXD2_DDONE BIT(31) #define PDMA_TXD2_LS0 BIT(30) -#define PDMA_TXD2_SDL0_M GENMASK(29, 16) -#define PDMA_TXD2_SDL0_SET(_v) FIELD_PREP(PDMA_TXD2_SDL0_M, (_v)) +#define PDMA_V1_TXD2_SDL0_M GENMASK(29, 16) +#define PDMA_V1_TXD2_SDL0_SET(_v) FIELD_PREP(PDMA_V1_TXD2_SDL0_M, (_v)) +#define PDMA_V2_TXD2_SDL0_M GENMASK(23, 8) +#define PDMA_V2_TXD2_SDL0_SET(_v) FIELD_PREP(PDMA_V2_TXD2_SDL0_M, (_v)) -#define PDMA_TXD4_FPORT_M GENMASK(27, 25) -#define PDMA_TXD4_FPORT_SET(_v) FIELD_PREP(PDMA_TXD4_FPORT_M, (_v)) +#define PDMA_V1_TXD4_FPORT_M GENMASK(27, 25) +#define PDMA_V1_TXD4_FPORT_SET(_v) FIELD_PREP(PDMA_V1_TXD4_FPORT_M, (_v)) +#define PDMA_V2_TXD4_FPORT_M GENMASK(27, 24) +#define PDMA_V2_TXD4_FPORT_SET(_v) FIELD_PREP(PDMA_V2_TXD4_FPORT_M, (_v)) + +#define PDMA_V2_TXD5_FPORT_M GENMASK(19, 16) +#define PDMA_V2_TXD5_FPORT_SET(_v) FIELD_PREP(PDMA_V2_TXD5_FPORT_M, (_v)) /* PDMA RXD fields */ #define PDMA_RXD2_DDONE BIT(31) #define PDMA_RXD2_LS0 BIT(30) -#define PDMA_RXD2_PLEN0_M GENMASK(29, 16) -#define PDMA_RXD2_PLEN0_GET(_v) FIELD_GET(PDMA_RXD2_PLEN0_M, (_v)) -#define PDMA_RXD2_PLEN0_SET(_v) FIELD_PREP(PDMA_RXD2_PLEN0_M, (_v)) +#define PDMA_V1_RXD2_PLEN0_M GENMASK(29, 16) +#define PDMA_V1_RXD2_PLEN0_GET(_v) FIELD_GET(PDMA_V1_RXD2_PLEN0_M, (_v)) +#define PDMA_V1_RXD2_PLEN0_SET(_v) FIELD_PREP(PDMA_V1_RXD2_PLEN0_M, (_v)) +#define PDMA_V2_RXD2_PLEN0_M GENMASK(23, 8) +#define PDMA_V2_RXD2_PLEN0_GET(_v) FIELD_GET(PDMA_V2_RXD2_PLEN0_M, (_v)) +#define PDMA_V2_RXD2_PLEN0_SET(_v) FIELD_PREP(PDMA_V2_RXD2_PLEN0_M, (_v)) #endif /* _MTK_ETH_H_ */ From 29a48bf9ccba45a5e560bb564bbe76e42629325f Mon Sep 17 00:00:00 2001 From: Weijie Gao Date: Fri, 9 Sep 2022 19:59:28 +0800 Subject: [PATCH 249/374] net: mediatek: add support for MediaTek MT7981/MT7986 This patch adds support for MediaTek MT7981 and MT7986. Both chips uses PDMA v2. Reviewed-by: Ramon Fried Tested-by: Daniel Golle Signed-off-by: Weijie Gao --- drivers/net/mtk_eth.c | 27 +++++++++++++++++++++++++++ drivers/net/mtk_eth.h | 5 +++++ 2 files changed, 32 insertions(+) diff --git a/drivers/net/mtk_eth.c b/drivers/net/mtk_eth.c index fb72baae68..4c9fb266c7 100644 --- a/drivers/net/mtk_eth.c +++ b/drivers/net/mtk_eth.c @@ -115,6 +115,7 @@ struct mtk_eth_priv { int force_mode; int speed; int duplex; + bool pn_swap; struct phy_device *phydev; int phy_interface; @@ -1057,6 +1058,12 @@ static void mtk_sgmii_init(struct mtk_eth_priv *priv) /* SGMII force mode setting */ writel(SGMII_FORCE_MODE, priv->sgmii_base + SGMSYS_SGMII_MODE); + /* SGMII PN SWAP setting */ + if (priv->pn_swap) { + setbits_le32(priv->sgmii_base + SGMSYS_QPHY_WRAP_CTRL, + SGMII_PN_SWAP_TX_RX); + } + /* Release PHYA power down state */ clrsetbits_le32(priv->sgmii_base + SGMSYS_QPHY_PWR_STATE_CTRL, SGMII_PHYA_PWD, 0); @@ -1470,6 +1477,8 @@ static int mtk_eth_of_to_plat(struct udevice *dev) dev_err(dev, "Unable to find sgmii\n"); return -ENODEV; } + + priv->pn_swap = ofnode_read_bool(args.node, "pn_swap"); } /* check for switch first, otherwise phy will be used */ @@ -1520,6 +1529,22 @@ static int mtk_eth_of_to_plat(struct udevice *dev) return 0; } +static const struct mtk_soc_data mt7986_data = { + .caps = MT7986_CAPS, + .ana_rgc3 = 0x128, + .pdma_base = PDMA_V2_BASE, + .txd_size = sizeof(struct mtk_tx_dma_v2), + .rxd_size = sizeof(struct mtk_rx_dma_v2), +}; + +static const struct mtk_soc_data mt7981_data = { + .caps = MT7986_CAPS, + .ana_rgc3 = 0x128, + .pdma_base = PDMA_V2_BASE, + .txd_size = sizeof(struct mtk_tx_dma_v2), + .rxd_size = sizeof(struct mtk_rx_dma_v2), +}; + static const struct mtk_soc_data mt7629_data = { .ana_rgc3 = 0x128, .pdma_base = PDMA_V1_BASE, @@ -1549,6 +1574,8 @@ static const struct mtk_soc_data mt7621_data = { }; static const struct udevice_id mtk_eth_ids[] = { + { .compatible = "mediatek,mt7986-eth", .data = (ulong)&mt7986_data }, + { .compatible = "mediatek,mt7981-eth", .data = (ulong)&mt7981_data }, { .compatible = "mediatek,mt7629-eth", .data = (ulong)&mt7629_data }, { .compatible = "mediatek,mt7623-eth", .data = (ulong)&mt7623_data }, { .compatible = "mediatek,mt7622-eth", .data = (ulong)&mt7622_data }, diff --git a/drivers/net/mtk_eth.h b/drivers/net/mtk_eth.h index 236c498a1b..1382ccbeb2 100644 --- a/drivers/net/mtk_eth.h +++ b/drivers/net/mtk_eth.h @@ -36,6 +36,8 @@ enum mkt_eth_capabilities { #define MT7623_CAPS (MTK_GMAC1_TRGMII) +#define MT7986_CAPS (MTK_NETSYS_V2) + /* Frame Engine Register Bases */ #define PDMA_V1_BASE 0x0800 #define PDMA_V2_BASE 0x6000 @@ -72,6 +74,9 @@ enum mkt_eth_capabilities { #define SGMSYS_QPHY_PWR_STATE_CTRL 0xe8 #define SGMII_PHYA_PWD BIT(4) +#define SGMSYS_QPHY_WRAP_CTRL 0xec +#define SGMII_PN_SWAP_TX_RX 0x03 + #define SGMSYS_GEN2_SPEED 0x2028 #define SGMSYS_GEN2_SPEED_V2 0x128 #define SGMSYS_SPEED_2500 BIT(2) From 3b17f2e2c2a93b5a0809c782c5bb7ed1b3f68ec1 Mon Sep 17 00:00:00 2001 From: Weijie Gao Date: Fri, 9 Sep 2022 19:59:31 +0800 Subject: [PATCH 250/374] serial: mtk: add support for using dynamic baud clock souce The baud clock on some platform may change due to assigned-clock-parent set in DT. In current flow the baud clock is only retrieved during probe stage. If the parent of the source clock changes after probe stage, the setbrg will set wrong baudrate. To get the right clock rate, this patch records the baud clk struct to the driver's priv, and changes the driver's flow to get the clock rate before calling _mtk_serial_setbrg(). Reviewed-by: Simon Glass Tested-by: Daniel Golle Signed-off-by: Weijie Gao --- drivers/serial/serial_mtk.c | 80 ++++++++++++++++++++++--------------- 1 file changed, 47 insertions(+), 33 deletions(-) diff --git a/drivers/serial/serial_mtk.c b/drivers/serial/serial_mtk.c index 22251c5f4c..03b9e86bfc 100644 --- a/drivers/serial/serial_mtk.c +++ b/drivers/serial/serial_mtk.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -70,27 +71,37 @@ struct mtk_serial_regs { #define BAUD_ALLOW_MAX(baud) ((baud) + (baud) * 3 / 100) #define BAUD_ALLOW_MIX(baud) ((baud) - (baud) * 3 / 100) +/* struct mtk_serial_priv - Structure holding all information used by the + * driver + * @regs: Register base of the serial port + * @clk: The baud clock device + * @fixed_clk_rate: Fallback fixed baud clock rate if baud clock + * device is not specified + * @force_highspeed: Force using high-speed mode + */ struct mtk_serial_priv { struct mtk_serial_regs __iomem *regs; - u32 clock; + struct clk clk; + u32 fixed_clk_rate; bool force_highspeed; }; -static void _mtk_serial_setbrg(struct mtk_serial_priv *priv, int baud) +static void _mtk_serial_setbrg(struct mtk_serial_priv *priv, int baud, + uint clk_rate) { u32 quot, realbaud, samplecount = 1; /* Special case for low baud clock */ - if (baud <= 115200 && priv->clock <= 12000000) { + if (baud <= 115200 && clk_rate == 12000000) { writel(3, &priv->regs->highspeed); - quot = DIV_ROUND_CLOSEST(priv->clock, 256 * baud); + quot = DIV_ROUND_CLOSEST(clk_rate, 256 * baud); if (quot == 0) quot = 1; - samplecount = DIV_ROUND_CLOSEST(priv->clock, quot * baud); + samplecount = DIV_ROUND_CLOSEST(clk_rate, quot * baud); - realbaud = priv->clock / samplecount / quot; + realbaud = clk_rate / samplecount / quot; if (realbaud > BAUD_ALLOW_MAX(baud) || realbaud < BAUD_ALLOW_MIX(baud)) { pr_info("baud %d can't be handled\n", baud); @@ -104,7 +115,7 @@ static void _mtk_serial_setbrg(struct mtk_serial_priv *priv, int baud) if (baud <= 115200) { writel(0, &priv->regs->highspeed); - quot = DIV_ROUND_CLOSEST(priv->clock, 16 * baud); + quot = DIV_ROUND_CLOSEST(clk_rate, 16 * baud); } else if (baud <= 576000) { writel(2, &priv->regs->highspeed); @@ -112,13 +123,13 @@ static void _mtk_serial_setbrg(struct mtk_serial_priv *priv, int baud) if ((baud == 500000) || (baud == 576000)) baud = 460800; - quot = DIV_ROUND_UP(priv->clock, 4 * baud); + quot = DIV_ROUND_UP(clk_rate, 4 * baud); } else { use_hs3: writel(3, &priv->regs->highspeed); - quot = DIV_ROUND_UP(priv->clock, 256 * baud); - samplecount = DIV_ROUND_CLOSEST(priv->clock, quot * baud); + quot = DIV_ROUND_UP(clk_rate, 256 * baud); + samplecount = DIV_ROUND_CLOSEST(clk_rate, quot * baud); } set_baud: @@ -167,8 +178,13 @@ static int _mtk_serial_pending(struct mtk_serial_priv *priv, bool input) static int mtk_serial_setbrg(struct udevice *dev, int baudrate) { struct mtk_serial_priv *priv = dev_get_priv(dev); + u32 clk_rate; - _mtk_serial_setbrg(priv, baudrate); + clk_rate = clk_get_rate(&priv->clk); + if (IS_ERR_VALUE(clk_rate) || clk_rate == 0) + clk_rate = priv->fixed_clk_rate; + + _mtk_serial_setbrg(priv, baudrate, clk_rate); return 0; } @@ -211,7 +227,6 @@ static int mtk_serial_of_to_plat(struct udevice *dev) { struct mtk_serial_priv *priv = dev_get_priv(dev); fdt_addr_t addr; - struct clk clk; int err; addr = dev_read_addr(dev); @@ -220,22 +235,19 @@ static int mtk_serial_of_to_plat(struct udevice *dev) priv->regs = map_physmem(addr, 0, MAP_NOCACHE); - err = clk_get_by_index(dev, 0, &clk); - if (!err) { - err = clk_get_rate(&clk); - if (!IS_ERR_VALUE(err)) - priv->clock = err; - } else if (err != -ENOENT && err != -ENODEV && err != -ENOSYS) { - debug("mtk_serial: failed to get clock\n"); - return err; - } - - if (!priv->clock) - priv->clock = dev_read_u32_default(dev, "clock-frequency", 0); - - if (!priv->clock) { - debug("mtk_serial: clock not defined\n"); - return -EINVAL; + err = clk_get_by_index(dev, 0, &priv->clk); + if (err) { + err = dev_read_u32(dev, "clock-frequency", &priv->fixed_clk_rate); + if (err) { + dev_err(dev, "baud clock not defined\n"); + return -EINVAL; + } + } else { + err = clk_get_rate(&priv->clk); + if (IS_ERR_VALUE(err)) { + dev_err(dev, "invalid baud clock\n"); + return -EINVAL; + } } priv->force_highspeed = dev_read_bool(dev, "mediatek,force-highspeed"); @@ -273,7 +285,7 @@ DECLARE_GLOBAL_DATA_PTR; #define DECLARE_HSUART_PRIV(port) \ static struct mtk_serial_priv mtk_hsuart##port = { \ .regs = (struct mtk_serial_regs *)CONFIG_SYS_NS16550_COM##port, \ - .clock = CONFIG_SYS_NS16550_CLK \ + .fixed_clk_rate = CONFIG_SYS_NS16550_CLK \ }; #define DECLARE_HSUART_FUNCTIONS(port) \ @@ -282,12 +294,14 @@ DECLARE_GLOBAL_DATA_PTR; writel(0, &mtk_hsuart##port.regs->ier); \ writel(UART_MCRVAL, &mtk_hsuart##port.regs->mcr); \ writel(UART_FCRVAL, &mtk_hsuart##port.regs->fcr); \ - _mtk_serial_setbrg(&mtk_hsuart##port, gd->baudrate); \ + _mtk_serial_setbrg(&mtk_hsuart##port, gd->baudrate, \ + mtk_hsuart##port.fixed_clk_rate); \ return 0 ; \ } \ static void mtk_serial##port##_setbrg(void) \ { \ - _mtk_serial_setbrg(&mtk_hsuart##port, gd->baudrate); \ + _mtk_serial_setbrg(&mtk_hsuart##port, gd->baudrate, \ + mtk_hsuart##port.fixed_clk_rate); \ } \ static int mtk_serial##port##_getc(void) \ { \ @@ -427,13 +441,13 @@ static inline void _debug_uart_init(void) struct mtk_serial_priv priv; priv.regs = (void *) CONFIG_VAL(DEBUG_UART_BASE); - priv.clock = CONFIG_DEBUG_UART_CLOCK; + priv.fixed_clk_rate = CONFIG_DEBUG_UART_CLOCK; writel(0, &priv.regs->ier); writel(UART_MCRVAL, &priv.regs->mcr); writel(UART_FCRVAL, &priv.regs->fcr); - _mtk_serial_setbrg(&priv, CONFIG_BAUDRATE); + _mtk_serial_setbrg(&priv, CONFIG_BAUDRATE, priv.fixed_clk_rate); } static inline void _debug_uart_putc(int ch) From bc15e30346e9ed181b74045e64fc496f9c4ce086 Mon Sep 17 00:00:00 2001 From: Weijie Gao Date: Fri, 9 Sep 2022 19:59:33 +0800 Subject: [PATCH 251/374] arm: dts: mt7622: force high-speed mode for uart The input clock for uart is too slow (25MHz) which introduces frequent data error on both receiving and transmitting even if the baudrate is 115200. Using high-speed can significantly solve this issue. Reviewed-by: Simon Glass Tested-by: Daniel Golle Signed-off-by: Weijie Gao --- arch/arm/dts/mt7622.dtsi | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/dts/mt7622.dtsi b/arch/arm/dts/mt7622.dtsi index 0127474c95..fb6c1b7154 100644 --- a/arch/arm/dts/mt7622.dtsi +++ b/arch/arm/dts/mt7622.dtsi @@ -175,6 +175,7 @@ status = "disabled"; assigned-clocks = <&topckgen CLK_TOP_AXI_SEL>; assigned-clock-parents = <&topckgen CLK_TOP_SYSPLL1_D2>; + mediatek,force-highspeed; }; mmc0: mmc@11230000 { From c986dd9f5839028e445853e286525c8b19a0e506 Mon Sep 17 00:00:00 2001 From: Weijie Gao Date: Fri, 9 Sep 2022 19:59:36 +0800 Subject: [PATCH 252/374] pwm: mtk: add support for MediaTek MT7986 SoC This patch adds PWM support for MediaTek MT7986 SoC. Reviewed-by: Simon Glass Signed-off-by: Weijie Gao --- drivers/pwm/pwm-mtk.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/pwm/pwm-mtk.c b/drivers/pwm/pwm-mtk.c index aee1d825a0..3100b5caaf 100644 --- a/drivers/pwm/pwm-mtk.c +++ b/drivers/pwm/pwm-mtk.c @@ -171,10 +171,16 @@ static const struct mtk_pwm_soc mt7629_data = { .pwm45_fixup = false, }; +static const struct mtk_pwm_soc mt7986_data = { + .num_pwms = 2, + .pwm45_fixup = false, +}; + static const struct udevice_id mtk_pwm_ids[] = { { .compatible = "mediatek,mt7622-pwm", .data = (ulong)&mt7622_data }, { .compatible = "mediatek,mt7623-pwm", .data = (ulong)&mt7623_data }, { .compatible = "mediatek,mt7629-pwm", .data = (ulong)&mt7629_data }, + { .compatible = "mediatek,mt7986-pwm", .data = (ulong)&mt7986_data }, { } }; From 1ac479587f18f14bbf54242c1ef2769a66d4b634 Mon Sep 17 00:00:00 2001 From: Weijie Gao Date: Fri, 9 Sep 2022 19:59:38 +0800 Subject: [PATCH 253/374] pwm: mtk: add support for MediaTek MT7981 SoC This patch adds PWM support for MediaTek MT7981 SoC. MT7981 uses a different register offset so we have to add a version field to indicate the IP core version. Reviewed-by: Simon Glass Signed-off-by: Weijie Gao --- drivers/pwm/pwm-mtk.c | 34 ++++++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/drivers/pwm/pwm-mtk.c b/drivers/pwm/pwm-mtk.c index 3100b5caaf..605142eab0 100644 --- a/drivers/pwm/pwm-mtk.c +++ b/drivers/pwm/pwm-mtk.c @@ -29,13 +29,23 @@ #define NSEC_PER_SEC 1000000000L -static const unsigned int mtk_pwm_reg_offset[] = { +enum mtk_pwm_reg_ver { + PWM_REG_V1, + PWM_REG_V2, +}; + +static const unsigned int mtk_pwm_reg_offset_v1[] = { 0x0010, 0x0050, 0x0090, 0x00d0, 0x0110, 0x0150, 0x0190, 0x0220 }; +static const unsigned int mtk_pwm_reg_offset_v2[] = { + 0x0080, 0x00c0, 0x0100, 0x0140, 0x0180, 0x01c0, 0x0200, 0x0240 +}; + struct mtk_pwm_soc { unsigned int num_pwms; bool pwm45_fixup; + enum mtk_pwm_reg_ver reg_ver; }; struct mtk_pwm_priv { @@ -49,7 +59,16 @@ struct mtk_pwm_priv { static void mtk_pwm_w32(struct udevice *dev, uint channel, uint reg, uint val) { struct mtk_pwm_priv *priv = dev_get_priv(dev); - u32 offset = mtk_pwm_reg_offset[channel]; + u32 offset; + + switch (priv->soc->reg_ver) { + case PWM_REG_V2: + offset = mtk_pwm_reg_offset_v2[channel]; + break; + + default: + offset = mtk_pwm_reg_offset_v1[channel]; + } writel(val, priv->base + offset + reg); } @@ -159,27 +178,38 @@ static const struct pwm_ops mtk_pwm_ops = { static const struct mtk_pwm_soc mt7622_data = { .num_pwms = 6, .pwm45_fixup = false, + .reg_ver = PWM_REG_V1, }; static const struct mtk_pwm_soc mt7623_data = { .num_pwms = 5, .pwm45_fixup = true, + .reg_ver = PWM_REG_V1, }; static const struct mtk_pwm_soc mt7629_data = { .num_pwms = 1, .pwm45_fixup = false, + .reg_ver = PWM_REG_V1, +}; + +static const struct mtk_pwm_soc mt7981_data = { + .num_pwms = 2, + .pwm45_fixup = false, + .reg_ver = PWM_REG_V2, }; static const struct mtk_pwm_soc mt7986_data = { .num_pwms = 2, .pwm45_fixup = false, + .reg_ver = PWM_REG_V1, }; static const struct udevice_id mtk_pwm_ids[] = { { .compatible = "mediatek,mt7622-pwm", .data = (ulong)&mt7622_data }, { .compatible = "mediatek,mt7623-pwm", .data = (ulong)&mt7623_data }, { .compatible = "mediatek,mt7629-pwm", .data = (ulong)&mt7629_data }, + { .compatible = "mediatek,mt7981-pwm", .data = (ulong)&mt7981_data }, { .compatible = "mediatek,mt7986-pwm", .data = (ulong)&mt7986_data }, { } }; From 980e107d0f353a24cd4dcf3466cea068ec5e2eed Mon Sep 17 00:00:00 2001 From: Weijie Gao Date: Fri, 9 Sep 2022 19:59:41 +0800 Subject: [PATCH 254/374] timer: mtk: add support for MediaTek MT7981/MT7986 SoCs This patch add general-purpose timer support for MediaTek MT7981/MT7986. These two SoCs uses a newer version of timer with its register definition slightly changed. Reviewed-by: Simon Glass Tested-by: Daniel Golle Signed-off-by: Weijie Gao --- drivers/timer/mtk_timer.c | 59 ++++++++++++++++++++++++--------------- 1 file changed, 37 insertions(+), 22 deletions(-) diff --git a/drivers/timer/mtk_timer.c b/drivers/timer/mtk_timer.c index f6b97f868c..223e63f6c1 100644 --- a/drivers/timer/mtk_timer.c +++ b/drivers/timer/mtk_timer.c @@ -13,24 +13,32 @@ #include #include -#define MTK_GPT4_CTRL 0x40 -#define MTK_GPT4_CLK 0x44 -#define MTK_GPT4_CNT 0x48 +#define MTK_GPT4_OFFSET_V1 0x40 +#define MTK_GPT4_OFFSET_V2 0x80 -#define GPT4_ENABLE BIT(0) -#define GPT4_CLEAR BIT(1) -#define GPT4_FREERUN GENMASK(5, 4) -#define GPT4_CLK_SYS 0x0 -#define GPT4_CLK_DIV1 0x0 +#define MTK_GPT_CON 0x0 +#define MTK_GPT_V1_CLK 0x4 +#define MTK_GPT_CNT 0x8 + +#define GPT_ENABLE BIT(0) +#define GPT_CLEAR BIT(1) +#define GPT_V1_FREERUN GENMASK(5, 4) +#define GPT_V2_FREERUN GENMASK(6, 5) + +enum mtk_gpt_ver { + MTK_GPT_V1, + MTK_GPT_V2 +}; struct mtk_timer_priv { void __iomem *base; + unsigned int gpt4_offset; }; static u64 mtk_timer_get_count(struct udevice *dev) { struct mtk_timer_priv *priv = dev_get_priv(dev); - u32 val = readl(priv->base + MTK_GPT4_CNT); + u32 val = readl(priv->base + priv->gpt4_offset + MTK_GPT_CNT); return timer_conv_64(val); } @@ -40,12 +48,27 @@ static int mtk_timer_probe(struct udevice *dev) struct timer_dev_priv *uc_priv = dev_get_uclass_priv(dev); struct mtk_timer_priv *priv = dev_get_priv(dev); struct clk clk, parent; - int ret; + int ret, gpt_ver; priv->base = dev_read_addr_ptr(dev); + gpt_ver = dev_get_driver_data(dev); + if (!priv->base) return -ENOENT; + if (gpt_ver == MTK_GPT_V2) { + priv->gpt4_offset = MTK_GPT4_OFFSET_V2; + + writel(GPT_V2_FREERUN | GPT_CLEAR | GPT_ENABLE, + priv->base + priv->gpt4_offset + MTK_GPT_CON); + } else { + priv->gpt4_offset = MTK_GPT4_OFFSET_V1; + + writel(GPT_V1_FREERUN | GPT_CLEAR | GPT_ENABLE, + priv->base + priv->gpt4_offset + MTK_GPT_CON); + writel(0, priv->base + priv->gpt4_offset + MTK_GPT_V1_CLK); + } + ret = clk_get_by_index(dev, 0, &clk); if (ret) return ret; @@ -61,16 +84,6 @@ static int mtk_timer_probe(struct udevice *dev) if (!uc_priv->clock_rate) return -EINVAL; - /* - * Initialize the timer: - * 1. set clock source to system clock with clock divider setting to 1 - * 2. set timer mode to free running - * 3. reset timer counter to 0 then enable the timer - */ - writel(GPT4_CLK_SYS | GPT4_CLK_DIV1, priv->base + MTK_GPT4_CLK); - writel(GPT4_FREERUN | GPT4_CLEAR | GPT4_ENABLE, - priv->base + MTK_GPT4_CTRL); - return 0; } @@ -79,8 +92,10 @@ static const struct timer_ops mtk_timer_ops = { }; static const struct udevice_id mtk_timer_ids[] = { - { .compatible = "mediatek,timer" }, - { .compatible = "mediatek,mt6577-timer" }, + { .compatible = "mediatek,timer", .data = MTK_GPT_V1 }, + { .compatible = "mediatek,mt6577-timer", .data = MTK_GPT_V1 }, + { .compatible = "mediatek,mt7981-timer", .data = MTK_GPT_V2 }, + { .compatible = "mediatek,mt7986-timer", .data = MTK_GPT_V2 }, { } }; From 7daf55d3d181e6564a2d441802c189276c2889b5 Mon Sep 17 00:00:00 2001 From: Weijie Gao Date: Fri, 9 Sep 2022 19:59:43 +0800 Subject: [PATCH 255/374] watchdog: mediatek: add support for MediaTek MT7986 SoC Add watchdog support for MediaTek MT7986 SoC Reviewed-by: Simon Glass Tested-by: Daniel Golle Signed-off-by: Weijie Gao --- drivers/watchdog/mtk_wdt.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/watchdog/mtk_wdt.c b/drivers/watchdog/mtk_wdt.c index b098b2e3cf..368b36849c 100644 --- a/drivers/watchdog/mtk_wdt.c +++ b/drivers/watchdog/mtk_wdt.c @@ -145,6 +145,7 @@ static const struct wdt_ops mtk_wdt_ops = { static const struct udevice_id mtk_wdt_ids[] = { { .compatible = "mediatek,wdt"}, { .compatible = "mediatek,mt6589-wdt"}, + { .compatible = "mediatek,mt7986-wdt" }, {} }; From b34a2368d61eafec7433c53a0fcdb7b276114d79 Mon Sep 17 00:00:00 2001 From: Weijie Gao Date: Fri, 9 Sep 2022 19:59:45 +0800 Subject: [PATCH 256/374] spi: add support for MediaTek spi-mem controller This patch adds support for spi-mem controller found on newer MediaTek SoCs This controller supports Single/Dual/Quad SPI mode. Reviewed-by: Simon Glass Tested-by: Daniel Golle Signed-off-by: SkyLake.Huang --- drivers/spi/Kconfig | 8 + drivers/spi/Makefile | 1 + drivers/spi/mtk_spim.c | 701 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 710 insertions(+) create mode 100644 drivers/spi/mtk_spim.c diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index ac91d82258..07e50e240e 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -286,6 +286,14 @@ config MTK_SNFI_SPI used to access SPI memory devices like SPI-NOR or SPI-NAND on platforms embedding this IP core, like MT7622/M7629. +config MTK_SPIM + bool "Mediatek SPI-MEM master controller driver" + depends on SPI_MEM + help + Enable MediaTek SPI-MEM master controller driver. This driver mainly + supports SPI flashes. You can use single, dual or quad mode + transmission on this controller. + config MVEBU_A3700_SPI bool "Marvell Armada 3700 SPI driver" select CLK_ARMADA_3720 diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index 7ba953d2df..50ba43550b 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile @@ -44,6 +44,7 @@ obj-$(CONFIG_MPC8XX_SPI) += mpc8xx_spi.o obj-$(CONFIG_MPC8XXX_SPI) += mpc8xxx_spi.o obj-$(CONFIG_MTK_SNFI_SPI) += mtk_snfi_spi.o obj-$(CONFIG_MTK_SNOR) += mtk_snor.o +obj-$(CONFIG_MTK_SPIM) += mtk_spim.o obj-$(CONFIG_MT7620_SPI) += mt7620_spi.o obj-$(CONFIG_MT7621_SPI) += mt7621_spi.o obj-$(CONFIG_MSCC_BB_SPI) += mscc_bb_spi.o diff --git a/drivers/spi/mtk_spim.c b/drivers/spi/mtk_spim.c new file mode 100644 index 0000000000..b45ef529a5 --- /dev/null +++ b/drivers/spi/mtk_spim.c @@ -0,0 +1,701 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2022 MediaTek Inc. All Rights Reserved. + * + * Author: SkyLake.Huang + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define SPI_CFG0_REG 0x0000 +#define SPI_CFG1_REG 0x0004 +#define SPI_TX_SRC_REG 0x0008 +#define SPI_RX_DST_REG 0x000c +#define SPI_TX_DATA_REG 0x0010 +#define SPI_RX_DATA_REG 0x0014 +#define SPI_CMD_REG 0x0018 +#define SPI_IRQ_REG 0x001c +#define SPI_STATUS_REG 0x0020 +#define SPI_PAD_SEL_REG 0x0024 +#define SPI_CFG2_REG 0x0028 +#define SPI_TX_SRC_REG_64 0x002c +#define SPI_RX_DST_REG_64 0x0030 +#define SPI_CFG3_IPM_REG 0x0040 + +#define SPI_CFG0_SCK_HIGH_OFFSET 0 +#define SPI_CFG0_SCK_LOW_OFFSET 8 +#define SPI_CFG0_CS_HOLD_OFFSET 16 +#define SPI_CFG0_CS_SETUP_OFFSET 24 +#define SPI_ADJUST_CFG0_CS_HOLD_OFFSET 0 +#define SPI_ADJUST_CFG0_CS_SETUP_OFFSET 16 + +#define SPI_CFG1_CS_IDLE_OFFSET 0 +#define SPI_CFG1_PACKET_LOOP_OFFSET 8 +#define SPI_CFG1_PACKET_LENGTH_OFFSET 16 +#define SPI_CFG1_GET_TICKDLY_OFFSET 29 + +#define SPI_CFG1_GET_TICKDLY_MASK GENMASK(31, 29) +#define SPI_CFG1_CS_IDLE_MASK 0xff +#define SPI_CFG1_PACKET_LOOP_MASK 0xff00 +#define SPI_CFG1_PACKET_LENGTH_MASK 0x3ff0000 +#define SPI_CFG1_IPM_PACKET_LENGTH_MASK GENMASK(31, 16) +#define SPI_CFG2_SCK_HIGH_OFFSET 0 +#define SPI_CFG2_SCK_LOW_OFFSET 16 +#define SPI_CFG2_SCK_HIGH_MASK GENMASK(15, 0) +#define SPI_CFG2_SCK_LOW_MASK GENMASK(31, 16) + +#define SPI_CMD_ACT BIT(0) +#define SPI_CMD_RESUME BIT(1) +#define SPI_CMD_RST BIT(2) +#define SPI_CMD_PAUSE_EN BIT(4) +#define SPI_CMD_DEASSERT BIT(5) +#define SPI_CMD_SAMPLE_SEL BIT(6) +#define SPI_CMD_CS_POL BIT(7) +#define SPI_CMD_CPHA BIT(8) +#define SPI_CMD_CPOL BIT(9) +#define SPI_CMD_RX_DMA BIT(10) +#define SPI_CMD_TX_DMA BIT(11) +#define SPI_CMD_TXMSBF BIT(12) +#define SPI_CMD_RXMSBF BIT(13) +#define SPI_CMD_RX_ENDIAN BIT(14) +#define SPI_CMD_TX_ENDIAN BIT(15) +#define SPI_CMD_FINISH_IE BIT(16) +#define SPI_CMD_PAUSE_IE BIT(17) +#define SPI_CMD_IPM_NONIDLE_MODE BIT(19) +#define SPI_CMD_IPM_SPIM_LOOP BIT(21) +#define SPI_CMD_IPM_GET_TICKDLY_OFFSET 22 + +#define SPI_CMD_IPM_GET_TICKDLY_MASK GENMASK(24, 22) + +#define PIN_MODE_CFG(x) ((x) / 2) + +#define SPI_CFG3_IPM_PIN_MODE_OFFSET 0 +#define SPI_CFG3_IPM_HALF_DUPLEX_DIR BIT(2) +#define SPI_CFG3_IPM_HALF_DUPLEX_EN BIT(3) +#define SPI_CFG3_IPM_XMODE_EN BIT(4) +#define SPI_CFG3_IPM_NODATA_FLAG BIT(5) +#define SPI_CFG3_IPM_CMD_BYTELEN_OFFSET 8 +#define SPI_CFG3_IPM_ADDR_BYTELEN_OFFSET 12 +#define SPI_CFG3_IPM_DUMMY_BYTELEN_OFFSET 16 + +#define SPI_CFG3_IPM_CMD_PIN_MODE_MASK GENMASK(1, 0) +#define SPI_CFG3_IPM_CMD_BYTELEN_MASK GENMASK(11, 8) +#define SPI_CFG3_IPM_ADDR_BYTELEN_MASK GENMASK(15, 12) +#define SPI_CFG3_IPM_DUMMY_BYTELEN_MASK GENMASK(19, 16) + +#define MT8173_SPI_MAX_PAD_SEL 3 + +#define MTK_SPI_PAUSE_INT_STATUS 0x2 + +#define MTK_SPI_IDLE 0 +#define MTK_SPI_PAUSED 1 + +#define MTK_SPI_MAX_FIFO_SIZE 32U +#define MTK_SPI_PACKET_SIZE 1024 +#define MTK_SPI_IPM_PACKET_SIZE SZ_64K +#define MTK_SPI_IPM_PACKET_LOOP SZ_256 + +#define MTK_SPI_32BITS_MASK 0xffffffff + +#define DMA_ADDR_EXT_BITS 36 +#define DMA_ADDR_DEF_BITS 32 + +#define CLK_TO_US(freq, clkcnt) DIV_ROUND_UP((clkcnt), (freq) / 1000000) + +/* struct mtk_spim_capability + * @enhance_timing: Some IC design adjust cfg register to enhance time accuracy + * @dma_ext: Some IC support DMA addr extension + * @ipm_design: The IPM IP design improves some features, and supports dual/quad mode + * @support_quad: Whether quad mode is supported + */ +struct mtk_spim_capability { + bool enhance_timing; + bool dma_ext; + bool ipm_design; + bool support_quad; +}; + +/* struct mtk_spim_priv + * @base: Base address of the spi controller + * @state: Controller state + * @sel_clk: Pad clock + * @spi_clk: Core clock + * @xfer_len: Current length of data for transfer + * @hw_cap: Controller capabilities + * @tick_dly: Used to postpone SPI sampling time + * @sample_sel: Sample edge of MISO + * @dev: udevice of this spi controller + * @tx_dma: Tx DMA address + * @rx_dma: Rx DMA address + */ +struct mtk_spim_priv { + void __iomem *base; + u32 state; + struct clk sel_clk, spi_clk; + u32 xfer_len; + struct mtk_spim_capability hw_cap; + u32 tick_dly; + u32 sample_sel; + + struct device *dev; + dma_addr_t tx_dma; + dma_addr_t rx_dma; +}; + +static void mtk_spim_reset(struct mtk_spim_priv *priv) +{ + /* set the software reset bit in SPI_CMD_REG. */ + setbits_le32(priv->base + SPI_CMD_REG, SPI_CMD_RST); + clrbits_le32(priv->base + SPI_CMD_REG, SPI_CMD_RST); +} + +static int mtk_spim_hw_init(struct spi_slave *slave) +{ + struct udevice *bus = dev_get_parent(slave->dev); + struct mtk_spim_priv *priv = dev_get_priv(bus); + u16 cpha, cpol; + u32 reg_val; + + cpha = slave->mode & SPI_CPHA ? 1 : 0; + cpol = slave->mode & SPI_CPOL ? 1 : 0; + + if (priv->hw_cap.enhance_timing) { + if (priv->hw_cap.ipm_design) { + /* CFG3 reg only used for spi-mem, + * here write to default value + */ + writel(0x0, priv->base + SPI_CFG3_IPM_REG); + clrsetbits_le32(priv->base + SPI_CMD_REG, + SPI_CMD_IPM_GET_TICKDLY_MASK, + priv->tick_dly << + SPI_CMD_IPM_GET_TICKDLY_OFFSET); + } else { + clrsetbits_le32(priv->base + SPI_CFG1_REG, + SPI_CFG1_GET_TICKDLY_MASK, + priv->tick_dly << + SPI_CFG1_GET_TICKDLY_OFFSET); + } + } + + reg_val = readl(priv->base + SPI_CMD_REG); + if (priv->hw_cap.ipm_design) { + /* SPI transfer without idle time until packet length done */ + reg_val |= SPI_CMD_IPM_NONIDLE_MODE; + if (slave->mode & SPI_LOOP) + reg_val |= SPI_CMD_IPM_SPIM_LOOP; + else + reg_val &= ~SPI_CMD_IPM_SPIM_LOOP; + } + + if (cpha) + reg_val |= SPI_CMD_CPHA; + else + reg_val &= ~SPI_CMD_CPHA; + if (cpol) + reg_val |= SPI_CMD_CPOL; + else + reg_val &= ~SPI_CMD_CPOL; + + /* set the mlsbx and mlsbtx */ + if (slave->mode & SPI_LSB_FIRST) { + reg_val &= ~SPI_CMD_TXMSBF; + reg_val &= ~SPI_CMD_RXMSBF; + } else { + reg_val |= SPI_CMD_TXMSBF; + reg_val |= SPI_CMD_RXMSBF; + } + + /* do not reverse tx/rx endian */ + reg_val &= ~SPI_CMD_TX_ENDIAN; + reg_val &= ~SPI_CMD_RX_ENDIAN; + + if (priv->hw_cap.enhance_timing) { + /* set CS polarity */ + if (slave->mode & SPI_CS_HIGH) + reg_val |= SPI_CMD_CS_POL; + else + reg_val &= ~SPI_CMD_CS_POL; + + if (priv->sample_sel) + reg_val |= SPI_CMD_SAMPLE_SEL; + else + reg_val &= ~SPI_CMD_SAMPLE_SEL; + } + + /* disable dma mode */ + reg_val &= ~(SPI_CMD_TX_DMA | SPI_CMD_RX_DMA); + + /* disable deassert mode */ + reg_val &= ~SPI_CMD_DEASSERT; + + writel(reg_val, priv->base + SPI_CMD_REG); + + return 0; +} + +static void mtk_spim_prepare_transfer(struct mtk_spim_priv *priv, + u32 speed_hz) +{ + u32 spi_clk_hz, div, sck_time, cs_time, reg_val; + + spi_clk_hz = clk_get_rate(&priv->spi_clk); + if (speed_hz <= spi_clk_hz / 4) + div = DIV_ROUND_UP(spi_clk_hz, speed_hz); + else + div = 4; + + sck_time = (div + 1) / 2; + cs_time = sck_time * 2; + + if (priv->hw_cap.enhance_timing) { + reg_val = ((sck_time - 1) & 0xffff) + << SPI_CFG2_SCK_HIGH_OFFSET; + reg_val |= ((sck_time - 1) & 0xffff) + << SPI_CFG2_SCK_LOW_OFFSET; + writel(reg_val, priv->base + SPI_CFG2_REG); + + reg_val = ((cs_time - 1) & 0xffff) + << SPI_ADJUST_CFG0_CS_HOLD_OFFSET; + reg_val |= ((cs_time - 1) & 0xffff) + << SPI_ADJUST_CFG0_CS_SETUP_OFFSET; + writel(reg_val, priv->base + SPI_CFG0_REG); + } else { + reg_val = ((sck_time - 1) & 0xff) + << SPI_CFG0_SCK_HIGH_OFFSET; + reg_val |= ((sck_time - 1) & 0xff) << SPI_CFG0_SCK_LOW_OFFSET; + reg_val |= ((cs_time - 1) & 0xff) << SPI_CFG0_CS_HOLD_OFFSET; + reg_val |= ((cs_time - 1) & 0xff) << SPI_CFG0_CS_SETUP_OFFSET; + writel(reg_val, priv->base + SPI_CFG0_REG); + } + + reg_val = readl(priv->base + SPI_CFG1_REG); + reg_val &= ~SPI_CFG1_CS_IDLE_MASK; + reg_val |= ((cs_time - 1) & 0xff) << SPI_CFG1_CS_IDLE_OFFSET; + writel(reg_val, priv->base + SPI_CFG1_REG); +} + +/** + * mtk_spim_setup_packet() - setup packet format. + * @priv: controller priv + * + * This controller sents/receives data in packets. The packet size is + * configurable. + * + * This function calculates the maximum packet size available for current + * data, and calculates the number of packets required to sent/receive data + * as much as possible. + */ +static void mtk_spim_setup_packet(struct mtk_spim_priv *priv) +{ + u32 packet_size, packet_loop, reg_val; + + /* Calculate maximum packet size */ + if (priv->hw_cap.ipm_design) + packet_size = min_t(u32, + priv->xfer_len, + MTK_SPI_IPM_PACKET_SIZE); + else + packet_size = min_t(u32, + priv->xfer_len, + MTK_SPI_PACKET_SIZE); + + /* Calculates number of packets to sent/receive */ + packet_loop = priv->xfer_len / packet_size; + + reg_val = readl(priv->base + SPI_CFG1_REG); + if (priv->hw_cap.ipm_design) + reg_val &= ~SPI_CFG1_IPM_PACKET_LENGTH_MASK; + else + reg_val &= ~SPI_CFG1_PACKET_LENGTH_MASK; + + reg_val |= (packet_size - 1) << SPI_CFG1_PACKET_LENGTH_OFFSET; + + reg_val &= ~SPI_CFG1_PACKET_LOOP_MASK; + + reg_val |= (packet_loop - 1) << SPI_CFG1_PACKET_LOOP_OFFSET; + + writel(reg_val, priv->base + SPI_CFG1_REG); +} + +static void mtk_spim_enable_transfer(struct mtk_spim_priv *priv) +{ + u32 cmd; + + cmd = readl(priv->base + SPI_CMD_REG); + if (priv->state == MTK_SPI_IDLE) + cmd |= SPI_CMD_ACT; + else + cmd |= SPI_CMD_RESUME; + writel(cmd, priv->base + SPI_CMD_REG); +} + +static bool mtk_spim_supports_op(struct spi_slave *slave, + const struct spi_mem_op *op) +{ + struct udevice *bus = dev_get_parent(slave->dev); + struct mtk_spim_priv *priv = dev_get_priv(bus); + + if (op->cmd.buswidth == 0 || op->cmd.buswidth > 4 || + op->addr.buswidth > 4 || op->dummy.buswidth > 4 || + op->data.buswidth > 4) + return false; + + if (!priv->hw_cap.support_quad && (op->cmd.buswidth > 2 || + op->addr.buswidth > 2 || op->dummy.buswidth > 2 || + op->data.buswidth > 2)) + return false; + + if (op->addr.nbytes && op->dummy.nbytes && + op->addr.buswidth != op->dummy.buswidth) + return false; + + if (op->addr.nbytes + op->dummy.nbytes > 16) + return false; + + if (op->data.nbytes > MTK_SPI_IPM_PACKET_SIZE) { + if (op->data.nbytes / MTK_SPI_IPM_PACKET_SIZE > + MTK_SPI_IPM_PACKET_LOOP || + op->data.nbytes % MTK_SPI_IPM_PACKET_SIZE != 0) + return false; + } + + return true; +} + +static void mtk_spim_setup_dma_xfer(struct mtk_spim_priv *priv, + const struct spi_mem_op *op) +{ + writel((u32)(priv->tx_dma & MTK_SPI_32BITS_MASK), + priv->base + SPI_TX_SRC_REG); + + if (priv->hw_cap.dma_ext) + writel((u32)(priv->tx_dma >> 32), + priv->base + SPI_TX_SRC_REG_64); + + if (op->data.dir == SPI_MEM_DATA_IN) { + writel((u32)(priv->rx_dma & MTK_SPI_32BITS_MASK), + priv->base + SPI_RX_DST_REG); + + if (priv->hw_cap.dma_ext) + writel((u32)(priv->rx_dma >> 32), + priv->base + SPI_RX_DST_REG_64); + } +} + +static int mtk_spim_transfer_wait(struct spi_slave *slave, + const struct spi_mem_op *op) +{ + struct udevice *bus = dev_get_parent(slave->dev); + struct mtk_spim_priv *priv = dev_get_priv(bus); + u32 sck_l, sck_h, spi_bus_clk, clk_count, reg; + ulong us = 1; + int ret = 0; + + if (op->data.dir == SPI_MEM_NO_DATA) + clk_count = 32; + else + clk_count = op->data.nbytes; + + spi_bus_clk = clk_get_rate(&priv->spi_clk); + sck_l = readl(priv->base + SPI_CFG2_REG) >> SPI_CFG2_SCK_LOW_OFFSET; + sck_h = readl(priv->base + SPI_CFG2_REG) & SPI_CFG2_SCK_HIGH_MASK; + do_div(spi_bus_clk, sck_l + sck_h + 2); + + us = CLK_TO_US(spi_bus_clk, clk_count * 8); + us += 1000 * 1000; /* 1s tolerance */ + + if (us > UINT_MAX) + us = UINT_MAX; + + ret = readl_poll_timeout(priv->base + SPI_STATUS_REG, reg, + reg & 0x1, us); + if (ret < 0) { + dev_err(priv->dev, "transfer timeout, val: 0x%lx\n", us); + return -ETIMEDOUT; + } + + return 0; +} + +static int mtk_spim_exec_op(struct spi_slave *slave, + const struct spi_mem_op *op) +{ + struct udevice *bus = dev_get_parent(slave->dev); + struct mtk_spim_priv *priv = dev_get_priv(bus); + u32 reg_val, nio = 1, tx_size; + char *tx_tmp_buf; + char *rx_tmp_buf; + int i, ret = 0; + + mtk_spim_reset(priv); + mtk_spim_hw_init(slave); + mtk_spim_prepare_transfer(priv, slave->max_hz); + + reg_val = readl(priv->base + SPI_CFG3_IPM_REG); + /* opcode byte len */ + reg_val &= ~SPI_CFG3_IPM_CMD_BYTELEN_MASK; + reg_val |= 1 << SPI_CFG3_IPM_CMD_BYTELEN_OFFSET; + + /* addr & dummy byte len */ + if (op->addr.nbytes || op->dummy.nbytes) + reg_val |= (op->addr.nbytes + op->dummy.nbytes) << + SPI_CFG3_IPM_ADDR_BYTELEN_OFFSET; + + /* data byte len */ + if (!op->data.nbytes) { + reg_val |= SPI_CFG3_IPM_NODATA_FLAG; + writel(0, priv->base + SPI_CFG1_REG); + } else { + reg_val &= ~SPI_CFG3_IPM_NODATA_FLAG; + priv->xfer_len = op->data.nbytes; + mtk_spim_setup_packet(priv); + } + + if (op->addr.nbytes || op->dummy.nbytes) { + if (op->addr.buswidth == 1 || op->dummy.buswidth == 1) + reg_val |= SPI_CFG3_IPM_XMODE_EN; + else + reg_val &= ~SPI_CFG3_IPM_XMODE_EN; + } + + if (op->addr.buswidth == 2 || + op->dummy.buswidth == 2 || + op->data.buswidth == 2) + nio = 2; + else if (op->addr.buswidth == 4 || + op->dummy.buswidth == 4 || + op->data.buswidth == 4) + nio = 4; + + reg_val &= ~SPI_CFG3_IPM_CMD_PIN_MODE_MASK; + reg_val |= PIN_MODE_CFG(nio) << SPI_CFG3_IPM_PIN_MODE_OFFSET; + + reg_val |= SPI_CFG3_IPM_HALF_DUPLEX_EN; + if (op->data.dir == SPI_MEM_DATA_IN) + reg_val |= SPI_CFG3_IPM_HALF_DUPLEX_DIR; + else + reg_val &= ~SPI_CFG3_IPM_HALF_DUPLEX_DIR; + writel(reg_val, priv->base + SPI_CFG3_IPM_REG); + + tx_size = 1 + op->addr.nbytes + op->dummy.nbytes; + if (op->data.dir == SPI_MEM_DATA_OUT) + tx_size += op->data.nbytes; + + tx_size = max(tx_size, (u32)32); + + /* Fill up tx data */ + tx_tmp_buf = kzalloc(tx_size, GFP_KERNEL); + if (!tx_tmp_buf) { + ret = -ENOMEM; + goto exit; + } + + tx_tmp_buf[0] = op->cmd.opcode; + + if (op->addr.nbytes) { + for (i = 0; i < op->addr.nbytes; i++) + tx_tmp_buf[i + 1] = op->addr.val >> + (8 * (op->addr.nbytes - i - 1)); + } + + if (op->dummy.nbytes) + memset(tx_tmp_buf + op->addr.nbytes + 1, 0xff, + op->dummy.nbytes); + + if (op->data.nbytes && op->data.dir == SPI_MEM_DATA_OUT) + memcpy(tx_tmp_buf + op->dummy.nbytes + op->addr.nbytes + 1, + op->data.buf.out, op->data.nbytes); + /* Finish filling up tx data */ + + priv->tx_dma = dma_map_single(tx_tmp_buf, tx_size, DMA_TO_DEVICE); + if (dma_mapping_error(priv->dev, priv->tx_dma)) { + ret = -ENOMEM; + goto tx_free; + } + + if (op->data.dir == SPI_MEM_DATA_IN) { + if (!IS_ALIGNED((size_t)op->data.buf.in, 4)) { + rx_tmp_buf = kzalloc(op->data.nbytes, GFP_KERNEL); + if (!rx_tmp_buf) { + ret = -ENOMEM; + goto tx_unmap; + } + } else { + rx_tmp_buf = op->data.buf.in; + } + + priv->rx_dma = dma_map_single(rx_tmp_buf, op->data.nbytes, + DMA_FROM_DEVICE); + if (dma_mapping_error(priv->dev, priv->rx_dma)) { + ret = -ENOMEM; + goto rx_free; + } + } + + reg_val = readl(priv->base + SPI_CMD_REG); + reg_val |= SPI_CMD_TX_DMA; + if (op->data.dir == SPI_MEM_DATA_IN) + reg_val |= SPI_CMD_RX_DMA; + + writel(reg_val, priv->base + SPI_CMD_REG); + + mtk_spim_setup_dma_xfer(priv, op); + + mtk_spim_enable_transfer(priv); + + /* Wait for the interrupt. */ + ret = mtk_spim_transfer_wait(slave, op); + if (ret) + goto rx_unmap; + + if (op->data.dir == SPI_MEM_DATA_IN && + !IS_ALIGNED((size_t)op->data.buf.in, 4)) + memcpy(op->data.buf.in, rx_tmp_buf, op->data.nbytes); + +rx_unmap: + /* spi disable dma */ + reg_val = readl(priv->base + SPI_CMD_REG); + reg_val &= ~SPI_CMD_TX_DMA; + if (op->data.dir == SPI_MEM_DATA_IN) + reg_val &= ~SPI_CMD_RX_DMA; + writel(reg_val, priv->base + SPI_CMD_REG); + + writel(0, priv->base + SPI_TX_SRC_REG); + writel(0, priv->base + SPI_RX_DST_REG); + + if (op->data.dir == SPI_MEM_DATA_IN) + dma_unmap_single(priv->rx_dma, + op->data.nbytes, DMA_FROM_DEVICE); +rx_free: + if (op->data.dir == SPI_MEM_DATA_IN && + !IS_ALIGNED((size_t)op->data.buf.in, 4)) + kfree(rx_tmp_buf); +tx_unmap: + dma_unmap_single(priv->tx_dma, + tx_size, DMA_TO_DEVICE); +tx_free: + kfree(tx_tmp_buf); +exit: + return ret; +} + +static int mtk_spim_adjust_op_size(struct spi_slave *slave, + struct spi_mem_op *op) +{ + int opcode_len; + + if (!op->data.nbytes) + return 0; + + if (op->data.dir != SPI_MEM_NO_DATA) { + opcode_len = 1 + op->addr.nbytes + op->dummy.nbytes; + if (opcode_len + op->data.nbytes > MTK_SPI_IPM_PACKET_SIZE) { + op->data.nbytes = MTK_SPI_IPM_PACKET_SIZE - opcode_len; + /* force data buffer dma-aligned. */ + op->data.nbytes -= op->data.nbytes % 4; + } + } + + return 0; +} + +static int mtk_spim_get_attr(struct mtk_spim_priv *priv, struct udevice *dev) +{ + int ret; + + priv->hw_cap.enhance_timing = dev_read_bool(dev, "enhance_timing"); + priv->hw_cap.dma_ext = dev_read_bool(dev, "dma_ext"); + priv->hw_cap.ipm_design = dev_read_bool(dev, "ipm_design"); + priv->hw_cap.support_quad = dev_read_bool(dev, "support_quad"); + + ret = dev_read_u32(dev, "tick_dly", &priv->tick_dly); + if (ret < 0) + dev_err(priv->dev, "tick dly not set.\n"); + + ret = dev_read_u32(dev, "sample_sel", &priv->sample_sel); + if (ret < 0) + dev_err(priv->dev, "sample sel not set.\n"); + + return ret; +} + +static int mtk_spim_probe(struct udevice *dev) +{ + struct mtk_spim_priv *priv = dev_get_priv(dev); + int ret; + + priv->base = (void __iomem *)devfdt_get_addr(dev); + if (!priv->base) + return -EINVAL; + + mtk_spim_get_attr(priv, dev); + + ret = clk_get_by_name(dev, "sel-clk", &priv->sel_clk); + if (ret < 0) { + dev_err(dev, "failed to get sel-clk\n"); + return ret; + } + + ret = clk_get_by_name(dev, "spi-clk", &priv->spi_clk); + if (ret < 0) { + dev_err(dev, "failed to get spi-clk\n"); + return ret; + } + + clk_enable(&priv->sel_clk); + clk_enable(&priv->spi_clk); + + return 0; +} + +static int mtk_spim_set_speed(struct udevice *dev, uint speed) +{ + return 0; +} + +static int mtk_spim_set_mode(struct udevice *dev, uint mode) +{ + return 0; +} + +static const struct spi_controller_mem_ops mtk_spim_mem_ops = { + .adjust_op_size = mtk_spim_adjust_op_size, + .supports_op = mtk_spim_supports_op, + .exec_op = mtk_spim_exec_op +}; + +static const struct dm_spi_ops mtk_spim_ops = { + .mem_ops = &mtk_spim_mem_ops, + .set_speed = mtk_spim_set_speed, + .set_mode = mtk_spim_set_mode, +}; + +static const struct udevice_id mtk_spim_ids[] = { + { .compatible = "mediatek,ipm-spi" }, + {} +}; + +U_BOOT_DRIVER(mtk_spim) = { + .name = "mtk_spim", + .id = UCLASS_SPI, + .of_match = mtk_spim_ids, + .ops = &mtk_spim_ops, + .priv_auto = sizeof(struct mtk_spim_priv), + .probe = mtk_spim_probe, +}; From 9ad71f63401b2a12b34c5be4ad9d605385afcf0e Mon Sep 17 00:00:00 2001 From: Weijie Gao Date: Fri, 9 Sep 2022 19:59:48 +0800 Subject: [PATCH 257/374] i2c: add support for MediaTek I2C interface This patch adds support for MediaTek I2C interface Reviewed-by: Heiko Schocher Reviewed-by: Simon Glass Signed-off-by: Weijie Gao --- drivers/i2c/Kconfig | 9 + drivers/i2c/Makefile | 1 + drivers/i2c/mtk_i2c.c | 822 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 832 insertions(+) create mode 100644 drivers/i2c/mtk_i2c.c diff --git a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig index be4724bf8e..08b6c7bdcc 100644 --- a/drivers/i2c/Kconfig +++ b/drivers/i2c/Kconfig @@ -261,6 +261,15 @@ config SYS_I2C_MESON internal buffer holding up to 8 bytes for transfers and supports both 7-bit and 10-bit addresses. +config SYS_I2C_MTK + bool "MediaTek I2C driver" + help + This selects the MediaTek Integrated Inter Circuit bus driver. + The I2C bus adapter is the base for some other I2C client, + eg: touch, sensors. + If you want to use MediaTek I2C interface, say Y here. + If unsure, say N. + config SYS_I2C_MICROCHIP bool "Microchip I2C driver" help diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile index 7e046f809a..920aafb91c 100644 --- a/drivers/i2c/Makefile +++ b/drivers/i2c/Makefile @@ -32,6 +32,7 @@ obj-$(CONFIG_SYS_I2C_MICROCHIP) += i2c-microchip.o obj-$(CONFIG_SYS_I2C_MV) += mv_i2c.o obj-$(CONFIG_SYS_I2C_MVTWSI) += mvtwsi.o obj-$(CONFIG_SYS_I2C_MXC) += mxc_i2c.o +obj-$(CONFIG_SYS_I2C_MTK) += mtk_i2c.o obj-$(CONFIG_SYS_I2C_NEXELL) += nx_i2c.o obj-$(CONFIG_SYS_I2C_NPCM) += npcm_i2c.o obj-$(CONFIG_SYS_I2C_OCORES) += ocores_i2c.o diff --git a/drivers/i2c/mtk_i2c.c b/drivers/i2c/mtk_i2c.c new file mode 100644 index 0000000000..5528bcd7cc --- /dev/null +++ b/drivers/i2c/mtk_i2c.c @@ -0,0 +1,822 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2022 MediaTek Inc. All Rights Reserved. + * + * Author: Mingming Lee + * + * MediaTek I2C Interface driver + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define I2C_RS_TRANSFER BIT(4) +#define I2C_HS_NACKERR BIT(2) +#define I2C_ACKERR BIT(1) +#define I2C_TRANSAC_COMP BIT(0) +#define I2C_TRANSAC_START BIT(0) +#define I2C_RS_MUL_CNFG BIT(15) +#define I2C_RS_MUL_TRIG BIT(14) +#define I2C_DCM_DISABLE 0x0000 +#define I2C_IO_CONFIG_OPEN_DRAIN 0x0003 +#define I2C_IO_CONFIG_PUSH_PULL 0x0000 +#define I2C_SOFT_RST 0x0001 +#define I2C_FIFO_ADDR_CLR 0x0001 +#define I2C_DELAY_LEN 0x0002 +#define I2C_ST_START_CON 0x8001 +#define I2C_FS_START_CON 0x1800 +#define I2C_TIME_CLR_VALUE 0x0000 +#define I2C_TIME_DEFAULT_VALUE 0x0003 +#define I2C_WRRD_TRANAC_VALUE 0x0002 +#define I2C_RD_TRANAC_VALUE 0x0001 + +#define I2C_DMA_CON_TX 0x0000 +#define I2C_DMA_CON_RX 0x0001 +#define I2C_DMA_START_EN 0x0001 +#define I2C_DMA_INT_FLAG_NONE 0x0000 +#define I2C_DMA_CLR_FLAG 0x0000 +#define I2C_DMA_TX_RX 0x0000 +#define I2C_DMA_HARD_RST 0x0002 + +#define MAX_ST_MODE_SPEED 100000 +#define MAX_FS_MODE_SPEED 400000 +#define MAX_HS_MODE_SPEED 3400000 +#define MAX_SAMPLE_CNT_DIV 8 +#define MAX_STEP_CNT_DIV 64 +#define MAX_HS_STEP_CNT_DIV 8 +#define I2C_DEFAULT_CLK_DIV 4 + +#define MAX_I2C_ADDR 0x7f +#define MAX_I2C_LEN 0xff +#define TRANS_ADDR_ONLY BIT(8) +#define TRANSFER_TIMEOUT 50000 /* us */ +#define I2C_FIFO_STAT1_MASK 0x001f +#define TIMING_SAMPLE_OFFSET 8 +#define HS_SAMPLE_OFFSET 12 +#define HS_STEP_OFFSET 8 + +#define I2C_CONTROL_WRAPPER BIT(0) +#define I2C_CONTROL_RS BIT(1) +#define I2C_CONTROL_DMA_EN BIT(2) +#define I2C_CONTROL_CLK_EXT_EN BIT(3) +#define I2C_CONTROL_DIR_CHANGE BIT(4) +#define I2C_CONTROL_ACKERR_DET_EN BIT(5) +#define I2C_CONTROL_TRANSFER_LEN_CHANGE BIT(6) +#define I2C_CONTROL_DMAACK BIT(8) +#define I2C_CONTROL_ASYNC BIT(9) + +#define I2C_MASTER_WR BIT(0) +#define I2C_MASTER_RD BIT(1) +#define I2C_MASTER_WRRD (I2C_MASTER_WR | I2C_MASTER_RD) + +enum I2C_REGS_OFFSET { + REG_PORT, + REG_SLAVE_ADDR, + REG_INTR_MASK, + REG_INTR_STAT, + REG_CONTROL, + REG_TRANSFER_LEN, + REG_TRANSAC_LEN, + REG_DELAY_LEN, + REG_TIMING, + REG_START, + REG_EXT_CONF, + REG_FIFO_STAT1, + REG_LTIMING, + REG_FIFO_STAT, + REG_FIFO_THRESH, + REG_FIFO_ADDR_CLR, + REG_IO_CONFIG, + REG_RSV_DEBUG, + REG_HS, + REG_SOFTRESET, + REG_DCM_EN, + REG_PATH_DIR, + REG_DEBUGSTAT, + REG_DEBUGCTRL, + REG_TRANSFER_LEN_AUX, + REG_CLOCK_DIV, + REG_SCL_HL_RATIO, + REG_SCL_HS_HL_RATIO, + REG_SCL_MIS_COMP_POINT, + REG_STA_STOP_AC_TIME, + REG_HS_STA_STOP_AC_TIME, + REG_DATA_TIME, +}; + +enum DMA_REGS_OFFSET { + REG_INT_FLAG = 0x0, + REG_INT_EN = 0x04, + REG_EN = 0x08, + REG_RST = 0x0c, + REG_CON = 0x18, + REG_TX_MEM_ADDR = 0x1c, + REG_RX_MEM_ADDR = 0x20, + REG_TX_LEN = 0x24, + REG_RX_LEN = 0x28, +}; + +static const uint mt_i2c_regs_v1[] = { + [REG_PORT] = 0x0, + [REG_SLAVE_ADDR] = 0x4, + [REG_INTR_MASK] = 0x8, + [REG_INTR_STAT] = 0xc, + [REG_CONTROL] = 0x10, + [REG_TRANSFER_LEN] = 0x14, + [REG_TRANSAC_LEN] = 0x18, + [REG_DELAY_LEN] = 0x1c, + [REG_TIMING] = 0x20, + [REG_START] = 0x24, + [REG_EXT_CONF] = 0x28, + [REG_FIFO_STAT1] = 0x2c, + [REG_FIFO_STAT] = 0x30, + [REG_FIFO_THRESH] = 0x34, + [REG_FIFO_ADDR_CLR] = 0x38, + [REG_IO_CONFIG] = 0x40, + [REG_RSV_DEBUG] = 0x44, + [REG_HS] = 0x48, + [REG_SOFTRESET] = 0x50, + [REG_SOFTRESET] = 0x50, + [REG_DCM_EN] = 0x54, + [REG_DEBUGSTAT] = 0x64, + [REG_DEBUGCTRL] = 0x68, + [REG_TRANSFER_LEN_AUX] = 0x6c, + [REG_CLOCK_DIV] = 0x70, + [REG_SCL_HL_RATIO] = 0x74, + [REG_SCL_HS_HL_RATIO] = 0x78, + [REG_SCL_MIS_COMP_POINT] = 0x7c, + [REG_STA_STOP_AC_TIME] = 0x80, + [REG_HS_STA_STOP_AC_TIME] = 0x84, + [REG_DATA_TIME] = 0x88, +}; + +static const uint mt_i2c_regs_v2[] = { + [REG_PORT] = 0x0, + [REG_SLAVE_ADDR] = 0x4, + [REG_INTR_MASK] = 0x8, + [REG_INTR_STAT] = 0xc, + [REG_CONTROL] = 0x10, + [REG_TRANSFER_LEN] = 0x14, + [REG_TRANSAC_LEN] = 0x18, + [REG_DELAY_LEN] = 0x1c, + [REG_TIMING] = 0x20, + [REG_START] = 0x24, + [REG_EXT_CONF] = 0x28, + [REG_LTIMING] = 0x2c, + [REG_HS] = 0x30, + [REG_IO_CONFIG] = 0x34, + [REG_FIFO_ADDR_CLR] = 0x38, + [REG_TRANSFER_LEN_AUX] = 0x44, + [REG_CLOCK_DIV] = 0x48, + [REG_SOFTRESET] = 0x50, + [REG_DEBUGSTAT] = 0xe0, + [REG_DEBUGCTRL] = 0xe8, + [REG_FIFO_STAT] = 0xf4, + [REG_FIFO_THRESH] = 0xf8, + [REG_DCM_EN] = 0xf88, +}; + +struct mtk_i2c_soc_data { + const uint *regs; + uint dma_sync: 1; +}; + +struct mtk_i2c_priv { + /* set in i2c probe */ + void __iomem *base; /* i2c base addr */ + void __iomem *pdmabase; /* dma base address*/ + struct clk clk_main; /* main clock for i2c bus */ + struct clk clk_dma; /* DMA clock for i2c via DMA */ + const struct mtk_i2c_soc_data *soc_data; /* Compatible data for different IC */ + int op; /* operation mode */ + bool zero_len; /* Only transfer slave address, no data */ + bool pushpull; /* push pull mode or open drain mode */ + bool filter_msg; /* filter msg error log */ + bool auto_restart; /* restart mode */ + bool ignore_restart_irq; /* ignore restart IRQ */ + uint speed; /* i2c speed, unit: hz */ +}; + +static inline void i2c_writel(struct mtk_i2c_priv *priv, uint reg, uint value) +{ + u32 offset = priv->soc_data->regs[reg]; + + writel(value, priv->base + offset); +} + +static inline uint i2c_readl(struct mtk_i2c_priv *priv, uint offset) +{ + return readl(priv->base + priv->soc_data->regs[offset]); +} + +static int mtk_i2c_clk_enable(struct mtk_i2c_priv *priv) +{ + int ret; + + ret = clk_enable(&priv->clk_main); + if (ret) + return log_msg_ret("enable clk_main", ret); + + ret = clk_enable(&priv->clk_dma); + if (ret) + return log_msg_ret("enable clk_dma", ret); + + return 0; +} + +static int mtk_i2c_clk_disable(struct mtk_i2c_priv *priv) +{ + int ret; + + ret = clk_disable(&priv->clk_dma); + if (ret) + return log_msg_ret("disable clk_dma", ret); + + ret = clk_disable(&priv->clk_main); + if (ret) + return log_msg_ret("disable clk_main", ret); + + return 0; +} + +static void mtk_i2c_init_hw(struct mtk_i2c_priv *priv) +{ + uint control_reg; + + writel(I2C_DMA_HARD_RST, priv->pdmabase + REG_RST); + writel(I2C_DMA_CLR_FLAG, priv->pdmabase + REG_RST); + i2c_writel(priv, REG_SOFTRESET, I2C_SOFT_RST); + /* set ioconfig */ + if (priv->pushpull) + i2c_writel(priv, REG_IO_CONFIG, I2C_IO_CONFIG_PUSH_PULL); + else + i2c_writel(priv, REG_IO_CONFIG, I2C_IO_CONFIG_OPEN_DRAIN); + + i2c_writel(priv, REG_DCM_EN, I2C_DCM_DISABLE); + control_reg = I2C_CONTROL_ACKERR_DET_EN | I2C_CONTROL_CLK_EXT_EN; + if (priv->soc_data->dma_sync) + control_reg |= I2C_CONTROL_DMAACK | I2C_CONTROL_ASYNC; + i2c_writel(priv, REG_CONTROL, control_reg); + i2c_writel(priv, REG_DELAY_LEN, I2C_DELAY_LEN); +} + +/* + * Calculate i2c port speed + * + * Hardware design: + * i2c_bus_freq = parent_clk / (clock_div * 2 * sample_cnt * step_cnt) + * clock_div: fixed in hardware, but may be various in different SoCs + * + * The calculation want to pick the highest bus frequency that is still + * less than or equal to target_speed. The calculation try to get + * sample_cnt and step_cn + * @param[in] + * clk_src: i2c clock source + * @param[out] + * timing_step_cnt: step cnt calculate result + * @param[out] + * timing_sample_cnt: sample cnt calculate result + * @return + * 0, set speed successfully. + * -EINVAL, Unsupported speed. + */ +static int mtk_i2c_calculate_speed(uint clk_src, + uint target_speed, + uint *timing_step_cnt, + uint *timing_sample_cnt) +{ + uint base_sample_cnt = MAX_SAMPLE_CNT_DIV; + uint base_step_cnt; + uint max_step_cnt; + uint sample_cnt; + uint step_cnt; + uint opt_div; + uint best_mul; + uint cnt_mul; + + if (target_speed > MAX_HS_MODE_SPEED) + target_speed = MAX_HS_MODE_SPEED; + + if (target_speed > MAX_FS_MODE_SPEED) + max_step_cnt = MAX_HS_STEP_CNT_DIV; + else + max_step_cnt = MAX_STEP_CNT_DIV; + + base_step_cnt = max_step_cnt; + /* Find the best combination */ + opt_div = DIV_ROUND_UP(clk_src >> 1, target_speed); + best_mul = MAX_SAMPLE_CNT_DIV * max_step_cnt; + + /* + * Search for the best pair (sample_cnt, step_cnt) with + * 0 < sample_cnt < MAX_SAMPLE_CNT_DIV + * 0 < step_cnt < max_step_cnt + * sample_cnt * step_cnt >= opt_div + * optimizing for sample_cnt * step_cnt being minimal + */ + for (sample_cnt = 1; sample_cnt <= MAX_SAMPLE_CNT_DIV; sample_cnt++) { + step_cnt = DIV_ROUND_UP(opt_div, sample_cnt); + cnt_mul = step_cnt * sample_cnt; + if (step_cnt > max_step_cnt) + continue; + + if (cnt_mul < best_mul) { + best_mul = cnt_mul; + base_sample_cnt = sample_cnt; + base_step_cnt = step_cnt; + if (best_mul == opt_div) + break; + } + } + + sample_cnt = base_sample_cnt; + step_cnt = base_step_cnt; + + if ((clk_src / (2 * sample_cnt * step_cnt)) > target_speed) { + /* + * In this case, hardware can't support such + * low i2c_bus_freq + */ + debug("Unsupported speed(%uhz)\n", target_speed); + return log_msg_ret("calculate speed", -EINVAL); + } + + *timing_step_cnt = step_cnt - 1; + *timing_sample_cnt = sample_cnt - 1; + + return 0; +} + +/* + * mtk_i2c_set_speed + * + * @par Description + * Calculate i2c speed and write sample_cnt, step_cnt to TIMING register. + * @param[in] + * dev: udevice pointer, struct udevice contains i2c source clock, + * clock divide and speed. + * @return + * 0, set speed successfully.\n + * error code from mtk_i2c_calculate_speed(). + */ +static int mtk_i2c_set_speed(struct udevice *dev, uint speed) +{ + struct mtk_i2c_priv *priv = dev_get_priv(dev); + uint high_speed_reg; + uint sample_cnt; + uint timing_reg; + uint step_cnt; + uint clk_src; + int ret = 0; + + priv->speed = speed; + if (mtk_i2c_clk_enable(priv)) + return log_msg_ret("set_speed enable clk", -1); + + clk_src = clk_get_rate(&priv->clk_main) / I2C_DEFAULT_CLK_DIV; + i2c_writel(priv, REG_CLOCK_DIV, (I2C_DEFAULT_CLK_DIV - 1)); + if (priv->speed > MAX_FS_MODE_SPEED) { + /* Set master code speed register */ + ret = mtk_i2c_calculate_speed(clk_src, MAX_FS_MODE_SPEED, + &step_cnt, &sample_cnt); + if (ret < 0) + goto exit; + + timing_reg = (sample_cnt << TIMING_SAMPLE_OFFSET) | step_cnt; + i2c_writel(priv, REG_TIMING, timing_reg); + /* Set the high speed mode register */ + ret = mtk_i2c_calculate_speed(clk_src, priv->speed, + &step_cnt, &sample_cnt); + if (ret < 0) + goto exit; + + high_speed_reg = I2C_TIME_DEFAULT_VALUE | + (sample_cnt << HS_SAMPLE_OFFSET) | + (step_cnt << HS_STEP_OFFSET); + i2c_writel(priv, REG_HS, high_speed_reg); + } else { + ret = mtk_i2c_calculate_speed(clk_src, priv->speed, + &step_cnt, &sample_cnt); + if (ret < 0) + goto exit; + + timing_reg = (sample_cnt << TIMING_SAMPLE_OFFSET) | step_cnt; + /* Disable the high speed transaction */ + high_speed_reg = I2C_TIME_CLR_VALUE; + i2c_writel(priv, REG_TIMING, timing_reg); + i2c_writel(priv, REG_HS, high_speed_reg); + } +exit: + if (mtk_i2c_clk_disable(priv)) + return log_msg_ret("set_speed disable clk", -1); + + return ret; +} + +/* + * mtk_i2c_do_transfer + * + * @par Description + * Configure i2c register and trigger transfer. + * @param[in] + * priv: mtk_i2cmtk_i2c_priv pointer, struct mtk_i2c_priv contains register base\n + * address, operation mode, interrupt status and i2c driver data. + * @param[in] + * msgs: i2c_msg pointer, struct i2c_msg contains slave\n + * address, operation mode, msg length and data buffer. + * @param[in] + * num: i2c_msg number. + * @param[in] + * left_num: left i2c_msg number. + * @return + * 0, i2c transfer successfully.\n + * -ETIMEDOUT, i2c transfer timeout.\n + * -EREMOTEIO, i2c transfer ack error. + */ +static int mtk_i2c_do_transfer(struct mtk_i2c_priv *priv, + struct i2c_msg *msgs, + int num, int left_num) +{ + struct i2c_msg *msg_rx = NULL; + uint restart_flag = 0; + uint trans_error = 0; + uint irq_stat = 0; + uint tmo_poll = 0; + uint control_reg; + bool tmo = false; + uint start_reg; + uint addr_reg; + int ret = 0; + + if (priv->auto_restart) + restart_flag = I2C_RS_TRANSFER; + + control_reg = i2c_readl(priv, REG_CONTROL) & + ~(I2C_CONTROL_DIR_CHANGE | I2C_CONTROL_RS); + + if (priv->speed > MAX_FS_MODE_SPEED || num > 1) + control_reg |= I2C_CONTROL_RS; + + if (priv->op == I2C_MASTER_WRRD) + control_reg |= I2C_CONTROL_DIR_CHANGE | I2C_CONTROL_RS; + + control_reg |= I2C_CONTROL_DMA_EN; + i2c_writel(priv, REG_CONTROL, control_reg); + + /* set start condition */ + if (priv->speed <= MAX_ST_MODE_SPEED) + i2c_writel(priv, REG_EXT_CONF, I2C_ST_START_CON); + else + i2c_writel(priv, REG_EXT_CONF, I2C_FS_START_CON); + + addr_reg = msgs->addr << 1; + if (priv->op == I2C_MASTER_RD) + addr_reg |= I2C_M_RD; + if (priv->zero_len) + i2c_writel(priv, REG_SLAVE_ADDR, addr_reg | TRANS_ADDR_ONLY); + else + i2c_writel(priv, REG_SLAVE_ADDR, addr_reg); + + /* clear interrupt status */ + i2c_writel(priv, REG_INTR_STAT, restart_flag | I2C_HS_NACKERR | + I2C_ACKERR | I2C_TRANSAC_COMP); + i2c_writel(priv, REG_FIFO_ADDR_CLR, I2C_FIFO_ADDR_CLR); + + /* enable interrupt */ + i2c_writel(priv, REG_INTR_MASK, restart_flag | I2C_HS_NACKERR | + I2C_ACKERR | I2C_TRANSAC_COMP); + + /* set transfer and transaction len */ + if (priv->op == I2C_MASTER_WRRD) { + i2c_writel(priv, REG_TRANSFER_LEN, msgs->len); + i2c_writel(priv, REG_TRANSFER_LEN_AUX, (msgs + 1)->len); + i2c_writel(priv, REG_TRANSAC_LEN, I2C_WRRD_TRANAC_VALUE); + } else { + i2c_writel(priv, REG_TRANSFER_LEN, msgs->len); + i2c_writel(priv, REG_TRANSAC_LEN, num); + } + + /* Clear DMA interrupt flag */ + writel(I2C_DMA_INT_FLAG_NONE, priv->pdmabase + REG_INT_FLAG); + + /* Flush cache for first msg */ + flush_cache((ulong)msgs->buf, msgs->len); + + /* + * prepare buffer data to start transfer + * three cases here: read, write, write then read + */ + if (priv->op & I2C_MASTER_WR) { + /* Set DMA direction TX (w/ or w/o RX) */ + writel(I2C_DMA_CON_TX, priv->pdmabase + REG_CON); + + /* Write the tx buffer address to dma register */ + writel((ulong)msgs->buf, priv->pdmabase + REG_TX_MEM_ADDR); + /* Write the tx length to dma register */ + writel(msgs->len, priv->pdmabase + REG_TX_LEN); + + if (priv->op & I2C_MASTER_RD) { + /* write then read */ + msg_rx = msgs + 1; + + /* Flush cache for second msg */ + flush_cache((ulong)msg_rx->buf, msg_rx->len); + } + } + + if (priv->op & I2C_MASTER_RD) { + if (!msg_rx) { + /* Set DMA direction RX */ + writel(I2C_DMA_CON_RX, priv->pdmabase + REG_CON); + + msg_rx = msgs; + } + + /* Write the rx buffer address to dma register */ + writel((ulong)msg_rx->buf, priv->pdmabase + REG_RX_MEM_ADDR); + /* Write the rx length to dma register */ + writel(msg_rx->len, priv->pdmabase + REG_RX_LEN); + } + + writel(I2C_DMA_START_EN, priv->pdmabase + REG_EN); + + if (!priv->auto_restart) { + start_reg = I2C_TRANSAC_START; + } else { + start_reg = I2C_TRANSAC_START | I2C_RS_MUL_TRIG; + if (left_num >= 1) + start_reg |= I2C_RS_MUL_CNFG; + } + i2c_writel(priv, REG_START, start_reg); + + for (;;) { + irq_stat = i2c_readl(priv, REG_INTR_STAT); + + /* ignore the first restart irq after the master code */ + if (priv->ignore_restart_irq && (irq_stat & restart_flag)) { + priv->ignore_restart_irq = false; + irq_stat = 0; + i2c_writel(priv, REG_START, I2C_RS_MUL_CNFG | + I2C_RS_MUL_TRIG | I2C_TRANSAC_START); + } + + if (irq_stat & (I2C_TRANSAC_COMP | restart_flag)) { + tmo = false; + if (irq_stat & (I2C_HS_NACKERR | I2C_ACKERR)) + trans_error = 1; + + break; + } + udelay(1); + if (tmo_poll++ >= TRANSFER_TIMEOUT) { + tmo = true; + break; + } + } + + /* clear interrupt mask */ + i2c_writel(priv, REG_INTR_MASK, ~(restart_flag | I2C_HS_NACKERR | + I2C_ACKERR | I2C_TRANSAC_COMP)); + + if (!tmo && trans_error != 0) { + if (tmo) { + ret = -ETIMEDOUT; + if (!priv->filter_msg) + debug("I2C timeout! addr: 0x%x,\n", msgs->addr); + } else { + ret = -EREMOTEIO; + if (!priv->filter_msg) + debug("I2C ACKERR! addr: 0x%x,IRQ:0x%x\n", + msgs->addr, irq_stat); + } + mtk_i2c_init_hw(priv); + } + + return ret; +} + +/* + * mtk_i2c_transfer + * + * @par Description + * Common i2c transfer API. Set i2c transfer mode according to i2c_msg\n + * information, then call mtk_i2c_do_transfer() to configure i2c register\n + * and trigger transfer. + * @param[in] + * dev: udevice pointer, struct udevice contains struct mtk_i2c_priv, \n + * struct mtk_i2c_priv contains register base\n + * address, operation mode, interrupt status and i2c driver data. + * @param[in] + * msgs: i2c_msg pointer, struct i2c_msg contains slave\n + * address, operation mode, msg length and data buffer. + * @param[in] + * num: i2c_msg number. + * @return + * i2c_msg number, i2c transfer successfully.\n + * -EINVAL, msg length is more than 16\n + * use DMA MODE or slave address more than 0x7f.\n + * error code from mtk_i2c_init_base().\n + * error code from mtk_i2c_set_speed().\n + * error code from mtk_i2c_do_transfer(). + */ +static int mtk_i2c_transfer(struct udevice *dev, struct i2c_msg *msg, + int nmsgs) +{ + struct mtk_i2c_priv *priv = dev_get_priv(dev); + int left_num; + uint num_cnt; + int ret; + + priv->auto_restart = true; + left_num = nmsgs; + if (mtk_i2c_clk_enable(priv)) + return log_msg_ret("transfer enable clk", -1); + + for (num_cnt = 0; num_cnt < nmsgs; num_cnt++) { + if (((msg + num_cnt)->addr) > MAX_I2C_ADDR) { + ret = -EINVAL; + goto err_exit; + } + if ((msg + num_cnt)->len > MAX_I2C_LEN) { + ret = -EINVAL; + goto err_exit; + } + } + + /* check if we can skip restart and optimize using WRRD mode */ + if (priv->auto_restart && nmsgs == 2) { + if (!(msg[0].flags & I2C_M_RD) && (msg[1].flags & I2C_M_RD) && + msg[0].addr == msg[1].addr) { + priv->auto_restart = false; + } + } + + if (priv->auto_restart && nmsgs >= 2 && priv->speed > MAX_FS_MODE_SPEED) + /* ignore the first restart irq after the master code, + * otherwise the first transfer will be discarded. + */ + priv->ignore_restart_irq = true; + else + priv->ignore_restart_irq = false; + + while (left_num--) { + /* transfer slave address only to support devices detect */ + if (!msg->buf) + priv->zero_len = true; + else + priv->zero_len = false; + + if (msg->flags & I2C_M_RD) + priv->op = I2C_MASTER_RD; + else + priv->op = I2C_MASTER_WR; + + if (!priv->auto_restart) { + if (nmsgs > 1) { + /* combined two messages into one transaction */ + priv->op = I2C_MASTER_WRRD; + left_num--; + } + } + ret = mtk_i2c_do_transfer(priv, msg, nmsgs, left_num); + if (ret < 0) + goto err_exit; + msg++; + } + ret = 0; + +err_exit: + if (mtk_i2c_clk_disable(priv)) + return log_msg_ret("transfer disable clk", -1); + + return ret; +} + +static int mtk_i2c_of_to_plat(struct udevice *dev) +{ + struct mtk_i2c_priv *priv = dev_get_priv(dev); + int ret; + + priv->base = dev_remap_addr_index(dev, 0); + priv->pdmabase = dev_remap_addr_index(dev, 1); + ret = clk_get_by_index(dev, 0, &priv->clk_main); + if (ret) + return log_msg_ret("clk_get_by_index 0", ret); + + ret = clk_get_by_index(dev, 1, &priv->clk_dma); + + return ret; +} + +static int mtk_i2c_probe(struct udevice *dev) +{ + struct mtk_i2c_priv *priv = dev_get_priv(dev); + + priv->soc_data = (struct mtk_i2c_soc_data *)dev_get_driver_data(dev); + + if (mtk_i2c_clk_enable(priv)) + return log_msg_ret("probe enable clk", -1); + + mtk_i2c_init_hw(priv); + + if (mtk_i2c_clk_disable(priv)) + return log_msg_ret("probe disable clk", -1); + + return 0; +} + +static int mtk_i2c_deblock(struct udevice *dev) +{ + struct mtk_i2c_priv *priv = dev_get_priv(dev); + + if (mtk_i2c_clk_enable(priv)) + return log_msg_ret("deblock enable clk", -1); + + mtk_i2c_init_hw(priv); + + if (mtk_i2c_clk_disable(priv)) + return log_msg_ret("deblock disable clk", -1); + + return 0; +} + +static const struct mtk_i2c_soc_data mt76xx_soc_data = { + .regs = mt_i2c_regs_v1, + .dma_sync = 0, +}; + +static const struct mtk_i2c_soc_data mt7981_soc_data = { + .regs = mt_i2c_regs_v1, + .dma_sync = 1, +}; + +static const struct mtk_i2c_soc_data mt7986_soc_data = { + .regs = mt_i2c_regs_v1, + .dma_sync = 1, +}; + +static const struct mtk_i2c_soc_data mt8183_soc_data = { + .regs = mt_i2c_regs_v2, + .dma_sync = 1, +}; + +static const struct mtk_i2c_soc_data mt8518_soc_data = { + .regs = mt_i2c_regs_v1, + .dma_sync = 0, +}; + +static const struct mtk_i2c_soc_data mt8512_soc_data = { + .regs = mt_i2c_regs_v1, + .dma_sync = 1, +}; + +static const struct dm_i2c_ops mtk_i2c_ops = { + .xfer = mtk_i2c_transfer, + .set_bus_speed = mtk_i2c_set_speed, + .deblock = mtk_i2c_deblock, +}; + +static const struct udevice_id mtk_i2c_ids[] = { + { + .compatible = "mediatek,mt7622-i2c", + .data = (ulong)&mt76xx_soc_data, + }, { + .compatible = "mediatek,mt7623-i2c", + .data = (ulong)&mt76xx_soc_data, + }, { + .compatible = "mediatek,mt7629-i2c", + .data = (ulong)&mt76xx_soc_data, + }, { + .compatible = "mediatek,mt7981-i2c", + .data = (ulong)&mt7981_soc_data, + }, { + .compatible = "mediatek,mt7986-i2c", + .data = (ulong)&mt7986_soc_data, + }, { + .compatible = "mediatek,mt8183-i2c", + .data = (ulong)&mt8183_soc_data, + }, { + .compatible = "mediatek,mt8512-i2c", + .data = (ulong)&mt8512_soc_data, + }, { + .compatible = "mediatek,mt8518-i2c", + .data = (ulong)&mt8518_soc_data, + } +}; + +U_BOOT_DRIVER(mtk_i2c) = { + .name = "mtk_i2c", + .id = UCLASS_I2C, + .of_match = mtk_i2c_ids, + .of_to_plat = mtk_i2c_of_to_plat, + .probe = mtk_i2c_probe, + .priv_auto = sizeof(struct mtk_i2c_priv), + .ops = &mtk_i2c_ops, +}; From 663e6262c5727111c91dbf570a2e0d21bb578811 Mon Sep 17 00:00:00 2001 From: Weijie Gao Date: Fri, 9 Sep 2022 19:59:50 +0800 Subject: [PATCH 258/374] arm: dts: mt7622: add i2c support Add both hardware and software i2c support for mt7622. Reviewed-by: Simon Glass Signed-off-by: Weijie Gao --- arch/arm/dts/mt7622-rfb.dts | 18 ++++++++++++++++++ arch/arm/dts/mt7622.dtsi | 24 ++++++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/arch/arm/dts/mt7622-rfb.dts b/arch/arm/dts/mt7622-rfb.dts index 30a9137407..b44f19f05a 100644 --- a/arch/arm/dts/mt7622-rfb.dts +++ b/arch/arm/dts/mt7622-rfb.dts @@ -159,6 +159,14 @@ }; }; + + i2c1_pins_default: i2c1-default { + mux { + function = "i2c"; + groups = "i2c1_0"; + }; + }; + }; &snfi { @@ -242,3 +250,13 @@ &u3phy { status = "okay"; }; + +&soft_i2c { + status = "disabled"; +}; + +&i2c1 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c1_pins_default>; + status = "okay"; +}; diff --git a/arch/arm/dts/mt7622.dtsi b/arch/arm/dts/mt7622.dtsi index fb6c1b7154..2d89fa08b4 100644 --- a/arch/arm/dts/mt7622.dtsi +++ b/arch/arm/dts/mt7622.dtsi @@ -424,4 +424,28 @@ status = "disabled"; }; + soft_i2c: soft_i2c@0 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "i2c-gpio"; + gpios = <&gpio 56 GPIO_ACTIVE_HIGH>, /* SDA */ + <&gpio 55 GPIO_ACTIVE_HIGH>; /* CLK */ + i2c-gpio,delay-us = <5>; + status = "disabled"; + }; + + i2c1: i2c@11008000 { + compatible = "mediatek,mt7622-i2c"; + reg = <0x11008000 0x90>, + <0x11000180 0x80>; + interrupts = ; + clock-div = <16>; + clocks = <&pericfg CLK_PERI_I2C1_PD>, + <&pericfg CLK_PERI_AP_DMA_PD>; + clock-names = "main", "dma"; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + }; From 14c81eb2f65a2d0b9fe4b1e63a93db20eee15d1f Mon Sep 17 00:00:00 2001 From: Weijie Gao Date: Fri, 9 Sep 2022 19:59:52 +0800 Subject: [PATCH 259/374] dt-bindings: pinctrl: mediatek: add a header for common pinconf parameters This patch adds a pinctrl header for common pinconf parameters such as pull-up/pull-down resistors and drive strengths. Reviewed-by: Simon Glass Signed-off-by: Weijie Gao --- include/dt-bindings/pinctrl/mt65xx.h | 41 ++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 include/dt-bindings/pinctrl/mt65xx.h diff --git a/include/dt-bindings/pinctrl/mt65xx.h b/include/dt-bindings/pinctrl/mt65xx.h new file mode 100644 index 0000000000..fbea8d35bc --- /dev/null +++ b/include/dt-bindings/pinctrl/mt65xx.h @@ -0,0 +1,41 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2022 MediaTek Inc. + * Author: Hongzhou.Yang + */ + +#ifndef _DT_BINDINGS_PINCTRL_MT65XX_H +#define _DT_BINDINGS_PINCTRL_MT65XX_H + +#define MTK_PIN_NO(x) ((x) << 8) +#define MTK_GET_PIN_NO(x) ((x) >> 8) +#define MTK_GET_PIN_FUNC(x) ((x) & 0xf) + +#define MTK_PUPD_SET_R1R0_00 100 +#define MTK_PUPD_SET_R1R0_01 101 +#define MTK_PUPD_SET_R1R0_10 102 +#define MTK_PUPD_SET_R1R0_11 103 + +#define MTK_PULL_SET_RSEL_000 200 +#define MTK_PULL_SET_RSEL_001 201 +#define MTK_PULL_SET_RSEL_010 202 +#define MTK_PULL_SET_RSEL_011 203 +#define MTK_PULL_SET_RSEL_100 204 +#define MTK_PULL_SET_RSEL_101 205 +#define MTK_PULL_SET_RSEL_110 206 +#define MTK_PULL_SET_RSEL_111 207 + +#define MTK_DRIVE_2mA 2 +#define MTK_DRIVE_4mA 4 +#define MTK_DRIVE_6mA 6 +#define MTK_DRIVE_8mA 8 +#define MTK_DRIVE_10mA 10 +#define MTK_DRIVE_12mA 12 +#define MTK_DRIVE_14mA 14 +#define MTK_DRIVE_16mA 16 +#define MTK_DRIVE_20mA 20 +#define MTK_DRIVE_24mA 24 +#define MTK_DRIVE_28mA 28 +#define MTK_DRIVE_32mA 32 + +#endif /* _DT_BINDINGS_PINCTRL_MT65XX_H */ From ace67d109719823c05a4c2c7c09b9c71ee82dd9b Mon Sep 17 00:00:00 2001 From: Weijie Gao Date: Fri, 9 Sep 2022 19:59:55 +0800 Subject: [PATCH 260/374] pinctrl: mediatek: add pinctrl driver for MT7981 SoC This patch adds pinctrl and gpio support for MT7981 SoC Reviewed-by: Simon Glass Signed-off-by: Weijie Gao --- drivers/pinctrl/mediatek/Kconfig | 4 + drivers/pinctrl/mediatek/Makefile | 1 + drivers/pinctrl/mediatek/pinctrl-mt7981.c | 1049 +++++++++++++++++++++ 3 files changed, 1054 insertions(+) create mode 100644 drivers/pinctrl/mediatek/pinctrl-mt7981.c diff --git a/drivers/pinctrl/mediatek/Kconfig b/drivers/pinctrl/mediatek/Kconfig index 58df508d7e..aceec9277d 100644 --- a/drivers/pinctrl/mediatek/Kconfig +++ b/drivers/pinctrl/mediatek/Kconfig @@ -16,6 +16,10 @@ config PINCTRL_MT7629 bool "MT7629 SoC pinctrl driver" select PINCTRL_MTK +config PINCTRL_MT7981 + bool "MT7981 SoC pinctrl driver" + select PINCTRL_MTK + config PINCTRL_MT8512 bool "MT8512 SoC pinctrl driver" select PINCTRL_MTK diff --git a/drivers/pinctrl/mediatek/Makefile b/drivers/pinctrl/mediatek/Makefile index d7e8cf1727..1879d7ae2a 100644 --- a/drivers/pinctrl/mediatek/Makefile +++ b/drivers/pinctrl/mediatek/Makefile @@ -6,6 +6,7 @@ obj-$(CONFIG_PINCTRL_MTK) += pinctrl-mtk-common.o obj-$(CONFIG_PINCTRL_MT7622) += pinctrl-mt7622.o obj-$(CONFIG_PINCTRL_MT7623) += pinctrl-mt7623.o obj-$(CONFIG_PINCTRL_MT7629) += pinctrl-mt7629.o +obj-$(CONFIG_PINCTRL_MT7981) += pinctrl-mt7981.o obj-$(CONFIG_PINCTRL_MT8512) += pinctrl-mt8512.o obj-$(CONFIG_PINCTRL_MT8516) += pinctrl-mt8516.o obj-$(CONFIG_PINCTRL_MT8518) += pinctrl-mt8518.o diff --git a/drivers/pinctrl/mediatek/pinctrl-mt7981.c b/drivers/pinctrl/mediatek/pinctrl-mt7981.c new file mode 100644 index 0000000000..d8875241cb --- /dev/null +++ b/drivers/pinctrl/mediatek/pinctrl-mt7981.c @@ -0,0 +1,1049 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * The MT7981 driver based on Linux generic pinctrl binding. + * + * Copyright (C) 2022 MediaTek Inc. + * Author: Sam Shih + */ + +#include +#include "pinctrl-mtk-common.h" + +#define MT7981_TYPE0_PIN(_number, _name) \ + MTK_TYPED_PIN(_number, _name, DRV_GRP4, IO_TYPE_GRP0) + +#define MT7981_TYPE1_PIN(_number, _name) \ + MTK_TYPED_PIN(_number, _name, DRV_GRP4, IO_TYPE_GRP1) + +#define PIN_FIELD_GPIO(_s_pin, _e_pin, _s_addr, _x_addrs, _s_bit, _x_bits) \ + PIN_FIELD_BASE_CALC(_s_pin, _e_pin, GPIO_BASE, _s_addr, _x_addrs, \ + _s_bit, _x_bits, 32, 0) + +#define PIN_FIELD_BASE(_s_pin, _e_pin, _i_base, _s_addr, _x_addrs, _s_bit, \ + _x_bits) \ + PIN_FIELD_BASE_CALC(_s_pin, _e_pin, _i_base, _s_addr, _x_addrs, _s_bit, \ + _x_bits, 32, 0) + +/** + * enum - Locking variants of the iocfg bases + * + * MT7981 have multiple bases to program pin configuration listed as the below: + * iocfg_rt:0x11c00000, iocfg_rm:0x11c10000, iocfg_rb:0x11d20000, + * iocfg_lb:0x11e00000, iocfg_bl:0x11e20000, iocfg_tm:0x11f00000, + * iocfg_tl:0x11f10000, + * _i_based could be used to indicate what base the pin should be mapped into. + * + * Each iocfg register base control different group of pads on the SoC + * + * + * chip carrier + * + * A B C D E F G H + * +------------------------+ + * 8 | o o o o o o o o | + * 7 | o o o o o o o o | + * 6 | o o o o o o o o | + * 5 | o o o o o o o o | + * 4 | o o o o o o o o | + * 3 | o o o o o o o o | + * 2 | o o o o o o o o | + * 1 | o o o o o o o o | + * +------------------------+ + * + * inside Chip carrier + * + * A B C D E F G H + * +------------------------+ + * 8 | | + * 7 | TL TM | + * 6 | +---------+ | + * 5 | | | RT | + * 4 | | | RM | + * 3 | LB | | RB | + * 2 | +---------+ | + * 1 | BL | + * +------------------------+ + * + */ + +enum { + GPIO_BASE, + IOCFG_RT_BASE, + IOCFG_RM_BASE, + IOCFG_RB_BASE, + IOCFG_LB_BASE, + IOCFG_BL_BASE, + IOCFG_TM_BASE, + IOCFG_TL_BASE, +}; + +static const struct mtk_pin_field_calc mt7981_pin_mode_range[] = { + PIN_FIELD_GPIO(0, 56, 0x300, 0x10, 0, 4), +}; + +static const struct mtk_pin_field_calc mt7981_pin_dir_range[] = { + PIN_FIELD_GPIO(0, 56, 0x0, 0x10, 0, 1), +}; + +static const struct mtk_pin_field_calc mt7981_pin_di_range[] = { + PIN_FIELD_GPIO(0, 56, 0x200, 0x10, 0, 1), +}; + +static const struct mtk_pin_field_calc mt7981_pin_do_range[] = { + PIN_FIELD_GPIO(0, 56, 0x100, 0x10, 0, 1), +}; + +static const struct mtk_pin_field_calc mt7981_pin_ies_range[] = { + PIN_FIELD_BASE(0, 0, 1, 0x10, 0x10, 1, 1), + PIN_FIELD_BASE(1, 1, 1, 0x10, 0x10, 0, 1), + PIN_FIELD_BASE(2, 2, 5, 0x20, 0x10, 6, 1), + PIN_FIELD_BASE(3, 3, 4, 0x20, 0x10, 6, 1), + PIN_FIELD_BASE(4, 4, 4, 0x20, 0x10, 2, 1), + PIN_FIELD_BASE(5, 5, 4, 0x20, 0x10, 1, 1), + PIN_FIELD_BASE(6, 6, 4, 0x20, 0x10, 3, 1), + PIN_FIELD_BASE(7, 7, 4, 0x20, 0x10, 0, 1), + PIN_FIELD_BASE(8, 8, 4, 0x20, 0x10, 4, 1), + PIN_FIELD_BASE(9, 9, 4, 0x20, 0x10, 9, 1), + + PIN_FIELD_BASE(10, 10, 5, 0x20, 0x10, 8, 1), + PIN_FIELD_BASE(11, 11, 5, 0x40, 0x10, 10, 1), + PIN_FIELD_BASE(12, 12, 5, 0x20, 0x10, 7, 1), + PIN_FIELD_BASE(13, 13, 5, 0x20, 0x10, 11, 1), + + PIN_FIELD_BASE(14, 14, 4, 0x20, 0x10, 8, 1), + + PIN_FIELD_BASE(15, 15, 2, 0x20, 0x10, 0, 1), + PIN_FIELD_BASE(16, 16, 2, 0x20, 0x10, 1, 1), + PIN_FIELD_BASE(17, 17, 2, 0x20, 0x10, 5, 1), + PIN_FIELD_BASE(18, 18, 2, 0x20, 0x10, 4, 1), + PIN_FIELD_BASE(19, 19, 2, 0x20, 0x10, 2, 1), + PIN_FIELD_BASE(20, 20, 2, 0x20, 0x10, 3, 1), + PIN_FIELD_BASE(21, 21, 2, 0x20, 0x10, 6, 1), + PIN_FIELD_BASE(22, 22, 2, 0x20, 0x10, 7, 1), + PIN_FIELD_BASE(23, 23, 2, 0x20, 0x10, 10, 1), + PIN_FIELD_BASE(24, 24, 2, 0x20, 0x10, 9, 1), + PIN_FIELD_BASE(25, 25, 2, 0x20, 0x10, 8, 1), + + PIN_FIELD_BASE(26, 26, 5, 0x20, 0x10, 0, 1), + PIN_FIELD_BASE(27, 27, 5, 0x20, 0x10, 4, 1), + PIN_FIELD_BASE(28, 28, 5, 0x20, 0x10, 3, 1), + PIN_FIELD_BASE(29, 29, 5, 0x20, 0x10, 1, 1), + PIN_FIELD_BASE(30, 30, 5, 0x20, 0x10, 2, 1), + PIN_FIELD_BASE(31, 31, 5, 0x20, 0x10, 5, 1), + + PIN_FIELD_BASE(32, 32, 1, 0x10, 0x10, 2, 1), + PIN_FIELD_BASE(33, 33, 1, 0x10, 0x10, 3, 1), + + PIN_FIELD_BASE(34, 34, 4, 0x20, 0x10, 5, 1), + PIN_FIELD_BASE(35, 35, 4, 0x20, 0x10, 7, 1), + + PIN_FIELD_BASE(36, 36, 3, 0x10, 0x10, 2, 1), + PIN_FIELD_BASE(37, 37, 3, 0x10, 0x10, 3, 1), + PIN_FIELD_BASE(38, 38, 3, 0x10, 0x10, 0, 1), + PIN_FIELD_BASE(39, 39, 3, 0x10, 0x10, 1, 1), + + PIN_FIELD_BASE(40, 40, 7, 0x30, 0x10, 1, 1), + PIN_FIELD_BASE(41, 41, 7, 0x30, 0x10, 0, 1), + PIN_FIELD_BASE(42, 42, 7, 0x30, 0x10, 9, 1), + PIN_FIELD_BASE(43, 43, 7, 0x30, 0x10, 7, 1), + PIN_FIELD_BASE(44, 44, 7, 0x30, 0x10, 8, 1), + PIN_FIELD_BASE(45, 45, 7, 0x30, 0x10, 3, 1), + PIN_FIELD_BASE(46, 46, 7, 0x30, 0x10, 4, 1), + PIN_FIELD_BASE(47, 47, 7, 0x30, 0x10, 5, 1), + PIN_FIELD_BASE(48, 48, 7, 0x30, 0x10, 6, 1), + PIN_FIELD_BASE(49, 49, 7, 0x30, 0x10, 2, 1), + + PIN_FIELD_BASE(50, 50, 6, 0x10, 0x10, 0, 1), + PIN_FIELD_BASE(51, 51, 6, 0x10, 0x10, 2, 1), + PIN_FIELD_BASE(52, 52, 6, 0x10, 0x10, 3, 1), + PIN_FIELD_BASE(53, 53, 6, 0x10, 0x10, 4, 1), + PIN_FIELD_BASE(54, 54, 6, 0x10, 0x10, 5, 1), + PIN_FIELD_BASE(55, 55, 6, 0x10, 0x10, 6, 1), + PIN_FIELD_BASE(56, 56, 6, 0x10, 0x10, 1, 1), +}; + +static const struct mtk_pin_field_calc mt7981_pin_smt_range[] = { + PIN_FIELD_BASE(0, 0, 1, 0x60, 0x10, 1, 1), + PIN_FIELD_BASE(1, 1, 1, 0x60, 0x10, 0, 1), + PIN_FIELD_BASE(2, 2, 5, 0x90, 0x10, 6, 1), + PIN_FIELD_BASE(3, 3, 4, 0x80, 0x10, 6, 1), + PIN_FIELD_BASE(4, 4, 4, 0x80, 0x10, 2, 1), + PIN_FIELD_BASE(5, 5, 4, 0x80, 0x10, 1, 1), + PIN_FIELD_BASE(6, 6, 4, 0x80, 0x10, 3, 1), + PIN_FIELD_BASE(7, 7, 4, 0x80, 0x10, 0, 1), + PIN_FIELD_BASE(8, 8, 4, 0x80, 0x10, 4, 1), + PIN_FIELD_BASE(9, 9, 4, 0x80, 0x10, 9, 1), + + PIN_FIELD_BASE(10, 10, 5, 0x90, 0x10, 8, 1), + PIN_FIELD_BASE(11, 11, 5, 0x90, 0x10, 10, 1), + PIN_FIELD_BASE(12, 12, 5, 0x90, 0x10, 7, 1), + PIN_FIELD_BASE(13, 13, 5, 0x90, 0x10, 11, 1), + + PIN_FIELD_BASE(14, 14, 4, 0x80, 0x10, 8, 1), + + PIN_FIELD_BASE(15, 15, 2, 0x90, 0x10, 0, 1), + PIN_FIELD_BASE(16, 16, 2, 0x90, 0x10, 1, 1), + PIN_FIELD_BASE(17, 17, 2, 0x90, 0x10, 5, 1), + PIN_FIELD_BASE(18, 18, 2, 0x90, 0x10, 4, 1), + PIN_FIELD_BASE(19, 19, 2, 0x90, 0x10, 2, 1), + PIN_FIELD_BASE(20, 20, 2, 0x90, 0x10, 3, 1), + PIN_FIELD_BASE(21, 21, 2, 0x90, 0x10, 6, 1), + PIN_FIELD_BASE(22, 22, 2, 0x90, 0x10, 7, 1), + PIN_FIELD_BASE(23, 23, 2, 0x90, 0x10, 10, 1), + PIN_FIELD_BASE(24, 24, 2, 0x90, 0x10, 9, 1), + PIN_FIELD_BASE(25, 25, 2, 0x90, 0x10, 8, 1), + + PIN_FIELD_BASE(26, 26, 5, 0x90, 0x10, 0, 1), + PIN_FIELD_BASE(27, 27, 5, 0x90, 0x10, 4, 1), + PIN_FIELD_BASE(28, 28, 5, 0x90, 0x10, 3, 1), + PIN_FIELD_BASE(29, 29, 5, 0x90, 0x10, 1, 1), + PIN_FIELD_BASE(30, 30, 5, 0x90, 0x10, 2, 1), + PIN_FIELD_BASE(31, 31, 5, 0x90, 0x10, 5, 1), + + PIN_FIELD_BASE(32, 32, 1, 0x60, 0x10, 2, 1), + PIN_FIELD_BASE(33, 33, 1, 0x60, 0x10, 3, 1), + + PIN_FIELD_BASE(34, 34, 4, 0x80, 0x10, 5, 1), + PIN_FIELD_BASE(35, 35, 4, 0x80, 0x10, 7, 1), + + PIN_FIELD_BASE(36, 36, 3, 0x60, 0x10, 2, 1), + PIN_FIELD_BASE(37, 37, 3, 0x60, 0x10, 3, 1), + PIN_FIELD_BASE(38, 38, 3, 0x60, 0x10, 0, 1), + PIN_FIELD_BASE(39, 39, 3, 0x60, 0x10, 1, 1), + + PIN_FIELD_BASE(40, 40, 7, 0x70, 0x10, 1, 1), + PIN_FIELD_BASE(41, 41, 7, 0x70, 0x10, 0, 1), + PIN_FIELD_BASE(42, 42, 7, 0x70, 0x10, 9, 1), + PIN_FIELD_BASE(43, 43, 7, 0x70, 0x10, 7, 1), + PIN_FIELD_BASE(44, 44, 7, 0x30, 0x10, 8, 1), + PIN_FIELD_BASE(45, 45, 7, 0x70, 0x10, 3, 1), + PIN_FIELD_BASE(46, 46, 7, 0x70, 0x10, 4, 1), + PIN_FIELD_BASE(47, 47, 7, 0x70, 0x10, 5, 1), + PIN_FIELD_BASE(48, 48, 7, 0x70, 0x10, 6, 1), + PIN_FIELD_BASE(49, 49, 7, 0x70, 0x10, 2, 1), + + PIN_FIELD_BASE(50, 50, 6, 0x50, 0x10, 0, 1), + PIN_FIELD_BASE(51, 51, 6, 0x50, 0x10, 2, 1), + PIN_FIELD_BASE(52, 52, 6, 0x50, 0x10, 3, 1), + PIN_FIELD_BASE(53, 53, 6, 0x50, 0x10, 4, 1), + PIN_FIELD_BASE(54, 54, 6, 0x50, 0x10, 5, 1), + PIN_FIELD_BASE(55, 55, 6, 0x50, 0x10, 6, 1), + PIN_FIELD_BASE(56, 56, 6, 0x50, 0x10, 1, 1), +}; + +static const struct mtk_pin_field_calc mt7981_pin_pu_range[] = { + PIN_FIELD_BASE(40, 40, 7, 0x50, 0x10, 1, 1), + PIN_FIELD_BASE(41, 41, 7, 0x50, 0x10, 0, 1), + PIN_FIELD_BASE(42, 42, 7, 0x50, 0x10, 9, 1), + PIN_FIELD_BASE(43, 43, 7, 0x50, 0x10, 7, 1), + PIN_FIELD_BASE(44, 44, 7, 0x50, 0x10, 8, 1), + PIN_FIELD_BASE(45, 45, 7, 0x50, 0x10, 3, 1), + PIN_FIELD_BASE(46, 46, 7, 0x50, 0x10, 4, 1), + PIN_FIELD_BASE(47, 47, 7, 0x50, 0x10, 5, 1), + PIN_FIELD_BASE(48, 48, 7, 0x50, 0x10, 6, 1), + PIN_FIELD_BASE(49, 49, 7, 0x50, 0x10, 2, 1), + + PIN_FIELD_BASE(50, 50, 6, 0x30, 0x10, 0, 1), + PIN_FIELD_BASE(51, 51, 6, 0x30, 0x10, 2, 1), + PIN_FIELD_BASE(52, 52, 6, 0x30, 0x10, 3, 1), + PIN_FIELD_BASE(53, 53, 6, 0x30, 0x10, 4, 1), + PIN_FIELD_BASE(54, 54, 6, 0x30, 0x10, 5, 1), + PIN_FIELD_BASE(55, 55, 6, 0x30, 0x10, 6, 1), + PIN_FIELD_BASE(56, 56, 6, 0x30, 0x10, 1, 1), +}; + +static const struct mtk_pin_field_calc mt7981_pin_pd_range[] = { + PIN_FIELD_BASE(40, 40, 7, 0x40, 0x10, 1, 1), + PIN_FIELD_BASE(41, 41, 7, 0x40, 0x10, 0, 1), + PIN_FIELD_BASE(42, 42, 7, 0x40, 0x10, 9, 1), + PIN_FIELD_BASE(43, 43, 7, 0x40, 0x10, 7, 1), + PIN_FIELD_BASE(44, 44, 7, 0x40, 0x10, 8, 1), + PIN_FIELD_BASE(45, 45, 7, 0x40, 0x10, 3, 1), + PIN_FIELD_BASE(46, 46, 7, 0x40, 0x10, 4, 1), + PIN_FIELD_BASE(47, 47, 7, 0x40, 0x10, 5, 1), + PIN_FIELD_BASE(48, 48, 7, 0x40, 0x10, 6, 1), + PIN_FIELD_BASE(49, 49, 7, 0x40, 0x10, 2, 1), + + PIN_FIELD_BASE(50, 50, 6, 0x20, 0x10, 0, 1), + PIN_FIELD_BASE(51, 51, 6, 0x20, 0x10, 2, 1), + PIN_FIELD_BASE(52, 52, 6, 0x20, 0x10, 3, 1), + PIN_FIELD_BASE(53, 53, 6, 0x20, 0x10, 4, 1), + PIN_FIELD_BASE(54, 54, 6, 0x20, 0x10, 5, 1), + PIN_FIELD_BASE(55, 55, 6, 0x20, 0x10, 6, 1), + PIN_FIELD_BASE(56, 56, 6, 0x20, 0x10, 1, 1), +}; + +static const struct mtk_pin_field_calc mt7981_pin_drv_range[] = { + PIN_FIELD_BASE(0, 0, 1, 0x00, 0x10, 3, 3), + PIN_FIELD_BASE(1, 1, 1, 0x00, 0x10, 0, 3), + + PIN_FIELD_BASE(2, 2, 5, 0x00, 0x10, 18, 3), + + PIN_FIELD_BASE(3, 3, 4, 0x00, 0x10, 18, 1), + PIN_FIELD_BASE(4, 4, 4, 0x00, 0x10, 6, 1), + PIN_FIELD_BASE(5, 5, 4, 0x00, 0x10, 3, 3), + PIN_FIELD_BASE(6, 6, 4, 0x00, 0x10, 9, 3), + PIN_FIELD_BASE(7, 7, 4, 0x00, 0x10, 0, 3), + PIN_FIELD_BASE(8, 8, 4, 0x00, 0x10, 12, 3), + PIN_FIELD_BASE(9, 9, 4, 0x00, 0x10, 27, 3), + + PIN_FIELD_BASE(10, 10, 5, 0x00, 0x10, 24, 3), + PIN_FIELD_BASE(11, 11, 5, 0x00, 0x10, 0, 3), + PIN_FIELD_BASE(12, 12, 5, 0x00, 0x10, 21, 3), + PIN_FIELD_BASE(13, 13, 5, 0x00, 0x10, 3, 3), + + PIN_FIELD_BASE(14, 14, 4, 0x00, 0x10, 27, 3), + + PIN_FIELD_BASE(15, 15, 2, 0x00, 0x10, 0, 3), + PIN_FIELD_BASE(16, 16, 2, 0x00, 0x10, 3, 3), + PIN_FIELD_BASE(17, 17, 2, 0x00, 0x10, 15, 3), + PIN_FIELD_BASE(18, 18, 2, 0x00, 0x10, 12, 3), + PIN_FIELD_BASE(19, 19, 2, 0x00, 0x10, 6, 3), + PIN_FIELD_BASE(20, 20, 2, 0x00, 0x10, 9, 3), + PIN_FIELD_BASE(21, 21, 2, 0x00, 0x10, 18, 3), + PIN_FIELD_BASE(22, 22, 2, 0x00, 0x10, 21, 3), + PIN_FIELD_BASE(23, 23, 2, 0x00, 0x10, 0, 3), + PIN_FIELD_BASE(24, 24, 2, 0x00, 0x10, 27, 3), + PIN_FIELD_BASE(25, 25, 2, 0x00, 0x10, 24, 3), + + PIN_FIELD_BASE(26, 26, 5, 0x00, 0x10, 0, 3), + PIN_FIELD_BASE(27, 27, 5, 0x00, 0x10, 12, 3), + PIN_FIELD_BASE(28, 28, 5, 0x00, 0x10, 9, 3), + PIN_FIELD_BASE(29, 29, 5, 0x00, 0x10, 3, 3), + PIN_FIELD_BASE(30, 30, 5, 0x00, 0x10, 6, 3), + PIN_FIELD_BASE(31, 31, 5, 0x00, 0x10, 15, 3), + + PIN_FIELD_BASE(32, 32, 1, 0x00, 0x10, 9, 3), + PIN_FIELD_BASE(33, 33, 1, 0x00, 0x10, 12, 3), + + PIN_FIELD_BASE(34, 34, 4, 0x00, 0x10, 15, 3), + PIN_FIELD_BASE(35, 35, 4, 0x00, 0x10, 21, 3), + + PIN_FIELD_BASE(36, 36, 3, 0x00, 0x10, 6, 3), + PIN_FIELD_BASE(37, 37, 3, 0x00, 0x10, 9, 3), + PIN_FIELD_BASE(38, 38, 3, 0x00, 0x10, 0, 3), + PIN_FIELD_BASE(39, 39, 3, 0x00, 0x10, 3, 3), + + PIN_FIELD_BASE(40, 40, 7, 0x00, 0x10, 3, 3), + PIN_FIELD_BASE(41, 41, 7, 0x00, 0x10, 0, 3), + PIN_FIELD_BASE(42, 42, 7, 0x00, 0x10, 27, 3), + PIN_FIELD_BASE(43, 43, 7, 0x00, 0x10, 21, 3), + PIN_FIELD_BASE(44, 44, 7, 0x00, 0x10, 24, 3), + PIN_FIELD_BASE(45, 45, 7, 0x00, 0x10, 9, 3), + PIN_FIELD_BASE(46, 46, 7, 0x00, 0x10, 12, 3), + PIN_FIELD_BASE(47, 47, 7, 0x00, 0x10, 15, 3), + PIN_FIELD_BASE(48, 48, 7, 0x00, 0x10, 18, 3), + PIN_FIELD_BASE(49, 49, 7, 0x00, 0x10, 6, 3), + + PIN_FIELD_BASE(50, 50, 6, 0x00, 0x10, 0, 3), + PIN_FIELD_BASE(51, 51, 6, 0x00, 0x10, 6, 3), + PIN_FIELD_BASE(52, 52, 6, 0x00, 0x10, 9, 3), + PIN_FIELD_BASE(53, 53, 6, 0x00, 0x10, 12, 3), + PIN_FIELD_BASE(54, 54, 6, 0x00, 0x10, 15, 3), + PIN_FIELD_BASE(55, 55, 6, 0x00, 0x10, 18, 3), + PIN_FIELD_BASE(56, 56, 6, 0x00, 0x10, 3, 3), +}; + +static const struct mtk_pin_field_calc mt7981_pin_pupd_range[] = { + PIN_FIELD_BASE(0, 0, 1, 0x20, 0x10, 1, 1), + PIN_FIELD_BASE(1, 1, 1, 0x20, 0x10, 0, 1), + PIN_FIELD_BASE(2, 2, 5, 0x30, 0x10, 6, 1), + PIN_FIELD_BASE(3, 3, 4, 0x30, 0x10, 6, 1), + PIN_FIELD_BASE(4, 4, 4, 0x30, 0x10, 2, 1), + PIN_FIELD_BASE(5, 5, 4, 0x30, 0x10, 1, 1), + PIN_FIELD_BASE(6, 6, 4, 0x30, 0x10, 3, 1), + PIN_FIELD_BASE(7, 7, 4, 0x30, 0x10, 0, 1), + PIN_FIELD_BASE(8, 8, 4, 0x30, 0x10, 4, 1), + PIN_FIELD_BASE(9, 9, 4, 0x30, 0x10, 9, 1), + + PIN_FIELD_BASE(10, 10, 5, 0x30, 0x10, 8, 1), + PIN_FIELD_BASE(11, 11, 5, 0x30, 0x10, 10, 1), + PIN_FIELD_BASE(12, 12, 5, 0x30, 0x10, 7, 1), + PIN_FIELD_BASE(13, 13, 5, 0x30, 0x10, 11, 1), + + PIN_FIELD_BASE(14, 14, 4, 0x30, 0x10, 8, 1), + + PIN_FIELD_BASE(15, 15, 2, 0x30, 0x10, 0, 1), + PIN_FIELD_BASE(16, 16, 2, 0x30, 0x10, 1, 1), + PIN_FIELD_BASE(17, 17, 2, 0x30, 0x10, 5, 1), + PIN_FIELD_BASE(18, 18, 2, 0x30, 0x10, 4, 1), + PIN_FIELD_BASE(19, 19, 2, 0x30, 0x10, 2, 1), + PIN_FIELD_BASE(20, 20, 2, 0x90, 0x10, 3, 1), + PIN_FIELD_BASE(21, 21, 2, 0x30, 0x10, 6, 1), + PIN_FIELD_BASE(22, 22, 2, 0x30, 0x10, 7, 1), + PIN_FIELD_BASE(23, 23, 2, 0x30, 0x10, 10, 1), + PIN_FIELD_BASE(24, 24, 2, 0x30, 0x10, 9, 1), + PIN_FIELD_BASE(25, 25, 2, 0x30, 0x10, 8, 1), + + PIN_FIELD_BASE(26, 26, 5, 0x30, 0x10, 0, 1), + PIN_FIELD_BASE(27, 27, 5, 0x30, 0x10, 4, 1), + PIN_FIELD_BASE(28, 28, 5, 0x30, 0x10, 3, 1), + PIN_FIELD_BASE(29, 29, 5, 0x30, 0x10, 1, 1), + PIN_FIELD_BASE(30, 30, 5, 0x30, 0x10, 2, 1), + PIN_FIELD_BASE(31, 31, 5, 0x30, 0x10, 5, 1), + + PIN_FIELD_BASE(32, 32, 1, 0x20, 0x10, 2, 1), + PIN_FIELD_BASE(33, 33, 1, 0x20, 0x10, 3, 1), + + PIN_FIELD_BASE(34, 34, 4, 0x30, 0x10, 5, 1), + PIN_FIELD_BASE(35, 35, 4, 0x30, 0x10, 7, 1), + + PIN_FIELD_BASE(36, 36, 3, 0x20, 0x10, 2, 1), + PIN_FIELD_BASE(37, 37, 3, 0x20, 0x10, 3, 1), + PIN_FIELD_BASE(38, 38, 3, 0x20, 0x10, 0, 1), + PIN_FIELD_BASE(39, 39, 3, 0x20, 0x10, 1, 1), +}; + +static const struct mtk_pin_field_calc mt7981_pin_r0_range[] = { + PIN_FIELD_BASE(0, 0, 1, 0x30, 0x10, 1, 1), + PIN_FIELD_BASE(1, 1, 1, 0x30, 0x10, 0, 1), + PIN_FIELD_BASE(2, 2, 5, 0x40, 0x10, 6, 1), + PIN_FIELD_BASE(3, 3, 4, 0x40, 0x10, 6, 1), + PIN_FIELD_BASE(4, 4, 4, 0x40, 0x10, 2, 1), + PIN_FIELD_BASE(5, 5, 4, 0x40, 0x10, 1, 1), + PIN_FIELD_BASE(6, 6, 4, 0x40, 0x10, 3, 1), + PIN_FIELD_BASE(7, 7, 4, 0x40, 0x10, 0, 1), + PIN_FIELD_BASE(8, 8, 4, 0x40, 0x10, 4, 1), + PIN_FIELD_BASE(9, 9, 4, 0x40, 0x10, 9, 1), + + PIN_FIELD_BASE(10, 10, 5, 0x40, 0x10, 8, 1), + PIN_FIELD_BASE(11, 11, 5, 0x40, 0x10, 10, 1), + PIN_FIELD_BASE(12, 12, 5, 0x40, 0x10, 7, 1), + PIN_FIELD_BASE(13, 13, 5, 0x40, 0x10, 11, 1), + + PIN_FIELD_BASE(14, 14, 4, 0x40, 0x10, 8, 1), + + PIN_FIELD_BASE(15, 15, 2, 0x40, 0x10, 0, 1), + PIN_FIELD_BASE(16, 16, 2, 0x40, 0x10, 1, 1), + PIN_FIELD_BASE(17, 17, 2, 0x40, 0x10, 5, 1), + PIN_FIELD_BASE(18, 18, 2, 0x40, 0x10, 4, 1), + PIN_FIELD_BASE(19, 19, 2, 0x40, 0x10, 2, 1), + PIN_FIELD_BASE(20, 20, 2, 0x40, 0x10, 3, 1), + PIN_FIELD_BASE(21, 21, 2, 0x40, 0x10, 6, 1), + PIN_FIELD_BASE(22, 22, 2, 0x40, 0x10, 7, 1), + PIN_FIELD_BASE(23, 23, 2, 0x40, 0x10, 10, 1), + PIN_FIELD_BASE(24, 24, 2, 0x40, 0x10, 9, 1), + PIN_FIELD_BASE(25, 25, 2, 0x40, 0x10, 8, 1), + + PIN_FIELD_BASE(26, 26, 5, 0x40, 0x10, 0, 1), + PIN_FIELD_BASE(27, 27, 5, 0x40, 0x10, 4, 1), + PIN_FIELD_BASE(28, 28, 5, 0x40, 0x10, 3, 1), + PIN_FIELD_BASE(29, 29, 5, 0x40, 0x10, 1, 1), + PIN_FIELD_BASE(30, 30, 5, 0x40, 0x10, 2, 1), + PIN_FIELD_BASE(31, 31, 5, 0x40, 0x10, 5, 1), + + PIN_FIELD_BASE(32, 32, 1, 0x30, 0x10, 2, 1), + PIN_FIELD_BASE(33, 33, 1, 0x30, 0x10, 3, 1), + + PIN_FIELD_BASE(34, 34, 4, 0x40, 0x10, 5, 1), + PIN_FIELD_BASE(35, 35, 4, 0x40, 0x10, 7, 1), + + PIN_FIELD_BASE(36, 36, 3, 0x30, 0x10, 2, 1), + PIN_FIELD_BASE(37, 37, 3, 0x30, 0x10, 3, 1), + PIN_FIELD_BASE(38, 38, 3, 0x30, 0x10, 0, 1), + PIN_FIELD_BASE(39, 39, 3, 0x30, 0x10, 1, 1), +}; + +static const struct mtk_pin_field_calc mt7981_pin_r1_range[] = { + PIN_FIELD_BASE(0, 0, 1, 0x40, 0x10, 1, 1), + PIN_FIELD_BASE(1, 1, 1, 0x40, 0x10, 0, 1), + PIN_FIELD_BASE(2, 2, 5, 0x50, 0x10, 6, 1), + PIN_FIELD_BASE(3, 3, 4, 0x50, 0x10, 6, 1), + PIN_FIELD_BASE(4, 4, 4, 0x50, 0x10, 2, 1), + PIN_FIELD_BASE(5, 5, 4, 0x50, 0x10, 1, 1), + PIN_FIELD_BASE(6, 6, 4, 0x50, 0x10, 3, 1), + PIN_FIELD_BASE(7, 7, 4, 0x50, 0x10, 0, 1), + PIN_FIELD_BASE(8, 8, 4, 0x50, 0x10, 4, 1), + PIN_FIELD_BASE(9, 9, 4, 0x50, 0x10, 9, 1), + + PIN_FIELD_BASE(10, 10, 5, 0x50, 0x10, 8, 1), + PIN_FIELD_BASE(11, 11, 5, 0x50, 0x10, 10, 1), + PIN_FIELD_BASE(12, 12, 5, 0x50, 0x10, 7, 1), + PIN_FIELD_BASE(13, 13, 5, 0x50, 0x10, 11, 1), + + PIN_FIELD_BASE(14, 14, 4, 0x50, 0x10, 8, 1), + + PIN_FIELD_BASE(15, 15, 2, 0x50, 0x10, 0, 1), + PIN_FIELD_BASE(16, 16, 2, 0x50, 0x10, 1, 1), + PIN_FIELD_BASE(17, 17, 2, 0x50, 0x10, 5, 1), + PIN_FIELD_BASE(18, 18, 2, 0x50, 0x10, 4, 1), + PIN_FIELD_BASE(19, 19, 2, 0x50, 0x10, 2, 1), + PIN_FIELD_BASE(20, 20, 2, 0x50, 0x10, 3, 1), + PIN_FIELD_BASE(21, 21, 2, 0x50, 0x10, 6, 1), + PIN_FIELD_BASE(22, 22, 2, 0x50, 0x10, 7, 1), + PIN_FIELD_BASE(23, 23, 2, 0x50, 0x10, 10, 1), + PIN_FIELD_BASE(24, 24, 2, 0x50, 0x10, 9, 1), + PIN_FIELD_BASE(25, 25, 2, 0x50, 0x10, 8, 1), + + PIN_FIELD_BASE(26, 26, 5, 0x50, 0x10, 0, 1), + PIN_FIELD_BASE(27, 27, 5, 0x50, 0x10, 4, 1), + PIN_FIELD_BASE(28, 28, 5, 0x50, 0x10, 3, 1), + PIN_FIELD_BASE(29, 29, 5, 0x50, 0x10, 1, 1), + PIN_FIELD_BASE(30, 30, 5, 0x50, 0x10, 2, 1), + PIN_FIELD_BASE(31, 31, 5, 0x50, 0x10, 5, 1), + + PIN_FIELD_BASE(32, 32, 1, 0x40, 0x10, 2, 1), + PIN_FIELD_BASE(33, 33, 1, 0x40, 0x10, 3, 1), + + PIN_FIELD_BASE(34, 34, 4, 0x50, 0x10, 5, 1), + PIN_FIELD_BASE(35, 35, 4, 0x50, 0x10, 7, 1), + + PIN_FIELD_BASE(36, 36, 3, 0x40, 0x10, 2, 1), + PIN_FIELD_BASE(37, 37, 3, 0x40, 0x10, 3, 1), + PIN_FIELD_BASE(38, 38, 3, 0x40, 0x10, 0, 1), + PIN_FIELD_BASE(39, 39, 3, 0x40, 0x10, 1, 1), +}; + +static const struct mtk_pin_reg_calc mt7981_reg_cals[] = { + [PINCTRL_PIN_REG_MODE] = MTK_RANGE(mt7981_pin_mode_range), + [PINCTRL_PIN_REG_DIR] = MTK_RANGE(mt7981_pin_dir_range), + [PINCTRL_PIN_REG_DI] = MTK_RANGE(mt7981_pin_di_range), + [PINCTRL_PIN_REG_DO] = MTK_RANGE(mt7981_pin_do_range), + [PINCTRL_PIN_REG_SMT] = MTK_RANGE(mt7981_pin_smt_range), + [PINCTRL_PIN_REG_IES] = MTK_RANGE(mt7981_pin_ies_range), + [PINCTRL_PIN_REG_PU] = MTK_RANGE(mt7981_pin_pu_range), + [PINCTRL_PIN_REG_PD] = MTK_RANGE(mt7981_pin_pd_range), + [PINCTRL_PIN_REG_DRV] = MTK_RANGE(mt7981_pin_drv_range), + [PINCTRL_PIN_REG_PUPD] = MTK_RANGE(mt7981_pin_pupd_range), + [PINCTRL_PIN_REG_R0] = MTK_RANGE(mt7981_pin_r0_range), + [PINCTRL_PIN_REG_R1] = MTK_RANGE(mt7981_pin_r1_range), +}; + +static const struct mtk_pin_desc mt7981_pins[] = { + MT7981_TYPE0_PIN(0, "GPIO_WPS"), + MT7981_TYPE0_PIN(1, "GPIO_RESET"), + MT7981_TYPE0_PIN(2, "SYS_WATCHDOG"), + MT7981_TYPE0_PIN(3, "PCIE_PERESET_N"), + MT7981_TYPE0_PIN(4, "JTAG_JTDO"), + MT7981_TYPE0_PIN(5, "JTAG_JTDI"), + MT7981_TYPE0_PIN(6, "JTAG_JTMS"), + MT7981_TYPE0_PIN(7, "JTAG_JTCLK"), + MT7981_TYPE0_PIN(8, "JTAG_JTRST_N"), + MT7981_TYPE0_PIN(9, "WO_JTAG_JTDO"), + MT7981_TYPE0_PIN(10, "WO_JTAG_JTDI"), + MT7981_TYPE0_PIN(11, "WO_JTAG_JTMS"), + MT7981_TYPE0_PIN(12, "WO_JTAG_JTCLK"), + MT7981_TYPE0_PIN(13, "WO_JTAG_JTRST_N"), + MT7981_TYPE0_PIN(14, "USB_VBUS"), + MT7981_TYPE0_PIN(15, "PWM0"), + MT7981_TYPE0_PIN(16, "SPI0_CLK"), + MT7981_TYPE0_PIN(17, "SPI0_MOSI"), + MT7981_TYPE0_PIN(18, "SPI0_MISO"), + MT7981_TYPE0_PIN(19, "SPI0_CS"), + MT7981_TYPE0_PIN(20, "SPI0_HOLD"), + MT7981_TYPE0_PIN(21, "SPI0_WP"), + MT7981_TYPE0_PIN(22, "SPI1_CLK"), + MT7981_TYPE0_PIN(23, "SPI1_MOSI"), + MT7981_TYPE0_PIN(24, "SPI1_MISO"), + MT7981_TYPE0_PIN(25, "SPI1_CS"), + MT7981_TYPE0_PIN(26, "SPI2_CLK"), + MT7981_TYPE0_PIN(27, "SPI2_MOSI"), + MT7981_TYPE0_PIN(28, "SPI2_MISO"), + MT7981_TYPE0_PIN(29, "SPI2_CS"), + MT7981_TYPE0_PIN(30, "SPI2_HOLD"), + MT7981_TYPE0_PIN(31, "SPI2_WP"), + MT7981_TYPE0_PIN(32, "UART0_RXD"), + MT7981_TYPE0_PIN(33, "UART0_TXD"), + MT7981_TYPE0_PIN(34, "PCIE_CLK_REQ"), + MT7981_TYPE0_PIN(35, "PCIE_WAKE_N"), + MT7981_TYPE0_PIN(36, "SMI_MDC"), + MT7981_TYPE0_PIN(37, "SMI_MDIO"), + MT7981_TYPE0_PIN(38, "GBE_INT"), + MT7981_TYPE0_PIN(39, "GBE_RESET"), + MT7981_TYPE1_PIN(40, "WF_DIG_RESETB"), + MT7981_TYPE1_PIN(41, "WF_CBA_RESETB"), + MT7981_TYPE1_PIN(42, "WF_XO_REQ"), + MT7981_TYPE1_PIN(43, "WF_TOP_CLK"), + MT7981_TYPE1_PIN(44, "WF_TOP_DATA"), + MT7981_TYPE1_PIN(45, "WF_HB1"), + MT7981_TYPE1_PIN(46, "WF_HB2"), + MT7981_TYPE1_PIN(47, "WF_HB3"), + MT7981_TYPE1_PIN(48, "WF_HB4"), + MT7981_TYPE1_PIN(49, "WF_HB0"), + MT7981_TYPE1_PIN(50, "WF_HB0_B"), + MT7981_TYPE1_PIN(51, "WF_HB5"), + MT7981_TYPE1_PIN(52, "WF_HB6"), + MT7981_TYPE1_PIN(53, "WF_HB7"), + MT7981_TYPE1_PIN(54, "WF_HB8"), + MT7981_TYPE1_PIN(55, "WF_HB9"), + MT7981_TYPE1_PIN(56, "WF_HB10"), +}; + +/* WA_AICE */ +static int mt7981_wa_aice1_pins[] = { 0, 1, }; +static int mt7981_wa_aice1_funcs[] = { 2, 2, }; + +static int mt7981_wa_aice2_pins[] = { 0, 1, }; +static int mt7981_wa_aice2_funcs[] = { 3, 3, }; + +static int mt7981_wa_aice3_pins[] = { 28, 29, }; +static int mt7981_wa_aice3_funcs[] = { 3, 3, }; + +static int mt7981_wm_aice1_pins[] = { 9, 10, }; +static int mt7981_wm_aice1_funcs[] = { 2, 2, }; + +static int mt7981_wm_aice2_pins[] = { 30, 31, }; +static int mt7981_wm_aice2_funcs[] = { 5, 5, }; + +/* WM_UART */ +static int mt7981_wm_uart_0_pins[] = { 0, 1, }; +static int mt7981_wm_uart_0_funcs[] = { 5, 5, }; + +static int mt7981_wm_uart_1_pins[] = { 20, 21, }; +static int mt7981_wm_uart_1_funcs[] = { 4, 4, }; + +static int mt7981_wm_uart_2_pins[] = { 30, 31, }; +static int mt7981_wm_uart_2_funcs[] = { 3, 3, }; + +/* DFD */ +static int mt7981_dfd_pins[] = { 0, 1, 4, 5, }; +static int mt7981_dfd_funcs[] = { 5, 5, 6, 6, }; + +/* SYS_WATCHDOG */ +static int mt7981_watchdog_pins[] = { 2, }; +static int mt7981_watchdog_funcs[] = { 1, }; + +static int mt7981_watchdog1_pins[] = { 13, }; +static int mt7981_watchdog1_funcs[] = { 5, }; + +/* PCIE_PERESET_N */ +static int mt7981_pcie_pereset_pins[] = { 3, }; +static int mt7981_pcie_pereset_funcs[] = { 1, }; + +/* JTAG */ +static int mt7981_jtag_pins[] = { 4, 5, 6, 7, 8, }; +static int mt7981_jtag_funcs[] = { 1, 1, 1, 1, 1, }; + +/* WM_JTAG */ +static int mt7981_wm_jtag_0_pins[] = { 4, 5, 6, 7, 8, }; +static int mt7981_wm_jtag_0_funcs[] = { 2, 2, 2, 2, 2, }; + +static int mt7981_wm_jtag_1_pins[] = { 20, 21, 22, 23, 24, }; +static int mt7981_wm_jtag_1_funcs[] = { 5, 5, 5, 5, 5, }; + +/* WO0_JTAG */ +static int mt7981_wo0_jtag_0_pins[] = { 9, 10, 11, 12, 13, }; +static int mt7981_wo0_jtag_0_funcs[] = { 1, 1, 1, 1, 1, }; + +static int mt7981_wo0_jtag_1_pins[] = { 25, 26, 27, 28, 29, }; +static int mt7981_wo0_jtag_1_funcs[] = { 5, 5, 5, 5, 5, }; + +/* UART2 */ +static int mt7981_uart2_0_pins[] = { 4, 5, 6, 7, }; +static int mt7981_uart2_0_funcs[] = { 3, 3, 3, 3, }; + +/* GBE_LED0 */ +static int mt7981_gbe_led0_pins[] = { 8, }; +static int mt7981_gbe_led0_funcs[] = { 3, }; + +/* PTA_EXT */ +static int mt7981_pta_ext_0_pins[] = { 4, 5, 6, }; +static int mt7981_pta_ext_0_funcs[] = { 4, 4, 4, }; + +static int mt7981_pta_ext_1_pins[] = { 22, 23, 24, }; +static int mt7981_pta_ext_1_funcs[] = { 4, 4, 4, }; + +/* PWM2 */ +static int mt7981_pwm2_pins[] = { 7, }; +static int mt7981_pwm2_funcs[] = { 4, }; + +/* NET_WO0_UART_TXD */ +static int mt7981_net_wo0_uart_txd_0_pins[] = { 8, }; +static int mt7981_net_wo0_uart_txd_0_funcs[] = { 4, }; + +static int mt7981_net_wo0_uart_txd_1_pins[] = { 14, }; +static int mt7981_net_wo0_uart_txd_1_funcs[] = { 3, }; + +static int mt7981_net_wo0_uart_txd_2_pins[] = { 15, }; +static int mt7981_net_wo0_uart_txd_2_funcs[] = { 4, }; + +/* SPI1 */ +static int mt7981_spi1_0_pins[] = { 4, 5, 6, 7, }; +static int mt7981_spi1_0_funcs[] = { 5, 5, 5, 5, }; + +/* I2C */ +static int mt7981_i2c0_0_pins[] = { 6, 7, }; +static int mt7981_i2c0_0_funcs[] = { 6, 6, }; + +static int mt7981_i2c0_1_pins[] = { 30, 31, }; +static int mt7981_i2c0_1_funcs[] = { 4, 4, }; + +static int mt7981_i2c0_2_pins[] = { 36, 37, }; +static int mt7981_i2c0_2_funcs[] = { 2, 2, }; + +static int mt7981_u2_phy_i2c_pins[] = { 30, 31, }; +static int mt7981_u2_phy_i2c_funcs[] = { 6, 6, }; + +static int mt7981_u3_phy_i2c_pins[] = { 32, 33, }; +static int mt7981_u3_phy_i2c_funcs[] = { 3, 3, }; + +static int mt7981_sgmii1_phy_i2c_pins[] = { 32, 33, }; +static int mt7981_sgmii1_phy_i2c_funcs[] = { 2, 2, }; + +static int mt7981_sgmii0_phy_i2c_pins[] = { 32, 33, }; +static int mt7981_sgmii0_phy_i2c_funcs[] = { 5, 5, }; + +/* DFD_NTRST */ +static int mt7981_dfd_ntrst_pins[] = { 8, }; +static int mt7981_dfd_ntrst_funcs[] = { 6, }; + +/* PWM0 */ +static int mt7981_pwm0_0_pins[] = { 13, }; +static int mt7981_pwm0_0_funcs[] = { 2, }; + +static int mt7981_pwm0_1_pins[] = { 15, }; +static int mt7981_pwm0_1_funcs[] = { 1, }; + +/* PWM1 */ +static int mt7981_pwm1_0_pins[] = { 14, }; +static int mt7981_pwm1_0_funcs[] = { 2, }; + +static int mt7981_pwm1_1_pins[] = { 15, }; +static int mt7981_pwm1_1_funcs[] = { 3, }; + +/* GBE_LED1 */ +static int mt7981_gbe_led1_pins[] = { 13, }; +static int mt7981_gbe_led1_funcs[] = { 3, }; + +/* PCM */ +static int mt7981_pcm_pins[] = { 9, 10, 11, 12, 13, 25 }; +static int mt7981_pcm_funcs[] = { 4, 4, 4, 4, 4, 4, }; + +/* UDI */ +static int mt7981_udi_pins[] = { 9, 10, 11, 12, 13, }; +static int mt7981_udi_funcs[] = { 6, 6, 6, 6, 6, }; + +/* DRV_VBUS */ +static int mt7981_drv_vbus_pins[] = { 14, }; +static int mt7981_drv_vbus_funcs[] = { 1, }; + +/* EMMC */ +static int mt7981_emmc_45_pins[] = { 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, }; +static int mt7981_emmc_45_funcs[] = { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, }; + +/* SNFI */ +static int mt7981_snfi_pins[] = { 16, 17, 18, 19, 20, 21, }; +static int mt7981_snfi_funcs[] = { 3, 3, 3, 3, 3, 3, }; + +/* SPI0 */ +static int mt7981_spi0_pins[] = { 16, 17, 18, 19, }; +static int mt7981_spi0_funcs[] = { 1, 1, 1, 1, }; + +/* SPI0 */ +static int mt7981_spi0_wp_hold_pins[] = { 20, 21, }; +static int mt7981_spi0_wp_hold_funcs[] = { 1, 1, }; + +/* SPI1 */ +static int mt7981_spi1_1_pins[] = { 22, 23, 24, 25, }; +static int mt7981_spi1_1_funcs[] = { 1, 1, 1, 1, }; + +/* SPI2 */ +static int mt7981_spi2_pins[] = { 26, 27, 28, 29, }; +static int mt7981_spi2_funcs[] = { 1, 1, 1, 1, }; + +/* SPI2 */ +static int mt7981_spi2_wp_hold_pins[] = { 30, 31, }; +static int mt7981_spi2_wp_hold_funcs[] = { 1, 1, }; + +/* UART1 */ +static int mt7981_uart1_0_pins[] = { 16, 17, 18, 19, }; +static int mt7981_uart1_0_funcs[] = { 4, 4, 4, 4, }; + +static int mt7981_uart1_1_pins[] = { 26, 27, 28, 29, }; +static int mt7981_uart1_1_funcs[] = { 2, 2, 2, 2, }; + +/* UART2 */ +static int mt7981_uart2_1_pins[] = { 22, 23, 24, 25, }; +static int mt7981_uart2_1_funcs[] = { 3, 3, 3, 3, }; + +/* UART0 */ +static int mt7981_uart0_pins[] = { 32, 33, }; +static int mt7981_uart0_funcs[] = { 1, 1, }; + +/* PCIE_CLK_REQ */ +static int mt7981_pcie_clk_pins[] = { 34, }; +static int mt7981_pcie_clk_funcs[] = { 2, }; + +/* PCIE_WAKE_N */ +static int mt7981_pcie_wake_pins[] = { 35, }; +static int mt7981_pcie_wake_funcs[] = { 2, }; + +/* MDC_MDIO */ +static int mt7981_smi_mdc_mdio_pins[] = { 36, 37, }; +static int mt7981_smi_mdc_mdio_funcs[] = { 1, 1, }; + +static int mt7981_gbe_ext_mdc_mdio_pins[] = { 36, 37, }; +static int mt7981_gbe_ext_mdc_mdio_funcs[] = { 3, 3, }; + +/* WF0_MODE1 */ +static int mt7981_wf0_mode1_pins[] = { 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, + 50, 51, 52, 53, 54, 55, 56 }; +static int mt7981_wf0_mode1_funcs[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1 }; + +/* WF0_MODE3 */ +static int mt7981_wf0_mode3_pins[] = { 45, 46, 47, 48, 49, 51 }; +static int mt7981_wf0_mode3_funcs[] = { 2, 2, 2, 2, 2, 2 }; + +/* WF2G_LED */ +static int mt7981_wf2g_led0_pins[] = { 30, }; +static int mt7981_wf2g_led0_funcs[] = { 2, }; + +static int mt7981_wf2g_led1_pins[] = { 34, }; +static int mt7981_wf2g_led1_funcs[] = { 1, }; + +/* WF5G_LED */ +static int mt7981_wf5g_led0_pins[] = { 31, }; +static int mt7981_wf5g_led0_funcs[] = { 2, }; + +static int mt7981_wf5g_led1_pins[] = { 35, }; +static int mt7981_wf5g_led1_funcs[] = { 1, }; + +/* MT7531_INT */ +static int mt7981_mt7531_int_pins[] = { 38, }; +static int mt7981_mt7531_int_funcs[] = { 1, }; + +/* ANT_SEL */ +static int mt7981_ant_sel_pins[] = { 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 34, 35 }; +static int mt7981_ant_sel_funcs[] = { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 }; + +static const struct mtk_group_desc mt7981_groups[] = { + /* @GPIO(0,1): WA_AICE(2) */ + PINCTRL_PIN_GROUP("wa_aice1", mt7981_wa_aice1), + /* @GPIO(0,1): WA_AICE(3) */ + PINCTRL_PIN_GROUP("wa_aice2", mt7981_wa_aice2), + /* @GPIO(0,1): WM_UART(5) */ + PINCTRL_PIN_GROUP("wm_uart_0", mt7981_wm_uart_0), + /* @GPIO(0,1,4,5): DFD(6) */ + PINCTRL_PIN_GROUP("dfd", mt7981_dfd), + /* @GPIO(2): SYS_WATCHDOG(1) */ + PINCTRL_PIN_GROUP("watchdog", mt7981_watchdog), + /* @GPIO(3): PCIE_PERESET_N(1) */ + PINCTRL_PIN_GROUP("pcie_pereset", mt7981_pcie_pereset), + /* @GPIO(4,8) JTAG(1) */ + PINCTRL_PIN_GROUP("jtag", mt7981_jtag), + /* @GPIO(4,8) WM_JTAG(2) */ + PINCTRL_PIN_GROUP("wm_jtag_0", mt7981_wm_jtag_0), + /* @GPIO(9,13) WO0_JTAG(1) */ + PINCTRL_PIN_GROUP("wo0_jtag_0", mt7981_wo0_jtag_0), + /* @GPIO(4,7) WM_JTAG(3) */ + PINCTRL_PIN_GROUP("uart2_0", mt7981_uart2_0), + /* @GPIO(8) GBE_LED0(3) */ + PINCTRL_PIN_GROUP("gbe_led0", mt7981_gbe_led0), + /* @GPIO(4,6) PTA_EXT(4) */ + PINCTRL_PIN_GROUP("pta_ext_0", mt7981_pta_ext_0), + /* @GPIO(7) PWM2(4) */ + PINCTRL_PIN_GROUP("pwm2", mt7981_pwm2), + /* @GPIO(8) NET_WO0_UART_TXD(4) */ + PINCTRL_PIN_GROUP("net_wo0_uart_txd_0", mt7981_net_wo0_uart_txd_0), + /* @GPIO(4,7) SPI1(5) */ + PINCTRL_PIN_GROUP("spi1_0", mt7981_spi1_0), + /* @GPIO(6,7) I2C(5) */ + PINCTRL_PIN_GROUP("i2c0_0", mt7981_i2c0_0), + /* @GPIO(8): DFD_NTRST(6) */ + PINCTRL_PIN_GROUP("dfd_ntrst", mt7981_dfd_ntrst), + /* @GPIO(9,10): WM_AICE(2) */ + PINCTRL_PIN_GROUP("wm_aice1", mt7981_wm_aice1), + /* @GPIO(13): PWM0(2) */ + PINCTRL_PIN_GROUP("pwm0_0", mt7981_pwm0_0), + /* @GPIO(15): PWM0(1) */ + PINCTRL_PIN_GROUP("pwm0_1", mt7981_pwm0_1), + /* @GPIO(14): PWM1(2) */ + PINCTRL_PIN_GROUP("pwm1_0", mt7981_pwm1_0), + /* @GPIO(15): PWM1(3) */ + PINCTRL_PIN_GROUP("pwm1_1", mt7981_pwm1_1), + /* @GPIO(14) NET_WO0_UART_TXD(3) */ + PINCTRL_PIN_GROUP("net_wo0_uart_txd_1", mt7981_net_wo0_uart_txd_1), + /* @GPIO(15) NET_WO0_UART_TXD(4) */ + PINCTRL_PIN_GROUP("net_wo0_uart_txd_2", mt7981_net_wo0_uart_txd_2), + /* @GPIO(13) GBE_LED0(3) */ + PINCTRL_PIN_GROUP("gbe_led1", mt7981_gbe_led1), + /* @GPIO(9,13) PCM(4) */ + PINCTRL_PIN_GROUP("pcm", mt7981_pcm), + /* @GPIO(13): SYS_WATCHDOG1(5) */ + PINCTRL_PIN_GROUP("watchdog1", mt7981_watchdog1), + /* @GPIO(9,13) UDI(4) */ + PINCTRL_PIN_GROUP("udi", mt7981_udi), + /* @GPIO(14) DRV_VBUS(1) */ + PINCTRL_PIN_GROUP("drv_vbus", mt7981_drv_vbus), + /* @GPIO(15,25): EMMC(2) */ + PINCTRL_PIN_GROUP("emmc_45", mt7981_emmc_45), + /* @GPIO(16,21): SNFI(3) */ + PINCTRL_PIN_GROUP("snfi", mt7981_snfi), + /* @GPIO(16,19): SPI0(1) */ + PINCTRL_PIN_GROUP("spi0", mt7981_spi0), + /* @GPIO(20,21): SPI0(1) */ + PINCTRL_PIN_GROUP("spi0_wp_hold", mt7981_spi0_wp_hold), + /* @GPIO(22,25) SPI1(1) */ + PINCTRL_PIN_GROUP("spi1_1", mt7981_spi1_1), + /* @GPIO(26,29): SPI2(1) */ + PINCTRL_PIN_GROUP("spi2", mt7981_spi2), + /* @GPIO(30,31): SPI2(1) */ + PINCTRL_PIN_GROUP("spi2_wp_hold", mt7981_spi2_wp_hold), + /* @GPIO(16,19): UART1(4) */ + PINCTRL_PIN_GROUP("uart1_0", mt7981_uart1_0), + /* @GPIO(26,29): UART1(2) */ + PINCTRL_PIN_GROUP("uart1_1", mt7981_uart1_1), + /* @GPIO(22,25): UART2(3) */ + PINCTRL_PIN_GROUP("uart2_0", mt7981_uart2_1), + /* @GPIO(22,24) PTA_EXT(4) */ + PINCTRL_PIN_GROUP("pta_ext_1", mt7981_pta_ext_1), + /* @GPIO(20,21): WM_UART(4) */ + PINCTRL_PIN_GROUP("wm_aurt_1", mt7981_wm_uart_1), + /* @GPIO(30,31): WM_UART(3) */ + PINCTRL_PIN_GROUP("wm_aurt_2", mt7981_wm_uart_2), + /* @GPIO(20,24) WM_JTAG(5) */ + PINCTRL_PIN_GROUP("wm_jtag_1", mt7981_wm_jtag_1), + /* @GPIO(25,29) WO0_JTAG(5) */ + PINCTRL_PIN_GROUP("wo0_jtag_1", mt7981_wo0_jtag_1), + /* @GPIO(28,29): WA_AICE(3) */ + PINCTRL_PIN_GROUP("wa_aice3", mt7981_wa_aice3), + /* @GPIO(30,31): WM_AICE(5) */ + PINCTRL_PIN_GROUP("wm_aice2", mt7981_wm_aice2), + /* @GPIO(30,31): I2C(4) */ + PINCTRL_PIN_GROUP("i2c0_1", mt7981_i2c0_1), + /* @GPIO(30,31): I2C(6) */ + PINCTRL_PIN_GROUP("u2_phy_i2c", mt7981_u2_phy_i2c), + /* @GPIO(32,33): I2C(1) */ + PINCTRL_PIN_GROUP("uart0", mt7981_uart0), + /* @GPIO(32,33): I2C(2) */ + PINCTRL_PIN_GROUP("sgmii1_phy_i2c", mt7981_sgmii1_phy_i2c), + /* @GPIO(32,33): I2C(3) */ + PINCTRL_PIN_GROUP("u3_phy_i2c", mt7981_u3_phy_i2c), + /* @GPIO(32,33): I2C(5) */ + PINCTRL_PIN_GROUP("sgmii0_phy_i2c", mt7981_sgmii0_phy_i2c), + /* @GPIO(34): PCIE_CLK_REQ(2) */ + PINCTRL_PIN_GROUP("pcie_clk", mt7981_pcie_clk), + /* @GPIO(35): PCIE_WAKE_N(2) */ + PINCTRL_PIN_GROUP("pcie_wake", mt7981_pcie_wake), + /* @GPIO(36,37): I2C(2) */ + PINCTRL_PIN_GROUP("i2c0_2", mt7981_i2c0_2), + /* @GPIO(36,37): MDC_MDIO(1) */ + PINCTRL_PIN_GROUP("smi_mdc_mdio", mt7981_smi_mdc_mdio), + /* @GPIO(36,37): MDC_MDIO(3) */ + PINCTRL_PIN_GROUP("gbe_ext_mdc_mdio", mt7981_gbe_ext_mdc_mdio), + /* @GPIO(40,56): WF0_MODE1(1) */ + PINCTRL_PIN_GROUP("wf0_mode1", mt7981_wf0_mode1), + /* @GPIO(45,46,47,48,49,51): WF0_MODE3(3) */ + PINCTRL_PIN_GROUP("wf0_mode3", mt7981_wf0_mode3), + /* @GPIO(30): WF2G_LED(2) */ + PINCTRL_PIN_GROUP("wf2g_led0", mt7981_wf2g_led0), + /* @GPIO(34): WF2G_LED(1) */ + PINCTRL_PIN_GROUP("wf2g_led1", mt7981_wf2g_led1), + /* @GPIO(31): WF5G_LED(2) */ + PINCTRL_PIN_GROUP("wf5g_led0", mt7981_wf5g_led0), + /* @GPIO(35): WF5G_LED(1) */ + PINCTRL_PIN_GROUP("wf5g_led1", mt7981_wf5g_led1), + /* @GPIO(38): MT7531_INT(1) */ + PINCTRL_PIN_GROUP("mt7531_int", mt7981_mt7531_int), + /* @GPIO(14,15,26,17,18,19,20,21,22,23,24,25,34,35): ANT_SEL(1) */ + PINCTRL_PIN_GROUP("ant_sel", mt7981_ant_sel), +}; + +static const struct mtk_io_type_desc mt7981_io_type_desc[] = { + [IO_TYPE_GRP0] = { + .name = "18OD33", + .bias_set = mtk_pinconf_bias_set_pupd_r1_r0, + .drive_set = mtk_pinconf_drive_set_v1, + .input_enable = mtk_pinconf_input_enable_v1, + }, + [IO_TYPE_GRP1] = { + .name = "18A01", + .bias_set = mtk_pinconf_bias_set_pu_pd, + .drive_set = mtk_pinconf_drive_set_v1, + .input_enable = mtk_pinconf_input_enable_v1, + }, +}; + +/* Joint those groups owning the same capability in user point of view which + * allows that people tend to use through the device tree. + */ +static const char *const mt7981_wa_aice_groups[] = { "wa_aice1", "wa_aice2", + "wm_aice1_1", "wa_aice3", "wm_aice1_2", }; +static const char *const mt7981_uart_groups[] = { "wm_uart_0", "uart2_0", + "net_wo0_uart_txd_0", "net_wo0_uart_txd_1", "net_wo0_uart_txd_2", + "uart1_0", "uart1_1", "uart2_0", "wm_aurt_1", "wm_aurt_2", "uart0", }; +static const char *const mt7981_dfd_groups[] = { "dfd", "dfd_ntrst", }; +static const char *const mt7981_wdt_groups[] = { "watchdog", "watchdog1", }; +static const char *const mt7981_pcie_groups[] = { "pcie_pereset", "pcie_clk", + "pcie_wake", }; +static const char *const mt7981_jtag_groups[] = { "jtag", "wm_jtag_0", + "wo0_jtag_0", "wo0_jtag_1", "wm_jtag_1", }; +static const char *const mt7981_led_groups[] = { "gbe_led0", "gbe_led1", + "wf2g_led0", "wf2g_led1", "wf5g_led0", "wf5g_led1", }; +static const char *const mt7981_pta_groups[] = { "pta_ext_0", "pta_ext_1", }; +static const char *const mt7981_pwm_groups[] = { "pwm2", "pwm0_0", "pwm0_1", + "pwm1_0", "pwm1_1", }; +static const char *const mt7981_spi_groups[] = { "spi1_0", "spi0", + "spi0_wp_hold", "spi1_1", "spi2", "spi2_wp_hold", }; +static const char *const mt7981_i2c_groups[] = { "i2c0_0", "i2c0_1", + "u2_phy_i2c", "sgmii1_phy_i2c", "u3_phy_i2c", "sgmii0_phy_i2c", + "i2c0_2", }; +static const char *const mt7981_pcm_groups[] = { "pcm", }; +static const char *const mt7981_udi_groups[] = { "udi", }; +static const char *const mt7981_usb_groups[] = { "drv_vbus", }; +static const char *const mt7981_flash_groups[] = { "emmc_45", "snfi", }; +static const char *const mt7981_ethernet_groups[] = { "smi_mdc_mdio", + "gbe_ext_mdc_mdio", "wf0_mode1", "wf0_mode3", "mt7531_int", }; +static const char *const mt7981_ant_groups[] = { "ant_sel", }; + +static const struct mtk_function_desc mt7981_functions[] = { + {"wa_aice", mt7981_wa_aice_groups, ARRAY_SIZE(mt7981_wa_aice_groups)}, + {"dfd", mt7981_dfd_groups, ARRAY_SIZE(mt7981_dfd_groups)}, + {"jtag", mt7981_jtag_groups, ARRAY_SIZE(mt7981_jtag_groups)}, + {"pta", mt7981_pta_groups, ARRAY_SIZE(mt7981_pta_groups)}, + {"pcm", mt7981_pcm_groups, ARRAY_SIZE(mt7981_pcm_groups)}, + {"udi", mt7981_udi_groups, ARRAY_SIZE(mt7981_udi_groups)}, + {"usb", mt7981_usb_groups, ARRAY_SIZE(mt7981_usb_groups)}, + {"ant", mt7981_ant_groups, ARRAY_SIZE(mt7981_ant_groups)}, + {"eth", mt7981_ethernet_groups, ARRAY_SIZE(mt7981_ethernet_groups)}, + {"i2c", mt7981_i2c_groups, ARRAY_SIZE(mt7981_i2c_groups)}, + {"led", mt7981_led_groups, ARRAY_SIZE(mt7981_led_groups)}, + {"pwm", mt7981_pwm_groups, ARRAY_SIZE(mt7981_pwm_groups)}, + {"spi", mt7981_spi_groups, ARRAY_SIZE(mt7981_spi_groups)}, + {"uart", mt7981_uart_groups, ARRAY_SIZE(mt7981_uart_groups)}, + {"watchdog", mt7981_wdt_groups, ARRAY_SIZE(mt7981_wdt_groups)}, + {"flash", mt7981_flash_groups, ARRAY_SIZE(mt7981_flash_groups)}, + {"pcie", mt7981_pcie_groups, ARRAY_SIZE(mt7981_pcie_groups)}, +}; + +static const char *const mt7981_pinctrl_register_base_names[] = { + "gpio_base", "iocfg_rt_base", "iocfg_rm_base", "iocfg_rb_base", + "iocfg_lb_base", "iocfg_bl_base", "iocfg_tm_base", "iocfg_tl_base", +}; + +static struct mtk_pinctrl_soc mt7981_data = { + .name = "mt7981_pinctrl", + .reg_cal = mt7981_reg_cals, + .pins = mt7981_pins, + .npins = ARRAY_SIZE(mt7981_pins), + .grps = mt7981_groups, + .ngrps = ARRAY_SIZE(mt7981_groups), + .funcs = mt7981_functions, + .nfuncs = ARRAY_SIZE(mt7981_functions), + .io_type = mt7981_io_type_desc, + .ntype = ARRAY_SIZE(mt7981_io_type_desc), + .gpio_mode = 0, + .base_names = mt7981_pinctrl_register_base_names, + .nbase_names = ARRAY_SIZE(mt7981_pinctrl_register_base_names), + .base_calc = 1, +}; + +static int mtk_pinctrl_mt7981_probe(struct udevice *dev) +{ + return mtk_pinctrl_common_probe(dev, &mt7981_data); +} + +static const struct udevice_id mt7981_pctrl_match[] = { + {.compatible = "mediatek,mt7981-pinctrl"}, + { /* sentinel */ } +}; + +U_BOOT_DRIVER(mt7981_pinctrl) = { + .name = "mt7981_pinctrl", + .id = UCLASS_PINCTRL, + .of_match = mt7981_pctrl_match, + .ops = &mtk_pinctrl_ops, + .probe = mtk_pinctrl_mt7981_probe, + .priv_auto = sizeof(struct mtk_pinctrl_priv), +}; From 59acdf8afe4a5c676f8b6ed7af48821980a2bda5 Mon Sep 17 00:00:00 2001 From: Weijie Gao Date: Fri, 9 Sep 2022 19:59:57 +0800 Subject: [PATCH 261/374] pinctrl: mediatek: add pinctrl driver for MT7986 SoC This patch adds pinctrl and gpio support for MT7986 SoC Reviewed-by: Simon Glass Tested-by: Daniel Golle Signed-off-by: Weijie Gao --- drivers/pinctrl/mediatek/Kconfig | 4 + drivers/pinctrl/mediatek/Makefile | 1 + drivers/pinctrl/mediatek/pinctrl-mt7986.c | 775 ++++++++++++++++++++++ 3 files changed, 780 insertions(+) create mode 100644 drivers/pinctrl/mediatek/pinctrl-mt7986.c diff --git a/drivers/pinctrl/mediatek/Kconfig b/drivers/pinctrl/mediatek/Kconfig index aceec9277d..27e8998e59 100644 --- a/drivers/pinctrl/mediatek/Kconfig +++ b/drivers/pinctrl/mediatek/Kconfig @@ -20,6 +20,10 @@ config PINCTRL_MT7981 bool "MT7981 SoC pinctrl driver" select PINCTRL_MTK +config PINCTRL_MT7986 + bool "MT7986 SoC pinctrl driver" + select PINCTRL_MTK + config PINCTRL_MT8512 bool "MT8512 SoC pinctrl driver" select PINCTRL_MTK diff --git a/drivers/pinctrl/mediatek/Makefile b/drivers/pinctrl/mediatek/Makefile index 1879d7ae2a..6e733759f5 100644 --- a/drivers/pinctrl/mediatek/Makefile +++ b/drivers/pinctrl/mediatek/Makefile @@ -7,6 +7,7 @@ obj-$(CONFIG_PINCTRL_MT7622) += pinctrl-mt7622.o obj-$(CONFIG_PINCTRL_MT7623) += pinctrl-mt7623.o obj-$(CONFIG_PINCTRL_MT7629) += pinctrl-mt7629.o obj-$(CONFIG_PINCTRL_MT7981) += pinctrl-mt7981.o +obj-$(CONFIG_PINCTRL_MT7986) += pinctrl-mt7986.o obj-$(CONFIG_PINCTRL_MT8512) += pinctrl-mt8512.o obj-$(CONFIG_PINCTRL_MT8516) += pinctrl-mt8516.o obj-$(CONFIG_PINCTRL_MT8518) += pinctrl-mt8518.o diff --git a/drivers/pinctrl/mediatek/pinctrl-mt7986.c b/drivers/pinctrl/mediatek/pinctrl-mt7986.c new file mode 100644 index 0000000000..449e5adcd9 --- /dev/null +++ b/drivers/pinctrl/mediatek/pinctrl-mt7986.c @@ -0,0 +1,775 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * The MT7986 driver based on Linux generic pinctrl binding. + * + * Copyright (C) 2022 MediaTek Inc. + * Author: Sam Shih + */ + +#include +#include "pinctrl-mtk-common.h" + +#define MT7986_TYPE0_PIN(_number, _name) \ + MTK_TYPED_PIN(_number, _name, DRV_GRP4, IO_TYPE_GRP0) + +#define MT7986_TYPE1_PIN(_number, _name) \ + MTK_TYPED_PIN(_number, _name, DRV_GRP4, IO_TYPE_GRP1) + +#define PIN_FIELD_GPIO(_s_pin, _e_pin, _s_addr, _x_addrs, _s_bit, _x_bits) \ + PIN_FIELD_BASE_CALC(_s_pin, _e_pin, GPIO_BASE, _s_addr, _x_addrs, \ + _s_bit, _x_bits, 32, 0) + +#define PIN_FIELD_BASE(_s_pin, _e_pin, _i_base, _s_addr, _x_addrs, _s_bit, \ + _x_bits) \ + PIN_FIELD_BASE_CALC(_s_pin, _e_pin, _i_base, _s_addr, _x_addrs, _s_bit, \ + _x_bits, 32, 0) + +/** + * enum - Locking variants of the iocfg bases + * + * MT7986 have multiple bases to program pin configuration listed as the below: + * iocfg_rt:0x11c30000, iocfg_rb:0x11c40000, iocfg_lt:0x11e20000, + * iocfg_lb:0x11e30000, iocfg_tr:0x11f00000, iocfg_tl:0x11f10000, + * _i_based could be used to indicate what base the pin should be mapped into. + * + * Each iocfg register base control different group of pads on the SoC + * + * + * chip carrier + * + * A B C D E F G H + * +------------------------+ + * 8 | o o o o o o o o | + * 7 | o o o o o o o o | + * 6 | o o o o o o o o | + * 5 | o o o o o o o o | + * 4 | o o o o o o o o | + * 3 | o o o o o o o o | + * 2 | o o o o o o o o | + * 1 | o o o o o o o o | + * +------------------------+ + * + * inside Chip carrier + * + * A B C D E F G H + * +------------------------+ + * 8 | | + * 7 | TL TR | + * 6 | +---------+ | + * 5 | LT | | RT | + * 4 | | | | + * 3 | LB | | RB | + * 2 | +---------+ | + * 1 | | + * +------------------------+ + * + */ + +enum { + GPIO_BASE, + IOCFG_RT_BASE, + IOCFG_RB_BASE, + IOCFG_LT_BASE, + IOCFG_LB_BASE, + IOCFG_TR_BASE, + IOCFG_TL_BASE, +}; + +static const char *const mt7986_pinctrl_register_base_names[] = { + "gpio", "iocfg_rt", "iocfg_rb", "iocfg_lt", "iocfg_lb", "iocfg_tr", + "iocfg_tl", +}; + +static const struct mtk_pin_field_calc mt7986_pin_mode_range[] = { + PIN_FIELD_GPIO(0, 100, 0x300, 0x10, 0, 4), +}; + +static const struct mtk_pin_field_calc mt7986_pin_dir_range[] = { + PIN_FIELD_GPIO(0, 100, 0x0, 0x10, 0, 1), +}; + +static const struct mtk_pin_field_calc mt7986_pin_di_range[] = { + PIN_FIELD_GPIO(0, 100, 0x200, 0x10, 0, 1), +}; + +static const struct mtk_pin_field_calc mt7986_pin_do_range[] = { + PIN_FIELD_GPIO(0, 100, 0x100, 0x10, 0, 1), +}; + +static const struct mtk_pin_field_calc mt7986_pin_ies_range[] = { + PIN_FIELD_BASE(0, 0, IOCFG_RB_BASE, 0x40, 0x10, 17, 1), + PIN_FIELD_BASE(1, 2, IOCFG_LT_BASE, 0x20, 0x10, 10, 1), + PIN_FIELD_BASE(3, 4, IOCFG_LB_BASE, 0x20, 0x10, 0, 1), + PIN_FIELD_BASE(5, 6, IOCFG_RB_BASE, 0x40, 0x10, 0, 1), + PIN_FIELD_BASE(7, 10, IOCFG_LT_BASE, 0x20, 0x10, 0, 1), + PIN_FIELD_BASE(11, 14, IOCFG_RB_BASE, 0x40, 0x10, 8, 1), + PIN_FIELD_BASE(15, 20, IOCFG_RB_BASE, 0x40, 0x10, 2, 1), + PIN_FIELD_BASE(21, 23, IOCFG_RT_BASE, 0x30, 0x10, 12, 1), + PIN_FIELD_BASE(24, 24, IOCFG_RT_BASE, 0x30, 0x10, 18, 1), + PIN_FIELD_BASE(25, 25, IOCFG_RT_BASE, 0x30, 0x10, 17, 1), + PIN_FIELD_BASE(26, 27, IOCFG_RT_BASE, 0x30, 0x10, 15, 1), + PIN_FIELD_BASE(28, 29, IOCFG_RT_BASE, 0x30, 0x10, 19, 1), + PIN_FIELD_BASE(30, 30, IOCFG_RT_BASE, 0x30, 0x10, 23, 1), + PIN_FIELD_BASE(31, 31, IOCFG_RT_BASE, 0x30, 0x10, 22, 1), + PIN_FIELD_BASE(32, 32, IOCFG_RT_BASE, 0x30, 0x10, 21, 1), + PIN_FIELD_BASE(33, 33, IOCFG_LT_BASE, 0x20, 0x10, 4, 1), + PIN_FIELD_BASE(34, 34, IOCFG_LT_BASE, 0x20, 0x10, 8, 1), + PIN_FIELD_BASE(35, 35, IOCFG_LT_BASE, 0x20, 0x10, 7, 1), + PIN_FIELD_BASE(36, 37, IOCFG_LT_BASE, 0x20, 0x10, 5, 1), + PIN_FIELD_BASE(38, 38, IOCFG_LT_BASE, 0x20, 0x10, 9, 1), + PIN_FIELD_BASE(39, 40, IOCFG_RB_BASE, 0x40, 0x10, 18, 1), + PIN_FIELD_BASE(41, 41, IOCFG_RB_BASE, 0x40, 0x10, 12, 1), + PIN_FIELD_BASE(42, 43, IOCFG_RB_BASE, 0x40, 0x10, 22, 1), + PIN_FIELD_BASE(44, 45, IOCFG_RB_BASE, 0x40, 0x10, 20, 1), + PIN_FIELD_BASE(46, 47, IOCFG_RB_BASE, 0x40, 0x10, 26, 1), + PIN_FIELD_BASE(48, 49, IOCFG_RB_BASE, 0x40, 0x10, 24, 1), + PIN_FIELD_BASE(50, 57, IOCFG_RT_BASE, 0x30, 0x10, 2, 1), + PIN_FIELD_BASE(58, 58, IOCFG_RT_BASE, 0x30, 0x10, 1, 1), + PIN_FIELD_BASE(59, 59, IOCFG_RT_BASE, 0x30, 0x10, 0, 1), + PIN_FIELD_BASE(60, 61, IOCFG_RT_BASE, 0x30, 0x10, 10, 1), + PIN_FIELD_BASE(62, 62, IOCFG_RB_BASE, 0x40, 0x10, 15, 1), + PIN_FIELD_BASE(63, 63, IOCFG_RB_BASE, 0x40, 0x10, 14, 1), + PIN_FIELD_BASE(64, 64, IOCFG_RB_BASE, 0x40, 0x10, 13, 1), + PIN_FIELD_BASE(65, 65, IOCFG_RB_BASE, 0x40, 0x10, 16, 1), + PIN_FIELD_BASE(66, 68, IOCFG_LB_BASE, 0x20, 0x10, 2, 1), + PIN_FIELD_BASE(69, 69, IOCFG_TR_BASE, 0x30, 0x10, 1, 1), + PIN_FIELD_BASE(70, 70, IOCFG_TR_BASE, 0x30, 0x10, 0, 1), + PIN_FIELD_BASE(71, 71, IOCFG_TR_BASE, 0x30, 0x10, 16, 1), + PIN_FIELD_BASE(72, 73, IOCFG_TR_BASE, 0x30, 0x10, 14, 1), + PIN_FIELD_BASE(74, 74, IOCFG_TR_BASE, 0x30, 0x10, 4, 1), + PIN_FIELD_BASE(75, 77, IOCFG_TR_BASE, 0x30, 0x10, 6, 1), + PIN_FIELD_BASE(78, 79, IOCFG_TR_BASE, 0x30, 0x10, 2, 1), + PIN_FIELD_BASE(80, 84, IOCFG_TR_BASE, 0x30, 0x10, 9, 1), + PIN_FIELD_BASE(85, 85, IOCFG_TR_BASE, 0x30, 0x10, 5, 1), + PIN_FIELD_BASE(86, 86, IOCFG_TL_BASE, 0x30, 0x10, 1, 1), + PIN_FIELD_BASE(87, 87, IOCFG_TL_BASE, 0x30, 0x10, 0, 1), + PIN_FIELD_BASE(88, 88, IOCFG_TL_BASE, 0x30, 0x10, 14, 1), + PIN_FIELD_BASE(89, 90, IOCFG_TL_BASE, 0x30, 0x10, 12, 1), + PIN_FIELD_BASE(91, 94, IOCFG_TL_BASE, 0x30, 0x10, 4, 1), + PIN_FIELD_BASE(95, 96, IOCFG_TL_BASE, 0x30, 0x10, 2, 1), + PIN_FIELD_BASE(97, 100, IOCFG_TL_BASE, 0x30, 0x10, 8, 1), +}; + +static const struct mtk_pin_field_calc mt7986_pin_smt_range[] = { + PIN_FIELD_BASE(0, 0, IOCFG_RB_BASE, 0xf0, 0x10, 17, 1), + PIN_FIELD_BASE(1, 2, IOCFG_LT_BASE, 0x90, 0x10, 10, 1), + PIN_FIELD_BASE(3, 4, IOCFG_LB_BASE, 0x90, 0x10, 0, 1), + PIN_FIELD_BASE(5, 6, IOCFG_RB_BASE, 0xf0, 0x10, 0, 1), + PIN_FIELD_BASE(7, 10, IOCFG_LT_BASE, 0x90, 0x10, 0, 1), + PIN_FIELD_BASE(11, 14, IOCFG_RB_BASE, 0xf0, 0x10, 8, 1), + PIN_FIELD_BASE(15, 20, IOCFG_RB_BASE, 0xf0, 0x10, 2, 1), + PIN_FIELD_BASE(21, 23, IOCFG_RT_BASE, 0xc0, 0x10, 12, 1), + PIN_FIELD_BASE(24, 24, IOCFG_RT_BASE, 0xc0, 0x10, 18, 1), + PIN_FIELD_BASE(25, 25, IOCFG_RT_BASE, 0xc0, 0x10, 17, 1), + PIN_FIELD_BASE(26, 27, IOCFG_RT_BASE, 0xc0, 0x10, 15, 1), + PIN_FIELD_BASE(28, 29, IOCFG_RT_BASE, 0xc0, 0x10, 19, 1), + PIN_FIELD_BASE(30, 30, IOCFG_RT_BASE, 0xc0, 0x10, 23, 1), + PIN_FIELD_BASE(31, 31, IOCFG_RT_BASE, 0xc0, 0x10, 22, 1), + PIN_FIELD_BASE(32, 32, IOCFG_RT_BASE, 0xc0, 0x10, 21, 1), + PIN_FIELD_BASE(33, 33, IOCFG_LT_BASE, 0x90, 0x10, 4, 1), + PIN_FIELD_BASE(34, 34, IOCFG_LT_BASE, 0x90, 0x10, 8, 1), + PIN_FIELD_BASE(35, 35, IOCFG_LT_BASE, 0x90, 0x10, 7, 1), + PIN_FIELD_BASE(36, 37, IOCFG_LT_BASE, 0x90, 0x10, 5, 1), + PIN_FIELD_BASE(38, 38, IOCFG_LT_BASE, 0x90, 0x10, 9, 1), + PIN_FIELD_BASE(39, 40, IOCFG_RB_BASE, 0xf0, 0x10, 18, 1), + PIN_FIELD_BASE(41, 41, IOCFG_RB_BASE, 0xf0, 0x10, 12, 1), + PIN_FIELD_BASE(42, 43, IOCFG_RB_BASE, 0xf0, 0x10, 22, 1), + PIN_FIELD_BASE(44, 45, IOCFG_RB_BASE, 0xf0, 0x10, 20, 1), + PIN_FIELD_BASE(46, 47, IOCFG_RB_BASE, 0xf0, 0x10, 26, 1), + PIN_FIELD_BASE(48, 49, IOCFG_RB_BASE, 0xf0, 0x10, 24, 1), + PIN_FIELD_BASE(50, 57, IOCFG_RT_BASE, 0xc0, 0x10, 2, 1), + PIN_FIELD_BASE(58, 58, IOCFG_RT_BASE, 0xc0, 0x10, 1, 1), + PIN_FIELD_BASE(59, 59, IOCFG_RT_BASE, 0xc0, 0x10, 0, 1), + PIN_FIELD_BASE(60, 61, IOCFG_RT_BASE, 0xc0, 0x10, 10, 1), + PIN_FIELD_BASE(62, 62, IOCFG_RB_BASE, 0xf0, 0x10, 15, 1), + PIN_FIELD_BASE(63, 63, IOCFG_RB_BASE, 0xf0, 0x10, 14, 1), + PIN_FIELD_BASE(64, 64, IOCFG_RB_BASE, 0xf0, 0x10, 13, 1), + PIN_FIELD_BASE(65, 65, IOCFG_RB_BASE, 0xf0, 0x10, 16, 1), + PIN_FIELD_BASE(66, 68, IOCFG_LB_BASE, 0x90, 0x10, 2, 1), + PIN_FIELD_BASE(69, 69, IOCFG_TR_BASE, 0x80, 0x10, 1, 1), + PIN_FIELD_BASE(70, 70, IOCFG_TR_BASE, 0x80, 0x10, 0, 1), + PIN_FIELD_BASE(71, 71, IOCFG_TR_BASE, 0x80, 0x10, 16, 1), + PIN_FIELD_BASE(72, 73, IOCFG_TR_BASE, 0x80, 0x10, 14, 1), + PIN_FIELD_BASE(74, 74, IOCFG_TR_BASE, 0x80, 0x10, 4, 1), + PIN_FIELD_BASE(75, 77, IOCFG_TR_BASE, 0x80, 0x10, 6, 1), + PIN_FIELD_BASE(78, 79, IOCFG_TR_BASE, 0x80, 0x10, 2, 1), + PIN_FIELD_BASE(80, 84, IOCFG_TR_BASE, 0x80, 0x10, 9, 1), + PIN_FIELD_BASE(85, 85, IOCFG_TR_BASE, 0x80, 0x10, 5, 1), + PIN_FIELD_BASE(86, 86, IOCFG_TL_BASE, 0x70, 0x10, 1, 1), + PIN_FIELD_BASE(87, 87, IOCFG_TL_BASE, 0x70, 0x10, 0, 1), + PIN_FIELD_BASE(88, 88, IOCFG_TL_BASE, 0x70, 0x10, 14, 1), + PIN_FIELD_BASE(89, 90, IOCFG_TL_BASE, 0x70, 0x10, 12, 1), + PIN_FIELD_BASE(91, 94, IOCFG_TL_BASE, 0x70, 0x10, 4, 1), + PIN_FIELD_BASE(95, 96, IOCFG_TL_BASE, 0x70, 0x10, 2, 1), + PIN_FIELD_BASE(97, 100, IOCFG_TL_BASE, 0x70, 0x10, 8, 1), +}; + +static const struct mtk_pin_field_calc mt7986_pin_pu_range[] = { + PIN_FIELD_BASE(69, 69, IOCFG_TR_BASE, 0x50, 0x10, 1, 1), + PIN_FIELD_BASE(70, 70, IOCFG_TR_BASE, 0x50, 0x10, 0, 1), + PIN_FIELD_BASE(71, 71, IOCFG_TR_BASE, 0x50, 0x10, 16, 1), + PIN_FIELD_BASE(72, 73, IOCFG_TR_BASE, 0x50, 0x10, 14, 1), + PIN_FIELD_BASE(74, 74, IOCFG_TR_BASE, 0x50, 0x10, 4, 1), + PIN_FIELD_BASE(75, 77, IOCFG_TR_BASE, 0x50, 0x10, 6, 1), + PIN_FIELD_BASE(78, 79, IOCFG_TR_BASE, 0x50, 0x10, 2, 1), + PIN_FIELD_BASE(80, 84, IOCFG_TR_BASE, 0x50, 0x10, 9, 1), + PIN_FIELD_BASE(85, 85, IOCFG_TR_BASE, 0x50, 0x10, 5, 1), + PIN_FIELD_BASE(86, 86, IOCFG_TL_BASE, 0x50, 0x10, 1, 1), + PIN_FIELD_BASE(87, 87, IOCFG_TL_BASE, 0x50, 0x10, 0, 1), + PIN_FIELD_BASE(88, 88, IOCFG_TL_BASE, 0x50, 0x10, 14, 1), + PIN_FIELD_BASE(89, 90, IOCFG_TL_BASE, 0x50, 0x10, 12, 1), + PIN_FIELD_BASE(91, 94, IOCFG_TL_BASE, 0x50, 0x10, 4, 1), + PIN_FIELD_BASE(95, 96, IOCFG_TL_BASE, 0x50, 0x10, 2, 1), + PIN_FIELD_BASE(97, 100, IOCFG_TL_BASE, 0x50, 0x10, 8, 1), +}; + +static const struct mtk_pin_field_calc mt7986_pin_pd_range[] = { + PIN_FIELD_BASE(69, 69, IOCFG_TR_BASE, 0x40, 0x10, 1, 1), + PIN_FIELD_BASE(70, 70, IOCFG_TR_BASE, 0x40, 0x10, 0, 1), + PIN_FIELD_BASE(71, 71, IOCFG_TR_BASE, 0x40, 0x10, 16, 1), + PIN_FIELD_BASE(72, 73, IOCFG_TR_BASE, 0x40, 0x10, 14, 1), + PIN_FIELD_BASE(74, 74, IOCFG_TR_BASE, 0x40, 0x10, 4, 1), + PIN_FIELD_BASE(75, 77, IOCFG_TR_BASE, 0x40, 0x10, 6, 1), + PIN_FIELD_BASE(78, 79, IOCFG_TR_BASE, 0x40, 0x10, 2, 1), + PIN_FIELD_BASE(80, 84, IOCFG_TR_BASE, 0x40, 0x10, 9, 1), + PIN_FIELD_BASE(85, 85, IOCFG_TR_BASE, 0x40, 0x10, 5, 1), + PIN_FIELD_BASE(86, 86, IOCFG_TL_BASE, 0x40, 0x10, 1, 1), + PIN_FIELD_BASE(87, 87, IOCFG_TL_BASE, 0x40, 0x10, 0, 1), + PIN_FIELD_BASE(88, 88, IOCFG_TL_BASE, 0x40, 0x10, 14, 1), + PIN_FIELD_BASE(89, 90, IOCFG_TL_BASE, 0x40, 0x10, 12, 1), + PIN_FIELD_BASE(91, 94, IOCFG_TL_BASE, 0x40, 0x10, 4, 1), + PIN_FIELD_BASE(95, 96, IOCFG_TL_BASE, 0x40, 0x10, 2, 1), + PIN_FIELD_BASE(97, 100, IOCFG_TL_BASE, 0x40, 0x10, 8, 1), +}; + +static const struct mtk_pin_field_calc mt7986_pin_drv_range[] = { + PIN_FIELD_BASE(0, 0, IOCFG_RB_BASE, 0x10, 0x10, 21, 3), + PIN_FIELD_BASE(1, 2, IOCFG_LT_BASE, 0x10, 0x10, 0, 3), + PIN_FIELD_BASE(3, 4, IOCFG_LB_BASE, 0x00, 0x10, 0, 1), + PIN_FIELD_BASE(5, 5, IOCFG_RB_BASE, 0x00, 0x10, 0, 3), + PIN_FIELD_BASE(6, 6, IOCFG_RB_BASE, 0x00, 0x10, 21, 3), + PIN_FIELD_BASE(7, 10, IOCFG_LT_BASE, 0x00, 0x10, 0, 3), + PIN_FIELD_BASE(11, 12, IOCFG_RB_BASE, 0x00, 0x10, 24, 3), + PIN_FIELD_BASE(13, 14, IOCFG_RB_BASE, 0x10, 0x10, 0, 3), + PIN_FIELD_BASE(15, 20, IOCFG_RB_BASE, 0x00, 0x10, 3, 3), + PIN_FIELD_BASE(21, 23, IOCFG_RT_BASE, 0x10, 0x10, 6, 3), + PIN_FIELD_BASE(24, 24, IOCFG_RT_BASE, 0x10, 0x10, 24, 3), + PIN_FIELD_BASE(25, 25, IOCFG_RT_BASE, 0x10, 0x10, 21, 3), + PIN_FIELD_BASE(26, 27, IOCFG_RT_BASE, 0x10, 0x10, 15, 3), + PIN_FIELD_BASE(28, 28, IOCFG_RT_BASE, 0x10, 0x10, 27, 3), + PIN_FIELD_BASE(29, 29, IOCFG_RT_BASE, 0x20, 0x10, 0, 3), + PIN_FIELD_BASE(30, 30, IOCFG_RT_BASE, 0x20, 0x10, 9, 3), + PIN_FIELD_BASE(31, 31, IOCFG_RT_BASE, 0x20, 0x10, 6, 3), + PIN_FIELD_BASE(32, 32, IOCFG_RT_BASE, 0x20, 0x10, 3, 3), + PIN_FIELD_BASE(33, 33, IOCFG_LT_BASE, 0x00, 0x10, 12, 3), + PIN_FIELD_BASE(34, 34, IOCFG_LT_BASE, 0x00, 0x10, 24, 3), + PIN_FIELD_BASE(35, 35, IOCFG_LT_BASE, 0x00, 0x10, 21, 3), + PIN_FIELD_BASE(36, 37, IOCFG_LT_BASE, 0x00, 0x10, 15, 3), + PIN_FIELD_BASE(38, 38, IOCFG_LT_BASE, 0x00, 0x10, 27, 3), + PIN_FIELD_BASE(39, 39, IOCFG_RB_BASE, 0x10, 0x10, 27, 3), + PIN_FIELD_BASE(40, 40, IOCFG_RB_BASE, 0x20, 0x10, 0, 3), + PIN_FIELD_BASE(41, 41, IOCFG_RB_BASE, 0x10, 0x10, 6, 3), + PIN_FIELD_BASE(42, 43, IOCFG_RB_BASE, 0x20, 0x10, 9, 3), + PIN_FIELD_BASE(44, 45, IOCFG_RB_BASE, 0x20, 0x10, 3, 3), + PIN_FIELD_BASE(46, 47, IOCFG_RB_BASE, 0x20, 0x10, 21, 3), + PIN_FIELD_BASE(48, 49, IOCFG_RB_BASE, 0x20, 0x10, 15, 3), + PIN_FIELD_BASE(50, 57, IOCFG_RT_BASE, 0x00, 0x10, 6, 3), + PIN_FIELD_BASE(58, 58, IOCFG_RT_BASE, 0x00, 0x10, 3, 3), + PIN_FIELD_BASE(59, 59, IOCFG_RT_BASE, 0x00, 0x10, 0, 3), + PIN_FIELD_BASE(60, 61, IOCFG_RT_BASE, 0x10, 0x10, 0, 3), + PIN_FIELD_BASE(62, 62, IOCFG_RB_BASE, 0x10, 0x10, 15, 3), + PIN_FIELD_BASE(63, 63, IOCFG_RB_BASE, 0x10, 0x10, 12, 3), + PIN_FIELD_BASE(64, 64, IOCFG_RB_BASE, 0x10, 0x10, 9, 3), + PIN_FIELD_BASE(65, 65, IOCFG_RB_BASE, 0x10, 0x10, 18, 3), + PIN_FIELD_BASE(66, 68, IOCFG_LB_BASE, 0x00, 0x10, 2, 3), + PIN_FIELD_BASE(69, 69, IOCFG_TR_BASE, 0x00, 0x10, 3, 3), + PIN_FIELD_BASE(70, 70, IOCFG_TR_BASE, 0x00, 0x10, 0, 3), + PIN_FIELD_BASE(71, 71, IOCFG_TR_BASE, 0x10, 0x10, 18, 3), + PIN_FIELD_BASE(72, 73, IOCFG_TR_BASE, 0x10, 0x10, 12, 3), + PIN_FIELD_BASE(74, 77, IOCFG_TR_BASE, 0x00, 0x10, 15, 3), + PIN_FIELD_BASE(78, 79, IOCFG_TR_BASE, 0x00, 0x10, 6, 3), + PIN_FIELD_BASE(80, 80, IOCFG_TR_BASE, 0x00, 0x10, 27, 3), + PIN_FIELD_BASE(81, 84, IOCFG_TR_BASE, 0x10, 0x10, 0, 3), + PIN_FIELD_BASE(85, 85, IOCFG_TR_BASE, 0x00, 0x10, 12, 3), + PIN_FIELD_BASE(86, 86, IOCFG_TL_BASE, 0x00, 0x10, 3, 3), + PIN_FIELD_BASE(87, 87, IOCFG_TL_BASE, 0x00, 0x10, 0, 3), + PIN_FIELD_BASE(88, 88, IOCFG_TL_BASE, 0x10, 0x10, 12, 3), + PIN_FIELD_BASE(89, 90, IOCFG_TL_BASE, 0x10, 0x10, 6, 3), + PIN_FIELD_BASE(91, 94, IOCFG_TL_BASE, 0x00, 0x10, 12, 3), + PIN_FIELD_BASE(95, 96, IOCFG_TL_BASE, 0x00, 0x10, 6, 3), + PIN_FIELD_BASE(97, 98, IOCFG_TL_BASE, 0x00, 0x10, 24, 3), + PIN_FIELD_BASE(99, 100, IOCFG_TL_BASE, 0x10, 0x10, 2, 3), +}; + +static const struct mtk_pin_field_calc mt7986_pin_pupd_range[] = { + PIN_FIELD_BASE(0, 0, IOCFG_RB_BASE, 0x60, 0x10, 17, 1), + PIN_FIELD_BASE(1, 2, IOCFG_LT_BASE, 0x30, 0x10, 10, 1), + PIN_FIELD_BASE(3, 4, IOCFG_LB_BASE, 0x40, 0x10, 0, 1), + PIN_FIELD_BASE(5, 6, IOCFG_RB_BASE, 0x60, 0x10, 0, 1), + PIN_FIELD_BASE(7, 10, IOCFG_LT_BASE, 0x30, 0x10, 0, 1), + PIN_FIELD_BASE(11, 14, IOCFG_RB_BASE, 0x60, 0x10, 8, 1), + PIN_FIELD_BASE(15, 20, IOCFG_RB_BASE, 0x60, 0x10, 2, 1), + PIN_FIELD_BASE(21, 23, IOCFG_RT_BASE, 0x40, 0x10, 12, 1), + PIN_FIELD_BASE(24, 24, IOCFG_RT_BASE, 0x40, 0x10, 18, 1), + PIN_FIELD_BASE(25, 25, IOCFG_RT_BASE, 0x40, 0x10, 17, 1), + PIN_FIELD_BASE(26, 27, IOCFG_RT_BASE, 0x40, 0x10, 15, 1), + PIN_FIELD_BASE(28, 29, IOCFG_RT_BASE, 0x40, 0x10, 19, 1), + PIN_FIELD_BASE(30, 30, IOCFG_RT_BASE, 0x40, 0x10, 23, 1), + PIN_FIELD_BASE(31, 31, IOCFG_RT_BASE, 0x40, 0x10, 22, 1), + PIN_FIELD_BASE(32, 32, IOCFG_RT_BASE, 0x40, 0x10, 21, 1), + PIN_FIELD_BASE(33, 33, IOCFG_LT_BASE, 0x30, 0x10, 4, 1), + PIN_FIELD_BASE(34, 34, IOCFG_LT_BASE, 0x30, 0x10, 8, 1), + PIN_FIELD_BASE(35, 35, IOCFG_LT_BASE, 0x30, 0x10, 7, 1), + PIN_FIELD_BASE(36, 37, IOCFG_LT_BASE, 0x30, 0x10, 5, 1), + PIN_FIELD_BASE(38, 38, IOCFG_LT_BASE, 0x30, 0x10, 9, 1), + PIN_FIELD_BASE(39, 40, IOCFG_RB_BASE, 0x60, 0x10, 18, 1), + PIN_FIELD_BASE(41, 41, IOCFG_RB_BASE, 0x60, 0x10, 12, 1), + PIN_FIELD_BASE(42, 43, IOCFG_RB_BASE, 0x60, 0x10, 23, 1), + PIN_FIELD_BASE(44, 45, IOCFG_RB_BASE, 0x60, 0x10, 21, 1), + PIN_FIELD_BASE(46, 47, IOCFG_RB_BASE, 0x60, 0x10, 27, 1), + PIN_FIELD_BASE(48, 49, IOCFG_RB_BASE, 0x60, 0x10, 25, 1), + PIN_FIELD_BASE(50, 57, IOCFG_RT_BASE, 0x40, 0x10, 2, 1), + PIN_FIELD_BASE(58, 58, IOCFG_RT_BASE, 0x40, 0x10, 1, 1), + PIN_FIELD_BASE(59, 59, IOCFG_RT_BASE, 0x40, 0x10, 0, 1), + PIN_FIELD_BASE(60, 61, IOCFG_RT_BASE, 0x40, 0x10, 10, 1), + PIN_FIELD_BASE(62, 62, IOCFG_RB_BASE, 0x60, 0x10, 15, 1), + PIN_FIELD_BASE(63, 63, IOCFG_RB_BASE, 0x60, 0x10, 14, 1), + PIN_FIELD_BASE(64, 64, IOCFG_RB_BASE, 0x60, 0x10, 13, 1), + PIN_FIELD_BASE(65, 65, IOCFG_RB_BASE, 0x60, 0x10, 16, 1), + PIN_FIELD_BASE(66, 68, IOCFG_LB_BASE, 0x40, 0x10, 2, 1), +}; + +static const struct mtk_pin_field_calc mt7986_pin_r0_range[] = { + PIN_FIELD_BASE(0, 0, IOCFG_RB_BASE, 0x70, 0x10, 17, 1), + PIN_FIELD_BASE(1, 2, IOCFG_LT_BASE, 0x40, 0x10, 10, 1), + PIN_FIELD_BASE(3, 4, IOCFG_LB_BASE, 0x50, 0x10, 0, 1), + PIN_FIELD_BASE(5, 6, IOCFG_RB_BASE, 0x70, 0x10, 0, 1), + PIN_FIELD_BASE(7, 10, IOCFG_LT_BASE, 0x40, 0x10, 0, 1), + PIN_FIELD_BASE(11, 14, IOCFG_RB_BASE, 0x70, 0x10, 8, 1), + PIN_FIELD_BASE(15, 20, IOCFG_RB_BASE, 0x70, 0x10, 2, 1), + PIN_FIELD_BASE(21, 23, IOCFG_RT_BASE, 0x50, 0x10, 12, 1), + PIN_FIELD_BASE(24, 24, IOCFG_RT_BASE, 0x50, 0x10, 18, 1), + PIN_FIELD_BASE(25, 25, IOCFG_RT_BASE, 0x50, 0x10, 17, 1), + PIN_FIELD_BASE(26, 27, IOCFG_RT_BASE, 0x50, 0x10, 15, 1), + PIN_FIELD_BASE(28, 29, IOCFG_RT_BASE, 0x50, 0x10, 19, 1), + PIN_FIELD_BASE(30, 30, IOCFG_RT_BASE, 0x50, 0x10, 23, 1), + PIN_FIELD_BASE(31, 31, IOCFG_RT_BASE, 0x50, 0x10, 22, 1), + PIN_FIELD_BASE(32, 32, IOCFG_RT_BASE, 0x50, 0x10, 21, 1), + PIN_FIELD_BASE(33, 33, IOCFG_LT_BASE, 0x40, 0x10, 4, 1), + PIN_FIELD_BASE(34, 34, IOCFG_LT_BASE, 0x40, 0x10, 8, 1), + PIN_FIELD_BASE(35, 35, IOCFG_LT_BASE, 0x40, 0x10, 7, 1), + PIN_FIELD_BASE(36, 37, IOCFG_LT_BASE, 0x40, 0x10, 5, 1), + PIN_FIELD_BASE(38, 38, IOCFG_LT_BASE, 0x40, 0x10, 9, 1), + PIN_FIELD_BASE(39, 40, IOCFG_RB_BASE, 0x70, 0x10, 18, 1), + PIN_FIELD_BASE(41, 41, IOCFG_RB_BASE, 0x70, 0x10, 12, 1), + PIN_FIELD_BASE(42, 43, IOCFG_RB_BASE, 0x70, 0x10, 23, 1), + PIN_FIELD_BASE(44, 45, IOCFG_RB_BASE, 0x70, 0x10, 21, 1), + PIN_FIELD_BASE(46, 47, IOCFG_RB_BASE, 0x70, 0x10, 27, 1), + PIN_FIELD_BASE(48, 49, IOCFG_RB_BASE, 0x70, 0x10, 25, 1), + PIN_FIELD_BASE(50, 57, IOCFG_RT_BASE, 0x50, 0x10, 2, 1), + PIN_FIELD_BASE(58, 58, IOCFG_RT_BASE, 0x50, 0x10, 1, 1), + PIN_FIELD_BASE(59, 59, IOCFG_RT_BASE, 0x50, 0x10, 0, 1), + PIN_FIELD_BASE(60, 61, IOCFG_RT_BASE, 0x50, 0x10, 10, 1), + PIN_FIELD_BASE(62, 62, IOCFG_RB_BASE, 0x70, 0x10, 15, 1), + PIN_FIELD_BASE(63, 63, IOCFG_RB_BASE, 0x70, 0x10, 14, 1), + PIN_FIELD_BASE(64, 64, IOCFG_RB_BASE, 0x70, 0x10, 13, 1), + PIN_FIELD_BASE(65, 65, IOCFG_RB_BASE, 0x70, 0x10, 16, 1), + PIN_FIELD_BASE(66, 68, IOCFG_LB_BASE, 0x50, 0x10, 2, 1), +}; + +static const struct mtk_pin_field_calc mt7986_pin_r1_range[] = { + PIN_FIELD_BASE(0, 0, IOCFG_RB_BASE, 0x80, 0x10, 17, 1), + PIN_FIELD_BASE(1, 2, IOCFG_LT_BASE, 0x50, 0x10, 10, 1), + PIN_FIELD_BASE(3, 4, IOCFG_LB_BASE, 0x60, 0x10, 0, 1), + PIN_FIELD_BASE(5, 6, IOCFG_RB_BASE, 0x80, 0x10, 0, 1), + PIN_FIELD_BASE(7, 10, IOCFG_LT_BASE, 0x50, 0x10, 0, 1), + PIN_FIELD_BASE(11, 14, IOCFG_RB_BASE, 0x80, 0x10, 8, 1), + PIN_FIELD_BASE(15, 20, IOCFG_RB_BASE, 0x80, 0x10, 2, 1), + PIN_FIELD_BASE(21, 23, IOCFG_RT_BASE, 0x60, 0x10, 12, 1), + PIN_FIELD_BASE(24, 24, IOCFG_RT_BASE, 0x60, 0x10, 18, 1), + PIN_FIELD_BASE(25, 25, IOCFG_RT_BASE, 0x60, 0x10, 17, 1), + PIN_FIELD_BASE(26, 27, IOCFG_RT_BASE, 0x60, 0x10, 15, 1), + PIN_FIELD_BASE(28, 29, IOCFG_RT_BASE, 0x60, 0x10, 19, 1), + PIN_FIELD_BASE(30, 30, IOCFG_RT_BASE, 0x60, 0x10, 23, 1), + PIN_FIELD_BASE(31, 31, IOCFG_RT_BASE, 0x60, 0x10, 22, 1), + PIN_FIELD_BASE(32, 32, IOCFG_RT_BASE, 0x60, 0x10, 21, 1), + PIN_FIELD_BASE(33, 33, IOCFG_LT_BASE, 0x50, 0x10, 4, 1), + PIN_FIELD_BASE(34, 34, IOCFG_LT_BASE, 0x50, 0x10, 8, 1), + PIN_FIELD_BASE(35, 35, IOCFG_LT_BASE, 0x50, 0x10, 7, 1), + PIN_FIELD_BASE(36, 37, IOCFG_LT_BASE, 0x50, 0x10, 5, 1), + PIN_FIELD_BASE(38, 38, IOCFG_LT_BASE, 0x50, 0x10, 9, 1), + PIN_FIELD_BASE(39, 40, IOCFG_RB_BASE, 0x80, 0x10, 18, 1), + PIN_FIELD_BASE(41, 41, IOCFG_RB_BASE, 0x80, 0x10, 12, 1), + PIN_FIELD_BASE(42, 43, IOCFG_RB_BASE, 0x80, 0x10, 23, 1), + PIN_FIELD_BASE(44, 45, IOCFG_RB_BASE, 0x80, 0x10, 21, 1), + PIN_FIELD_BASE(46, 47, IOCFG_RB_BASE, 0x80, 0x10, 27, 1), + PIN_FIELD_BASE(48, 49, IOCFG_RB_BASE, 0x80, 0x10, 25, 1), + PIN_FIELD_BASE(50, 57, IOCFG_RT_BASE, 0x60, 0x10, 2, 1), + PIN_FIELD_BASE(58, 58, IOCFG_RT_BASE, 0x60, 0x10, 1, 1), + PIN_FIELD_BASE(59, 59, IOCFG_RT_BASE, 0x60, 0x10, 0, 1), + PIN_FIELD_BASE(60, 61, IOCFG_RT_BASE, 0x60, 0x10, 10, 1), + PIN_FIELD_BASE(62, 62, IOCFG_RB_BASE, 0x80, 0x10, 15, 1), + PIN_FIELD_BASE(63, 63, IOCFG_RB_BASE, 0x80, 0x10, 14, 1), + PIN_FIELD_BASE(64, 64, IOCFG_RB_BASE, 0x80, 0x10, 13, 1), + PIN_FIELD_BASE(65, 65, IOCFG_RB_BASE, 0x80, 0x10, 16, 1), + PIN_FIELD_BASE(66, 68, IOCFG_LB_BASE, 0x60, 0x10, 2, 1), +}; + +static const struct mtk_pin_reg_calc mt7986_reg_cals[] = { + [PINCTRL_PIN_REG_MODE] = MTK_RANGE(mt7986_pin_mode_range), + [PINCTRL_PIN_REG_DIR] = MTK_RANGE(mt7986_pin_dir_range), + [PINCTRL_PIN_REG_DI] = MTK_RANGE(mt7986_pin_di_range), + [PINCTRL_PIN_REG_DO] = MTK_RANGE(mt7986_pin_do_range), + [PINCTRL_PIN_REG_SMT] = MTK_RANGE(mt7986_pin_smt_range), + [PINCTRL_PIN_REG_IES] = MTK_RANGE(mt7986_pin_ies_range), + [PINCTRL_PIN_REG_DRV] = MTK_RANGE(mt7986_pin_drv_range), + [PINCTRL_PIN_REG_PU] = MTK_RANGE(mt7986_pin_pu_range), + [PINCTRL_PIN_REG_PD] = MTK_RANGE(mt7986_pin_pd_range), + [PINCTRL_PIN_REG_PUPD] = MTK_RANGE(mt7986_pin_pupd_range), + [PINCTRL_PIN_REG_R0] = MTK_RANGE(mt7986_pin_r0_range), + [PINCTRL_PIN_REG_R1] = MTK_RANGE(mt7986_pin_r1_range), +}; + +static const struct mtk_pin_desc mt7986_pins[] = { + MT7986_TYPE0_PIN(0, "SYS_WATCHDOG"), + MT7986_TYPE0_PIN(1, "WF2G_LED"), + MT7986_TYPE0_PIN(2, "WF5G_LED"), + MT7986_TYPE0_PIN(3, "I2C_SCL"), + MT7986_TYPE0_PIN(4, "I2C_SDA"), + MT7986_TYPE0_PIN(5, "GPIO_0"), + MT7986_TYPE0_PIN(6, "GPIO_1"), + MT7986_TYPE0_PIN(7, "GPIO_2"), + MT7986_TYPE0_PIN(8, "GPIO_3"), + MT7986_TYPE0_PIN(9, "GPIO_4"), + MT7986_TYPE0_PIN(10, "GPIO_5"), + MT7986_TYPE0_PIN(11, "GPIO_6"), + MT7986_TYPE0_PIN(12, "GPIO_7"), + MT7986_TYPE0_PIN(13, "GPIO_8"), + MT7986_TYPE0_PIN(14, "GPIO_9"), + MT7986_TYPE0_PIN(15, "GPIO_10"), + MT7986_TYPE0_PIN(16, "GPIO_11"), + MT7986_TYPE0_PIN(17, "GPIO_12"), + MT7986_TYPE0_PIN(18, "GPIO_13"), + MT7986_TYPE0_PIN(19, "GPIO_14"), + MT7986_TYPE0_PIN(20, "GPIO_15"), + MT7986_TYPE0_PIN(21, "PWM0"), + MT7986_TYPE0_PIN(22, "PWM1"), + MT7986_TYPE0_PIN(23, "SPI0_CLK"), + MT7986_TYPE0_PIN(24, "SPI0_MOSI"), + MT7986_TYPE0_PIN(25, "SPI0_MISO"), + MT7986_TYPE0_PIN(26, "SPI0_CS"), + MT7986_TYPE0_PIN(27, "SPI0_HOLD"), + MT7986_TYPE0_PIN(28, "SPI0_WP"), + MT7986_TYPE0_PIN(29, "SPI1_CLK"), + MT7986_TYPE0_PIN(30, "SPI1_MOSI"), + MT7986_TYPE0_PIN(31, "SPI1_MISO"), + MT7986_TYPE0_PIN(32, "SPI1_CS"), + MT7986_TYPE0_PIN(33, "SPI2_CLK"), + MT7986_TYPE0_PIN(34, "SPI2_MOSI"), + MT7986_TYPE0_PIN(35, "SPI2_MISO"), + MT7986_TYPE0_PIN(36, "SPI2_CS"), + MT7986_TYPE0_PIN(37, "SPI2_HOLD"), + MT7986_TYPE0_PIN(38, "SPI2_WP"), + MT7986_TYPE0_PIN(39, "UART0_RXD"), + MT7986_TYPE0_PIN(40, "UART0_TXD"), + MT7986_TYPE0_PIN(41, "PCIE_PERESET_N"), + MT7986_TYPE0_PIN(42, "UART1_RXD"), + MT7986_TYPE0_PIN(43, "UART1_TXD"), + MT7986_TYPE0_PIN(44, "UART1_CTS"), + MT7986_TYPE0_PIN(45, "UART1_RTS"), + MT7986_TYPE0_PIN(46, "UART2_RXD"), + MT7986_TYPE0_PIN(47, "UART2_TXD"), + MT7986_TYPE0_PIN(48, "UART2_CTS"), + MT7986_TYPE0_PIN(49, "UART2_RTS"), + MT7986_TYPE0_PIN(50, "EMMC_DATA_0"), + MT7986_TYPE0_PIN(51, "EMMC_DATA_1"), + MT7986_TYPE0_PIN(52, "EMMC_DATA_2"), + MT7986_TYPE0_PIN(53, "EMMC_DATA_3"), + MT7986_TYPE0_PIN(54, "EMMC_DATA_4"), + MT7986_TYPE0_PIN(55, "EMMC_DATA_5"), + MT7986_TYPE0_PIN(56, "EMMC_DATA_6"), + MT7986_TYPE0_PIN(57, "EMMC_DATA_7"), + MT7986_TYPE0_PIN(58, "EMMC_CMD"), + MT7986_TYPE0_PIN(59, "EMMC_CK"), + MT7986_TYPE0_PIN(60, "EMMC_DSL"), + MT7986_TYPE0_PIN(61, "EMMC_RSTB"), + MT7986_TYPE0_PIN(62, "PCM_DTX"), + MT7986_TYPE0_PIN(63, "PCM_DRX"), + MT7986_TYPE0_PIN(64, "PCM_CLK"), + MT7986_TYPE0_PIN(65, "PCM_FS"), + MT7986_TYPE0_PIN(66, "MT7531_INT"), + MT7986_TYPE0_PIN(67, "SMI_MDC"), + MT7986_TYPE0_PIN(68, "SMI_MDIO"), + MT7986_TYPE1_PIN(69, "WF0_DIG_RESETB"), + MT7986_TYPE1_PIN(70, "WF0_CBA_RESETB"), + MT7986_TYPE1_PIN(71, "WF0_XO_REQ"), + MT7986_TYPE1_PIN(72, "WF0_TOP_CLK"), + MT7986_TYPE1_PIN(73, "WF0_TOP_DATA"), + MT7986_TYPE1_PIN(74, "WF0_HB1"), + MT7986_TYPE1_PIN(75, "WF0_HB2"), + MT7986_TYPE1_PIN(76, "WF0_HB3"), + MT7986_TYPE1_PIN(77, "WF0_HB4"), + MT7986_TYPE1_PIN(78, "WF0_HB0"), + MT7986_TYPE1_PIN(79, "WF0_HB0_B"), + MT7986_TYPE1_PIN(80, "WF0_HB5"), + MT7986_TYPE1_PIN(81, "WF0_HB6"), + MT7986_TYPE1_PIN(82, "WF0_HB7"), + MT7986_TYPE1_PIN(83, "WF0_HB8"), + MT7986_TYPE1_PIN(84, "WF0_HB9"), + MT7986_TYPE1_PIN(85, "WF0_HB10"), + MT7986_TYPE1_PIN(86, "WF1_DIG_RESETB"), + MT7986_TYPE1_PIN(87, "WF1_CBA_RESETB"), + MT7986_TYPE1_PIN(88, "WF1_XO_REQ"), + MT7986_TYPE1_PIN(89, "WF1_TOP_CLK"), + MT7986_TYPE1_PIN(90, "WF1_TOP_DATA"), + MT7986_TYPE1_PIN(91, "WF1_HB1"), + MT7986_TYPE1_PIN(92, "WF1_HB2"), + MT7986_TYPE1_PIN(93, "WF1_HB3"), + MT7986_TYPE1_PIN(94, "WF1_HB4"), + MT7986_TYPE1_PIN(95, "WF1_HB0"), + MT7986_TYPE1_PIN(96, "WF1_HB0_B"), + MT7986_TYPE1_PIN(97, "WF1_HB5"), + MT7986_TYPE1_PIN(98, "WF1_HB6"), + MT7986_TYPE1_PIN(99, "WF1_HB7"), + MT7986_TYPE1_PIN(100, "WF1_HB8"), +}; + +static const struct mtk_io_type_desc mt7986_io_type_desc[] = { + [IO_TYPE_GRP0] = { + .name = "18OD33", + .bias_set = mtk_pinconf_bias_set_pupd_r1_r0, + .drive_set = mtk_pinconf_drive_set_v1, + .input_enable = mtk_pinconf_input_enable_v1, + }, + [IO_TYPE_GRP1] = { + .name = "18A01", + .bias_set = mtk_pinconf_bias_set_pu_pd, + .drive_set = mtk_pinconf_drive_set_v1, + .input_enable = mtk_pinconf_input_enable_v1, + }, +}; + +/* List all groups consisting of these pins dedicated to the enablement of + * certain hardware block and the corresponding mode for all of the pins. + * The hardware probably has multiple combinations of these pinouts. + */ + +static int mt7986_watchdog_pins[] = { 0, }; +static int mt7986_watchdog_funcs[] = { 1, }; + +static int mt7986_wifi_led_pins[] = { 1, 2, }; +static int mt7986_wifi_led_funcs[] = { 1, 1, }; + +static int mt7986_i2c_pins[] = { 3, 4, }; +static int mt7986_i2c_funcs[] = { 1, 1, }; + +static int mt7986_uart1_0_pins[] = { 7, 8, 9, 10, }; +static int mt7986_uart1_0_funcs[] = { 3, 3, 3, 3, }; + +static int mt7986_spi1_0_pins[] = { 11, 12, 13, 14, }; +static int mt7986_spi1_0_funcs[] = { 3, 3, 3, 3, }; + +static int mt7986_pwm1_1_pins[] = { 20, }; +static int mt7986_pwm1_1_funcs[] = { 2, }; + +static int mt7986_pwm0_pins[] = { 21, }; +static int mt7986_pwm0_funcs[] = { 1, }; + +static int mt7986_pwm1_0_pins[] = { 22, }; +static int mt7986_pwm1_0_funcs[] = { 1, }; + +static int mt7986_emmc_45_pins[] = { + 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, }; +static int mt7986_emmc_45_funcs[] = { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, }; + +static int mt7986_snfi_pins[] = { 23, 24, 25, 26, 27, 28, }; +static int mt7986_snfi_funcs[] = { 1, 1, 1, 1, 1, 1, }; + +static int mt7986_spi1_1_pins[] = { 23, 24, 25, 26, }; +static int mt7986_spi1_1_funcs[] = { 3, 3, 3, 3, }; + +static int mt7986_uart1_1_pins[] = { 23, 24, 25, 26, }; +static int mt7986_uart1_1_funcs[] = { 4, 4, 4, 4, }; + +static int mt7986_spi1_2_pins[] = { 29, 30, 31, 32, }; +static int mt7986_spi1_2_funcs[] = { 1, 1, 1, 1, }; + +static int mt7986_uart1_2_pins[] = { 29, 30, 31, 32, }; +static int mt7986_uart1_2_funcs[] = { 3, 3, 3, 3, }; + +static int mt7986_uart2_0_pins[] = { 29, 30, 31, 32, }; +static int mt7986_uart2_0_funcs[] = { 4, 4, 4, 4, }; + +static int mt7986_spi0_pins[] = { 33, 34, 35, 36, }; +static int mt7986_spi0_funcs[] = { 1, 1, 1, 1, }; + +static int mt7986_spi0_wp_hold_pins[] = { 37, 38, }; +static int mt7986_spi0_wp_hold_funcs[] = { 1, 1, }; + +static int mt7986_uart2_1_pins[] = { 33, 34, 35, 36, }; +static int mt7986_uart2_1_funcs[] = { 3, 3, 3, 3, }; + +static int mt7986_uart1_3_rx_tx_pins[] = { 35, 36, }; +static int mt7986_uart1_3_rx_tx_funcs[] = { 2, 2, }; + +static int mt7986_uart1_3_cts_rts_pins[] = { 37, 38, }; +static int mt7986_uart1_3_cts_rts_funcs[] = { 2, 2, }; + +static int mt7986_spi1_3_pins[] = { 33, 34, 35, 36, }; +static int mt7986_spi1_3_funcs[] = { 4, 4, 4, 4, }; + +static int mt7986_uart0_pins[] = { 39, 40, }; +static int mt7986_uart0_funcs[] = { 1, 1, }; + +static int mt7986_pcie_reset_pins[] = { 41, }; +static int mt7986_pcie_reset_funcs[] = { 1, }; + +static int mt7986_uart1_pins[] = { 42, 43, 44, 45, }; +static int mt7986_uart1_funcs[] = { 1, 1, 1, 1, }; + +static int mt7986_uart2_pins[] = { 46, 47, 48, 49, }; +static int mt7986_uart2_funcs[] = { 1, 1, 1, 1, }; + +static int mt7986_emmc_51_pins[] = { + 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, }; +static int mt7986_emmc_51_funcs[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, }; + +static int mt7986_pcm_pins[] = { 62, 63, 64, 65, }; +static int mt7986_pcm_funcs[] = { 1, 1, 1, 1, }; + +static int mt7986_i2s_pins[] = { 62, 63, 64, 65, }; +static int mt7986_i2s_funcs[] = { 1, 1, 1, 1, }; + +static int mt7986_switch_int_pins[] = { 66, }; +static int mt7986_switch_int_funcs[] = { 1, }; + +static int mt7986_mdc_mdio_pins[] = { 67, 68, }; +static int mt7986_mdc_mdio_funcs[] = { 1, 1, }; + +static int mt7986_wf_2g_pins[] = {74, 75, 76, 77, 78, 79, 80, 81, 82, 83, }; +static int mt7986_wf_2g_funcs[] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, }; + +static int mt7986_wf_5g_pins[] = {91, 92, 93, 94, 95, 96, 97, 98, 99, 100, }; +static int mt7986_wf_5g_funcs[] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, }; + +static int mt7986_wf_dbdc_pins[] = { + 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, }; +static int mt7986_wf_dbdc_funcs[] = { + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, }; + +static int mt7986_pcie_clk_pins[] = { 9, }; +static int mt7986_pcie_clk_funcs[] = { 1, }; + +static int mt7986_pcie_wake_pins[] = { 10, }; +static int mt7986_pcie_wake_funcs[] = { 1, }; + +static const struct mtk_group_desc mt7986_groups[] = { + PINCTRL_PIN_GROUP("watchdog", mt7986_watchdog), + PINCTRL_PIN_GROUP("wifi_led", mt7986_wifi_led), + PINCTRL_PIN_GROUP("i2c", mt7986_i2c), + PINCTRL_PIN_GROUP("uart1_0", mt7986_uart1_0), + PINCTRL_PIN_GROUP("pcie_clk", mt7986_pcie_clk), + PINCTRL_PIN_GROUP("pcie_wake", mt7986_pcie_wake), + PINCTRL_PIN_GROUP("spi1_0", mt7986_spi1_0), + PINCTRL_PIN_GROUP("pwm1_1", mt7986_pwm1_1), + PINCTRL_PIN_GROUP("pwm0", mt7986_pwm0), + PINCTRL_PIN_GROUP("pwm1_0", mt7986_pwm1_0), + PINCTRL_PIN_GROUP("emmc_45", mt7986_emmc_45), + PINCTRL_PIN_GROUP("snfi", mt7986_snfi), + PINCTRL_PIN_GROUP("spi1_1", mt7986_spi1_1), + PINCTRL_PIN_GROUP("uart1_1", mt7986_uart1_1), + PINCTRL_PIN_GROUP("spi1_2", mt7986_spi1_2), + PINCTRL_PIN_GROUP("uart1_2", mt7986_uart1_2), + PINCTRL_PIN_GROUP("uart2_0", mt7986_uart2_0), + PINCTRL_PIN_GROUP("spi0", mt7986_spi0), + PINCTRL_PIN_GROUP("spi0_wp_hold", mt7986_spi0_wp_hold), + PINCTRL_PIN_GROUP("uart2_1", mt7986_uart2_1), + PINCTRL_PIN_GROUP("uart1_3_rx_tx", mt7986_uart1_3_rx_tx), + PINCTRL_PIN_GROUP("uart1_3_cts_rts", mt7986_uart1_3_cts_rts), + PINCTRL_PIN_GROUP("spi1_3", mt7986_spi1_3), + PINCTRL_PIN_GROUP("uart0", mt7986_uart0), + PINCTRL_PIN_GROUP("switch_int", mt7986_switch_int), + PINCTRL_PIN_GROUP("mdc_mdio", mt7986_mdc_mdio), + PINCTRL_PIN_GROUP("pcie_pereset", mt7986_pcie_reset), + PINCTRL_PIN_GROUP("uart1", mt7986_uart1), + PINCTRL_PIN_GROUP("uart2", mt7986_uart2), + PINCTRL_PIN_GROUP("emmc_51", mt7986_emmc_51), + PINCTRL_PIN_GROUP("pcm", mt7986_pcm), + PINCTRL_PIN_GROUP("i2s", mt7986_i2s), + PINCTRL_PIN_GROUP("wf_2g", mt7986_wf_2g), + PINCTRL_PIN_GROUP("wf_5g", mt7986_wf_5g), + PINCTRL_PIN_GROUP("wf_dbdc", mt7986_wf_dbdc), +}; + +/* Joint those groups owning the same capability in user point of view which + * allows that people tend to use through the device tree. + */ + +static const char *const mt7986_audio_groups[] = { "pcm", "i2s" }; +static const char *const mt7986_emmc_groups[] = { "emmc_45", "emmc_51", }; +static const char *const mt7986_ethernet_groups[] = { "switch_int", + "mdc_mdio", }; +static const char *const mt7986_i2c_groups[] = { "i2c", }; +static const char *const mt7986_led_groups[] = { "wifi_led", }; +static const char *const mt7986_flash_groups[] = { "snfi", }; +static const char *const mt7986_pcie_groups[] = { "pcie_clk", "pcie_wake", + "pcie_pereset" }; +static const char *const mt7986_pwm_groups[] = { "pwm0", "pwm1_0", "pwm1_1", }; +static const char *const mt7986_spi_groups[] = { "spi0", "spi0_wp_hold", + "spi1_0", "spi1_1", "spi1_2", "spi1_3", }; +static const char *const mt7986_uart_groups[] = { "uart1_0", "uart1_1", + "uart1_2", "uart1_3_rx_tx", "uart1_3_cts_rts", "uart2_0", "uart2_1", + "uart0", "uart1", "uart2", }; +static const char *const mt7986_wdt_groups[] = { "watchdog", }; +static const char *const mt7986_wf_groups[] = { "wf_2g", "wf_5g", "wf_dbdc", }; + +static const struct mtk_function_desc mt7986_functions[] = { + {"audio", mt7986_audio_groups, ARRAY_SIZE(mt7986_audio_groups)}, + {"emmc", mt7986_emmc_groups, ARRAY_SIZE(mt7986_emmc_groups)}, + {"eth", mt7986_ethernet_groups, ARRAY_SIZE(mt7986_ethernet_groups)}, + {"i2c", mt7986_i2c_groups, ARRAY_SIZE(mt7986_i2c_groups)}, + {"led", mt7986_led_groups, ARRAY_SIZE(mt7986_led_groups)}, + {"flash", mt7986_flash_groups, ARRAY_SIZE(mt7986_flash_groups)}, + {"pcie", mt7986_pcie_groups, ARRAY_SIZE(mt7986_pcie_groups)}, + {"pwm", mt7986_pwm_groups, ARRAY_SIZE(mt7986_pwm_groups)}, + {"spi", mt7986_spi_groups, ARRAY_SIZE(mt7986_spi_groups)}, + {"uart", mt7986_uart_groups, ARRAY_SIZE(mt7986_uart_groups)}, + {"watchdog", mt7986_wdt_groups, ARRAY_SIZE(mt7986_wdt_groups)}, + {"wifi", mt7986_wf_groups, ARRAY_SIZE(mt7986_wf_groups)}, +}; + +static struct mtk_pinctrl_soc mt7986_data = { + .name = "mt7986_pinctrl", + .reg_cal = mt7986_reg_cals, + .pins = mt7986_pins, + .npins = ARRAY_SIZE(mt7986_pins), + .grps = mt7986_groups, + .ngrps = ARRAY_SIZE(mt7986_groups), + .funcs = mt7986_functions, + .nfuncs = ARRAY_SIZE(mt7986_functions), + .io_type = mt7986_io_type_desc, + .ntype = ARRAY_SIZE(mt7986_io_type_desc), + .gpio_mode = 0, + .base_names = mt7986_pinctrl_register_base_names, + .nbase_names = ARRAY_SIZE(mt7986_pinctrl_register_base_names), + .base_calc = 1, +}; + +static int mtk_pinctrl_mt7986_probe(struct udevice *dev) +{ + return mtk_pinctrl_common_probe(dev, &mt7986_data); +} + +static const struct udevice_id mt7986_pctrl_match[] = { + {.compatible = "mediatek,mt7986-pinctrl"}, + { /* sentinel */ } +}; + +U_BOOT_DRIVER(mt7986_pinctrl) = { + .name = "mt7986_pinctrl", + .id = UCLASS_PINCTRL, + .of_match = mt7986_pctrl_match, + .ops = &mtk_pinctrl_ops, + .probe = mtk_pinctrl_mt7986_probe, + .priv_auto = sizeof(struct mtk_pinctrl_priv), +}; From 7fb33e9aea514cfd873d8005954108a482e9e693 Mon Sep 17 00:00:00 2001 From: Weijie Gao Date: Fri, 9 Sep 2022 19:59:59 +0800 Subject: [PATCH 262/374] clk: mediatek: add CLK_BYPASS_XTAL flag to allow bypassing searching clock parent of xtal clock The mtk clock framework in u-boot uses array index for searching clock parent (kernel uses strings for search), so we need to specify a special clock with ID=0 for CLK_XTAL in u-boot. In the mt7622/mt7629 clock tree, the clocks with ID=0 never call mtk_topckgen_get_mux_rate, adn return xtal clock directly. This what we expected. However for newer chips, they may have some clocks with ID=0 not representing the xtal clock and still needs mtk_topckgen_get_mux_rate be called. Current logic will make entire clock driver not working. This patch adds a flag to indicate that whether a clock driver needs clocks with ID=0 to call mtk_topckgen_get_mux_rate. Reviewed-by: Simon Glass Tested-by: Daniel Golle Signed-off-by: Weijie Gao --- drivers/clk/mediatek/clk-mtk.c | 4 +++- drivers/clk/mediatek/clk-mtk.h | 6 ++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/clk/mediatek/clk-mtk.c b/drivers/clk/mediatek/clk-mtk.c index d43b8a0648..7d145f4975 100644 --- a/drivers/clk/mediatek/clk-mtk.c +++ b/drivers/clk/mediatek/clk-mtk.c @@ -319,7 +319,9 @@ static ulong mtk_topckgen_get_mux_rate(struct clk *clk, u32 off) index &= mux->mux_mask << mux->mux_shift; index = index >> mux->mux_shift; - if (mux->parent[index]) + if (mux->parent[index] > 0 || + (mux->parent[index] == CLK_XTAL && + priv->tree->flags & CLK_BYPASS_XTAL)) return mtk_clk_find_parent_rate(clk, mux->parent[index], NULL); diff --git a/drivers/clk/mediatek/clk-mtk.h b/drivers/clk/mediatek/clk-mtk.h index 95a23d14a8..e0c5550c80 100644 --- a/drivers/clk/mediatek/clk-mtk.h +++ b/drivers/clk/mediatek/clk-mtk.h @@ -11,6 +11,11 @@ #define CLK_XTAL 0 #define MHZ (1000 * 1000) +/* flags in struct mtk_clk_tree */ + +/* clk id == 0 doesn't mean it's xtal clk */ +#define CLK_BYPASS_XTAL BIT(0) + #define HAVE_RST_BAR BIT(0) #define CLK_DOMAIN_SCPSYS BIT(0) #define CLK_MUX_SETCLR_UPD BIT(1) @@ -197,6 +202,7 @@ struct mtk_clk_tree { const struct mtk_fixed_clk *fclks; const struct mtk_fixed_factor *fdivs; const struct mtk_composite *muxes; + u32 flags; }; struct mtk_clk_priv { From 98a8bbb9ea6de81407f338926e10cc1f743b9ba6 Mon Sep 17 00:00:00 2001 From: Weijie Gao Date: Fri, 9 Sep 2022 20:00:01 +0800 Subject: [PATCH 263/374] clk: mediatek: add support to configure clock driver parent This patch adds support for a clock node to configure its parent clock where possible. Reviewed-by: Simon Glass Tested-by: Daniel Golle Signed-off-by: Weijie Gao --- drivers/clk/mediatek/clk-mtk.c | 79 ++++++++++++++++++++-------------- drivers/clk/mediatek/clk-mtk.h | 2 + 2 files changed, 48 insertions(+), 33 deletions(-) diff --git a/drivers/clk/mediatek/clk-mtk.c b/drivers/clk/mediatek/clk-mtk.c index 7d145f4975..a537ff259f 100644 --- a/drivers/clk/mediatek/clk-mtk.c +++ b/drivers/clk/mediatek/clk-mtk.c @@ -42,20 +42,14 @@ * the accurate frequency. */ static ulong mtk_clk_find_parent_rate(struct clk *clk, int id, - const struct driver *drv) + struct udevice *pdev) { struct clk parent = { .id = id, }; - if (drv) { - struct udevice *dev; - - if (uclass_get_device_by_driver(UCLASS_CLK, drv, &dev)) - return -ENODEV; - - parent.dev = dev; - } else { + if (pdev) + parent.dev = pdev; + else parent.dev = clk->dev; - } return clk_get_rate(&parent); } @@ -296,7 +290,7 @@ static ulong mtk_topckgen_get_factor_rate(struct clk *clk, u32 off) switch (fdiv->flags & CLK_PARENT_MASK) { case CLK_PARENT_APMIXED: rate = mtk_clk_find_parent_rate(clk, fdiv->parent, - DM_DRIVER_GET(mtk_clk_apmixedsys)); + priv->parent); break; case CLK_PARENT_TOPCKGEN: rate = mtk_clk_find_parent_rate(clk, fdiv->parent, NULL); @@ -321,9 +315,18 @@ static ulong mtk_topckgen_get_mux_rate(struct clk *clk, u32 off) if (mux->parent[index] > 0 || (mux->parent[index] == CLK_XTAL && - priv->tree->flags & CLK_BYPASS_XTAL)) - return mtk_clk_find_parent_rate(clk, mux->parent[index], - NULL); + priv->tree->flags & CLK_BYPASS_XTAL)) { + switch (mux->flags & CLK_PARENT_MASK) { + case CLK_PARENT_APMIXED: + return mtk_clk_find_parent_rate(clk, mux->parent[index], + priv->parent); + break; + default: + return mtk_clk_find_parent_rate(clk, mux->parent[index], + NULL); + break; + } + } return priv->tree->xtal_rate; } @@ -342,7 +345,7 @@ static ulong mtk_topckgen_get_rate(struct clk *clk) priv->tree->muxes_offs); } -static int mtk_topckgen_enable(struct clk *clk) +static int mtk_clk_mux_enable(struct clk *clk) { struct mtk_clk_priv *priv = dev_get_priv(clk->dev); const struct mtk_composite *mux; @@ -375,7 +378,7 @@ static int mtk_topckgen_enable(struct clk *clk) return 0; } -static int mtk_topckgen_disable(struct clk *clk) +static int mtk_clk_mux_disable(struct clk *clk) { struct mtk_clk_priv *priv = dev_get_priv(clk->dev); const struct mtk_composite *mux; @@ -401,7 +404,7 @@ static int mtk_topckgen_disable(struct clk *clk) return 0; } -static int mtk_topckgen_set_parent(struct clk *clk, struct clk *parent) +static int mtk_common_clk_set_parent(struct clk *clk, struct clk *parent) { struct mtk_clk_priv *priv = dev_get_priv(clk->dev); @@ -473,19 +476,7 @@ static ulong mtk_clk_gate_get_rate(struct clk *clk) struct mtk_cg_priv *priv = dev_get_priv(clk->dev); const struct mtk_gate *gate = &priv->gates[clk->id]; - switch (gate->flags & CLK_PARENT_MASK) { - case CLK_PARENT_APMIXED: - return mtk_clk_find_parent_rate(clk, gate->parent, - DM_DRIVER_GET(mtk_clk_apmixedsys)); - break; - case CLK_PARENT_TOPCKGEN: - return mtk_clk_find_parent_rate(clk, gate->parent, - DM_DRIVER_GET(mtk_clk_topckgen)); - break; - - default: - return priv->tree->xtal_rate; - } + return mtk_clk_find_parent_rate(clk, gate->parent, priv->parent); } const struct clk_ops mtk_clk_apmixedsys_ops = { @@ -496,10 +487,10 @@ const struct clk_ops mtk_clk_apmixedsys_ops = { }; const struct clk_ops mtk_clk_topckgen_ops = { - .enable = mtk_topckgen_enable, - .disable = mtk_topckgen_disable, + .enable = mtk_clk_mux_enable, + .disable = mtk_clk_mux_disable, .get_rate = mtk_topckgen_get_rate, - .set_parent = mtk_topckgen_set_parent, + .set_parent = mtk_common_clk_set_parent, }; const struct clk_ops mtk_clk_gate_ops = { @@ -512,11 +503,22 @@ int mtk_common_clk_init(struct udevice *dev, const struct mtk_clk_tree *tree) { struct mtk_clk_priv *priv = dev_get_priv(dev); + struct udevice *parent; + int ret; priv->base = dev_read_addr_ptr(dev); if (!priv->base) return -ENOENT; + ret = uclass_get_device_by_phandle(UCLASS_CLK, dev, "clock-parent", &parent); + if (ret || !parent) { + ret = uclass_get_device_by_driver(UCLASS_CLK, + DM_DRIVER_GET(mtk_clk_apmixedsys), &parent); + if (ret || !parent) + return -ENOENT; + } + + priv->parent = parent; priv->tree = tree; return 0; @@ -527,11 +529,22 @@ int mtk_common_clk_gate_init(struct udevice *dev, const struct mtk_gate *gates) { struct mtk_cg_priv *priv = dev_get_priv(dev); + struct udevice *parent; + int ret; priv->base = dev_read_addr_ptr(dev); if (!priv->base) return -ENOENT; + ret = uclass_get_device_by_phandle(UCLASS_CLK, dev, "clock-parent", &parent); + if (ret || !parent) { + ret = uclass_get_device_by_driver(UCLASS_CLK, + DM_DRIVER_GET(mtk_clk_topckgen), &parent); + if (ret || !parent) + return -ENOENT; + } + + priv->parent = parent; priv->tree = tree; priv->gates = gates; diff --git a/drivers/clk/mediatek/clk-mtk.h b/drivers/clk/mediatek/clk-mtk.h index e0c5550c80..41854879c6 100644 --- a/drivers/clk/mediatek/clk-mtk.h +++ b/drivers/clk/mediatek/clk-mtk.h @@ -206,11 +206,13 @@ struct mtk_clk_tree { }; struct mtk_clk_priv { + struct udevice *parent; void __iomem *base; const struct mtk_clk_tree *tree; }; struct mtk_cg_priv { + struct udevice *parent; void __iomem *base; const struct mtk_clk_tree *tree; const struct mtk_gate *gates; From 570b0840b19a34ca6e42923c2cba0c8c64677e15 Mon Sep 17 00:00:00 2001 From: Weijie Gao Date: Fri, 9 Sep 2022 20:00:04 +0800 Subject: [PATCH 264/374] clk: mediatek: add infrasys clock mux support This patch adds infrasys clock mux support for mediatek clock drivers. Reviewed-by: Simon Glass Tested-by: Daniel Golle Signed-off-by: Weijie Gao --- drivers/clk/mediatek/clk-mtk.c | 71 ++++++++++++++++++++++++++++++++++ drivers/clk/mediatek/clk-mtk.h | 4 +- 2 files changed, 74 insertions(+), 1 deletion(-) diff --git a/drivers/clk/mediatek/clk-mtk.c b/drivers/clk/mediatek/clk-mtk.c index a537ff259f..207a4c6b11 100644 --- a/drivers/clk/mediatek/clk-mtk.c +++ b/drivers/clk/mediatek/clk-mtk.c @@ -303,6 +303,24 @@ static ulong mtk_topckgen_get_factor_rate(struct clk *clk, u32 off) return mtk_factor_recalc_rate(fdiv, rate); } +static ulong mtk_infrasys_get_factor_rate(struct clk *clk, u32 off) +{ + struct mtk_clk_priv *priv = dev_get_priv(clk->dev); + const struct mtk_fixed_factor *fdiv = &priv->tree->fdivs[off]; + ulong rate; + + switch (fdiv->flags & CLK_PARENT_MASK) { + case CLK_PARENT_TOPCKGEN: + rate = mtk_clk_find_parent_rate(clk, fdiv->parent, + priv->parent); + break; + default: + rate = mtk_clk_find_parent_rate(clk, fdiv->parent, NULL); + } + + return mtk_factor_recalc_rate(fdiv, rate); +} + static ulong mtk_topckgen_get_mux_rate(struct clk *clk, u32 off) { struct mtk_clk_priv *priv = dev_get_priv(clk->dev); @@ -331,6 +349,33 @@ static ulong mtk_topckgen_get_mux_rate(struct clk *clk, u32 off) return priv->tree->xtal_rate; } +static ulong mtk_infrasys_get_mux_rate(struct clk *clk, u32 off) +{ + struct mtk_clk_priv *priv = dev_get_priv(clk->dev); + const struct mtk_composite *mux = &priv->tree->muxes[off]; + u32 index; + + index = readl(priv->base + mux->mux_reg); + index &= mux->mux_mask << mux->mux_shift; + index = index >> mux->mux_shift; + + if (mux->parent[index] > 0 || + (mux->parent[index] == CLK_XTAL && + priv->tree->flags & CLK_BYPASS_XTAL)) { + switch (mux->flags & CLK_PARENT_MASK) { + case CLK_PARENT_TOPCKGEN: + return mtk_clk_find_parent_rate(clk, mux->parent[index], + priv->parent); + break; + default: + return mtk_clk_find_parent_rate(clk, mux->parent[index], + NULL); + break; + } + } + return 0; +} + static ulong mtk_topckgen_get_rate(struct clk *clk) { struct mtk_clk_priv *priv = dev_get_priv(clk->dev); @@ -345,6 +390,25 @@ static ulong mtk_topckgen_get_rate(struct clk *clk) priv->tree->muxes_offs); } +static ulong mtk_infrasys_get_rate(struct clk *clk) +{ + struct mtk_clk_priv *priv = dev_get_priv(clk->dev); + + ulong rate; + + if (clk->id < priv->tree->fdivs_offs) { + rate = priv->tree->fclks[clk->id].rate; + } else if (clk->id < priv->tree->muxes_offs) { + rate = mtk_infrasys_get_factor_rate(clk, clk->id - + priv->tree->fdivs_offs); + } else { + rate = mtk_infrasys_get_mux_rate(clk, clk->id - + priv->tree->muxes_offs); + } + + return rate; +} + static int mtk_clk_mux_enable(struct clk *clk) { struct mtk_clk_priv *priv = dev_get_priv(clk->dev); @@ -493,6 +557,13 @@ const struct clk_ops mtk_clk_topckgen_ops = { .set_parent = mtk_common_clk_set_parent, }; +const struct clk_ops mtk_clk_infrasys_ops = { + .enable = mtk_clk_mux_enable, + .disable = mtk_clk_mux_disable, + .get_rate = mtk_infrasys_get_rate, + .set_parent = mtk_common_clk_set_parent, +}; + const struct clk_ops mtk_clk_gate_ops = { .enable = mtk_clk_gate_enable, .disable = mtk_clk_gate_disable, diff --git a/drivers/clk/mediatek/clk-mtk.h b/drivers/clk/mediatek/clk-mtk.h index 41854879c6..e7c61ae483 100644 --- a/drivers/clk/mediatek/clk-mtk.h +++ b/drivers/clk/mediatek/clk-mtk.h @@ -28,7 +28,8 @@ #define CLK_PARENT_APMIXED BIT(4) #define CLK_PARENT_TOPCKGEN BIT(5) -#define CLK_PARENT_MASK GENMASK(5, 4) +#define CLK_PARENT_INFRASYS BIT(6) +#define CLK_PARENT_MASK GENMASK(6, 4) #define ETHSYS_HIFSYS_RST_CTRL_OFS 0x34 @@ -220,6 +221,7 @@ struct mtk_cg_priv { extern const struct clk_ops mtk_clk_apmixedsys_ops; extern const struct clk_ops mtk_clk_topckgen_ops; +extern const struct clk_ops mtk_clk_infrasys_ops; extern const struct clk_ops mtk_clk_gate_ops; int mtk_common_clk_init(struct udevice *dev, From ad832b915a7f07e60eb58ed99bc36da5c3de8d42 Mon Sep 17 00:00:00 2001 From: Weijie Gao Date: Fri, 9 Sep 2022 20:00:07 +0800 Subject: [PATCH 265/374] clk: mediatek: add CLK_XTAL support for clock driver This adds the CLK_XTAL macro/flag to allow modeling clocks which are directly connected to the xtal clock. Reviewed-by: Simon Glass Tested-by: Daniel Golle Signed-off-by: Weijie Gao --- drivers/clk/mediatek/clk-mtk.c | 4 ++++ drivers/clk/mediatek/clk-mtk.h | 3 ++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/clk/mediatek/clk-mtk.c b/drivers/clk/mediatek/clk-mtk.c index 207a4c6b11..4303300d3a 100644 --- a/drivers/clk/mediatek/clk-mtk.c +++ b/drivers/clk/mediatek/clk-mtk.c @@ -296,6 +296,7 @@ static ulong mtk_topckgen_get_factor_rate(struct clk *clk, u32 off) rate = mtk_clk_find_parent_rate(clk, fdiv->parent, NULL); break; + case CLK_PARENT_XTAL: default: rate = priv->tree->xtal_rate; } @@ -314,6 +315,9 @@ static ulong mtk_infrasys_get_factor_rate(struct clk *clk, u32 off) rate = mtk_clk_find_parent_rate(clk, fdiv->parent, priv->parent); break; + case CLK_PARENT_XTAL: + rate = priv->tree->xtal_rate; + break; default: rate = mtk_clk_find_parent_rate(clk, fdiv->parent, NULL); } diff --git a/drivers/clk/mediatek/clk-mtk.h b/drivers/clk/mediatek/clk-mtk.h index e7c61ae483..48ce16484e 100644 --- a/drivers/clk/mediatek/clk-mtk.h +++ b/drivers/clk/mediatek/clk-mtk.h @@ -29,7 +29,8 @@ #define CLK_PARENT_APMIXED BIT(4) #define CLK_PARENT_TOPCKGEN BIT(5) #define CLK_PARENT_INFRASYS BIT(6) -#define CLK_PARENT_MASK GENMASK(6, 4) +#define CLK_PARENT_XTAL BIT(7) +#define CLK_PARENT_MASK GENMASK(7, 4) #define ETHSYS_HIFSYS_RST_CTRL_OFS 0x34 From 37d5a9a29dce9fba04e77e89373d3404c7fdb2ec Mon Sep 17 00:00:00 2001 From: Weijie Gao Date: Fri, 9 Sep 2022 20:00:09 +0800 Subject: [PATCH 266/374] clk: mediatek: add clock driver support for MediaTek MT7986 SoC This patch adds clock driver support for MediaTek MT7986 SoC Reviewed-by: Sean Anderson Reviewed-by: Simon Glass Tested-by: Daniel Golle Signed-off-by: Weijie Gao --- drivers/clk/mediatek/Makefile | 1 + drivers/clk/mediatek/clk-mt7986.c | 672 +++++++++++++++++++++++++ include/dt-bindings/clock/mt7986-clk.h | 249 +++++++++ 3 files changed, 922 insertions(+) create mode 100644 drivers/clk/mediatek/clk-mt7986.c create mode 100644 include/dt-bindings/clock/mt7986-clk.h diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile index 522e724221..1aa38215bf 100644 --- a/drivers/clk/mediatek/Makefile +++ b/drivers/clk/mediatek/Makefile @@ -7,6 +7,7 @@ obj-$(CONFIG_MT8512) += clk-mt8512.o obj-$(CONFIG_TARGET_MT7623) += clk-mt7623.o obj-$(CONFIG_TARGET_MT7622) += clk-mt7622.o obj-$(CONFIG_TARGET_MT7629) += clk-mt7629.o +obj-$(CONFIG_TARGET_MT7986) += clk-mt7986.o obj-$(CONFIG_TARGET_MT8183) += clk-mt8183.o obj-$(CONFIG_TARGET_MT8516) += clk-mt8516.o obj-$(CONFIG_TARGET_MT8518) += clk-mt8518.o diff --git a/drivers/clk/mediatek/clk-mt7986.c b/drivers/clk/mediatek/clk-mt7986.c new file mode 100644 index 0000000000..b3fa63fc0a --- /dev/null +++ b/drivers/clk/mediatek/clk-mt7986.c @@ -0,0 +1,672 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * MediaTek clock driver for MT7986 SoC + * + * Copyright (C) 2022 MediaTek Inc. + * Author: Sam Shih + */ + +#include +#include +#include +#include +#include +#include + +#include "clk-mtk.h" + +#define MT7986_CLK_PDN 0x250 +#define MT7986_CLK_PDN_EN_WRITE BIT(31) + +#define PLL_FACTOR(_id, _name, _parent, _mult, _div) \ + FACTOR(_id, _parent, _mult, _div, CLK_PARENT_APMIXED) + +#define TOP_FACTOR(_id, _name, _parent, _mult, _div) \ + FACTOR(_id, _parent, _mult, _div, CLK_PARENT_TOPCKGEN) + +#define INFRA_FACTOR(_id, _name, _parent, _mult, _div) \ + FACTOR(_id, _parent, _mult, _div, CLK_PARENT_INFRASYS) + +/* FIXED PLLS */ +static const struct mtk_fixed_clk fixed_pll_clks[] = { + FIXED_CLK(CK_APMIXED_ARMPLL, CLK_XTAL, 2000000000), + FIXED_CLK(CK_APMIXED_NET2PLL, CLK_XTAL, 800000000), + FIXED_CLK(CK_APMIXED_MMPLL, CLK_XTAL, 1440000000), + FIXED_CLK(CK_APMIXED_SGMPLL, CLK_XTAL, 325000000), + FIXED_CLK(CK_APMIXED_WEDMCUPLL, CLK_XTAL, 760000000), + FIXED_CLK(CK_APMIXED_NET1PLL, CLK_XTAL, 2500000000), + FIXED_CLK(CK_APMIXED_MPLL, CLK_XTAL, 416000000), + FIXED_CLK(CK_APMIXED_APLL2, CLK_XTAL, 196608000), +}; + +/* TOPCKGEN FIXED CLK */ +static const struct mtk_fixed_clk top_fixed_clks[] = { + FIXED_CLK(CK_TOP_CB_CKSQ_40M, CLK_XTAL, 40000000), +}; + +/* TOPCKGEN FIXED DIV */ +static const struct mtk_fixed_factor top_fixed_divs[] = { + PLL_FACTOR(CK_TOP_CB_M_416M, "cb_m_416m", CK_APMIXED_MPLL, 1, 1), + PLL_FACTOR(CK_TOP_CB_M_D2, "cb_m_d2", CK_APMIXED_MPLL, 1, 2), + PLL_FACTOR(CK_TOP_CB_M_D4, "cb_m_d4", CK_APMIXED_MPLL, 1, 4), + PLL_FACTOR(CK_TOP_CB_M_D8, "cb_m_d8", CK_APMIXED_MPLL, 1, 8), + PLL_FACTOR(CK_TOP_M_D8_D2, "m_d8_d2", CK_APMIXED_MPLL, 1, 16), + PLL_FACTOR(CK_TOP_M_D3_D2, "m_d3_d2", CK_APMIXED_MPLL, 1, 2), + PLL_FACTOR(CK_TOP_CB_MM_D2, "cb_mm_d2", CK_APMIXED_MMPLL, 1, 2), + PLL_FACTOR(CK_TOP_CB_MM_D4, "cb_mm_d4", CK_APMIXED_MMPLL, 1, 4), + PLL_FACTOR(CK_TOP_CB_MM_D8, "cb_mm_d8", CK_APMIXED_MMPLL, 1, 8), + PLL_FACTOR(CK_TOP_MM_D8_D2, "mm_d8_d2", CK_APMIXED_MMPLL, 1, 16), + PLL_FACTOR(CK_TOP_MM_D3_D8, "mm_d3_d8", CK_APMIXED_MMPLL, 1, 8), + PLL_FACTOR(CK_TOP_CB_U2_PHYD_CK, "cb_u2_phyd", CK_APMIXED_MMPLL, 1, 30), + PLL_FACTOR(CK_TOP_CB_APLL2_196M, "cb_apll2_196m", CK_APMIXED_APLL2, 1, + 1), + PLL_FACTOR(CK_TOP_APLL2_D4, "apll2_d4", CK_APMIXED_APLL2, 1, 4), + PLL_FACTOR(CK_TOP_CB_NET1_D4, "cb_net1_d4", CK_APMIXED_NET1PLL, 1, 4), + PLL_FACTOR(CK_TOP_CB_NET1_D5, "cb_net1_d5", CK_APMIXED_NET1PLL, 1, 5), + PLL_FACTOR(CK_TOP_NET1_D5_D2, "net1_d5_d2", CK_APMIXED_NET1PLL, 1, 10), + PLL_FACTOR(CK_TOP_NET1_D5_D4, "net1_d5_d4", CK_APMIXED_NET1PLL, 1, 20), + PLL_FACTOR(CK_TOP_NET1_D8_D2, "net1_d8_d2", CK_APMIXED_NET1PLL, 1, 16), + PLL_FACTOR(CK_TOP_NET1_D8_D4, "net1_d8_d4", CK_APMIXED_NET1PLL, 1, 32), + PLL_FACTOR(CK_TOP_CB_NET2_800M, "cb_net2_800m", CK_APMIXED_NET2PLL, 1, + 1), + PLL_FACTOR(CK_TOP_CB_NET2_D4, "cb_net2_d4", CK_APMIXED_NET2PLL, 1, 4), + PLL_FACTOR(CK_TOP_NET2_D4_D2, "net2_d4_d2", CK_APMIXED_NET2PLL, 1, 8), + PLL_FACTOR(CK_TOP_NET2_D3_D2, "net2_d3_d2", CK_APMIXED_NET2PLL, 1, 2), + PLL_FACTOR(CK_TOP_CB_WEDMCU_760M, "cb_wedmcu_760m", + CK_APMIXED_WEDMCUPLL, 1, 1), + PLL_FACTOR(CK_TOP_WEDMCU_D5_D2, "wedmcu_d5_d2", CK_APMIXED_WEDMCUPLL, 1, + 10), + PLL_FACTOR(CK_TOP_CB_SGM_325M, "cb_sgm_325m", CK_APMIXED_SGMPLL, 1, 1), + TOP_FACTOR(CK_TOP_CB_CKSQ_40M_D2, "cb_cksq_40m_d2", CK_TOP_CB_CKSQ_40M, + 1, 2), + TOP_FACTOR(CK_TOP_CB_RTC_32K, "cb_rtc_32k", CK_TOP_CB_CKSQ_40M, 1, + 1250), + TOP_FACTOR(CK_TOP_CB_RTC_32P7K, "cb_rtc_32p7k", CK_TOP_CB_CKSQ_40M, 1, + 1220), + TOP_FACTOR(CK_TOP_NFI1X, "nfi1x", CK_TOP_NFI1X_SEL, 1, 1), + TOP_FACTOR(CK_TOP_USB_EQ_RX250M, "usb_eq_rx250m", CK_TOP_CB_CKSQ_40M, 1, + 1), + TOP_FACTOR(CK_TOP_USB_TX250M, "usb_tx250m", CK_TOP_CB_CKSQ_40M, 1, 1), + TOP_FACTOR(CK_TOP_USB_LN0_CK, "usb_ln0", CK_TOP_CB_CKSQ_40M, 1, 1), + TOP_FACTOR(CK_TOP_USB_CDR_CK, "usb_cdr", CK_TOP_CB_CKSQ_40M, 1, 1), + TOP_FACTOR(CK_TOP_SPINFI_BCK, "spinfi_bck", CK_TOP_SPINFI_SEL, 1, 1), + TOP_FACTOR(CK_TOP_I2C_BCK, "i2c_bck", CK_TOP_I2C_SEL, 1, 1), + TOP_FACTOR(CK_TOP_PEXTP_TL, "pextp_tl", CK_TOP_PEXTP_TL_SEL, 1, 1), + TOP_FACTOR(CK_TOP_EMMC_250M, "emmc_250m", CK_TOP_EMMC_250M_SEL, 1, 1), + TOP_FACTOR(CK_TOP_EMMC_416M, "emmc_416m", CK_TOP_EMMC_416M_SEL, 1, 1), + TOP_FACTOR(CK_TOP_F_26M_ADC_CK, "f_26m_adc", CK_TOP_F_26M_ADC_SEL, 1, + 1), + TOP_FACTOR(CK_TOP_SYSAXI, "sysaxi", CK_TOP_SYSAXI_SEL, 1, 1), + TOP_FACTOR(CK_TOP_NETSYS_WED_MCU, "netsys_wed_mcu", + CK_TOP_NETSYS_MCU_SEL, 1, 1), + TOP_FACTOR(CK_TOP_NETSYS_2X, "netsys_2x", CK_TOP_NETSYS_2X_SEL, 1, 1), + TOP_FACTOR(CK_TOP_SGM_325M, "sgm_325m", CK_TOP_SGM_325M_SEL, 1, 1), + TOP_FACTOR(CK_TOP_A1SYS, "a1sys", CK_TOP_A1SYS_SEL, 1, 1), + TOP_FACTOR(CK_TOP_EIP_B, "eip_b", CK_TOP_EIP_B_SEL, 1, 1), + TOP_FACTOR(CK_TOP_F26M, "csw_f26m", CK_TOP_F26M_SEL, 1, 1), + TOP_FACTOR(CK_TOP_AUD_L, "aud_l", CK_TOP_AUD_L_SEL, 1, 1), + TOP_FACTOR(CK_TOP_A_TUNER, "a_tuner", CK_TOP_A_TUNER_SEL, 2, 1), + TOP_FACTOR(CK_TOP_U2U3_REF, "u2u3_ref", CK_TOP_U2U3_SEL, 1, 1), + TOP_FACTOR(CK_TOP_U2U3_SYS, "u2u3_sys", CK_TOP_U2U3_SYS_SEL, 1, 1), + TOP_FACTOR(CK_TOP_U2U3_XHCI, "u2u3_xhci", CK_TOP_U2U3_XHCI_SEL, 1, 1), + TOP_FACTOR(CK_TOP_AP2CNN_HOST, "ap2cnn_host", CK_TOP_AP2CNN_HOST_SEL, 1, + 1), +}; + +/* TOPCKGEN MUX PARENTS */ +static const int nfi1x_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_CB_MM_D8, + CK_TOP_NET1_D8_D2, CK_TOP_NET2_D3_D2, + CK_TOP_CB_M_D4, CK_TOP_MM_D8_D2, + CK_TOP_WEDMCU_D5_D2, CK_TOP_CB_M_D8 }; + +static const int spinfi_parents[] = { + CK_TOP_CB_CKSQ_40M_D2, CK_TOP_CB_CKSQ_40M, CK_TOP_NET1_D5_D4, + CK_TOP_CB_M_D4, CK_TOP_MM_D8_D2, CK_TOP_WEDMCU_D5_D2, + CK_TOP_MM_D3_D8, CK_TOP_CB_M_D8 +}; + +static const int spi_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_CB_M_D2, + CK_TOP_CB_MM_D8, CK_TOP_NET1_D8_D2, + CK_TOP_NET2_D3_D2, CK_TOP_NET1_D5_D4, + CK_TOP_CB_M_D4, CK_TOP_WEDMCU_D5_D2 }; + +static const int uart_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_CB_M_D8, + CK_TOP_M_D8_D2 }; + +static const int pwm_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_NET1_D8_D2, + CK_TOP_NET1_D5_D4, CK_TOP_CB_M_D4 }; + +static const int i2c_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_NET1_D5_D4, + CK_TOP_CB_M_D4, CK_TOP_NET1_D8_D4 }; + +static const int pextp_tl_ck_parents[] = { CK_TOP_CB_CKSQ_40M, + CK_TOP_NET1_D5_D4, CK_TOP_NET2_D4_D2, + CK_TOP_CB_RTC_32K }; + +static const int emmc_250m_parents[] = { CK_TOP_CB_CKSQ_40M, + CK_TOP_NET1_D5_D2 }; + +static const int emmc_416m_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_CB_M_416M }; + +static const int f_26m_adc_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_M_D8_D2 }; + +static const int dramc_md32_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_CB_M_D2 }; + +static const int sysaxi_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_NET1_D8_D2, + CK_TOP_CB_NET2_D4 }; + +static const int sysapb_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_M_D3_D2, + CK_TOP_NET2_D4_D2 }; + +static const int arm_db_main_parents[] = { CK_TOP_CB_CKSQ_40M, + CK_TOP_NET2_D3_D2 }; + +static const int arm_db_jtsel_parents[] = { -1, CK_TOP_CB_CKSQ_40M }; + +static const int netsys_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_CB_MM_D4 }; + +static const int netsys_500m_parents[] = { CK_TOP_CB_CKSQ_40M, + CK_TOP_CB_NET1_D5 }; + +static const int netsys_mcu_parents[] = { CK_TOP_CB_CKSQ_40M, + CK_TOP_CB_WEDMCU_760M, + CK_TOP_CB_MM_D2, CK_TOP_CB_NET1_D4, + CK_TOP_CB_NET1_D5 }; + +static const int netsys_2x_parents[] = { CK_TOP_CB_CKSQ_40M, + CK_TOP_CB_NET2_800M, + CK_TOP_CB_WEDMCU_760M, + CK_TOP_CB_MM_D2 }; + +static const int sgm_325m_parents[] = { CK_TOP_CB_CKSQ_40M, + CK_TOP_CB_SGM_325M }; + +static const int sgm_reg_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_NET1_D8_D4 }; + +static const int a1sys_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_APLL2_D4 }; + +static const int conn_mcusys_parents[] = { CK_TOP_CB_CKSQ_40M, + CK_TOP_CB_MM_D2 }; + +static const int eip_b_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_CB_NET2_800M }; + +static const int aud_l_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_CB_APLL2_196M, + CK_TOP_M_D8_D2 }; + +static const int a_tuner_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_APLL2_D4, + CK_TOP_M_D8_D2 }; + +static const int u2u3_sys_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_NET1_D5_D4 }; + +static const int da_u2_refsel_parents[] = { CK_TOP_CB_CKSQ_40M, + CK_TOP_CB_U2_PHYD_CK }; + +#define TOP_MUX(_id, _name, _parents, _mux_ofs, _mux_set_ofs, _mux_clr_ofs, \ + _shift, _width, _gate, _upd_ofs, _upd) \ + { \ + .id = _id, .mux_reg = _mux_ofs, .mux_set_reg = _mux_set_ofs, \ + .mux_clr_reg = _mux_clr_ofs, .upd_reg = _upd_ofs, \ + .upd_shift = _upd, .mux_shift = _shift, \ + .mux_mask = BIT(_width) - 1, .gate_reg = _mux_ofs, \ + .gate_shift = _gate, .parent = _parents, \ + .num_parents = ARRAY_SIZE(_parents), \ + .flags = CLK_MUX_SETCLR_UPD, \ + } + +/* TOPCKGEN MUX_GATE */ +static const struct mtk_composite top_muxes[] = { + /* CLK_CFG_0 */ + TOP_MUX(CK_TOP_NFI1X_SEL, "nfi1x_sel", nfi1x_parents, 0x000, 0x004, + 0x008, 0, 3, 7, 0x1C0, 0), + TOP_MUX(CK_TOP_SPINFI_SEL, "spinfi_sel", spinfi_parents, 0x000, 0x004, + 0x008, 8, 3, 15, 0x1C0, 1), + TOP_MUX(CK_TOP_SPI_SEL, "spi_sel", spi_parents, 0x000, 0x004, 0x008, 16, + 3, 23, 0x1C0, 2), + TOP_MUX(CK_TOP_SPIM_MST_SEL, "spim_mst_sel", spi_parents, 0x000, 0x004, + 0x008, 24, 3, 31, 0x1C0, 3), + /* CLK_CFG_1 */ + TOP_MUX(CK_TOP_UART_SEL, "uart_sel", uart_parents, 0x010, 0x014, 0x018, + 0, 2, 7, 0x1C0, 4), + TOP_MUX(CK_TOP_PWM_SEL, "pwm_sel", pwm_parents, 0x010, 0x014, 0x018, 8, + 2, 15, 0x1C0, 5), + TOP_MUX(CK_TOP_I2C_SEL, "i2c_sel", i2c_parents, 0x010, 0x014, 0x018, 16, + 2, 23, 0x1C0, 6), + TOP_MUX(CK_TOP_PEXTP_TL_SEL, "pextp_tl_ck_sel", pextp_tl_ck_parents, + 0x010, 0x014, 0x018, 24, 2, 31, 0x1C0, 7), + /* CLK_CFG_2 */ + TOP_MUX(CK_TOP_EMMC_250M_SEL, "emmc_250m_sel", emmc_250m_parents, 0x020, + 0x024, 0x028, 0, 1, 7, 0x1C0, 8), + TOP_MUX(CK_TOP_EMMC_416M_SEL, "emmc_416m_sel", emmc_416m_parents, 0x020, + 0x024, 0x028, 8, 1, 15, 0x1C0, 9), + TOP_MUX(CK_TOP_F_26M_ADC_SEL, "f_26m_adc_sel", f_26m_adc_parents, 0x020, + 0x024, 0x028, 16, 1, 23, 0x1C0, 10), + TOP_MUX(CK_TOP_DRAMC_SEL, "dramc_sel", f_26m_adc_parents, 0x020, 0x024, + 0x028, 24, 1, 31, 0x1C0, 11), + /* CLK_CFG_3 */ + TOP_MUX(CK_TOP_DRAMC_MD32_SEL, "dramc_md32_sel", dramc_md32_parents, + 0x030, 0x034, 0x038, 0, 1, 7, 0x1C0, 12), + TOP_MUX(CK_TOP_SYSAXI_SEL, "sysaxi_sel", sysaxi_parents, 0x030, 0x034, + 0x038, 8, 2, 15, 0x1C0, 13), + TOP_MUX(CK_TOP_SYSAPB_SEL, "sysapb_sel", sysapb_parents, 0x030, 0x034, + 0x038, 16, 2, 23, 0x1C0, 14), + TOP_MUX(CK_TOP_ARM_DB_MAIN_SEL, "arm_db_main_sel", arm_db_main_parents, + 0x030, 0x034, 0x038, 24, 1, 31, 0x1C0, 15), + /* CLK_CFG_4 */ + TOP_MUX(CK_TOP_ARM_DB_JTSEL, "arm_db_jtsel", arm_db_jtsel_parents, + 0x040, 0x044, 0x048, 0, 1, 7, 0x1C0, 16), + TOP_MUX(CK_TOP_NETSYS_SEL, "netsys_sel", netsys_parents, 0x040, 0x044, + 0x048, 8, 1, 15, 0x1C0, 17), + TOP_MUX(CK_TOP_NETSYS_500M_SEL, "netsys_500m_sel", netsys_500m_parents, + 0x040, 0x044, 0x048, 16, 1, 23, 0x1C0, 18), + TOP_MUX(CK_TOP_NETSYS_MCU_SEL, "netsys_mcu_sel", netsys_mcu_parents, + 0x040, 0x044, 0x048, 24, 3, 31, 0x1C0, 19), + /* CLK_CFG_5 */ + TOP_MUX(CK_TOP_NETSYS_2X_SEL, "netsys_2x_sel", netsys_2x_parents, 0x050, + 0x054, 0x058, 0, 2, 7, 0x1C0, 20), + TOP_MUX(CK_TOP_SGM_325M_SEL, "sgm_325m_sel", sgm_325m_parents, 0x050, + 0x054, 0x058, 8, 1, 15, 0x1C0, 21), + TOP_MUX(CK_TOP_SGM_REG_SEL, "sgm_reg_sel", sgm_reg_parents, 0x050, + 0x054, 0x058, 16, 1, 23, 0x1C0, 22), + TOP_MUX(CK_TOP_A1SYS_SEL, "a1sys_sel", a1sys_parents, 0x050, 0x054, + 0x058, 24, 1, 31, 0x1C0, 23), + /* CLK_CFG_6 */ + TOP_MUX(CK_TOP_CONN_MCUSYS_SEL, "conn_mcusys_sel", conn_mcusys_parents, + 0x060, 0x064, 0x068, 0, 1, 7, 0x1C0, 24), + TOP_MUX(CK_TOP_EIP_B_SEL, "eip_b_sel", eip_b_parents, 0x060, 0x064, + 0x068, 8, 1, 15, 0x1C0, 25), + TOP_MUX(CK_TOP_PCIE_PHY_SEL, "pcie_phy_sel", f_26m_adc_parents, 0x060, + 0x064, 0x068, 16, 1, 23, 0x1C0, 26), + TOP_MUX(CK_TOP_USB3_PHY_SEL, "usb3_phy_sel", f_26m_adc_parents, 0x060, + 0x064, 0x068, 24, 1, 31, 0x1C0, 27), + /* CLK_CFG_7 */ + TOP_MUX(CK_TOP_F26M_SEL, "csw_f26m_sel", f_26m_adc_parents, 0x070, + 0x074, 0x078, 0, 1, 7, 0x1C0, 28), + TOP_MUX(CK_TOP_AUD_L_SEL, "aud_l_sel", aud_l_parents, 0x070, 0x074, + 0x078, 8, 2, 15, 0x1C0, 29), + TOP_MUX(CK_TOP_A_TUNER_SEL, "a_tuner_sel", a_tuner_parents, 0x070, + 0x074, 0x078, 16, 2, 23, 0x1C0, 30), + TOP_MUX(CK_TOP_U2U3_SEL, "u2u3_sel", f_26m_adc_parents, 0x070, 0x074, + 0x078, 24, 1, 31, 0x1C4, 0), + /* CLK_CFG_8 */ + TOP_MUX(CK_TOP_U2U3_SYS_SEL, "u2u3_sys_sel", u2u3_sys_parents, 0x080, + 0x084, 0x088, 0, 1, 7, 0x1C4, 1), + TOP_MUX(CK_TOP_U2U3_XHCI_SEL, "u2u3_xhci_sel", u2u3_sys_parents, 0x080, + 0x084, 0x088, 8, 1, 15, 0x1C4, 2), + TOP_MUX(CK_TOP_DA_U2_REFSEL, "da_u2_refsel", da_u2_refsel_parents, + 0x080, 0x084, 0x088, 16, 1, 23, 0x1C4, 3), + TOP_MUX(CK_TOP_DA_U2_CK_1P_SEL, "da_u2_ck_1p_sel", da_u2_refsel_parents, + 0x080, 0x084, 0x088, 24, 1, 31, 0x1C4, 4), + /* CLK_CFG_9 */ + TOP_MUX(CK_TOP_AP2CNN_HOST_SEL, "ap2cnn_host_sel", sgm_reg_parents, + 0x090, 0x094, 0x098, 0, 1, 7, 0x1C4, 5), +}; + +/* INFRA FIXED DIV */ +static const struct mtk_fixed_factor infra_fixed_divs[] = { + TOP_FACTOR(CK_INFRA_CK_F26M, "infra_ck_f26m", CK_TOP_F26M_SEL, 1, 1), + TOP_FACTOR(CK_INFRA_UART, "infra_uart", CK_TOP_UART_SEL, 1, 1), + TOP_FACTOR(CK_INFRA_ISPI0, "infra_ispi0", CK_TOP_SPI_SEL, 1, 1), + TOP_FACTOR(CK_INFRA_I2C, "infra_i2c", CK_TOP_I2C_SEL, 1, 1), + TOP_FACTOR(CK_INFRA_ISPI1, "infra_ispi1", CK_TOP_SPINFI_SEL, 1, 1), + TOP_FACTOR(CK_INFRA_PWM, "infra_pwm", CK_TOP_PWM_SEL, 1, 1), + TOP_FACTOR(CK_INFRA_66M_MCK, "infra_66m_mck", CK_TOP_SYSAXI_SEL, 1, 2), + TOP_FACTOR(CK_INFRA_CK_F32K, "infra_ck_f32k", CK_TOP_CB_RTC_32P7K, 1, + 1), + TOP_FACTOR(CK_INFRA_PCIE_CK, "infra_pcie", CK_TOP_PEXTP_TL_SEL, 1, 1), + INFRA_FACTOR(CK_INFRA_PWM_BCK, "infra_pwm_bck", CK_INFRA_PWM_BSEL, 1, + 1), + INFRA_FACTOR(CK_INFRA_PWM_CK1, "infra_pwm_ck1", CK_INFRA_PWM1_SEL, 1, + 1), + INFRA_FACTOR(CK_INFRA_PWM_CK2, "infra_pwm_ck2", CK_INFRA_PWM2_SEL, 1, + 1), + TOP_FACTOR(CK_INFRA_133M_HCK, "infra_133m_hck", CK_TOP_SYSAXI, 1, 1), + TOP_FACTOR(CK_INFRA_EIP_CK, "infra_eip", CK_TOP_EIP_B, 1, 1), + INFRA_FACTOR(CK_INFRA_66M_PHCK, "infra_66m_phck", CK_INFRA_133M_HCK, 1, + 1), + TOP_FACTOR(CK_INFRA_FAUD_L_CK, "infra_faud_l", CK_TOP_AUD_L, 1, 1), + TOP_FACTOR(CK_INFRA_FAUD_AUD_CK, "infra_faud_aud", CK_TOP_A1SYS, 1, 1), + TOP_FACTOR(CK_INFRA_FAUD_EG2_CK, "infra_faud_eg2", CK_TOP_A_TUNER, 1, + 1), + TOP_FACTOR(CK_INFRA_I2CS_CK, "infra_i2cs", CK_TOP_I2C_BCK, 1, 1), + INFRA_FACTOR(CK_INFRA_MUX_UART0, "infra_mux_uart0", CK_INFRA_UART0_SEL, + 1, 1), + INFRA_FACTOR(CK_INFRA_MUX_UART1, "infra_mux_uart1", CK_INFRA_UART1_SEL, + 1, 1), + INFRA_FACTOR(CK_INFRA_MUX_UART2, "infra_mux_uart2", CK_INFRA_UART2_SEL, + 1, 1), + TOP_FACTOR(CK_INFRA_NFI_CK, "infra_nfi", CK_TOP_NFI1X, 1, 1), + TOP_FACTOR(CK_INFRA_SPINFI_CK, "infra_spinfi", CK_TOP_SPINFI_BCK, 1, 1), + INFRA_FACTOR(CK_INFRA_MUX_SPI0, "infra_mux_spi0", CK_INFRA_SPI0_SEL, 1, + 1), + INFRA_FACTOR(CK_INFRA_MUX_SPI1, "infra_mux_spi1", CK_INFRA_SPI1_SEL, 1, + 1), + TOP_FACTOR(CK_INFRA_RTC_32K, "infra_rtc_32k", CK_TOP_CB_RTC_32K, 1, 1), + TOP_FACTOR(CK_INFRA_FMSDC_CK, "infra_fmsdc", CK_TOP_EMMC_416M, 1, 1), + TOP_FACTOR(CK_INFRA_FMSDC_HCK_CK, "infra_fmsdc_hck", CK_TOP_EMMC_250M, + 1, 1), + TOP_FACTOR(CK_INFRA_PERI_133M, "infra_peri_133m", CK_TOP_SYSAXI, 1, 1), + TOP_FACTOR(CK_INFRA_133M_PHCK, "infra_133m_phck", CK_TOP_SYSAXI, 1, 1), + TOP_FACTOR(CK_INFRA_USB_SYS_CK, "infra_usb_sys", CK_TOP_U2U3_SYS, 1, 1), + TOP_FACTOR(CK_INFRA_USB_CK, "infra_usb", CK_TOP_U2U3_REF, 1, 1), + TOP_FACTOR(CK_INFRA_USB_XHCI_CK, "infra_usb_xhci", CK_TOP_U2U3_XHCI, 1, + 1), + TOP_FACTOR(CK_INFRA_PCIE_GFMUX_TL_O_PRE, "infra_pcie_mux", + CK_TOP_PEXTP_TL, 1, 1), + TOP_FACTOR(CK_INFRA_F26M_CK0, "infra_f26m_ck0", CK_TOP_F26M, 1, 1), + TOP_FACTOR(CK_INFRA_HD_133M, "infra_hd_133m", CK_TOP_SYSAXI, 1, 1), +}; + +/* INFRASYS MUX PARENTS */ +static const int infra_uart0_parents[] = { CK_INFRA_CK_F26M, CK_INFRA_UART }; + +static const int infra_spi0_parents[] = { CK_INFRA_I2C, CK_INFRA_ISPI0 }; + +static const int infra_spi1_parents[] = { CK_INFRA_I2C, CK_INFRA_ISPI1 }; + +static const int infra_pwm_bsel_parents[] = { CK_INFRA_CK_F32K, + CK_INFRA_CK_F26M, + CK_INFRA_66M_MCK, CK_INFRA_PWM }; + +static const int infra_pcie_parents[] = { CK_INFRA_CK_F32K, CK_INFRA_CK_F26M, + -1, CK_INFRA_PCIE_CK }; + +#define INFRA_MUX(_id, _name, _parents, _reg, _shift, _width) \ + { \ + .id = _id, .mux_reg = (_reg) + 0x8, \ + .mux_set_reg = (_reg) + 0x0, .mux_clr_reg = (_reg) + 0x4, \ + .mux_shift = _shift, .mux_mask = BIT(_width) - 1, \ + .parent = _parents, .num_parents = ARRAY_SIZE(_parents), \ + .flags = CLK_MUX_SETCLR_UPD | CLK_PARENT_INFRASYS, \ + } + +/* INFRA MUX */ + +static const struct mtk_composite infra_muxes[] = { + /* MODULE_CLK_SEL_0 */ + INFRA_MUX(CK_INFRA_UART0_SEL, "infra_uart0_sel", infra_uart0_parents, + 0x10, 0, 1), + INFRA_MUX(CK_INFRA_UART1_SEL, "infra_uart1_sel", infra_uart0_parents, + 0x10, 1, 1), + INFRA_MUX(CK_INFRA_UART2_SEL, "infra_uart2_sel", infra_uart0_parents, + 0x10, 2, 1), + INFRA_MUX(CK_INFRA_SPI0_SEL, "infra_spi0_sel", infra_spi0_parents, 0x10, + 4, 1), + INFRA_MUX(CK_INFRA_SPI1_SEL, "infra_spi1_sel", infra_spi1_parents, 0x10, + 5, 1), + INFRA_MUX(CK_INFRA_PWM1_SEL, "infra_pwm1_sel", infra_pwm_bsel_parents, + 0x10, 9, 2), + INFRA_MUX(CK_INFRA_PWM2_SEL, "infra_pwm2_sel", infra_pwm_bsel_parents, + 0x10, 11, 2), + INFRA_MUX(CK_INFRA_PWM_BSEL, "infra_pwm_bsel", infra_pwm_bsel_parents, + 0x10, 13, 2), + /* MODULE_CLK_SEL_1 */ + INFRA_MUX(CK_INFRA_PCIE_SEL, "infra_pcie_sel", infra_pcie_parents, 0x20, + 0, 2), +}; + +static const struct mtk_gate_regs infra_0_cg_regs = { + .set_ofs = 0x40, + .clr_ofs = 0x44, + .sta_ofs = 0x48, +}; + +static const struct mtk_gate_regs infra_1_cg_regs = { + .set_ofs = 0x50, + .clr_ofs = 0x54, + .sta_ofs = 0x58, +}; + +static const struct mtk_gate_regs infra_2_cg_regs = { + .set_ofs = 0x60, + .clr_ofs = 0x64, + .sta_ofs = 0x68, +}; + +#define GATE_INFRA0(_id, _name, _parent, _shift) \ + { \ + .id = _id, .parent = _parent, .regs = &infra_0_cg_regs, \ + .shift = _shift, \ + .flags = CLK_GATE_SETCLR | CLK_PARENT_INFRASYS, \ + } + +#define GATE_INFRA1(_id, _name, _parent, _shift) \ + { \ + .id = _id, .parent = _parent, .regs = &infra_1_cg_regs, \ + .shift = _shift, \ + .flags = CLK_GATE_SETCLR | CLK_PARENT_INFRASYS, \ + } + +#define GATE_INFRA2(_id, _name, _parent, _shift) \ + { \ + .id = _id, .parent = _parent, .regs = &infra_2_cg_regs, \ + .shift = _shift, \ + .flags = CLK_GATE_SETCLR | CLK_PARENT_INFRASYS, \ + } + +/* INFRA GATE */ + +static const struct mtk_gate infracfg_ao_gates[] = { + /* INFRA0 */ + GATE_INFRA0(CK_INFRA_GPT_STA, "infra_gpt_sta", CK_INFRA_66M_MCK, 0), + GATE_INFRA0(CK_INFRA_PWM_HCK, "infra_pwm_hck", CK_INFRA_66M_MCK, 1), + GATE_INFRA0(CK_INFRA_PWM_STA, "infra_pwm_sta", CK_INFRA_PWM_BCK, 2), + GATE_INFRA0(CK_INFRA_PWM1_CK, "infra_pwm1", CK_INFRA_PWM_CK1, 3), + GATE_INFRA0(CK_INFRA_PWM2_CK, "infra_pwm2", CK_INFRA_PWM_CK2, 4), + GATE_INFRA0(CK_INFRA_CQ_DMA_CK, "infra_cq_dma", CK_INFRA_133M_HCK, 6), + GATE_INFRA0(CK_INFRA_EIP97_CK, "infra_eip97", CK_INFRA_EIP_CK, 7), + GATE_INFRA0(CK_INFRA_AUD_BUS_CK, "infra_aud_bus", CK_INFRA_66M_PHCK, 8), + GATE_INFRA0(CK_INFRA_AUD_26M_CK, "infra_aud_26m", CK_INFRA_CK_F26M, 9), + GATE_INFRA0(CK_INFRA_AUD_L_CK, "infra_aud_l", CK_INFRA_FAUD_L_CK, 10), + GATE_INFRA0(CK_INFRA_AUD_AUD_CK, "infra_aud_aud", CK_INFRA_FAUD_AUD_CK, + 11), + GATE_INFRA0(CK_INFRA_AUD_EG2_CK, "infra_aud_eg2", CK_INFRA_FAUD_EG2_CK, + 13), + GATE_INFRA0(CK_INFRA_DRAMC_26M_CK, "infra_dramc_26m", CK_INFRA_CK_F26M, + 14), + GATE_INFRA0(CK_INFRA_DBG_CK, "infra_dbg", CK_INFRA_66M_MCK, 15), + GATE_INFRA0(CK_INFRA_AP_DMA_CK, "infra_ap_dma", CK_INFRA_66M_MCK, 16), + GATE_INFRA0(CK_INFRA_SEJ_CK, "infra_sej", CK_INFRA_66M_MCK, 24), + GATE_INFRA0(CK_INFRA_SEJ_13M_CK, "infra_sej_13m", CK_INFRA_CK_F26M, 25), + GATE_INFRA0(CK_INFRA_TRNG_CK, "infra_trng", CK_INFRA_HD_133M, 26), + /* INFRA1 */ + GATE_INFRA1(CK_INFRA_THERM_CK, "infra_therm", CK_INFRA_CK_F26M, 0), + GATE_INFRA1(CK_INFRA_I2CO_CK, "infra_i2co", CK_INFRA_I2CS_CK, 1), + GATE_INFRA1(CK_INFRA_UART0_CK, "infra_uart0", CK_INFRA_MUX_UART0, 2), + GATE_INFRA1(CK_INFRA_UART1_CK, "infra_uart1", CK_INFRA_MUX_UART1, 3), + GATE_INFRA1(CK_INFRA_UART2_CK, "infra_uart2", CK_INFRA_MUX_UART2, 4), + GATE_INFRA1(CK_INFRA_NFI1_CK, "infra_nfi1", CK_INFRA_NFI_CK, 8), + GATE_INFRA1(CK_INFRA_SPINFI1_CK, "infra_spinfi1", CK_INFRA_SPINFI_CK, + 9), + GATE_INFRA1(CK_INFRA_NFI_HCK_CK, "infra_nfi_hck", CK_INFRA_66M_MCK, 10), + GATE_INFRA1(CK_INFRA_SPI0_CK, "infra_spi0", CK_INFRA_MUX_SPI0, 11), + GATE_INFRA1(CK_INFRA_SPI1_CK, "infra_spi1", CK_INFRA_MUX_SPI1, 12), + GATE_INFRA1(CK_INFRA_SPI0_HCK_CK, "infra_spi0_hck", CK_INFRA_66M_MCK, + 13), + GATE_INFRA1(CK_INFRA_SPI1_HCK_CK, "infra_spi1_hck", CK_INFRA_66M_MCK, + 14), + GATE_INFRA1(CK_INFRA_FRTC_CK, "infra_frtc", CK_INFRA_RTC_32K, 15), + GATE_INFRA1(CK_INFRA_MSDC_CK, "infra_msdc", CK_INFRA_FMSDC_CK, 16), + GATE_INFRA1(CK_INFRA_MSDC_HCK_CK, "infra_msdc_hck", + CK_INFRA_FMSDC_HCK_CK, 17), + GATE_INFRA1(CK_INFRA_MSDC_133M_CK, "infra_msdc_133m", + CK_INFRA_PERI_133M, 18), + GATE_INFRA1(CK_INFRA_MSDC_66M_CK, "infra_msdc_66m", CK_INFRA_66M_PHCK, + 19), + GATE_INFRA1(CK_INFRA_ADC_26M_CK, "infra_adc_26m", CK_INFRA_CK_F26M, 20), + GATE_INFRA1(CK_INFRA_ADC_FRC_CK, "infra_adc_frc", CK_INFRA_CK_F26M, 21), + GATE_INFRA1(CK_INFRA_FBIST2FPC_CK, "infra_fbist2fpc", CK_INFRA_NFI_CK, + 23), + /* INFRA2 */ + GATE_INFRA2(CK_INFRA_IUSB_133_CK, "infra_iusb_133", CK_INFRA_133M_PHCK, + 0), + GATE_INFRA2(CK_INFRA_IUSB_66M_CK, "infra_iusb_66m", CK_INFRA_66M_PHCK, + 1), + GATE_INFRA2(CK_INFRA_IUSB_SYS_CK, "infra_iusb_sys", CK_INFRA_USB_SYS_CK, + 2), + GATE_INFRA2(CK_INFRA_IUSB_CK, "infra_iusb", CK_INFRA_USB_CK, 3), + GATE_INFRA2(CK_INFRA_IPCIE_CK, "infra_ipcie", CK_INFRA_PCIE_CK, 13), + GATE_INFRA2(CK_INFRA_IPCIER_CK, "infra_ipcier", CK_INFRA_F26M_CK0, 15), + GATE_INFRA2(CK_INFRA_IPCIEB_CK, "infra_ipcieb", CK_INFRA_133M_PHCK, 15), +}; + +static const struct mtk_clk_tree mt7986_fixed_pll_clk_tree = { + .fdivs_offs = CLK_APMIXED_NR_CLK, + .xtal_rate = 40 * MHZ, + .fclks = fixed_pll_clks, +}; + +static const struct mtk_clk_tree mt7986_topckgen_clk_tree = { + .fdivs_offs = CK_TOP_CB_M_416M, + .muxes_offs = CK_TOP_NFI1X_SEL, + .fclks = top_fixed_clks, + .fdivs = top_fixed_divs, + .muxes = top_muxes, + .flags = CLK_BYPASS_XTAL, +}; + +static const struct mtk_clk_tree mt7986_infracfg_clk_tree = { + .fdivs_offs = CK_INFRA_CK_F26M, + .muxes_offs = CK_INFRA_UART0_SEL, + .fdivs = infra_fixed_divs, + .muxes = infra_muxes, +}; + +static const struct udevice_id mt7986_fixed_pll_compat[] = { + { .compatible = "mediatek,mt7986-fixed-plls" }, + {} +}; + +static const struct udevice_id mt7986_topckgen_compat[] = { + { .compatible = "mediatek,mt7986-topckgen" }, + {} +}; + +static int mt7986_fixed_pll_probe(struct udevice *dev) +{ + return mtk_common_clk_init(dev, &mt7986_fixed_pll_clk_tree); +} + +static int mt7986_topckgen_probe(struct udevice *dev) +{ + struct mtk_clk_priv *priv = dev_get_priv(dev); + + priv->base = dev_read_addr_ptr(dev); + writel(MT7986_CLK_PDN_EN_WRITE, priv->base + MT7986_CLK_PDN); + + return mtk_common_clk_init(dev, &mt7986_topckgen_clk_tree); +} + +U_BOOT_DRIVER(mtk_clk_apmixedsys) = { + .name = "mt7986-clock-fixed-pll", + .id = UCLASS_CLK, + .of_match = mt7986_fixed_pll_compat, + .probe = mt7986_fixed_pll_probe, + .priv_auto = sizeof(struct mtk_clk_priv), + .ops = &mtk_clk_topckgen_ops, + .flags = DM_FLAG_PRE_RELOC, +}; + +U_BOOT_DRIVER(mtk_clk_topckgen) = { + .name = "mt7986-clock-topckgen", + .id = UCLASS_CLK, + .of_match = mt7986_topckgen_compat, + .probe = mt7986_topckgen_probe, + .priv_auto = sizeof(struct mtk_clk_priv), + .ops = &mtk_clk_topckgen_ops, + .flags = DM_FLAG_PRE_RELOC, +}; + +static const struct udevice_id mt7986_infracfg_compat[] = { + { .compatible = "mediatek,mt7986-infracfg" }, + {} +}; + +static const struct udevice_id mt7986_infracfg_ao_compat[] = { + { .compatible = "mediatek,mt7986-infracfg_ao" }, + {} +}; + +static int mt7986_infracfg_probe(struct udevice *dev) +{ + return mtk_common_clk_init(dev, &mt7986_infracfg_clk_tree); +} + +static int mt7986_infracfg_ao_probe(struct udevice *dev) +{ + return mtk_common_clk_gate_init(dev, &mt7986_infracfg_clk_tree, + infracfg_ao_gates); +} + +U_BOOT_DRIVER(mtk_clk_infracfg) = { + .name = "mt7986-clock-infracfg", + .id = UCLASS_CLK, + .of_match = mt7986_infracfg_compat, + .probe = mt7986_infracfg_probe, + .priv_auto = sizeof(struct mtk_clk_priv), + .ops = &mtk_clk_infrasys_ops, + .flags = DM_FLAG_PRE_RELOC, +}; + +U_BOOT_DRIVER(mtk_clk_infracfg_ao) = { + .name = "mt7986-clock-infracfg-ao", + .id = UCLASS_CLK, + .of_match = mt7986_infracfg_ao_compat, + .probe = mt7986_infracfg_ao_probe, + .priv_auto = sizeof(struct mtk_cg_priv), + .ops = &mtk_clk_gate_ops, + .flags = DM_FLAG_PRE_RELOC, +}; + +/* ethsys */ +static const struct mtk_gate_regs eth_cg_regs = { + .sta_ofs = 0x30, +}; + +#define GATE_ETH(_id, _name, _parent, _shift) \ + { \ + .id = _id, .parent = _parent, .regs = ð_cg_regs, \ + .shift = _shift, \ + .flags = CLK_GATE_NO_SETCLR_INV | CLK_PARENT_TOPCKGEN, \ + } + +static const struct mtk_gate eth_cgs[] = { + GATE_ETH(CK_ETH_FE_EN, "eth_fe_en", CK_TOP_NETSYS_2X, 7), + GATE_ETH(CK_ETH_GP2_EN, "eth_gp2_en", CK_TOP_SGM_325M, 8), + GATE_ETH(CK_ETH_GP1_EN, "eth_gp1_en", CK_TOP_SGM_325M, 8), + GATE_ETH(CK_ETH_WOCPU1_EN, "eth_wocpu1_en", CK_TOP_NETSYS_WED_MCU, 14), + GATE_ETH(CK_ETH_WOCPU0_EN, "eth_wocpu0_en", CK_TOP_NETSYS_WED_MCU, 15), +}; + +static int mt7986_ethsys_probe(struct udevice *dev) +{ + return mtk_common_clk_gate_init(dev, &mt7986_topckgen_clk_tree, + eth_cgs); +} + +static int mt7986_ethsys_bind(struct udevice *dev) +{ + int ret = 0; + + if (CONFIG_IS_ENABLED(RESET_MEDIATEK)) { + ret = mediatek_reset_bind(dev, ETHSYS_HIFSYS_RST_CTRL_OFS, 1); + if (ret) + debug("Warning: failed to bind reset controller\n"); + } + + return ret; +} + +static const struct udevice_id mt7986_ethsys_compat[] = { + { .compatible = "mediatek,mt7986-ethsys" }, + { } +}; + +U_BOOT_DRIVER(mtk_clk_ethsys) = { + .name = "mt7986-clock-ethsys", + .id = UCLASS_CLK, + .of_match = mt7986_ethsys_compat, + .probe = mt7986_ethsys_probe, + .bind = mt7986_ethsys_bind, + .priv_auto = sizeof(struct mtk_cg_priv), + .ops = &mtk_clk_gate_ops, +}; diff --git a/include/dt-bindings/clock/mt7986-clk.h b/include/dt-bindings/clock/mt7986-clk.h new file mode 100644 index 0000000000..820f863183 --- /dev/null +++ b/include/dt-bindings/clock/mt7986-clk.h @@ -0,0 +1,249 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2022 MediaTek Inc. All rights reserved. + * + * Author: Sam Shih + */ + +#ifndef _DT_BINDINGS_CLK_MT7986_H +#define _DT_BINDINGS_CLK_MT7986_H + +/* INFRACFG */ + +#define CK_INFRA_CK_F26M 0 +#define CK_INFRA_UART 1 +#define CK_INFRA_ISPI0 2 +#define CK_INFRA_I2C 3 +#define CK_INFRA_ISPI1 4 +#define CK_INFRA_PWM 5 +#define CK_INFRA_66M_MCK 6 +#define CK_INFRA_CK_F32K 7 +#define CK_INFRA_PCIE_CK 8 +#define CK_INFRA_PWM_BCK 9 +#define CK_INFRA_PWM_CK1 10 +#define CK_INFRA_PWM_CK2 11 +#define CK_INFRA_133M_HCK 12 +#define CK_INFRA_EIP_CK 13 +#define CK_INFRA_66M_PHCK 14 +#define CK_INFRA_FAUD_L_CK 15 +#define CK_INFRA_FAUD_AUD_CK 17 +#define CK_INFRA_FAUD_EG2_CK 17 +#define CK_INFRA_I2CS_CK 18 +#define CK_INFRA_MUX_UART0 19 +#define CK_INFRA_MUX_UART1 20 +#define CK_INFRA_MUX_UART2 21 +#define CK_INFRA_NFI_CK 22 +#define CK_INFRA_SPINFI_CK 23 +#define CK_INFRA_MUX_SPI0 24 +#define CK_INFRA_MUX_SPI1 25 +#define CK_INFRA_RTC_32K 26 +#define CK_INFRA_FMSDC_CK 27 +#define CK_INFRA_FMSDC_HCK_CK 28 +#define CK_INFRA_PERI_133M 29 +#define CK_INFRA_133M_PHCK 30 +#define CK_INFRA_USB_SYS_CK 31 +#define CK_INFRA_USB_CK 32 +#define CK_INFRA_USB_XHCI_CK 33 +#define CK_INFRA_PCIE_GFMUX_TL_O_PRE 34 +#define CK_INFRA_F26M_CK0 35 +#define CK_INFRA_HD_133M 36 +#define CLK_INFRA_NR_CLK 37 + +/* TOPCKGEN */ + +#define CK_TOP_CB_CKSQ_40M 0 +#define CK_TOP_CB_M_416M 1 +#define CK_TOP_CB_M_D2 2 +#define CK_TOP_CB_M_D4 3 +#define CK_TOP_CB_M_D8 4 +#define CK_TOP_M_D8_D2 5 +#define CK_TOP_M_D3_D2 6 +#define CK_TOP_CB_MM_D2 7 +#define CK_TOP_CB_MM_D4 8 +#define CK_TOP_CB_MM_D8 9 +#define CK_TOP_MM_D8_D2 10 +#define CK_TOP_MM_D3_D8 11 +#define CK_TOP_CB_U2_PHYD_CK 12 +#define CK_TOP_CB_APLL2_196M 13 +#define CK_TOP_APLL2_D4 14 +#define CK_TOP_CB_NET1_D4 15 +#define CK_TOP_CB_NET1_D5 16 +#define CK_TOP_NET1_D5_D2 17 +#define CK_TOP_NET1_D5_D4 18 +#define CK_TOP_NET1_D8_D2 19 +#define CK_TOP_NET1_D8_D4 20 +#define CK_TOP_CB_NET2_800M 21 +#define CK_TOP_CB_NET2_D4 22 +#define CK_TOP_NET2_D4_D2 23 +#define CK_TOP_NET2_D3_D2 24 +#define CK_TOP_CB_WEDMCU_760M 25 +#define CK_TOP_WEDMCU_D5_D2 26 +#define CK_TOP_CB_SGM_325M 27 +#define CK_TOP_CB_CKSQ_40M_D2 28 +#define CK_TOP_CB_RTC_32K 29 +#define CK_TOP_CB_RTC_32P7K 30 +#define CK_TOP_NFI1X 31 +#define CK_TOP_USB_EQ_RX250M 32 +#define CK_TOP_USB_TX250M 33 +#define CK_TOP_USB_LN0_CK 34 +#define CK_TOP_USB_CDR_CK 35 +#define CK_TOP_SPINFI_BCK 36 +#define CK_TOP_I2C_BCK 37 +#define CK_TOP_PEXTP_TL 38 +#define CK_TOP_EMMC_250M 39 +#define CK_TOP_EMMC_416M 40 +#define CK_TOP_F_26M_ADC_CK 41 +#define CK_TOP_SYSAXI 42 +#define CK_TOP_NETSYS_WED_MCU 43 +#define CK_TOP_NETSYS_2X 44 +#define CK_TOP_SGM_325M 45 +#define CK_TOP_A1SYS 46 +#define CK_TOP_EIP_B 47 +#define CK_TOP_F26M 48 +#define CK_TOP_AUD_L 49 +#define CK_TOP_A_TUNER 50 +#define CK_TOP_U2U3_REF 51 +#define CK_TOP_U2U3_SYS 52 +#define CK_TOP_U2U3_XHCI 53 +#define CK_TOP_AP2CNN_HOST 54 +#define CK_TOP_NFI1X_SEL 55 +#define CK_TOP_SPINFI_SEL 56 +#define CK_TOP_SPI_SEL 57 +#define CK_TOP_SPIM_MST_SEL 58 +#define CK_TOP_UART_SEL 59 +#define CK_TOP_PWM_SEL 60 +#define CK_TOP_I2C_SEL 61 +#define CK_TOP_PEXTP_TL_SEL 62 +#define CK_TOP_EMMC_250M_SEL 63 +#define CK_TOP_EMMC_416M_SEL 64 +#define CK_TOP_F_26M_ADC_SEL 65 +#define CK_TOP_DRAMC_SEL 66 +#define CK_TOP_DRAMC_MD32_SEL 67 +#define CK_TOP_SYSAXI_SEL 68 +#define CK_TOP_SYSAPB_SEL 69 +#define CK_TOP_ARM_DB_MAIN_SEL 70 +#define CK_TOP_ARM_DB_JTSEL 71 +#define CK_TOP_NETSYS_SEL 72 +#define CK_TOP_NETSYS_500M_SEL 73 +#define CK_TOP_NETSYS_MCU_SEL 74 +#define CK_TOP_NETSYS_2X_SEL 75 +#define CK_TOP_SGM_325M_SEL 76 +#define CK_TOP_SGM_REG_SEL 77 +#define CK_TOP_A1SYS_SEL 78 +#define CK_TOP_CONN_MCUSYS_SEL 79 +#define CK_TOP_EIP_B_SEL 80 +#define CK_TOP_PCIE_PHY_SEL 81 +#define CK_TOP_USB3_PHY_SEL 82 +#define CK_TOP_F26M_SEL 83 +#define CK_TOP_AUD_L_SEL 84 +#define CK_TOP_A_TUNER_SEL 85 +#define CK_TOP_U2U3_SEL 86 +#define CK_TOP_U2U3_SYS_SEL 87 +#define CK_TOP_U2U3_XHCI_SEL 88 +#define CK_TOP_DA_U2_REFSEL 89 +#define CK_TOP_DA_U2_CK_1P_SEL 90 +#define CK_TOP_AP2CNN_HOST_SEL 91 +#define CLK_TOP_NR_CLK 92 + +/* + * INFRACFG_AO + * clock muxes need to be append to infracfg domain, and clock gates + * need to be keep in infracgh_ao domain + */ + +#define CK_INFRA_UART0_SEL (0 + CLK_INFRA_NR_CLK) +#define CK_INFRA_UART1_SEL (1 + CLK_INFRA_NR_CLK) +#define CK_INFRA_UART2_SEL (2 + CLK_INFRA_NR_CLK) +#define CK_INFRA_SPI0_SEL (3 + CLK_INFRA_NR_CLK) +#define CK_INFRA_SPI1_SEL (4 + CLK_INFRA_NR_CLK) +#define CK_INFRA_PWM1_SEL (5 + CLK_INFRA_NR_CLK) +#define CK_INFRA_PWM2_SEL (6 + CLK_INFRA_NR_CLK) +#define CK_INFRA_PWM_BSEL (7 + CLK_INFRA_NR_CLK) +#define CK_INFRA_PCIE_SEL (8 + CLK_INFRA_NR_CLK) +#define CK_INFRA_GPT_STA 0 +#define CK_INFRA_PWM_HCK 1 +#define CK_INFRA_PWM_STA 2 +#define CK_INFRA_PWM1_CK 3 +#define CK_INFRA_PWM2_CK 4 +#define CK_INFRA_CQ_DMA_CK 5 +#define CK_INFRA_EIP97_CK 6 +#define CK_INFRA_AUD_BUS_CK 7 +#define CK_INFRA_AUD_26M_CK 8 +#define CK_INFRA_AUD_L_CK 9 +#define CK_INFRA_AUD_AUD_CK 10 +#define CK_INFRA_AUD_EG2_CK 11 +#define CK_INFRA_DRAMC_26M_CK 12 +#define CK_INFRA_DBG_CK 13 +#define CK_INFRA_AP_DMA_CK 14 +#define CK_INFRA_SEJ_CK 15 +#define CK_INFRA_SEJ_13M_CK 16 +#define CK_INFRA_THERM_CK 17 +#define CK_INFRA_I2CO_CK 18 +#define CK_INFRA_TRNG_CK 19 +#define CK_INFRA_UART0_CK 20 +#define CK_INFRA_UART1_CK 21 +#define CK_INFRA_UART2_CK 22 +#define CK_INFRA_NFI1_CK 23 +#define CK_INFRA_SPINFI1_CK 24 +#define CK_INFRA_NFI_HCK_CK 25 +#define CK_INFRA_SPI0_CK 26 +#define CK_INFRA_SPI1_CK 27 +#define CK_INFRA_SPI0_HCK_CK 28 +#define CK_INFRA_SPI1_HCK_CK 29 +#define CK_INFRA_FRTC_CK 30 +#define CK_INFRA_MSDC_CK 31 +#define CK_INFRA_MSDC_HCK_CK 32 +#define CK_INFRA_MSDC_133M_CK 33 +#define CK_INFRA_MSDC_66M_CK 34 +#define CK_INFRA_ADC_26M_CK 35 +#define CK_INFRA_ADC_FRC_CK 36 +#define CK_INFRA_FBIST2FPC_CK 37 +#define CK_INFRA_IUSB_133_CK 38 +#define CK_INFRA_IUSB_66M_CK 39 +#define CK_INFRA_IUSB_SYS_CK 40 +#define CK_INFRA_IUSB_CK 41 +#define CK_INFRA_IPCIE_CK 42 +#define CK_INFRA_IPCIER_CK 43 +#define CK_INFRA_IPCIEB_CK 44 +#define CLK_INFRA_AO_NR_CLK 45 + +/* APMIXEDSYS */ + +#define CK_APMIXED_ARMPLL 0 +#define CK_APMIXED_NET2PLL 1 +#define CK_APMIXED_MMPLL 2 +#define CK_APMIXED_SGMPLL 3 +#define CK_APMIXED_WEDMCUPLL 4 +#define CK_APMIXED_NET1PLL 5 +#define CK_APMIXED_MPLL 6 +#define CK_APMIXED_APLL2 7 +#define CLK_APMIXED_NR_CLK 8 + +/* SGMIISYS_0 */ + +#define CK_SGM0_TX_EN 0 +#define CK_SGM0_RX_EN 1 +#define CK_SGM0_CK0_EN 2 +#define CK_SGM0_CDR_CK0_EN 3 +#define CLK_SGMII0_NR_CLK 4 + +/* SGMIISYS_1 */ + +#define CK_SGM1_TX_EN 0 +#define CK_SGM1_RX_EN 1 +#define CK_SGM1_CK1_EN 2 +#define CK_SGM1_CDR_CK1_EN 3 +#define CLK_SGMII1_NR_CLK 4 + +/* ETHSYS */ + +#define CK_ETH_FE_EN 0 +#define CK_ETH_GP2_EN 1 +#define CK_ETH_GP1_EN 2 +#define CK_ETH_WOCPU1_EN 3 +#define CK_ETH_WOCPU0_EN 4 +#define CLK_ETH_NR_CLK 5 + +#endif + +/* _DT_BINDINGS_CLK_MT7986_H */ From 40746bf429d22e28680290cb73afe60924efda1c Mon Sep 17 00:00:00 2001 From: Weijie Gao Date: Fri, 9 Sep 2022 20:00:12 +0800 Subject: [PATCH 267/374] clk: mediatek: add clock driver support for MediaTek MT7981 SoC This patch adds clock driver support for MediaTek MT7981 SoC Reviewed-by: Sean Anderson Reviewed-by: Simon Glass Signed-off-by: Weijie Gao --- drivers/clk/mediatek/Makefile | 1 + drivers/clk/mediatek/clk-mt7981.c | 683 +++++++++++++++++++++++++ include/dt-bindings/clock/mt7981-clk.h | 267 ++++++++++ 3 files changed, 951 insertions(+) create mode 100644 drivers/clk/mediatek/clk-mt7981.c create mode 100644 include/dt-bindings/clock/mt7981-clk.h diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile index 1aa38215bf..1decf31a77 100644 --- a/drivers/clk/mediatek/Makefile +++ b/drivers/clk/mediatek/Makefile @@ -8,6 +8,7 @@ obj-$(CONFIG_TARGET_MT7623) += clk-mt7623.o obj-$(CONFIG_TARGET_MT7622) += clk-mt7622.o obj-$(CONFIG_TARGET_MT7629) += clk-mt7629.o obj-$(CONFIG_TARGET_MT7986) += clk-mt7986.o +obj-$(CONFIG_TARGET_MT7981) += clk-mt7981.o obj-$(CONFIG_TARGET_MT8183) += clk-mt8183.o obj-$(CONFIG_TARGET_MT8516) += clk-mt8516.o obj-$(CONFIG_TARGET_MT8518) += clk-mt8518.o diff --git a/drivers/clk/mediatek/clk-mt7981.c b/drivers/clk/mediatek/clk-mt7981.c new file mode 100644 index 0000000000..7fcb81419c --- /dev/null +++ b/drivers/clk/mediatek/clk-mt7981.c @@ -0,0 +1,683 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * MediaTek clock driver for MT7981 SoC + * + * Copyright (C) 2022 MediaTek Inc. + * Author: Sam Shih + */ + +#include +#include +#include +#include +#include +#include + +#include "clk-mtk.h" + +#define MT7981_CLK_PDN 0x250 +#define MT7981_CLK_PDN_EN_WRITE BIT(31) + +#define PLL_FACTOR(_id, _name, _parent, _mult, _div) \ + FACTOR(_id, _parent, _mult, _div, CLK_PARENT_APMIXED) + +#define TOP_FACTOR(_id, _name, _parent, _mult, _div) \ + FACTOR(_id, _parent, _mult, _div, CLK_PARENT_TOPCKGEN) + +#define INFRA_FACTOR(_id, _name, _parent, _mult, _div) \ + FACTOR(_id, _parent, _mult, _div, CLK_PARENT_INFRASYS) + +/* FIXED PLLS */ +static const struct mtk_fixed_clk fixed_pll_clks[] = { + FIXED_CLK(CK_APMIXED_ARMPLL, CLK_XTAL, 1300000000), + FIXED_CLK(CK_APMIXED_NET2PLL, CLK_XTAL, 800000000), + FIXED_CLK(CK_APMIXED_MMPLL, CLK_XTAL, 720000000), + FIXED_CLK(CK_APMIXED_SGMPLL, CLK_XTAL, 325000000), + FIXED_CLK(CK_APMIXED_WEDMCUPLL, CLK_XTAL, 208000000), + FIXED_CLK(CK_APMIXED_NET1PLL, CLK_XTAL, 2500000000), + FIXED_CLK(CK_APMIXED_MPLL, CLK_XTAL, 416000000), + FIXED_CLK(CK_APMIXED_APLL2, CLK_XTAL, 196608000), +}; + +/* TOPCKGEN FIXED CLK */ +static const struct mtk_fixed_clk top_fixed_clks[] = { + FIXED_CLK(CK_TOP_CB_CKSQ_40M, CLK_XTAL, 40000000), +}; + +/* TOPCKGEN FIXED DIV */ +static const struct mtk_fixed_factor top_fixed_divs[] = { + PLL_FACTOR(CK_TOP_CB_M_416M, "cb_m_416m", CK_APMIXED_MPLL, 1, 1), + PLL_FACTOR(CK_TOP_CB_M_D2, "cb_m_d2", CK_APMIXED_MPLL, 1, 2), + PLL_FACTOR(CK_TOP_CB_M_D3, "cb_m_d3", CK_APMIXED_MPLL, 1, 3), + PLL_FACTOR(CK_TOP_M_D3_D2, "m_d3_d2", CK_APMIXED_MPLL, 1, 2), + PLL_FACTOR(CK_TOP_CB_M_D4, "cb_m_d4", CK_APMIXED_MPLL, 1, 4), + PLL_FACTOR(CK_TOP_CB_M_D8, "cb_m_d8", CK_APMIXED_MPLL, 1, 8), + PLL_FACTOR(CK_TOP_M_D8_D2, "m_d8_d2", CK_APMIXED_MPLL, 1, 16), + PLL_FACTOR(CK_TOP_CB_MM_720M, "cb_mm_720m", CK_APMIXED_MMPLL, 1, 1), + PLL_FACTOR(CK_TOP_CB_MM_D2, "cb_mm_d2", CK_APMIXED_MMPLL, 1, 2), + PLL_FACTOR(CK_TOP_CB_MM_D3, "cb_mm_d3", CK_APMIXED_MMPLL, 1, 3), + PLL_FACTOR(CK_TOP_CB_MM_D3_D5, "cb_mm_d3_d5", CK_APMIXED_MMPLL, 1, 15), + PLL_FACTOR(CK_TOP_CB_MM_D4, "cb_mm_d4", CK_APMIXED_MMPLL, 1, 4), + PLL_FACTOR(CK_TOP_CB_MM_D6, "cb_mm_d6", CK_APMIXED_MMPLL, 1, 6), + PLL_FACTOR(CK_TOP_MM_D6_D2, "mm_d6_d2", CK_APMIXED_MMPLL, 1, 12), + PLL_FACTOR(CK_TOP_CB_MM_D8, "cb_mm_d8", CK_APMIXED_MMPLL, 1, 8), + PLL_FACTOR(CK_TOP_CB_APLL2_196M, "cb_apll2_196m", CK_APMIXED_APLL2, 1, + 1), + PLL_FACTOR(CK_TOP_APLL2_D2, "apll2_d2", CK_APMIXED_APLL2, 1, 2), + PLL_FACTOR(CK_TOP_APLL2_D4, "apll2_d4", CK_APMIXED_APLL2, 1, 4), + PLL_FACTOR(CK_TOP_NET1_2500M, "net1_2500m", CK_APMIXED_NET1PLL, 1, 1), + PLL_FACTOR(CK_TOP_CB_NET1_D4, "cb_net1_d4", CK_APMIXED_NET1PLL, 1, 4), + PLL_FACTOR(CK_TOP_CB_NET1_D5, "cb_net1_d5", CK_APMIXED_NET1PLL, 1, 5), + PLL_FACTOR(CK_TOP_NET1_D5_D2, "net1_d5_d2", CK_APMIXED_NET1PLL, 1, 10), + PLL_FACTOR(CK_TOP_NET1_D5_D4, "net1_d5_d4", CK_APMIXED_NET1PLL, 1, 20), + PLL_FACTOR(CK_TOP_CB_NET1_D8, "cb_net1_d8", CK_APMIXED_NET1PLL, 1, 8), + PLL_FACTOR(CK_TOP_NET1_D8_D2, "net1_d8_d2", CK_APMIXED_NET1PLL, 1, 16), + PLL_FACTOR(CK_TOP_NET1_D8_D4, "net1_d8_d4", CK_APMIXED_NET1PLL, 1, 32), + PLL_FACTOR(CK_TOP_CB_NET2_800M, "cb_net2_800m", CK_APMIXED_NET2PLL, 1, + 1), + PLL_FACTOR(CK_TOP_CB_NET2_D2, "cb_net2_d2", CK_APMIXED_NET2PLL, 1, 2), + PLL_FACTOR(CK_TOP_CB_NET2_D4, "cb_net2_d4", CK_APMIXED_NET2PLL, 1, 4), + PLL_FACTOR(CK_TOP_NET2_D4_D2, "net2_d4_d2", CK_APMIXED_NET2PLL, 1, 8), + PLL_FACTOR(CK_TOP_NET2_D4_D4, "net2_d4_d4", CK_APMIXED_NET2PLL, 1, 16), + PLL_FACTOR(CK_TOP_CB_NET2_D6, "cb_net2_d6", CK_APMIXED_NET2PLL, 1, 6), + PLL_FACTOR(CK_TOP_CB_WEDMCU_208M, "cb_wedmcu_208m", + CK_APMIXED_WEDMCUPLL, 1, 1), + PLL_FACTOR(CK_TOP_CB_SGM_325M, "cb_sgm_325m", CK_APMIXED_SGMPLL, 1, 1), + TOP_FACTOR(CK_TOP_CKSQ_40M_D2, "cksq_40m_d2", CK_TOP_CB_CKSQ_40M, 1, 2), + TOP_FACTOR(CK_TOP_CB_RTC_32K, "cb_rtc_32k", CK_TOP_CB_CKSQ_40M, 1, + 1250), + TOP_FACTOR(CK_TOP_CB_RTC_32P7K, "cb_rtc_32p7k", CK_TOP_CB_CKSQ_40M, 1, + 1220), + TOP_FACTOR(CK_TOP_USB_TX250M, "usb_tx250m", CK_TOP_CB_CKSQ_40M, 1, 1), + TOP_FACTOR(CK_TOP_FAUD, "faud", CK_TOP_CB_CKSQ_40M, 1, 1), + TOP_FACTOR(CK_TOP_NFI1X, "nfi1x", CK_TOP_NFI1X_SEL, 1, 1), + TOP_FACTOR(CK_TOP_USB_EQ_RX250M, "usb_eq_rx250m", CK_TOP_CB_CKSQ_40M, 1, + 1), + TOP_FACTOR(CK_TOP_USB_CDR_CK, "usb_cdr", CK_TOP_CB_CKSQ_40M, 1, 1), + TOP_FACTOR(CK_TOP_USB_LN0_CK, "usb_ln0", CK_TOP_CB_CKSQ_40M, 1, 1), + TOP_FACTOR(CK_TOP_SPINFI_BCK, "spinfi_bck", CK_TOP_SPINFI_SEL, 1, 1), + TOP_FACTOR(CK_TOP_SPI, "spi", CK_TOP_SPI_SEL, 1, 1), + TOP_FACTOR(CK_TOP_SPIM_MST, "spim_mst", CK_TOP_SPIM_MST_SEL, 1, 1), + TOP_FACTOR(CK_TOP_UART_BCK, "uart_bck", CK_TOP_UART_SEL, 1, 1), + TOP_FACTOR(CK_TOP_PWM_BCK, "pwm_bck", CK_TOP_PWM_SEL, 1, 1), + TOP_FACTOR(CK_TOP_I2C_BCK, "i2c_bck", CK_TOP_I2C_SEL, 1, 1), + TOP_FACTOR(CK_TOP_PEXTP_TL, "pextp_tl", CK_TOP_PEXTP_TL_SEL, 1, 1), + TOP_FACTOR(CK_TOP_EMMC_208M, "emmc_208m", CK_TOP_EMMC_208M_SEL, 1, 1), + TOP_FACTOR(CK_TOP_EMMC_400M, "emmc_400m", CK_TOP_EMMC_400M_SEL, 1, 1), + TOP_FACTOR(CK_TOP_DRAMC_REF, "dramc_ref", CK_TOP_DRAMC_SEL, 1, 1), + TOP_FACTOR(CK_TOP_DRAMC_MD32, "dramc_md32", CK_TOP_DRAMC_MD32_SEL, 1, + 1), + TOP_FACTOR(CK_TOP_SYSAXI, "sysaxi", CK_TOP_SYSAXI_SEL, 1, 1), + TOP_FACTOR(CK_TOP_SYSAPB, "sysapb", CK_TOP_SYSAPB_SEL, 1, 1), + TOP_FACTOR(CK_TOP_ARM_DB_MAIN, "arm_db_main", CK_TOP_ARM_DB_MAIN_SEL, 1, + 1), + TOP_FACTOR(CK_TOP_AP2CNN_HOST, "ap2cnn_host", CK_TOP_AP2CNN_HOST_SEL, 1, + 1), + TOP_FACTOR(CK_TOP_NETSYS, "netsys", CK_TOP_NETSYS_SEL, 1, 1), + TOP_FACTOR(CK_TOP_NETSYS_500M, "netsys_500m", CK_TOP_NETSYS_500M_SEL, 1, + 1), + TOP_FACTOR(CK_TOP_NETSYS_WED_MCU, "netsys_wed_mcu", + CK_TOP_NETSYS_MCU_SEL, 1, 1), + TOP_FACTOR(CK_TOP_NETSYS_2X, "netsys_2x", CK_TOP_NETSYS_2X_SEL, 1, 1), + TOP_FACTOR(CK_TOP_SGM_325M, "sgm_325m", CK_TOP_SGM_325M_SEL, 1, 1), + TOP_FACTOR(CK_TOP_SGM_REG, "sgm_reg", CK_TOP_SGM_REG_SEL, 1, 1), + TOP_FACTOR(CK_TOP_F26M, "csw_f26m", CK_TOP_F26M_SEL, 1, 1), + TOP_FACTOR(CK_TOP_EIP97B, "eip97b", CK_TOP_EIP97B_SEL, 1, 1), + TOP_FACTOR(CK_TOP_USB3_PHY, "usb3_phy", CK_TOP_USB3_PHY_SEL, 1, 1), + TOP_FACTOR(CK_TOP_AUD, "aud", CK_TOP_FAUD, 1, 1), + TOP_FACTOR(CK_TOP_A1SYS, "a1sys", CK_TOP_A1SYS_SEL, 1, 1), + TOP_FACTOR(CK_TOP_AUD_L, "aud_l", CK_TOP_AUD_L_SEL, 1, 1), + TOP_FACTOR(CK_TOP_A_TUNER, "a_tuner", CK_TOP_A_TUNER_SEL, 1, 1), + TOP_FACTOR(CK_TOP_U2U3_REF, "u2u3_ref", CK_TOP_U2U3_SEL, 1, 1), + TOP_FACTOR(CK_TOP_U2U3_SYS, "u2u3_sys", CK_TOP_U2U3_SYS_SEL, 1, 1), + TOP_FACTOR(CK_TOP_U2U3_XHCI, "u2u3_xhci", CK_TOP_U2U3_XHCI_SEL, 1, 1), + TOP_FACTOR(CK_TOP_USB_FRMCNT, "usb_frmcnt", CK_TOP_USB_FRMCNT_SEL, 1, + 1), +}; + +/* TOPCKGEN MUX PARENTS */ +static const int nfi1x_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_CB_MM_D4, + CK_TOP_NET1_D8_D2, CK_TOP_CB_NET2_D6, + CK_TOP_CB_M_D4, CK_TOP_CB_MM_D8, + CK_TOP_NET1_D8_D4, CK_TOP_CB_M_D8 }; + +static const int spinfi_parents[] = { CK_TOP_CKSQ_40M_D2, CK_TOP_CB_CKSQ_40M, + CK_TOP_NET1_D5_D4, CK_TOP_CB_M_D4, + CK_TOP_CB_MM_D8, CK_TOP_NET1_D8_D4, + CK_TOP_MM_D6_D2, CK_TOP_CB_M_D8 }; + +static const int spi_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_CB_M_D2, + CK_TOP_CB_MM_D4, CK_TOP_NET1_D8_D2, + CK_TOP_CB_NET2_D6, CK_TOP_NET1_D5_D4, + CK_TOP_CB_M_D4, CK_TOP_NET1_D8_D4 }; + +static const int uart_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_CB_M_D8, + CK_TOP_M_D8_D2 }; + +static const int pwm_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_NET1_D8_D2, + CK_TOP_NET1_D5_D4, CK_TOP_CB_M_D4, + CK_TOP_M_D8_D2, CK_TOP_CB_RTC_32K }; + +static const int i2c_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_NET1_D5_D4, + CK_TOP_CB_M_D4, CK_TOP_NET1_D8_D4 }; + +static const int pextp_tl_ck_parents[] = { CK_TOP_CB_CKSQ_40M, + CK_TOP_NET1_D5_D4, CK_TOP_CB_M_D4, + CK_TOP_CB_RTC_32K }; + +static const int emmc_208m_parents[] = { + CK_TOP_CB_CKSQ_40M, CK_TOP_CB_M_D2, CK_TOP_CB_NET2_D4, + CK_TOP_CB_APLL2_196M, CK_TOP_CB_MM_D4, CK_TOP_NET1_D8_D2, + CK_TOP_CB_MM_D6 +}; + +static const int emmc_400m_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_CB_NET2_D2, + CK_TOP_CB_MM_D2, CK_TOP_CB_NET2_D2 }; + +static const int csw_f26m_parents[] = { CK_TOP_CKSQ_40M_D2, CK_TOP_M_D8_D2 }; + +static const int dramc_md32_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_CB_M_D2, + CK_TOP_CB_WEDMCU_208M }; + +static const int sysaxi_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_NET1_D8_D2 }; + +static const int sysapb_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_M_D3_D2 }; + +static const int arm_db_main_parents[] = { CK_TOP_CB_CKSQ_40M, + CK_TOP_CB_NET2_D6 }; + +static const int ap2cnn_host_parents[] = { CK_TOP_CB_CKSQ_40M, + CK_TOP_NET1_D8_D4 }; + +static const int netsys_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_CB_MM_D2 }; + +static const int netsys_500m_parents[] = { CK_TOP_CB_CKSQ_40M, + CK_TOP_CB_NET1_D5 }; + +static const int netsys_mcu_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_CB_MM_720M, + CK_TOP_CB_NET1_D4, CK_TOP_CB_NET1_D5, + CK_TOP_CB_M_416M }; + +static const int netsys_2x_parents[] = { CK_TOP_CB_CKSQ_40M, + CK_TOP_CB_NET2_800M, + CK_TOP_CB_MM_720M }; + +static const int sgm_325m_parents[] = { CK_TOP_CB_CKSQ_40M, + CK_TOP_CB_SGM_325M }; + +static const int sgm_reg_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_CB_NET2_D4 }; + +static const int eip97b_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_CB_NET1_D5, + CK_TOP_CB_M_416M, CK_TOP_CB_MM_D2, + CK_TOP_NET1_D5_D2 }; + +static const int aud_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_CB_APLL2_196M }; + +static const int a1sys_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_APLL2_D4 }; + +static const int aud_l_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_CB_APLL2_196M, + CK_TOP_M_D8_D2 }; + +static const int a_tuner_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_APLL2_D4, + CK_TOP_M_D8_D2 }; + +static const int u2u3_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_M_D8_D2 }; + +static const int u2u3_sys_parents[] = { CK_TOP_CB_CKSQ_40M, CK_TOP_NET1_D5_D4 }; + +static const int usb_frmcnt_parents[] = { CK_TOP_CB_CKSQ_40M, + CK_TOP_CB_MM_D3_D5 }; + +#define TOP_MUX(_id, _name, _parents, _mux_ofs, _mux_set_ofs, _mux_clr_ofs, \ + _shift, _width, _gate, _upd_ofs, _upd) \ + { \ + .id = _id, .mux_reg = _mux_ofs, .mux_set_reg = _mux_set_ofs, \ + .mux_clr_reg = _mux_clr_ofs, .upd_reg = _upd_ofs, \ + .upd_shift = _upd, .mux_shift = _shift, \ + .mux_mask = BIT(_width) - 1, .gate_reg = _mux_ofs, \ + .gate_shift = _gate, .parent = _parents, \ + .num_parents = ARRAY_SIZE(_parents), \ + .flags = CLK_MUX_SETCLR_UPD, \ + } + +/* TOPCKGEN MUX_GATE */ +static const struct mtk_composite top_muxes[] = { + TOP_MUX(CK_TOP_NFI1X_SEL, "nfi1x_sel", nfi1x_parents, 0x0, 0x4, 0x8, 0, + 3, 7, 0x1c0, 0), + TOP_MUX(CK_TOP_SPINFI_SEL, "spinfi_sel", spinfi_parents, 0x0, 0x4, 0x8, + 8, 3, 15, 0x1c0, 1), + TOP_MUX(CK_TOP_SPI_SEL, "spi_sel", spi_parents, 0x0, 0x4, 0x8, 16, 3, + 23, 0x1c0, 2), + TOP_MUX(CK_TOP_SPIM_MST_SEL, "spim_mst_sel", spi_parents, 0x0, 0x4, 0x8, + 24, 3, 31, 0x1c0, 3), + TOP_MUX(CK_TOP_UART_SEL, "uart_sel", uart_parents, 0x10, 0x14, 0x18, 0, + 2, 7, 0x1c0, 4), + TOP_MUX(CK_TOP_PWM_SEL, "pwm_sel", pwm_parents, 0x10, 0x14, 0x18, 8, 3, + 15, 0x1c0, 5), + TOP_MUX(CK_TOP_I2C_SEL, "i2c_sel", i2c_parents, 0x10, 0x14, 0x18, 16, 2, + 23, 0x1c0, 6), + TOP_MUX(CK_TOP_PEXTP_TL_SEL, "pextp_tl_ck_sel", pextp_tl_ck_parents, + 0x10, 0x14, 0x18, 24, 2, 31, 0x1c0, 7), + TOP_MUX(CK_TOP_EMMC_208M_SEL, "emmc_208m_sel", emmc_208m_parents, 0x20, + 0x24, 0x28, 0, 3, 7, 0x1c0, 8), + TOP_MUX(CK_TOP_EMMC_400M_SEL, "emmc_400m_sel", emmc_400m_parents, 0x20, + 0x24, 0x28, 8, 2, 15, 0x1c0, 9), + TOP_MUX(CK_TOP_F26M_SEL, "csw_f26m_sel", csw_f26m_parents, 0x20, 0x24, + 0x28, 16, 1, 23, 0x1c0, 10), + TOP_MUX(CK_TOP_DRAMC_SEL, "dramc_sel", csw_f26m_parents, 0x20, 0x24, + 0x28, 24, 1, 31, 0x1c0, 11), + TOP_MUX(CK_TOP_DRAMC_MD32_SEL, "dramc_md32_sel", dramc_md32_parents, + 0x30, 0x34, 0x38, 0, 2, 7, 0x1c0, 12), + TOP_MUX(CK_TOP_SYSAXI_SEL, "sysaxi_sel", sysaxi_parents, 0x30, 0x34, + 0x38, 8, 1, 15, 0x1c0, 13), + TOP_MUX(CK_TOP_SYSAPB_SEL, "sysapb_sel", sysapb_parents, 0x30, 0x34, + 0x38, 16, 1, 23, 0x1c0, 14), + TOP_MUX(CK_TOP_ARM_DB_MAIN_SEL, "arm_db_main_sel", arm_db_main_parents, + 0x30, 0x34, 0x38, 24, 1, 31, 0x1c0, 15), + TOP_MUX(CK_TOP_AP2CNN_HOST_SEL, "ap2cnn_host_sel", ap2cnn_host_parents, + 0x40, 0x44, 0x48, 0, 1, 7, 0x1c0, 16), + TOP_MUX(CK_TOP_NETSYS_SEL, "netsys_sel", netsys_parents, 0x40, 0x44, + 0x48, 8, 1, 15, 0x1c0, 17), + TOP_MUX(CK_TOP_NETSYS_500M_SEL, "netsys_500m_sel", netsys_500m_parents, + 0x40, 0x44, 0x48, 16, 1, 23, 0x1c0, 18), + TOP_MUX(CK_TOP_NETSYS_MCU_SEL, "netsys_mcu_sel", netsys_mcu_parents, + 0x40, 0x44, 0x48, 24, 3, 31, 0x1c0, 19), + TOP_MUX(CK_TOP_NETSYS_2X_SEL, "netsys_2x_sel", netsys_2x_parents, 0x50, + 0x54, 0x58, 0, 2, 7, 0x1c0, 20), + TOP_MUX(CK_TOP_SGM_325M_SEL, "sgm_325m_sel", sgm_325m_parents, 0x50, + 0x54, 0x58, 8, 1, 15, 0x1c0, 21), + TOP_MUX(CK_TOP_SGM_REG_SEL, "sgm_reg_sel", sgm_reg_parents, 0x50, 0x54, + 0x58, 16, 1, 23, 0x1c0, 22), + TOP_MUX(CK_TOP_EIP97B_SEL, "eip97b_sel", eip97b_parents, 0x50, 0x54, + 0x58, 24, 3, 31, 0x1c0, 23), + TOP_MUX(CK_TOP_USB3_PHY_SEL, "usb3_phy_sel", csw_f26m_parents, 0x60, + 0x64, 0x68, 0, 1, 7, 0x1c0, 24), + TOP_MUX(CK_TOP_AUD_SEL, "aud_sel", aud_parents, 0x60, 0x64, 0x68, 8, 1, + 15, 0x1c0, 25), + TOP_MUX(CK_TOP_A1SYS_SEL, "a1sys_sel", a1sys_parents, 0x60, 0x64, 0x68, + 16, 1, 23, 0x1c0, 26), + TOP_MUX(CK_TOP_AUD_L_SEL, "aud_l_sel", aud_l_parents, 0x60, 0x64, 0x68, + 24, 2, 31, 0x1c0, 27), + TOP_MUX(CK_TOP_A_TUNER_SEL, "a_tuner_sel", a_tuner_parents, 0x70, 0x74, + 0x78, 0, 2, 7, 0x1c0, 28), + TOP_MUX(CK_TOP_U2U3_SEL, "u2u3_sel", u2u3_parents, 0x70, 0x74, 0x78, 8, + 1, 15, 0x1c0, 29), + TOP_MUX(CK_TOP_U2U3_SYS_SEL, "u2u3_sys_sel", u2u3_sys_parents, 0x70, + 0x74, 0x78, 16, 1, 23, 0x1c0, 30), + TOP_MUX(CK_TOP_U2U3_XHCI_SEL, "u2u3_xhci_sel", u2u3_sys_parents, 0x70, + 0x74, 0x78, 24, 1, 31, 0x1c4, 0), + TOP_MUX(CK_TOP_USB_FRMCNT_SEL, "usb_frmcnt_sel", usb_frmcnt_parents, + 0x80, 0x84, 0x88, 0, 1, 7, 0x1c4, 1), +}; + +/* INFRA FIXED DIV */ +static const struct mtk_fixed_factor infra_fixed_divs[] = { + TOP_FACTOR(CK_INFRA_CK_F26M, "infra_ck_f26m", CK_TOP_F26M_SEL, 1, 1), + TOP_FACTOR(CK_INFRA_UART, "infra_uart", CK_TOP_UART_SEL, 1, 1), + TOP_FACTOR(CK_INFRA_ISPI0, "infra_ispi0", CK_TOP_SPI_SEL, 1, 1), + TOP_FACTOR(CK_INFRA_I2C, "infra_i2c", CK_TOP_I2C_SEL, 1, 1), + TOP_FACTOR(CK_INFRA_ISPI1, "infra_ispi1", CK_TOP_SPIM_MST_SEL, 1, 1), + TOP_FACTOR(CK_INFRA_PWM, "infra_pwm", CK_TOP_PWM_SEL, 1, 1), + TOP_FACTOR(CK_INFRA_66M_MCK, "infra_66m_mck", CK_TOP_SYSAXI_SEL, 1, 2), + TOP_FACTOR(CK_INFRA_CK_F32K, "infra_ck_f32k", CK_TOP_CB_RTC_32P7K, 1, + 1), + TOP_FACTOR(CK_INFRA_PCIE_CK, "infra_pcie", CK_TOP_PEXTP_TL_SEL, 1, 1), + INFRA_FACTOR(CK_INFRA_PWM_BCK, "infra_pwm_bck", CK_INFRA_PWM_BSEL, 1, + 1), + INFRA_FACTOR(CK_INFRA_PWM_CK1, "infra_pwm_ck1", CK_INFRA_PWM1_SEL, 1, + 1), + INFRA_FACTOR(CK_INFRA_PWM_CK2, "infra_pwm_ck2", CK_INFRA_PWM2_SEL, 1, + 1), + TOP_FACTOR(CK_INFRA_133M_HCK, "infra_133m_hck", CK_TOP_SYSAXI, 1, 1), + INFRA_FACTOR(CK_INFRA_66M_PHCK, "infra_66m_phck", CK_INFRA_133M_HCK, 1, + 1), + TOP_FACTOR(CK_INFRA_FAUD_L_CK, "infra_faud_l", CK_TOP_AUD_L, 1, 1), + TOP_FACTOR(CK_INFRA_FAUD_AUD_CK, "infra_faud_aud", CK_TOP_A1SYS, 1, 1), + TOP_FACTOR(CK_INFRA_FAUD_EG2_CK, "infra_faud_eg2", CK_TOP_A_TUNER, 1, + 1), + TOP_FACTOR(CK_INFRA_I2CS_CK, "infra_i2cs", CK_TOP_I2C_BCK, 1, 1), + INFRA_FACTOR(CK_INFRA_MUX_UART0, "infra_mux_uart0", CK_INFRA_UART0_SEL, + 1, 1), + INFRA_FACTOR(CK_INFRA_MUX_UART1, "infra_mux_uart1", CK_INFRA_UART1_SEL, + 1, 1), + INFRA_FACTOR(CK_INFRA_MUX_UART2, "infra_mux_uart2", CK_INFRA_UART2_SEL, + 1, 1), + TOP_FACTOR(CK_INFRA_NFI_CK, "infra_nfi", CK_TOP_NFI1X, 1, 1), + TOP_FACTOR(CK_INFRA_SPINFI_CK, "infra_spinfi", CK_TOP_SPINFI_BCK, 1, 1), + INFRA_FACTOR(CK_INFRA_MUX_SPI0, "infra_mux_spi0", CK_INFRA_SPI0_SEL, 1, + 1), + INFRA_FACTOR(CK_INFRA_MUX_SPI1, "infra_mux_spi1", CK_INFRA_SPI1_SEL, 1, + 1), + INFRA_FACTOR(CK_INFRA_MUX_SPI2, "infra_mux_spi2", CK_INFRA_SPI2_SEL, 1, + 1), + TOP_FACTOR(CK_INFRA_RTC_32K, "infra_rtc_32k", CK_TOP_CB_RTC_32K, 1, 1), + TOP_FACTOR(CK_INFRA_FMSDC_CK, "infra_fmsdc", CK_TOP_EMMC_400M, 1, 1), + TOP_FACTOR(CK_INFRA_FMSDC_HCK_CK, "infra_fmsdc_hck", CK_TOP_EMMC_208M, + 1, 1), + TOP_FACTOR(CK_INFRA_PERI_133M, "infra_peri_133m", CK_TOP_SYSAXI, 1, 1), + TOP_FACTOR(CK_INFRA_133M_PHCK, "infra_133m_phck", CK_TOP_SYSAXI, 1, 1), + TOP_FACTOR(CK_INFRA_USB_SYS_CK, "infra_usb_sys", CK_TOP_U2U3_SYS, 1, 1), + TOP_FACTOR(CK_INFRA_USB_CK, "infra_usb", CK_TOP_U2U3_REF, 1, 1), + TOP_FACTOR(CK_INFRA_USB_XHCI_CK, "infra_usb_xhci", CK_TOP_U2U3_XHCI, 1, + 1), + TOP_FACTOR(CK_INFRA_PCIE_GFMUX_TL_O_PRE, "infra_pcie_mux", + CK_TOP_PEXTP_TL, 1, 1), + TOP_FACTOR(CK_INFRA_F26M_CK0, "infra_f26m_ck0", CK_TOP_F26M, 1, 1), + TOP_FACTOR(CK_INFRA_133M_MCK, "infra_133m_mck", CK_TOP_SYSAXI, 1, 1), +}; + +/* INFRASYS MUX PARENTS */ +static const int infra_uart0_parents[] = { CK_INFRA_CK_F26M, CK_INFRA_UART }; + +static const int infra_spi0_parents[] = { CK_INFRA_I2C, CK_INFRA_ISPI0 }; + +static const int infra_spi1_parents[] = { CK_INFRA_I2C, CK_INFRA_ISPI1 }; + +static const int infra_pwm1_parents[] = { -1, -1, -1, CK_INFRA_PWM }; + +static const int infra_pwm_bsel_parents[] = { -1, -1, -1, CK_INFRA_PWM }; + +static const int infra_pcie_parents[] = { CK_INFRA_CK_F32K, CK_INFRA_CK_F26M, + CK_TOP_CB_CKSQ_40M, CK_INFRA_PCIE_CK}; + +#define INFRA_MUX(_id, _name, _parents, _reg, _shift, _width) \ + { \ + .id = _id, .mux_reg = (_reg) + 0x8, \ + .mux_set_reg = (_reg) + 0x0, .mux_clr_reg = (_reg) + 0x4, \ + .mux_shift = _shift, .mux_mask = BIT(_width) - 1, \ + .parent = _parents, .num_parents = ARRAY_SIZE(_parents), \ + .flags = CLK_MUX_SETCLR_UPD | CLK_PARENT_INFRASYS, \ + } + +/* INFRA MUX */ +static const struct mtk_composite infra_muxes[] = { + INFRA_MUX(CK_INFRA_UART0_SEL, "infra_uart0_sel", infra_uart0_parents, + 0x10, 0, 1), + INFRA_MUX(CK_INFRA_UART1_SEL, "infra_uart1_sel", infra_uart0_parents, + 0x10, 1, 1), + INFRA_MUX(CK_INFRA_UART2_SEL, "infra_uart2_sel", infra_uart0_parents, + 0x10, 2, 1), + INFRA_MUX(CK_INFRA_SPI0_SEL, "infra_spi0_sel", infra_spi0_parents, 0x10, + 4, 1), + INFRA_MUX(CK_INFRA_SPI1_SEL, "infra_spi1_sel", infra_spi1_parents, 0x10, + 5, 1), + INFRA_MUX(CK_INFRA_SPI2_SEL, "infra_spi2_sel", infra_spi0_parents, 0x10, + 6, 1), + INFRA_MUX(CK_INFRA_PWM1_SEL, "infra_pwm1_sel", infra_pwm1_parents, 0x10, + 9, 2), + INFRA_MUX(CK_INFRA_PWM2_SEL, "infra_pwm2_sel", infra_pwm1_parents, 0x10, + 11, 2), + INFRA_MUX(CK_INFRA_PWM_BSEL, "infra_pwm_bsel", infra_pwm_bsel_parents, + 0x10, 13, 2), + INFRA_MUX(CK_INFRA_PCIE_SEL, "infra_pcie_sel", infra_pcie_parents, 0x20, + 0, 2), +}; + +static const struct mtk_gate_regs infra_0_cg_regs = { + .set_ofs = 0x40, + .clr_ofs = 0x44, + .sta_ofs = 0x48, +}; + +static const struct mtk_gate_regs infra_1_cg_regs = { + .set_ofs = 0x50, + .clr_ofs = 0x54, + .sta_ofs = 0x58, +}; + +static const struct mtk_gate_regs infra_2_cg_regs = { + .set_ofs = 0x60, + .clr_ofs = 0x64, + .sta_ofs = 0x68, +}; + +#define GATE_INFRA0(_id, _name, _parent, _shift) \ + { \ + .id = _id, .parent = _parent, .regs = &infra_0_cg_regs, \ + .shift = _shift, \ + .flags = CLK_GATE_SETCLR | CLK_PARENT_INFRASYS, \ + } + +#define GATE_INFRA1(_id, _name, _parent, _shift) \ + { \ + .id = _id, .parent = _parent, .regs = &infra_1_cg_regs, \ + .shift = _shift, \ + .flags = CLK_GATE_SETCLR | CLK_PARENT_INFRASYS, \ + } + +#define GATE_INFRA2(_id, _name, _parent, _shift) \ + { \ + .id = _id, .parent = _parent, .regs = &infra_2_cg_regs, \ + .shift = _shift, \ + .flags = CLK_GATE_SETCLR | CLK_PARENT_INFRASYS, \ + } + +/* INFRA GATE */ +static const struct mtk_gate infracfg_ao_gates[] = { + GATE_INFRA0(CK_INFRA_GPT_STA, "infra_gpt_sta", CK_INFRA_66M_MCK, 0), + GATE_INFRA0(CK_INFRA_PWM_HCK, "infra_pwm_hck", CK_INFRA_66M_MCK, 1), + GATE_INFRA0(CK_INFRA_PWM_STA, "infra_pwm_sta", CK_INFRA_PWM_BCK, 2), + GATE_INFRA0(CK_INFRA_PWM1_CK, "infra_pwm1", CK_INFRA_PWM_CK1, 3), + GATE_INFRA0(CK_INFRA_PWM2_CK, "infra_pwm2", CK_INFRA_PWM_CK2, 4), + GATE_INFRA0(CK_INFRA_CQ_DMA_CK, "infra_cq_dma", CK_INFRA_133M_HCK, 6), + GATE_INFRA0(CK_INFRA_AUD_BUS_CK, "infra_aud_bus", CK_INFRA_66M_PHCK, 8), + GATE_INFRA0(CK_INFRA_AUD_26M_CK, "infra_aud_26m", CK_INFRA_CK_F26M, 9), + GATE_INFRA0(CK_INFRA_AUD_L_CK, "infra_aud_l", CK_INFRA_FAUD_L_CK, 10), + GATE_INFRA0(CK_INFRA_AUD_AUD_CK, "infra_aud_aud", CK_INFRA_FAUD_AUD_CK, + 11), + GATE_INFRA0(CK_INFRA_AUD_EG2_CK, "infra_aud_eg2", CK_INFRA_FAUD_EG2_CK, + 13), + GATE_INFRA0(CK_INFRA_DRAMC_26M_CK, "infra_dramc_26m", CK_INFRA_CK_F26M, + 14), + GATE_INFRA0(CK_INFRA_DBG_CK, "infra_dbg", CK_INFRA_66M_MCK, 15), + GATE_INFRA0(CK_INFRA_AP_DMA_CK, "infra_ap_dma", CK_INFRA_66M_MCK, 16), + GATE_INFRA0(CK_INFRA_SEJ_CK, "infra_sej", CK_INFRA_66M_MCK, 24), + GATE_INFRA0(CK_INFRA_SEJ_13M_CK, "infra_sej_13m", CK_INFRA_CK_F26M, 25), + GATE_INFRA1(CK_INFRA_THERM_CK, "infra_therm", CK_INFRA_CK_F26M, 0), + GATE_INFRA1(CK_INFRA_I2CO_CK, "infra_i2co", CK_INFRA_I2CS_CK, 1), + GATE_INFRA1(CK_INFRA_UART0_CK, "infra_uart0", CK_INFRA_MUX_UART0, 2), + GATE_INFRA1(CK_INFRA_UART1_CK, "infra_uart1", CK_INFRA_MUX_UART1, 3), + GATE_INFRA1(CK_INFRA_UART2_CK, "infra_uart2", CK_INFRA_MUX_UART2, 4), + GATE_INFRA1(CK_INFRA_SPI2_CK, "infra_spi2", CK_INFRA_MUX_SPI2, 6), + GATE_INFRA1(CK_INFRA_SPI2_HCK_CK, "infra_spi2_hck", CK_INFRA_66M_MCK, + 7), + GATE_INFRA1(CK_INFRA_NFI1_CK, "infra_nfi1", CK_INFRA_NFI_CK, 8), + GATE_INFRA1(CK_INFRA_SPINFI1_CK, "infra_spinfi1", CK_INFRA_SPINFI_CK, + 9), + GATE_INFRA1(CK_INFRA_NFI_HCK_CK, "infra_nfi_hck", CK_INFRA_66M_MCK, 10), + GATE_INFRA1(CK_INFRA_SPI0_CK, "infra_spi0", CK_INFRA_MUX_SPI0, 11), + GATE_INFRA1(CK_INFRA_SPI1_CK, "infra_spi1", CK_INFRA_MUX_SPI1, 12), + GATE_INFRA1(CK_INFRA_SPI0_HCK_CK, "infra_spi0_hck", CK_INFRA_66M_MCK, + 13), + GATE_INFRA1(CK_INFRA_SPI1_HCK_CK, "infra_spi1_hck", CK_INFRA_66M_MCK, + 14), + GATE_INFRA1(CK_INFRA_FRTC_CK, "infra_frtc", CK_INFRA_RTC_32K, 15), + GATE_INFRA1(CK_INFRA_MSDC_CK, "infra_msdc", CK_INFRA_FMSDC_CK, 16), + GATE_INFRA1(CK_INFRA_MSDC_HCK_CK, "infra_msdc_hck", + CK_INFRA_FMSDC_HCK_CK, 17), + GATE_INFRA1(CK_INFRA_MSDC_133M_CK, "infra_msdc_133m", + CK_INFRA_PERI_133M, 18), + GATE_INFRA1(CK_INFRA_MSDC_66M_CK, "infra_msdc_66m", CK_INFRA_66M_PHCK, + 19), + GATE_INFRA1(CK_INFRA_ADC_26M_CK, "infra_adc_26m", CK_TOP_F26M, 20), + GATE_INFRA1(CK_INFRA_ADC_FRC_CK, "infra_adc_frc", CK_TOP_F26M, 21), + GATE_INFRA1(CK_INFRA_FBIST2FPC_CK, "infra_fbist2fpc", CK_INFRA_NFI_CK, + 23), + GATE_INFRA1(CK_INFRA_I2C_MCK_CK, "infra_i2c_mck", CK_INFRA_133M_MCK, + 25), + GATE_INFRA1(CK_INFRA_I2C_PCK_CK, "infra_i2c_pck", CK_INFRA_66M_MCK, 26), + GATE_INFRA2(CK_INFRA_IUSB_133_CK, "infra_iusb_133", CK_INFRA_133M_PHCK, + 0), + GATE_INFRA2(CK_INFRA_IUSB_66M_CK, "infra_iusb_66m", CK_INFRA_66M_PHCK, + 1), + GATE_INFRA2(CK_INFRA_IUSB_SYS_CK, "infra_iusb_sys", CK_INFRA_USB_SYS_CK, + 2), + GATE_INFRA2(CK_INFRA_IUSB_CK, "infra_iusb", CK_INFRA_USB_CK, 3), + GATE_INFRA2(CK_INFRA_IPCIE_CK, "infra_ipcie", + CK_INFRA_PCIE_GFMUX_TL_O_PRE, 12), + GATE_INFRA2(CK_INFRA_IPCIER_CK, "infra_ipcier", CK_INFRA_F26M_CK0, 14), + GATE_INFRA2(CK_INFRA_IPCIEB_CK, "infra_ipcieb", CK_INFRA_133M_PHCK, 15), +}; + +static const struct mtk_clk_tree mt7981_fixed_pll_clk_tree = { + .fdivs_offs = CLK_APMIXED_NR_CLK, + .xtal_rate = 40 * MHZ, + .fclks = fixed_pll_clks, +}; + +static const struct mtk_clk_tree mt7981_topckgen_clk_tree = { + .fdivs_offs = CK_TOP_CB_M_416M, + .muxes_offs = CK_TOP_NFI1X_SEL, + .fclks = top_fixed_clks, + .fdivs = top_fixed_divs, + .muxes = top_muxes, + .flags = CLK_BYPASS_XTAL, +}; + +static const struct mtk_clk_tree mt7981_infracfg_clk_tree = { + .fdivs_offs = CK_INFRA_CK_F26M, + .muxes_offs = CK_INFRA_UART0_SEL, + .fdivs = infra_fixed_divs, + .muxes = infra_muxes, +}; + +static const struct udevice_id mt7981_fixed_pll_compat[] = { + { .compatible = "mediatek,mt7981-fixed-plls" }, + {} +}; + +static const struct udevice_id mt7981_topckgen_compat[] = { + { .compatible = "mediatek,mt7981-topckgen" }, + {} +}; + +static int mt7981_fixed_pll_probe(struct udevice *dev) +{ + return mtk_common_clk_init(dev, &mt7981_fixed_pll_clk_tree); +} + +static int mt7981_topckgen_probe(struct udevice *dev) +{ + struct mtk_clk_priv *priv = dev_get_priv(dev); + + priv->base = dev_read_addr_ptr(dev); + writel(MT7981_CLK_PDN_EN_WRITE, priv->base + MT7981_CLK_PDN); + + return mtk_common_clk_init(dev, &mt7981_topckgen_clk_tree); +} + +U_BOOT_DRIVER(mtk_clk_apmixedsys) = { + .name = "mt7981-clock-fixed-pll", + .id = UCLASS_CLK, + .of_match = mt7981_fixed_pll_compat, + .probe = mt7981_fixed_pll_probe, + .priv_auto = sizeof(struct mtk_clk_priv), + .ops = &mtk_clk_topckgen_ops, + .flags = DM_FLAG_PRE_RELOC, +}; + +U_BOOT_DRIVER(mtk_clk_topckgen) = { + .name = "mt7981-clock-topckgen", + .id = UCLASS_CLK, + .of_match = mt7981_topckgen_compat, + .probe = mt7981_topckgen_probe, + .priv_auto = sizeof(struct mtk_clk_priv), + .ops = &mtk_clk_topckgen_ops, + .flags = DM_FLAG_PRE_RELOC, +}; + +static const struct udevice_id mt7981_infracfg_compat[] = { + { .compatible = "mediatek,mt7981-infracfg" }, + {} +}; + +static const struct udevice_id mt7981_infracfg_ao_compat[] = { + { .compatible = "mediatek,mt7981-infracfg_ao" }, + {} +}; + +static int mt7981_infracfg_probe(struct udevice *dev) +{ + return mtk_common_clk_init(dev, &mt7981_infracfg_clk_tree); +} + +static int mt7981_infracfg_ao_probe(struct udevice *dev) +{ + return mtk_common_clk_gate_init(dev, &mt7981_infracfg_clk_tree, + infracfg_ao_gates); +} + +U_BOOT_DRIVER(mtk_clk_infracfg) = { + .name = "mt7981-clock-infracfg", + .id = UCLASS_CLK, + .of_match = mt7981_infracfg_compat, + .probe = mt7981_infracfg_probe, + .priv_auto = sizeof(struct mtk_clk_priv), + .ops = &mtk_clk_infrasys_ops, + .flags = DM_FLAG_PRE_RELOC, +}; + +U_BOOT_DRIVER(mtk_clk_infracfg_ao) = { + .name = "mt7981-clock-infracfg-ao", + .id = UCLASS_CLK, + .of_match = mt7981_infracfg_ao_compat, + .probe = mt7981_infracfg_ao_probe, + .priv_auto = sizeof(struct mtk_cg_priv), + .ops = &mtk_clk_gate_ops, + .flags = DM_FLAG_PRE_RELOC, +}; + +/* ethsys */ +static const struct mtk_gate_regs eth_cg_regs = { + .set_ofs = 0x30, + .clr_ofs = 0x30, + .sta_ofs = 0x30, +}; + +#define GATE_ETH(_id, _name, _parent, _shift) \ + { \ + .id = _id, .parent = _parent, .regs = ð_cg_regs, \ + .shift = _shift, \ + .flags = CLK_GATE_NO_SETCLR_INV | CLK_PARENT_TOPCKGEN, \ + } + +static const struct mtk_gate eth_cgs[] = { + GATE_ETH(CK_ETH_FE_EN, "eth_fe_en", CK_TOP_NETSYS_2X, 6), + GATE_ETH(CK_ETH_GP2_EN, "eth_gp2_en", CK_TOP_SGM_325M, 7), + GATE_ETH(CK_ETH_GP1_EN, "eth_gp1_en", CK_TOP_SGM_325M, 8), + GATE_ETH(CK_ETH_WOCPU0_EN, "eth_wocpu0_en", CK_TOP_NETSYS_WED_MCU, 15), +}; + +static int mt7981_ethsys_probe(struct udevice *dev) +{ + return mtk_common_clk_gate_init(dev, &mt7981_topckgen_clk_tree, + eth_cgs); +} + +static int mt7981_ethsys_bind(struct udevice *dev) +{ + int ret = 0; + + if (CONFIG_IS_ENABLED(RESET_MEDIATEK)) { + ret = mediatek_reset_bind(dev, ETHSYS_HIFSYS_RST_CTRL_OFS, 1); + if (ret) + debug("Warning: failed to bind reset controller\n"); + } + + return ret; +} + +static const struct udevice_id mt7981_ethsys_compat[] = { + { .compatible = "mediatek,mt7981-ethsys", }, + {} +}; + +U_BOOT_DRIVER(mtk_clk_ethsys) = { + .name = "mt7981-clock-ethsys", + .id = UCLASS_CLK, + .of_match = mt7981_ethsys_compat, + .probe = mt7981_ethsys_probe, + .bind = mt7981_ethsys_bind, + .priv_auto = sizeof(struct mtk_cg_priv), + .ops = &mtk_clk_gate_ops, +}; diff --git a/include/dt-bindings/clock/mt7981-clk.h b/include/dt-bindings/clock/mt7981-clk.h new file mode 100644 index 0000000000..e24c759e49 --- /dev/null +++ b/include/dt-bindings/clock/mt7981-clk.h @@ -0,0 +1,267 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2022 MediaTek Inc. All rights reserved. + * + * Author: Sam Shih + */ + +#ifndef _DT_BINDINGS_CLK_MT7981_H +#define _DT_BINDINGS_CLK_MT7981_H + +/* INFRACFG */ + +#define CK_INFRA_CK_F26M 0 +#define CK_INFRA_UART 1 +#define CK_INFRA_ISPI0 2 +#define CK_INFRA_I2C 3 +#define CK_INFRA_ISPI1 4 +#define CK_INFRA_PWM 5 +#define CK_INFRA_66M_MCK 6 +#define CK_INFRA_CK_F32K 7 +#define CK_INFRA_PCIE_CK 8 +#define CK_INFRA_PWM_BCK 9 +#define CK_INFRA_PWM_CK1 10 +#define CK_INFRA_PWM_CK2 11 +#define CK_INFRA_133M_HCK 12 +#define CK_INFRA_66M_PHCK 13 +#define CK_INFRA_FAUD_L_CK 14 +#define CK_INFRA_FAUD_AUD_CK 15 +#define CK_INFRA_FAUD_EG2_CK 16 +#define CK_INFRA_I2CS_CK 17 +#define CK_INFRA_MUX_UART0 18 +#define CK_INFRA_MUX_UART1 19 +#define CK_INFRA_MUX_UART2 20 +#define CK_INFRA_NFI_CK 21 +#define CK_INFRA_SPINFI_CK 22 +#define CK_INFRA_MUX_SPI0 23 +#define CK_INFRA_MUX_SPI1 24 +#define CK_INFRA_MUX_SPI2 25 +#define CK_INFRA_RTC_32K 26 +#define CK_INFRA_FMSDC_CK 27 +#define CK_INFRA_FMSDC_HCK_CK 28 +#define CK_INFRA_PERI_133M 29 +#define CK_INFRA_133M_PHCK 30 +#define CK_INFRA_USB_SYS_CK 31 +#define CK_INFRA_USB_CK 32 +#define CK_INFRA_USB_XHCI_CK 33 +#define CK_INFRA_PCIE_GFMUX_TL_O_PRE 34 +#define CK_INFRA_F26M_CK0 35 +#define CK_INFRA_133M_MCK 36 +#define CLK_INFRA_NR_CLK 37 + +/* TOPCKGEN */ + +#define CK_TOP_CB_CKSQ_40M 0 +#define CK_TOP_CB_M_416M 1 +#define CK_TOP_CB_M_D2 2 +#define CK_TOP_CB_M_D3 3 +#define CK_TOP_M_D3_D2 4 +#define CK_TOP_CB_M_D4 5 +#define CK_TOP_CB_M_D8 6 +#define CK_TOP_M_D8_D2 7 +#define CK_TOP_CB_MM_720M 8 +#define CK_TOP_CB_MM_D2 9 +#define CK_TOP_CB_MM_D3 10 +#define CK_TOP_CB_MM_D3_D5 11 +#define CK_TOP_CB_MM_D4 12 +#define CK_TOP_CB_MM_D6 13 +#define CK_TOP_MM_D6_D2 14 +#define CK_TOP_CB_MM_D8 15 +#define CK_TOP_CB_APLL2_196M 16 +#define CK_TOP_APLL2_D2 17 +#define CK_TOP_APLL2_D4 18 +#define CK_TOP_NET1_2500M 19 +#define CK_TOP_CB_NET1_D4 20 +#define CK_TOP_CB_NET1_D5 21 +#define CK_TOP_NET1_D5_D2 22 +#define CK_TOP_NET1_D5_D4 23 +#define CK_TOP_CB_NET1_D8 24 +#define CK_TOP_NET1_D8_D2 25 +#define CK_TOP_NET1_D8_D4 26 +#define CK_TOP_CB_NET2_800M 27 +#define CK_TOP_CB_NET2_D2 28 +#define CK_TOP_CB_NET2_D4 29 +#define CK_TOP_NET2_D4_D2 30 +#define CK_TOP_NET2_D4_D4 31 +#define CK_TOP_CB_NET2_D6 32 +#define CK_TOP_CB_WEDMCU_208M 33 +#define CK_TOP_CB_SGM_325M 34 +#define CK_TOP_CKSQ_40M_D2 35 +#define CK_TOP_CB_RTC_32K 36 +#define CK_TOP_CB_RTC_32P7K 37 +#define CK_TOP_USB_TX250M 38 +#define CK_TOP_FAUD 39 +#define CK_TOP_NFI1X 40 +#define CK_TOP_USB_EQ_RX250M 41 +#define CK_TOP_USB_CDR_CK 42 +#define CK_TOP_USB_LN0_CK 43 +#define CK_TOP_SPINFI_BCK 44 +#define CK_TOP_SPI 45 +#define CK_TOP_SPIM_MST 46 +#define CK_TOP_UART_BCK 47 +#define CK_TOP_PWM_BCK 48 +#define CK_TOP_I2C_BCK 49 +#define CK_TOP_PEXTP_TL 50 +#define CK_TOP_EMMC_208M 51 +#define CK_TOP_EMMC_400M 52 +#define CK_TOP_DRAMC_REF 53 +#define CK_TOP_DRAMC_MD32 54 +#define CK_TOP_SYSAXI 55 +#define CK_TOP_SYSAPB 56 +#define CK_TOP_ARM_DB_MAIN 57 +#define CK_TOP_AP2CNN_HOST 58 +#define CK_TOP_NETSYS 59 +#define CK_TOP_NETSYS_500M 60 +#define CK_TOP_NETSYS_WED_MCU 61 +#define CK_TOP_NETSYS_2X 62 +#define CK_TOP_SGM_325M 63 +#define CK_TOP_SGM_REG 64 +#define CK_TOP_F26M 65 +#define CK_TOP_EIP97B 66 +#define CK_TOP_USB3_PHY 67 +#define CK_TOP_AUD 68 +#define CK_TOP_A1SYS 69 +#define CK_TOP_AUD_L 70 +#define CK_TOP_A_TUNER 71 +#define CK_TOP_U2U3_REF 72 +#define CK_TOP_U2U3_SYS 73 +#define CK_TOP_U2U3_XHCI 74 +#define CK_TOP_USB_FRMCNT 75 +#define CK_TOP_NFI1X_SEL 76 +#define CK_TOP_SPINFI_SEL 77 +#define CK_TOP_SPI_SEL 78 +#define CK_TOP_SPIM_MST_SEL 79 +#define CK_TOP_UART_SEL 80 +#define CK_TOP_PWM_SEL 81 +#define CK_TOP_I2C_SEL 82 +#define CK_TOP_PEXTP_TL_SEL 83 +#define CK_TOP_EMMC_208M_SEL 84 +#define CK_TOP_EMMC_400M_SEL 85 +#define CK_TOP_F26M_SEL 86 +#define CK_TOP_DRAMC_SEL 87 +#define CK_TOP_DRAMC_MD32_SEL 88 +#define CK_TOP_SYSAXI_SEL 89 +#define CK_TOP_SYSAPB_SEL 90 +#define CK_TOP_ARM_DB_MAIN_SEL 91 +#define CK_TOP_AP2CNN_HOST_SEL 92 +#define CK_TOP_NETSYS_SEL 93 +#define CK_TOP_NETSYS_500M_SEL 94 +#define CK_TOP_NETSYS_MCU_SEL 95 +#define CK_TOP_NETSYS_2X_SEL 96 +#define CK_TOP_SGM_325M_SEL 97 +#define CK_TOP_SGM_REG_SEL 98 +#define CK_TOP_EIP97B_SEL 99 +#define CK_TOP_USB3_PHY_SEL 100 +#define CK_TOP_AUD_SEL 101 +#define CK_TOP_A1SYS_SEL 102 +#define CK_TOP_AUD_L_SEL 103 +#define CK_TOP_A_TUNER_SEL 104 +#define CK_TOP_U2U3_SEL 105 +#define CK_TOP_U2U3_SYS_SEL 106 +#define CK_TOP_U2U3_XHCI_SEL 107 +#define CK_TOP_USB_FRMCNT_SEL 108 +#define CLK_TOP_NR_CLK 109 + +/* + * INFRACFG_AO + * clock muxes need to be append to infracfg domain, and clock gates + * need to be keep in infracgh_ao domain + */ +#define INFRACFG_AO_OFFSET 10 + +#define CK_INFRA_UART0_SEL (0 + CLK_INFRA_NR_CLK) +#define CK_INFRA_UART1_SEL (1 + CLK_INFRA_NR_CLK) +#define CK_INFRA_UART2_SEL (2 + CLK_INFRA_NR_CLK) +#define CK_INFRA_SPI0_SEL (3 + CLK_INFRA_NR_CLK) +#define CK_INFRA_SPI1_SEL (4 + CLK_INFRA_NR_CLK) +#define CK_INFRA_SPI2_SEL (5 + CLK_INFRA_NR_CLK) +#define CK_INFRA_PWM1_SEL (6 + CLK_INFRA_NR_CLK) +#define CK_INFRA_PWM2_SEL (7 + CLK_INFRA_NR_CLK) +#define CK_INFRA_PWM_BSEL (8 + CLK_INFRA_NR_CLK) +#define CK_INFRA_PCIE_SEL (9 + CLK_INFRA_NR_CLK) +#define CK_INFRA_GPT_STA (10 - INFRACFG_AO_OFFSET) +#define CK_INFRA_PWM_HCK (11 - INFRACFG_AO_OFFSET) +#define CK_INFRA_PWM_STA (12 - INFRACFG_AO_OFFSET) +#define CK_INFRA_PWM1_CK (13 - INFRACFG_AO_OFFSET) +#define CK_INFRA_PWM2_CK (14 - INFRACFG_AO_OFFSET) +#define CK_INFRA_CQ_DMA_CK (15 - INFRACFG_AO_OFFSET) +#define CK_INFRA_AUD_BUS_CK (16 - INFRACFG_AO_OFFSET) +#define CK_INFRA_AUD_26M_CK (17 - INFRACFG_AO_OFFSET) +#define CK_INFRA_AUD_L_CK (18 - INFRACFG_AO_OFFSET) +#define CK_INFRA_AUD_AUD_CK (19 - INFRACFG_AO_OFFSET) +#define CK_INFRA_AUD_EG2_CK (20 - INFRACFG_AO_OFFSET) +#define CK_INFRA_DRAMC_26M_CK (21 - INFRACFG_AO_OFFSET) +#define CK_INFRA_DBG_CK (22 - INFRACFG_AO_OFFSET) +#define CK_INFRA_AP_DMA_CK (23 - INFRACFG_AO_OFFSET) +#define CK_INFRA_SEJ_CK (24 - INFRACFG_AO_OFFSET) +#define CK_INFRA_SEJ_13M_CK (25 - INFRACFG_AO_OFFSET) +#define CK_INFRA_THERM_CK (26 - INFRACFG_AO_OFFSET) +#define CK_INFRA_I2CO_CK (27 - INFRACFG_AO_OFFSET) +#define CK_INFRA_UART0_CK (28 - INFRACFG_AO_OFFSET) +#define CK_INFRA_UART1_CK (29 - INFRACFG_AO_OFFSET) +#define CK_INFRA_UART2_CK (30 - INFRACFG_AO_OFFSET) +#define CK_INFRA_SPI2_CK (31 - INFRACFG_AO_OFFSET) +#define CK_INFRA_SPI2_HCK_CK (32 - INFRACFG_AO_OFFSET) +#define CK_INFRA_NFI1_CK (33 - INFRACFG_AO_OFFSET) +#define CK_INFRA_SPINFI1_CK (34 - INFRACFG_AO_OFFSET) +#define CK_INFRA_NFI_HCK_CK (35 - INFRACFG_AO_OFFSET) +#define CK_INFRA_SPI0_CK (36 - INFRACFG_AO_OFFSET) +#define CK_INFRA_SPI1_CK (37 - INFRACFG_AO_OFFSET) +#define CK_INFRA_SPI0_HCK_CK (38 - INFRACFG_AO_OFFSET) +#define CK_INFRA_SPI1_HCK_CK (39 - INFRACFG_AO_OFFSET) +#define CK_INFRA_FRTC_CK (40 - INFRACFG_AO_OFFSET) +#define CK_INFRA_MSDC_CK (41 - INFRACFG_AO_OFFSET) +#define CK_INFRA_MSDC_HCK_CK (42 - INFRACFG_AO_OFFSET) +#define CK_INFRA_MSDC_133M_CK (43 - INFRACFG_AO_OFFSET) +#define CK_INFRA_MSDC_66M_CK (44 - INFRACFG_AO_OFFSET) +#define CK_INFRA_ADC_26M_CK (45 - INFRACFG_AO_OFFSET) +#define CK_INFRA_ADC_FRC_CK (46 - INFRACFG_AO_OFFSET) +#define CK_INFRA_FBIST2FPC_CK (47 - INFRACFG_AO_OFFSET) +#define CK_INFRA_I2C_MCK_CK (48 - INFRACFG_AO_OFFSET) +#define CK_INFRA_I2C_PCK_CK (49 - INFRACFG_AO_OFFSET) +#define CK_INFRA_IUSB_133_CK (50 - INFRACFG_AO_OFFSET) +#define CK_INFRA_IUSB_66M_CK (51 - INFRACFG_AO_OFFSET) +#define CK_INFRA_IUSB_SYS_CK (52 - INFRACFG_AO_OFFSET) +#define CK_INFRA_IUSB_CK (53 - INFRACFG_AO_OFFSET) +#define CK_INFRA_IPCIE_CK (54 - INFRACFG_AO_OFFSET) +#define CK_INFRA_IPCIER_CK (55 - INFRACFG_AO_OFFSET) +#define CK_INFRA_IPCIEB_CK (56 - INFRACFG_AO_OFFSET) +#define CLK_INFRA_AO_NR_CLK (57 - INFRACFG_AO_OFFSET) + +/* APMIXEDSYS */ + +#define CK_APMIXED_ARMPLL 0 +#define CK_APMIXED_NET2PLL 1 +#define CK_APMIXED_MMPLL 2 +#define CK_APMIXED_SGMPLL 3 +#define CK_APMIXED_WEDMCUPLL 4 +#define CK_APMIXED_NET1PLL 5 +#define CK_APMIXED_MPLL 6 +#define CK_APMIXED_APLL2 7 +#define CLK_APMIXED_NR_CLK 8 + +/* SGMIISYS_0 */ + +#define CK_SGM0_TX_EN 0 +#define CK_SGM0_RX_EN 1 +#define CK_SGM0_CK0_EN 2 +#define CK_SGM0_CDR_CK0_EN 3 +#define CLK_SGMII0_NR_CLK 4 + +/* SGMIISYS_1 */ + +#define CK_SGM1_TX_EN 0 +#define CK_SGM1_RX_EN 1 +#define CK_SGM1_CK1_EN 2 +#define CK_SGM1_CDR_CK1_EN 3 +#define CLK_SGMII1_NR_CLK 4 + +/* ETHSYS */ + +#define CK_ETH_FE_EN 0 +#define CK_ETH_GP2_EN 1 +#define CK_ETH_GP1_EN 2 +#define CK_ETH_WOCPU0_EN 3 +#define CLK_ETH_NR_CLK 4 + +#endif /* _DT_BINDINGS_CLK_MT7981_H */ From 6136a232637fb141a38c0432b8786d19c8e8797f Mon Sep 17 00:00:00 2001 From: Weijie Gao Date: Fri, 9 Sep 2022 20:00:16 +0800 Subject: [PATCH 268/374] cpu: add basic cpu driver for MediaTek ARM chips Add basic CPU driver used to retrieve CPU model information. Tested-by: Daniel Golle Signed-off-by: Weijie Gao Reviewed-by: Simon Glass --- drivers/cpu/Makefile | 1 + drivers/cpu/mtk_cpu.c | 86 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 87 insertions(+) create mode 100644 drivers/cpu/mtk_cpu.c diff --git a/drivers/cpu/Makefile b/drivers/cpu/Makefile index 20884b1795..3b38ba9c58 100644 --- a/drivers/cpu/Makefile +++ b/drivers/cpu/Makefile @@ -9,6 +9,7 @@ obj-$(CONFIG_CPU) += cpu-uclass.o obj-$(CONFIG_ARCH_BMIPS) += bmips_cpu.o obj-$(CONFIG_ARCH_IMX8) += imx8_cpu.o obj-$(CONFIG_ARCH_AT91) += at91_cpu.o +obj-$(CONFIG_ARCH_MEDIATEK) += mtk_cpu.o obj-$(CONFIG_CPU_MPC83XX) += mpc83xx_cpu.o obj-$(CONFIG_CPU_RISCV) += riscv_cpu.o obj-$(CONFIG_CPU_MICROBLAZE) += microblaze_cpu.o diff --git a/drivers/cpu/mtk_cpu.c b/drivers/cpu/mtk_cpu.c new file mode 100644 index 0000000000..2a08be9b6d --- /dev/null +++ b/drivers/cpu/mtk_cpu.c @@ -0,0 +1,86 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2022 MediaTek Inc. All rights reserved. + * + * Author: Weijie Gao + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +struct mtk_cpu_plat { + struct regmap *hwver; +}; + +static int mtk_cpu_get_desc(const struct udevice *dev, char *buf, int size) +{ + struct mtk_cpu_plat *plat = dev_get_plat(dev); + uint val; + + regmap_read(plat->hwver, 0, &val); + + snprintf(buf, size, "MediaTek MT%04X", val); + + return 0; +} + +static int mtk_cpu_get_count(const struct udevice *dev) +{ + return 1; +} + +static int mtk_cpu_get_vendor(const struct udevice *dev, char *buf, int size) +{ + snprintf(buf, size, "MediaTek"); + + return 0; +} + +static int mtk_cpu_probe(struct udevice *dev) +{ + struct mtk_cpu_plat *plat = dev_get_plat(dev); + struct ofnode_phandle_args args; + int ret; + + ret = dev_read_phandle_with_args(dev, "mediatek,hwver", NULL, 0, 0, + &args); + if (ret) + return ret; + + plat->hwver = syscon_node_to_regmap(args.node); + if (IS_ERR(plat->hwver)) + return PTR_ERR(plat->hwver); + + return 0; +} + +static const struct cpu_ops mtk_cpu_ops = { + .get_desc = mtk_cpu_get_desc, + .get_count = mtk_cpu_get_count, + .get_vendor = mtk_cpu_get_vendor, +}; + +static const struct udevice_id mtk_cpu_ids[] = { + { .compatible = "arm,cortex-a7" }, + { .compatible = "arm,cortex-a53" }, + { .compatible = "arm,cortex-a73" }, + { /* sentinel */ } +}; + +U_BOOT_DRIVER(cpu_mtk) = { + .name = "mtk-cpu", + .id = UCLASS_CPU, + .of_match = mtk_cpu_ids, + .ops = &mtk_cpu_ops, + .probe = mtk_cpu_probe, + .plat_auto = sizeof(struct mtk_cpu_plat), + .flags = DM_FLAG_PRE_RELOC, +}; From 687e10ec49eb0231c9b2b59ee86bbefc0b86e6e1 Mon Sep 17 00:00:00 2001 From: Weijie Gao Date: Fri, 9 Sep 2022 20:00:18 +0800 Subject: [PATCH 269/374] tools: mtk_image: split gfh header verification into a new function The verification code of gfh header for NAND and non-NAND are identical. It's better to define a individual function to reduce redundancy. Reviewed-by: Simon Glass Tested-by: Daniel Golle Signed-off-by: Weijie Gao --- tools/mtk_image.c | 51 +++++++++++++++++++---------------------------- 1 file changed, 21 insertions(+), 30 deletions(-) diff --git a/tools/mtk_image.c b/tools/mtk_image.c index de5ce4d964..dcd6525f32 100644 --- a/tools/mtk_image.c +++ b/tools/mtk_image.c @@ -480,6 +480,25 @@ static int mtk_image_vrec_header(struct image_tool_params *params, return SHA256_SUM_LEN; } +static int mtk_image_verify_gfh(struct gfh_header *gfh, uint32_t type, int print) +{ + if (strcmp(gfh->file_info.name, GFH_FILE_INFO_NAME)) + return -1; + + if (le32_to_cpu(gfh->file_info.flash_type) != type) + return -1; + + if (print) + printf("Load Address: %08x\n", + le32_to_cpu(gfh->file_info.load_addr) + + le32_to_cpu(gfh->file_info.jump_offset)); + + if (print) + printf("Architecture: %s\n", is_arm64_image ? "ARM64" : "ARM"); + + return 0; +} + static int mtk_image_verify_gen_header(const uint8_t *ptr, int print) { union gen_boot_header *gbh = (union gen_boot_header *)ptr; @@ -542,21 +561,7 @@ static int mtk_image_verify_gen_header(const uint8_t *ptr, int print) gfh = (struct gfh_header *)(ptr + gfh_offset); - if (strcmp(gfh->file_info.name, GFH_FILE_INFO_NAME)) - return -1; - - if (le32_to_cpu(gfh->file_info.flash_type) != GFH_FLASH_TYPE_GEN) - return -1; - - if (print) - printf("Load Address: %08x\n", - le32_to_cpu(gfh->file_info.load_addr) + - le32_to_cpu(gfh->file_info.jump_offset)); - - if (print) - printf("Architecture: %s\n", is_arm64_image ? "ARM64" : "ARM"); - - return 0; + return mtk_image_verify_gfh(gfh, GFH_FLASH_TYPE_GEN, print); } static int mtk_image_verify_nand_header(const uint8_t *ptr, int print) @@ -610,21 +615,7 @@ static int mtk_image_verify_nand_header(const uint8_t *ptr, int print) gfh = (struct gfh_header *)(ptr + 2 * le16_to_cpu(nh->pagesize)); - if (strcmp(gfh->file_info.name, GFH_FILE_INFO_NAME)) - return -1; - - if (le32_to_cpu(gfh->file_info.flash_type) != GFH_FLASH_TYPE_NAND) - return -1; - - if (print) - printf("Load Address: %08x\n", - le32_to_cpu(gfh->file_info.load_addr) + - le32_to_cpu(gfh->file_info.jump_offset)); - - if (print) - printf("Architecture: %s\n", is_arm64_image ? "ARM64" : "ARM"); - - return 0; + return mtk_image_verify_gfh(gfh, GFH_FLASH_TYPE_NAND, print); } static uint32_t crc32be_cal(const void *data, size_t length) From cadb1a858d071e4ec6afdacc9ad5c7057cae699d Mon Sep 17 00:00:00 2001 From: Weijie Gao Date: Fri, 9 Sep 2022 20:00:21 +0800 Subject: [PATCH 270/374] tools: mtk_image: split the code of generating NAND header into a new file The predefined NAND headers take too much spaces in the mtk_image.c. Moving them into a new file can significantly improve the readability of both mtk_image.c and the new mtk_nand_headers.c. This is a preparation for adding more NAND headers. Reviewed-by: Simon Glass Tested-by: Daniel Golle Signed-off-by: Weijie Gao --- tools/Makefile | 1 + tools/mtk_image.c | 305 ++++++--------------------------------- tools/mtk_image.h | 25 ---- tools/mtk_nand_headers.c | 286 ++++++++++++++++++++++++++++++++++++ tools/mtk_nand_headers.h | 61 ++++++++ 5 files changed, 389 insertions(+), 289 deletions(-) create mode 100644 tools/mtk_nand_headers.c create mode 100644 tools/mtk_nand_headers.h diff --git a/tools/Makefile b/tools/Makefile index 3626919633..34a1aa7a8b 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -147,6 +147,7 @@ dumpimage-mkimage-objs := aisimage.o \ gpimage.o \ gpimage-common.o \ mtk_image.o \ + mtk_nand_headers.o \ $(ECDSA_OBJS-y) \ $(RSA_OBJS-y) \ $(AES_OBJS-y) diff --git a/tools/mtk_image.c b/tools/mtk_image.c index dcd6525f32..1f7396aa69 100644 --- a/tools/mtk_image.c +++ b/tools/mtk_image.c @@ -12,216 +12,7 @@ #include #include "imagetool.h" #include "mtk_image.h" - -/* NAND header for SPI-NAND with 2KB page + 64B spare */ -static const union nand_boot_header snand_hdr_2k_64_data = { - .data = { - 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44, - 0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36, - 0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00, - 0x00, 0x00, 0x00, 0x08, 0x03, 0x00, 0x40, 0x00, - 0x40, 0x00, 0x00, 0x08, 0x10, 0x00, 0x16, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x7B, 0xC4, 0x17, 0x9D, - 0xCA, 0x42, 0x90, 0xD0, 0x98, 0xD0, 0xE0, 0xF7, - 0xDB, 0xCD, 0x16, 0xF6, 0x03, 0x73, 0xD2, 0xB8, - 0x93, 0xB2, 0x56, 0x5A, 0x84, 0x6E, 0x00, 0x00 - } -}; - -/* NAND header for SPI-NAND with 2KB page + 120B/128B spare */ -static const union nand_boot_header snand_hdr_2k_128_data = { - .data = { - 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44, - 0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36, - 0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00, - 0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x70, 0x00, - 0x40, 0x00, 0x00, 0x08, 0x10, 0x00, 0x16, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x90, 0x28, 0xED, 0x13, - 0x7F, 0x12, 0x22, 0xCD, 0x3D, 0x06, 0xF1, 0xB3, - 0x6F, 0x2E, 0xD9, 0xA0, 0x9D, 0x7A, 0xBD, 0xD7, - 0xB3, 0x28, 0x3C, 0x13, 0xDB, 0x4E, 0x00, 0x00 - } -}; - -/* NAND header for SPI-NAND with 4KB page + 256B spare */ -static const union nand_boot_header snand_hdr_4k_256_data = { - .data = { - 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44, - 0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36, - 0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00, - 0x00, 0x00, 0x00, 0x10, 0x05, 0x00, 0xE0, 0x00, - 0x40, 0x00, 0x00, 0x08, 0x10, 0x00, 0x16, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x47, 0xED, 0x0E, 0xC3, - 0x83, 0xBF, 0x41, 0xD2, 0x85, 0x21, 0x97, 0x57, - 0xC4, 0x2E, 0x6B, 0x7A, 0x40, 0xE0, 0xCF, 0x8F, - 0x37, 0xBD, 0x17, 0xB6, 0xC7, 0xFE, 0x00, 0x00 - } -}; - -/* NAND header for Parallel NAND 1Gb with 2KB page + 64B spare */ -static const union nand_boot_header nand_hdr_1gb_2k_64_data = { - .data = { - 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44, - 0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36, - 0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00, - 0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x40, 0x00, - 0x40, 0x00, 0x00, 0x04, 0x0B, 0x00, 0x11, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x12, 0x28, 0x1C, 0x12, - 0x8F, 0xFD, 0xF8, 0x32, 0x6F, 0x6D, 0xCF, 0x6C, - 0xDA, 0x21, 0x70, 0x8C, 0xDA, 0x0A, 0x22, 0x82, - 0xAA, 0x59, 0xFA, 0x7C, 0x42, 0x2D, 0x00, 0x00 - } -}; - -/* NAND header for Parallel NAND 2Gb with 2KB page + 64B spare */ -static const union nand_boot_header nand_hdr_2gb_2k_64_data = { - .data = { - 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44, - 0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36, - 0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00, - 0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x40, 0x00, - 0x40, 0x00, 0x00, 0x08, 0x0B, 0x00, 0x11, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x20, 0x9C, 0x3D, 0x2D, - 0x7B, 0x68, 0x63, 0x52, 0x2E, 0x04, 0x63, 0xF1, - 0x35, 0x4E, 0x44, 0x3E, 0xF8, 0xAC, 0x9B, 0x95, - 0xAB, 0xFE, 0xE4, 0xE1, 0xD5, 0xF9, 0x00, 0x00 - } -}; - -/* NAND header for Parallel NAND 4Gb with 2KB page + 64B spare */ -static const union nand_boot_header nand_hdr_4gb_2k_64_data = { - .data = { - 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44, - 0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36, - 0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00, - 0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x40, 0x00, - 0x40, 0x00, 0x00, 0x10, 0x0B, 0x00, 0x11, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xE3, 0x0F, 0x86, 0x32, - 0x68, 0x05, 0xD9, 0xC8, 0x13, 0xDF, 0xC5, 0x0B, - 0x35, 0x3A, 0x68, 0xA5, 0x3C, 0x0C, 0x73, 0x87, - 0x63, 0xB0, 0xBE, 0xCC, 0x84, 0x47, 0x00, 0x00 - } -}; - -/* NAND header for Parallel NAND 2Gb with 2KB page + 128B spare */ -static const union nand_boot_header nand_hdr_2gb_2k_128_data = { - .data = { - 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44, - 0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36, - 0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00, - 0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x70, 0x00, - 0x40, 0x00, 0x00, 0x08, 0x0B, 0x00, 0x11, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0xA5, 0xE9, 0x5A, - 0xDF, 0x58, 0x62, 0x41, 0xD6, 0x26, 0x77, 0xBC, - 0x76, 0x1F, 0x27, 0x4E, 0x4F, 0x6C, 0xC3, 0xF0, - 0x36, 0xDE, 0xD9, 0xB3, 0xFF, 0x93, 0x00, 0x00 - } -}; - -/* NAND header for Parallel NAND 4Gb with 2KB page + 128B spare */ -static const union nand_boot_header nand_hdr_4gb_2k_128_data = { - .data = { - 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44, - 0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36, - 0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00, - 0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x70, 0x00, - 0x40, 0x00, 0x00, 0x10, 0x0B, 0x00, 0x11, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xC2, 0x36, 0x52, 0x45, - 0xCC, 0x35, 0xD8, 0xDB, 0xEB, 0xFD, 0xD1, 0x46, - 0x76, 0x6B, 0x0B, 0xD5, 0x8B, 0xCC, 0x2B, 0xE2, - 0xFE, 0x90, 0x83, 0x9E, 0xAE, 0x2D, 0x00, 0x00 - } -}; - -static const struct nand_header_type { - const char *name; - const union nand_boot_header *data; -} nand_headers[] = { - { - .name = "2k+64", - .data = &snand_hdr_2k_64_data - }, { - .name = "2k+120", - .data = &snand_hdr_2k_128_data - }, { - .name = "2k+128", - .data = &snand_hdr_2k_128_data - }, { - .name = "4k+256", - .data = &snand_hdr_4k_256_data - }, { - .name = "1g:2k+64", - .data = &nand_hdr_1gb_2k_64_data - }, { - .name = "2g:2k+64", - .data = &nand_hdr_2gb_2k_64_data - }, { - .name = "4g:2k+64", - .data = &nand_hdr_4gb_2k_64_data - }, { - .name = "2g:2k+128", - .data = &nand_hdr_2gb_2k_128_data - }, { - .name = "4g:2k+128", - .data = &nand_hdr_4gb_2k_128_data - } -}; +#include "mtk_nand_headers.h" static const struct brom_img_type { const char *name; @@ -264,6 +55,7 @@ static uint32_t crc32tbl[256]; /* NAND header selected by user */ static const union nand_boot_header *hdr_nand; +static uint32_t hdr_nand_size; /* GFH header + 2 * 4KB pages of NAND */ static char hdr_tmp[sizeof(struct gfh_header) + 0x2000]; @@ -402,12 +194,7 @@ static int mtk_brom_parse_imagename(const char *imagename) } /* parse nand header type */ - for (i = 0; i < ARRAY_SIZE(nand_headers); i++) { - if (!strcmp(nand_headers[i].name, nandinfo)) { - hdr_nand = nand_headers[i].data; - break; - } - } + hdr_nand = mtk_nand_header_find(nandinfo); /* parse device header offset */ if (hdr_offs && hdr_offs[0]) @@ -432,6 +219,9 @@ static int mtk_brom_parse_imagename(const char *imagename) return -EINVAL; } + if (hdr_media == BRLYT_TYPE_NAND || hdr_media == BRLYT_TYPE_SNAND) + hdr_nand_size = mtk_nand_header_size(hdr_nand); + return 0; } @@ -468,7 +258,7 @@ static int mtk_image_vrec_header(struct image_tool_params *params, } if (hdr_media == BRLYT_TYPE_NAND || hdr_media == BRLYT_TYPE_SNAND) - tparams->header_size = 2 * le16_to_cpu(hdr_nand->pagesize); + tparams->header_size = hdr_nand_size; else tparams->header_size = sizeof(struct gen_device_header); @@ -566,16 +356,17 @@ static int mtk_image_verify_gen_header(const uint8_t *ptr, int print) static int mtk_image_verify_nand_header(const uint8_t *ptr, int print) { - union nand_boot_header *nh = (union nand_boot_header *)ptr; struct brom_layout_header *bh; + struct nand_header_info info; struct gfh_header *gfh; const char *bootmedia; + int ret; - if (strncmp(nh->version, NAND_BOOT_VERSION, sizeof(nh->version)) || - strcmp(nh->id, NAND_BOOT_ID)) - return -1; + ret = mtk_nand_header_info(ptr, &info); + if (ret < 0) + return ret; - bh = (struct brom_layout_header *)(ptr + le16_to_cpu(nh->pagesize)); + bh = (struct brom_layout_header *)(ptr + info.page_size); if (strcmp(bh->name, BRLYT_NAME)) return -1; @@ -586,34 +377,23 @@ static int mtk_image_verify_nand_header(const uint8_t *ptr, int print) if (le32_to_cpu(bh->type) == BRLYT_TYPE_NAND) bootmedia = "Parallel NAND"; else if (le32_to_cpu(bh->type) == BRLYT_TYPE_SNAND) - bootmedia = "Serial NAND"; + bootmedia = "Serial NAND (SNFI/AP)"; else return -1; } if (print) { - printf("Boot Media: %s\n", bootmedia); + printf("Boot Media: %s\n", bootmedia); - if (le32_to_cpu(bh->type) == BRLYT_TYPE_NAND) { - uint64_t capacity = - (uint64_t)le16_to_cpu(nh->numblocks) * - (uint64_t)le16_to_cpu(nh->pages_of_block) * - (uint64_t)le16_to_cpu(nh->pagesize) * 8; - printf("Capacity: %dGb\n", - (uint32_t)(capacity >> 30)); - } - - if (le16_to_cpu(nh->pagesize) >= 1024) - printf("Page Size: %dKB\n", - le16_to_cpu(nh->pagesize) >> 10); + if (info.page_size >= 1024) + printf("Page Size: %dKB\n", info.page_size >> 10); else - printf("Page Size: %dB\n", - le16_to_cpu(nh->pagesize)); + printf("Page Size: %dB\n", info.page_size); - printf("Spare Size: %dB\n", le16_to_cpu(nh->oobsize)); + printf("Spare Size: %dB\n", info.spare_size); } - gfh = (struct gfh_header *)(ptr + 2 * le16_to_cpu(nh->pagesize)); + gfh = (struct gfh_header *)(ptr + info.gfh_offset); return mtk_image_verify_gfh(gfh, GFH_FLASH_TYPE_NAND, print); } @@ -713,7 +493,7 @@ static int mtk_image_verify_header(unsigned char *ptr, int image_size, if (image_get_magic(hdr) == IH_MAGIC) return mtk_image_verify_mt7621_header(ptr, 0); - if (!strcmp((char *)ptr, NAND_BOOT_NAME)) + if (is_mtk_nand_header(ptr)) return mtk_image_verify_nand_header(ptr, 0); else return mtk_image_verify_gen_header(ptr, 0); @@ -739,7 +519,7 @@ static void mtk_image_print_header(const void *ptr) return; } - if (!strcmp((char *)ptr, NAND_BOOT_NAME)) + if (is_mtk_nand_header(ptr)) mtk_image_verify_nand_header(ptr, 1); else mtk_image_verify_gen_header(ptr, 1); @@ -870,36 +650,33 @@ static void mtk_image_set_gen_header(void *ptr, off_t filesize, static void mtk_image_set_nand_header(void *ptr, off_t filesize, uint32_t loadaddr) { - union nand_boot_header *nh = (union nand_boot_header *)ptr; struct brom_layout_header *brlyt; struct gfh_header *gfh; - uint32_t payload_pages; - int i; + uint32_t payload_pages, nand_page_size; - /* NAND device header, repeat 4 times */ - for (i = 0; i < 4; i++) - memcpy(nh + i, hdr_nand, sizeof(union nand_boot_header)); + /* NAND header */ + nand_page_size = mtk_nand_header_put(hdr_nand, ptr); - /* BRLYT header */ - payload_pages = (filesize + le16_to_cpu(hdr_nand->pagesize) - 1) / - le16_to_cpu(hdr_nand->pagesize); - brlyt = (struct brom_layout_header *) - (ptr + le16_to_cpu(hdr_nand->pagesize)); - put_brom_layout_header(brlyt, hdr_media); - brlyt->header_size = cpu_to_le32(2); - brlyt->total_size = cpu_to_le32(payload_pages); - brlyt->header_size_2 = brlyt->header_size; - brlyt->total_size_2 = brlyt->total_size; - brlyt->unused = cpu_to_le32(1); + if (nand_page_size) { + /* BRLYT header */ + payload_pages = (filesize + nand_page_size - 1) / + nand_page_size; + brlyt = (struct brom_layout_header *)(ptr + nand_page_size); + put_brom_layout_header(brlyt, hdr_media); + brlyt->header_size = cpu_to_le32(2); + brlyt->total_size = cpu_to_le32(payload_pages); + brlyt->header_size_2 = brlyt->header_size; + brlyt->total_size_2 = brlyt->total_size; + brlyt->unused = cpu_to_le32(1); + } /* GFH header */ - gfh = (struct gfh_header *)(ptr + 2 * le16_to_cpu(hdr_nand->pagesize)); - put_ghf_header(gfh, filesize, 2 * le16_to_cpu(hdr_nand->pagesize), - loadaddr, GFH_FLASH_TYPE_NAND); + gfh = (struct gfh_header *)(ptr + hdr_nand_size); + put_ghf_header(gfh, filesize, hdr_nand_size, loadaddr, + GFH_FLASH_TYPE_NAND); /* Generate SHA256 hash */ - put_hash((uint8_t *)gfh, - filesize - 2 * le16_to_cpu(hdr_nand->pagesize) - SHA256_SUM_LEN); + put_hash((uint8_t *)gfh, filesize - hdr_nand_size - SHA256_SUM_LEN); } static void mtk_image_set_mt7621_header(void *ptr, off_t filesize, diff --git a/tools/mtk_image.h b/tools/mtk_image.h index d868545a33..fad9372100 100644 --- a/tools/mtk_image.h +++ b/tools/mtk_image.h @@ -26,31 +26,6 @@ union gen_boot_header { #define SF_BOOT_NAME "SF_BOOT" #define SDMMC_BOOT_NAME "SDMMC_BOOT" -/* Header for NAND */ -union nand_boot_header { - struct { - char name[12]; - char version[4]; - char id[8]; - uint16_t ioif; - uint16_t pagesize; - uint16_t addrcycles; - uint16_t oobsize; - uint16_t pages_of_block; - uint16_t numblocks; - uint16_t writesize_shift; - uint16_t erasesize_shift; - uint8_t dummy[60]; - uint8_t ecc_parity[28]; - }; - - uint8_t data[0x80]; -}; - -#define NAND_BOOT_NAME "BOOTLOADER!" -#define NAND_BOOT_VERSION "V006" -#define NAND_BOOT_ID "NFIINFO" - /* BootROM layout header */ struct brom_layout_header { char name[8]; diff --git a/tools/mtk_nand_headers.c b/tools/mtk_nand_headers.c new file mode 100644 index 0000000000..12f827c39f --- /dev/null +++ b/tools/mtk_nand_headers.c @@ -0,0 +1,286 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * MediaTek BootROM NAND header definitions + * + * Copyright (C) 2022 MediaTek Inc. + * Author: Weijie Gao + */ + +#include +#include +#include "imagetool.h" +#include "mtk_image.h" +#include "mtk_nand_headers.h" + +/* NAND header for SPI-NAND with 2KB page + 64B spare */ +static const union nand_boot_header snand_hdr_2k_64_data = { + .data = { + 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44, + 0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36, + 0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x03, 0x00, 0x40, 0x00, + 0x40, 0x00, 0x00, 0x08, 0x10, 0x00, 0x16, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x7B, 0xC4, 0x17, 0x9D, + 0xCA, 0x42, 0x90, 0xD0, 0x98, 0xD0, 0xE0, 0xF7, + 0xDB, 0xCD, 0x16, 0xF6, 0x03, 0x73, 0xD2, 0xB8, + 0x93, 0xB2, 0x56, 0x5A, 0x84, 0x6E, 0x00, 0x00 + } +}; + +/* NAND header for SPI-NAND with 2KB page + 120B/128B spare */ +static const union nand_boot_header snand_hdr_2k_128_data = { + .data = { + 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44, + 0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36, + 0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x70, 0x00, + 0x40, 0x00, 0x00, 0x08, 0x10, 0x00, 0x16, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x90, 0x28, 0xED, 0x13, + 0x7F, 0x12, 0x22, 0xCD, 0x3D, 0x06, 0xF1, 0xB3, + 0x6F, 0x2E, 0xD9, 0xA0, 0x9D, 0x7A, 0xBD, 0xD7, + 0xB3, 0x28, 0x3C, 0x13, 0xDB, 0x4E, 0x00, 0x00 + } +}; + +/* NAND header for SPI-NAND with 4KB page + 256B spare */ +static const union nand_boot_header snand_hdr_4k_256_data = { + .data = { + 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44, + 0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36, + 0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00, + 0x00, 0x00, 0x00, 0x10, 0x05, 0x00, 0xE0, 0x00, + 0x40, 0x00, 0x00, 0x08, 0x10, 0x00, 0x16, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x47, 0xED, 0x0E, 0xC3, + 0x83, 0xBF, 0x41, 0xD2, 0x85, 0x21, 0x97, 0x57, + 0xC4, 0x2E, 0x6B, 0x7A, 0x40, 0xE0, 0xCF, 0x8F, + 0x37, 0xBD, 0x17, 0xB6, 0xC7, 0xFE, 0x00, 0x00 + } +}; + +/* NAND header for Parallel NAND 1Gb with 2KB page + 64B spare */ +static const union nand_boot_header nand_hdr_1gb_2k_64_data = { + .data = { + 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44, + 0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36, + 0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x40, 0x00, + 0x40, 0x00, 0x00, 0x04, 0x0B, 0x00, 0x11, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x12, 0x28, 0x1C, 0x12, + 0x8F, 0xFD, 0xF8, 0x32, 0x6F, 0x6D, 0xCF, 0x6C, + 0xDA, 0x21, 0x70, 0x8C, 0xDA, 0x0A, 0x22, 0x82, + 0xAA, 0x59, 0xFA, 0x7C, 0x42, 0x2D, 0x00, 0x00 + } +}; + +/* NAND header for Parallel NAND 2Gb with 2KB page + 64B spare */ +static const union nand_boot_header nand_hdr_2gb_2k_64_data = { + .data = { + 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44, + 0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36, + 0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x40, 0x00, + 0x40, 0x00, 0x00, 0x08, 0x0B, 0x00, 0x11, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x20, 0x9C, 0x3D, 0x2D, + 0x7B, 0x68, 0x63, 0x52, 0x2E, 0x04, 0x63, 0xF1, + 0x35, 0x4E, 0x44, 0x3E, 0xF8, 0xAC, 0x9B, 0x95, + 0xAB, 0xFE, 0xE4, 0xE1, 0xD5, 0xF9, 0x00, 0x00 + } +}; + +/* NAND header for Parallel NAND 4Gb with 2KB page + 64B spare */ +static const union nand_boot_header nand_hdr_4gb_2k_64_data = { + .data = { + 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44, + 0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36, + 0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x40, 0x00, + 0x40, 0x00, 0x00, 0x10, 0x0B, 0x00, 0x11, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xE3, 0x0F, 0x86, 0x32, + 0x68, 0x05, 0xD9, 0xC8, 0x13, 0xDF, 0xC5, 0x0B, + 0x35, 0x3A, 0x68, 0xA5, 0x3C, 0x0C, 0x73, 0x87, + 0x63, 0xB0, 0xBE, 0xCC, 0x84, 0x47, 0x00, 0x00 + } +}; + +/* NAND header for Parallel NAND 2Gb with 2KB page + 128B spare */ +static const union nand_boot_header nand_hdr_2gb_2k_128_data = { + .data = { + 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44, + 0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36, + 0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x70, 0x00, + 0x40, 0x00, 0x00, 0x08, 0x0B, 0x00, 0x11, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0xA5, 0xE9, 0x5A, + 0xDF, 0x58, 0x62, 0x41, 0xD6, 0x26, 0x77, 0xBC, + 0x76, 0x1F, 0x27, 0x4E, 0x4F, 0x6C, 0xC3, 0xF0, + 0x36, 0xDE, 0xD9, 0xB3, 0xFF, 0x93, 0x00, 0x00 + } +}; + +/* NAND header for Parallel NAND 4Gb with 2KB page + 128B spare */ +static const union nand_boot_header nand_hdr_4gb_2k_128_data = { + .data = { + 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44, + 0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36, + 0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x70, 0x00, + 0x40, 0x00, 0x00, 0x10, 0x0B, 0x00, 0x11, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xC2, 0x36, 0x52, 0x45, + 0xCC, 0x35, 0xD8, 0xDB, 0xEB, 0xFD, 0xD1, 0x46, + 0x76, 0x6B, 0x0B, 0xD5, 0x8B, 0xCC, 0x2B, 0xE2, + 0xFE, 0x90, 0x83, 0x9E, 0xAE, 0x2D, 0x00, 0x00 + } +}; + +static const struct nand_header_type { + const char *name; + const union nand_boot_header *data; +} nand_headers[] = { + { + .name = "2k+64", + .data = &snand_hdr_2k_64_data + }, { + .name = "2k+120", + .data = &snand_hdr_2k_128_data + }, { + .name = "2k+128", + .data = &snand_hdr_2k_128_data + }, { + .name = "4k+256", + .data = &snand_hdr_4k_256_data + }, { + .name = "1g:2k+64", + .data = &nand_hdr_1gb_2k_64_data + }, { + .name = "2g:2k+64", + .data = &nand_hdr_2gb_2k_64_data + }, { + .name = "4g:2k+64", + .data = &nand_hdr_4gb_2k_64_data + }, { + .name = "2g:2k+128", + .data = &nand_hdr_2gb_2k_128_data + }, { + .name = "4g:2k+128", + .data = &nand_hdr_4gb_2k_128_data + } +}; + +const union nand_boot_header *mtk_nand_header_find(const char *name) +{ + uint32_t i; + + for (i = 0; i < ARRAY_SIZE(nand_headers); i++) { + if (!strcmp(nand_headers[i].name, name)) + return nand_headers[i].data; + } + + return NULL; +} + +uint32_t mtk_nand_header_size(const union nand_boot_header *hdr_nand) +{ + return 2 * le16_to_cpu(hdr_nand->pagesize); +} + +static int mtk_nand_header_ap_info(const void *ptr, + struct nand_header_info *info) +{ + union nand_boot_header *nh = (union nand_boot_header *)ptr; + + if (strncmp(nh->version, NAND_BOOT_VERSION, sizeof(nh->version)) || + strcmp(nh->id, NAND_BOOT_ID)) + return -1; + + info->page_size = le16_to_cpu(nh->pagesize); + info->spare_size = le16_to_cpu(nh->oobsize); + info->gfh_offset = 2 * info->page_size; + + return 0; +} + +int mtk_nand_header_info(const void *ptr, struct nand_header_info *info) +{ + if (!strcmp((char *)ptr, NAND_BOOT_NAME)) + return mtk_nand_header_ap_info(ptr, info); + + return -1; +} + +bool is_mtk_nand_header(const void *ptr) +{ + struct nand_header_info info; + + if (mtk_nand_header_info(ptr, &info) >= 0) + return true; + + return false; +} + +uint32_t mtk_nand_header_put(const union nand_boot_header *hdr_nand, void *ptr) +{ + union nand_boot_header *nh = (union nand_boot_header *)ptr; + int i; + + /* NAND device header, repeat 4 times */ + for (i = 0; i < 4; i++) + memcpy(nh + i, hdr_nand, sizeof(union nand_boot_header)); + + return le16_to_cpu(hdr_nand->pagesize); +} diff --git a/tools/mtk_nand_headers.h b/tools/mtk_nand_headers.h new file mode 100644 index 0000000000..20506cab38 --- /dev/null +++ b/tools/mtk_nand_headers.h @@ -0,0 +1,61 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * MediaTek BootROM NAND header definitions + * + * Copyright (C) 2022 MediaTek Inc. + * Author: Weijie Gao + */ + +#ifndef _MTK_NAND_HEADERS_H +#define _MTK_NAND_HEADERS_H + +#include +#include + +struct nand_header_info { + uint32_t page_size; + uint32_t spare_size; + uint32_t gfh_offset; +}; + +/* AP BROM Header for NAND */ +union nand_boot_header { + struct { + char name[12]; + char version[4]; + char id[8]; + uint16_t ioif; /* I/O interface */ + uint16_t pagesize; /* NAND page size */ + uint16_t addrcycles; /* Address cycles */ + uint16_t oobsize; /* NAND page spare size */ + uint16_t pages_of_block; /* Pages of one block */ + uint16_t numblocks; /* Total blocks of NAND chip */ + uint16_t writesize_shift; + uint16_t erasesize_shift; + uint8_t dummy[60]; + uint8_t ecc_parity[28]; /* ECC parity of this header */ + }; + + uint8_t data[0x80]; +}; + +#define NAND_BOOT_NAME "BOOTLOADER!" +#define NAND_BOOT_VERSION "V006" +#define NAND_BOOT_ID "NFIINFO" + +/* Find nand header data by name */ +const union nand_boot_header *mtk_nand_header_find(const char *name); + +/* Device header size using this nand header */ +uint32_t mtk_nand_header_size(const union nand_boot_header *hdr_nand); + +/* Get nand info from nand header (page size, spare size, ...) */ +int mtk_nand_header_info(const void *ptr, struct nand_header_info *info); + +/* Whether given header data is valid */ +bool is_mtk_nand_header(const void *ptr); + +/* Generate Device header using give nand header */ +uint32_t mtk_nand_header_put(const union nand_boot_header *hdr_nand, void *ptr); + +#endif /* _MTK_NAND_HEADERS_H */ From 3e3332130f4e99278f3686381b80b243a54948b0 Mon Sep 17 00:00:00 2001 From: Weijie Gao Date: Fri, 9 Sep 2022 20:00:25 +0800 Subject: [PATCH 271/374] tools: mtk_image: add support for nand headers used by newer chips This patch adds more nand headers in two new types: 1. HSM header, used for spi-nand thru SNFI interface 2. SPIM header, used for spi-nand thru spi-mem interface The original nand header is renamed to AP header. Tested-by: Daniel Golle Signed-off-by: Weijie Gao --- tools/mtk_image.c | 23 +- tools/mtk_nand_headers.c | 462 +++++++++++++++++++++++++++++++++++---- tools/mtk_nand_headers.h | 110 +++++++++- 3 files changed, 545 insertions(+), 50 deletions(-) diff --git a/tools/mtk_image.c b/tools/mtk_image.c index 1f7396aa69..9b3136afa3 100644 --- a/tools/mtk_image.c +++ b/tools/mtk_image.c @@ -33,6 +33,9 @@ static const struct brom_img_type { }, { .name = "snand", .type = BRLYT_TYPE_SNAND + }, { + .name = "spim-nand", + .type = BRLYT_TYPE_SNAND } }; @@ -54,7 +57,7 @@ static char lk_name[32] = "U-Boot"; static uint32_t crc32tbl[256]; /* NAND header selected by user */ -static const union nand_boot_header *hdr_nand; +static const struct nand_header_type *hdr_nand; static uint32_t hdr_nand_size; /* GFH header + 2 * 4KB pages of NAND */ @@ -366,20 +369,26 @@ static int mtk_image_verify_nand_header(const uint8_t *ptr, int print) if (ret < 0) return ret; - bh = (struct brom_layout_header *)(ptr + info.page_size); + if (!ret) { + bh = (struct brom_layout_header *)(ptr + info.page_size); - if (strcmp(bh->name, BRLYT_NAME)) - return -1; + if (strcmp(bh->name, BRLYT_NAME)) + return -1; + + if (le32_to_cpu(bh->magic) != BRLYT_MAGIC) + return -1; - if (le32_to_cpu(bh->magic) != BRLYT_MAGIC) { - return -1; - } else { if (le32_to_cpu(bh->type) == BRLYT_TYPE_NAND) bootmedia = "Parallel NAND"; else if (le32_to_cpu(bh->type) == BRLYT_TYPE_SNAND) bootmedia = "Serial NAND (SNFI/AP)"; else return -1; + } else { + if (info.snfi) + bootmedia = "Serial NAND (SNFI/HSM)"; + else + bootmedia = "Serial NAND (SPIM)"; } if (print) { diff --git a/tools/mtk_nand_headers.c b/tools/mtk_nand_headers.c index 12f827c39f..2fa91e7af0 100644 --- a/tools/mtk_nand_headers.c +++ b/tools/mtk_nand_headers.c @@ -188,55 +188,346 @@ static const union nand_boot_header nand_hdr_4gb_2k_128_data = { } }; -static const struct nand_header_type { - const char *name; - const union nand_boot_header *data; -} nand_headers[] = { - { - .name = "2k+64", - .data = &snand_hdr_2k_64_data - }, { - .name = "2k+120", - .data = &snand_hdr_2k_128_data - }, { - .name = "2k+128", - .data = &snand_hdr_2k_128_data - }, { - .name = "4k+256", - .data = &snand_hdr_4k_256_data - }, { - .name = "1g:2k+64", - .data = &nand_hdr_1gb_2k_64_data - }, { - .name = "2g:2k+64", - .data = &nand_hdr_2gb_2k_64_data - }, { - .name = "4g:2k+64", - .data = &nand_hdr_4gb_2k_64_data - }, { - .name = "2g:2k+128", - .data = &nand_hdr_2gb_2k_128_data - }, { - .name = "4g:2k+128", - .data = &nand_hdr_4gb_2k_128_data +/* HSM BROM NAND header for SPI NAND with 2KB page + 64B spare */ +static const union hsm_nand_boot_header hsm_nand_hdr_2k_64_data = { + .data = { + 0x4E, 0x41, 0x4E, 0x44, 0x43, 0x46, 0x47, 0x21, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x08, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, + 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0xFF, 0x00, 0x00, 0x00, 0x21, 0xD2, 0xEE, 0xF6, + 0xAE, 0xDD, 0x5E, 0xC2, 0x82, 0x8E, 0x9A, 0x62, + 0x09, 0x8E, 0x80, 0xE2, 0x37, 0x0D, 0xC9, 0xFA, + 0xA9, 0xDD, 0xFC, 0x92, 0x34, 0x2A, 0xED, 0x51, + 0xA4, 0x1B, 0xF7, 0x63, 0xCC, 0x5A, 0xC7, 0xFB, + 0xED, 0x21, 0x02, 0x23, 0x51, 0x31 } }; -const union nand_boot_header *mtk_nand_header_find(const char *name) +/* HSM BROM NAND header for SPI NAND with 2KB page + 128B spare */ +static const union hsm_nand_boot_header hsm_nand_hdr_2k_128_data = { + .data = { + 0x4E, 0x41, 0x4E, 0x44, 0x43, 0x46, 0x47, 0x21, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x08, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, + 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0xFF, 0x00, 0x00, 0x00, 0x71, 0x7f, 0x71, 0xAC, + 0x42, 0xD0, 0x5B, 0xD2, 0x12, 0x81, 0x15, 0x0A, + 0x0C, 0xD4, 0xF6, 0x32, 0x1E, 0x63, 0xE7, 0x81, + 0x8A, 0x7F, 0xDE, 0xF9, 0x4B, 0x91, 0xEC, 0xC2, + 0x70, 0x00, 0x7F, 0x57, 0xAF, 0xDC, 0xE4, 0x24, + 0x57, 0x09, 0xBC, 0xC5, 0x35, 0xDC + } +}; + +/* HSM BROM NAND header for SPI NAND with 4KB page + 256B spare */ +static const union hsm_nand_boot_header hsm_nand_hdr_4k_256_data = { + .data = { + 0x4E, 0x41, 0x4E, 0x44, 0x43, 0x46, 0x47, 0x21, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, + 0x0C, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0xFF, 0x00, 0x00, 0x00, 0x62, 0x04, 0xD6, 0x1F, + 0x2B, 0x57, 0x7A, 0x2D, 0xFE, 0xBB, 0x4A, 0x50, + 0xEC, 0xF8, 0x70, 0x1A, 0x44, 0x15, 0xF6, 0xA2, + 0x8E, 0xB0, 0xFD, 0xFA, 0xDC, 0xAA, 0x5A, 0x4E, + 0xCB, 0x8E, 0xC9, 0x72, 0x08, 0xDC, 0x20, 0xB9, + 0x98, 0xC8, 0x82, 0xD8, 0xBE, 0x44 + } +}; + +/* HSM2.0 BROM NAND header for SPI NAND with 2KB page + 64B spare */ +static const union hsm20_nand_boot_header hsm20_nand_hdr_2k_64_data = { + .data = { + 0x4E, 0x41, 0x4E, 0x44, 0x43, 0x46, 0x47, 0x21, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, + 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x08, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, + 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0x01, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x5F, 0x4B, 0xB2, 0x5B, 0x8B, 0x1C, 0x35, 0xDA, + 0x83, 0xE6, 0x6C, 0xC3, 0xFB, 0x8C, 0x78, 0x23, + 0xD0, 0x89, 0x24, 0xD9, 0x6C, 0x35, 0x2C, 0x5D, + 0x8F, 0xBB, 0xFC, 0x10, 0xD0, 0xE2, 0x22, 0x7D, + 0xC8, 0x97, 0x9A, 0xEF, 0xC6, 0xB5, 0xA7, 0x4E, + 0x4E, 0x0E + } +}; + +/* HSM2.0 BROM NAND header for SPI NAND with 2KB page + 128B spare */ +static const union hsm20_nand_boot_header hsm20_nand_hdr_2k_128_data = { + .data = { + 0x4E, 0x41, 0x4E, 0x44, 0x43, 0x46, 0x47, 0x21, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, + 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x08, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, + 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0x01, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xF8, 0x7E, 0xC1, 0x5D, 0x61, 0x54, 0xEA, 0x9F, + 0x5E, 0x66, 0x39, 0x66, 0x21, 0xFF, 0x8C, 0x3B, + 0xBE, 0xA7, 0x5A, 0x9E, 0xD7, 0xBD, 0x9E, 0x89, + 0xEE, 0x7E, 0x10, 0x31, 0x9A, 0x1D, 0x82, 0x49, + 0xA3, 0x4E, 0xD8, 0x47, 0xD7, 0x19, 0xF4, 0x2D, + 0x8E, 0x53 + } +}; + +/* HSM2.0 BROM NAND header for SPI NAND with 4KB page + 256B spare */ +static const union hsm20_nand_boot_header hsm20_nand_hdr_4k_256_data = { + .data = { + 0x4E, 0x41, 0x4E, 0x44, 0x43, 0x46, 0x47, 0x21, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, + 0x00, 0x04, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, + 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0x01, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x79, 0x01, 0x1F, 0x86, 0x62, 0x6A, 0x43, 0xAE, + 0xE6, 0xF8, 0xDD, 0x5B, 0x29, 0xB7, 0xA2, 0x7F, + 0x29, 0x72, 0x54, 0x37, 0xBE, 0x50, 0xD4, 0x24, + 0xAB, 0x60, 0xF4, 0x44, 0x97, 0x3B, 0x65, 0x21, + 0x73, 0x24, 0x1F, 0x93, 0x0E, 0x9E, 0x96, 0x88, + 0x78, 0x6C + } +}; + +/* SPIM-NAND header for SPI NAND with 2KB page + 64B spare */ +static const union spim_nand_boot_header spim_nand_hdr_2k_64_data = { + .data = { + 0x53, 0x50, 0x49, 0x4e, 0x41, 0x4e, 0x44, 0x21, + 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x08, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x40, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x20, 0x30, + 0x01, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + } +}; + +/* SPIM-NAND header for SPI NAND with 2KB page + 128B spare */ +static const union spim_nand_boot_header spim_nand_hdr_2k_128_data = { + .data = { + 0x53, 0x50, 0x49, 0x4e, 0x41, 0x4e, 0x44, 0x21, + 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x08, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, + 0x40, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x20, 0x30, + 0x01, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + } +}; + +/* SPIM-NAND header for SPI NAND with 4KB page + 256B spare */ +static const union spim_nand_boot_header spim_nand_hdr_4k_256_data = { + .data = { + 0x53, 0x50, 0x49, 0x4e, 0x41, 0x4e, 0x44, 0x21, + 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x40, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x20, 0x30, + 0x01, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + } +}; + +struct nand_header_type { + const char *name; + enum nand_boot_header_type type; + union { + const union nand_boot_header *ap; + const union hsm_nand_boot_header *hsm; + const union hsm20_nand_boot_header *hsm20; + const union spim_nand_boot_header *spim; + }; +} nand_headers[] = { + { + .name = "2k+64", + .type = NAND_BOOT_AP_HEADER, + .ap = &snand_hdr_2k_64_data, + }, { + .name = "2k+120", + .type = NAND_BOOT_AP_HEADER, + .ap = &snand_hdr_2k_128_data, + }, { + .name = "2k+128", + .type = NAND_BOOT_AP_HEADER, + .ap = &snand_hdr_2k_128_data, + }, { + .name = "4k+256", + .type = NAND_BOOT_AP_HEADER, + .ap = &snand_hdr_4k_256_data, + }, { + .name = "1g:2k+64", + .type = NAND_BOOT_AP_HEADER, + .ap = &nand_hdr_1gb_2k_64_data, + }, { + .name = "2g:2k+64", + .type = NAND_BOOT_AP_HEADER, + .ap = &nand_hdr_2gb_2k_64_data, + }, { + .name = "4g:2k+64", + .type = NAND_BOOT_AP_HEADER, + .ap = &nand_hdr_4gb_2k_64_data, + }, { + .name = "2g:2k+128", + .type = NAND_BOOT_AP_HEADER, + .ap = &nand_hdr_2gb_2k_128_data, + }, { + .name = "4g:2k+128", + .type = NAND_BOOT_AP_HEADER, + .ap = &nand_hdr_4gb_2k_128_data, + }, { + .name = "hsm:2k+64", + .type = NAND_BOOT_HSM_HEADER, + .hsm = &hsm_nand_hdr_2k_64_data, + }, { + .name = "hsm:2k+128", + .type = NAND_BOOT_HSM_HEADER, + .hsm = &hsm_nand_hdr_2k_128_data, + }, { + .name = "hsm:4k+256", + .type = NAND_BOOT_HSM_HEADER, + .hsm = &hsm_nand_hdr_4k_256_data, + }, { + .name = "hsm20:2k+64", + .type = NAND_BOOT_HSM20_HEADER, + .hsm20 = &hsm20_nand_hdr_2k_64_data, + }, { + .name = "hsm20:2k+128", + .type = NAND_BOOT_HSM20_HEADER, + .hsm20 = &hsm20_nand_hdr_2k_128_data, + }, { + .name = "hsm20:4k+256", + .type = NAND_BOOT_HSM20_HEADER, + .hsm20 = &hsm20_nand_hdr_4k_256_data, + }, { + .name = "spim:2k+64", + .type = NAND_BOOT_SPIM_HEADER, + .spim = &spim_nand_hdr_2k_64_data, + }, { + .name = "spim:2k+128", + .type = NAND_BOOT_SPIM_HEADER, + .spim = &spim_nand_hdr_2k_128_data, + }, { + .name = "spim:4k+256", + .type = NAND_BOOT_SPIM_HEADER, + .spim = &spim_nand_hdr_4k_256_data, + } +}; + +const struct nand_header_type *mtk_nand_header_find(const char *name) { uint32_t i; for (i = 0; i < ARRAY_SIZE(nand_headers); i++) { if (!strcmp(nand_headers[i].name, name)) - return nand_headers[i].data; + return &nand_headers[i]; } return NULL; } -uint32_t mtk_nand_header_size(const union nand_boot_header *hdr_nand) +uint32_t mtk_nand_header_size(const struct nand_header_type *hdr_nand) { - return 2 * le16_to_cpu(hdr_nand->pagesize); + switch (hdr_nand->type) { + case NAND_BOOT_HSM_HEADER: + return le32_to_cpu(hdr_nand->hsm->page_size); + + case NAND_BOOT_HSM20_HEADER: + return le32_to_cpu(hdr_nand->hsm20->page_size); + + case NAND_BOOT_SPIM_HEADER: + return le32_to_cpu(hdr_nand->spim->page_size); + + default: + return 2 * le16_to_cpu(hdr_nand->ap->pagesize); + } } static int mtk_nand_header_ap_info(const void *ptr, @@ -251,14 +542,45 @@ static int mtk_nand_header_ap_info(const void *ptr, info->page_size = le16_to_cpu(nh->pagesize); info->spare_size = le16_to_cpu(nh->oobsize); info->gfh_offset = 2 * info->page_size; + info->snfi = true; return 0; } +static int mtk_nand_header_hsm_info(const void *ptr, + struct nand_header_info *info) +{ + union hsm_nand_boot_header *nh = (union hsm_nand_boot_header *)ptr; + + info->page_size = le16_to_cpu(nh->page_size); + info->spare_size = le16_to_cpu(nh->spare_size); + info->gfh_offset = info->page_size; + info->snfi = true; + + return 1; +} + +static int mtk_nand_header_spim_info(const void *ptr, + struct nand_header_info *info) +{ + union spim_nand_boot_header *nh = (union spim_nand_boot_header *)ptr; + + info->page_size = le16_to_cpu(nh->page_size); + info->spare_size = le16_to_cpu(nh->spare_size); + info->gfh_offset = info->page_size; + info->snfi = false; + + return 1; +} + int mtk_nand_header_info(const void *ptr, struct nand_header_info *info) { if (!strcmp((char *)ptr, NAND_BOOT_NAME)) return mtk_nand_header_ap_info(ptr, info); + else if (!strncmp((char *)ptr, HSM_NAND_BOOT_NAME, 8)) + return mtk_nand_header_hsm_info(ptr, info); + else if (!strncmp((char *)ptr, SPIM_NAND_BOOT_NAME, 8)) + return mtk_nand_header_spim_info(ptr, info); return -1; } @@ -273,14 +595,74 @@ bool is_mtk_nand_header(const void *ptr) return false; } -uint32_t mtk_nand_header_put(const union nand_boot_header *hdr_nand, void *ptr) +static uint16_t crc16(const uint8_t *p, uint32_t len) +{ + uint16_t crc = 0x4f4e; + uint32_t i; + + while (len--) { + crc ^= *p++ << 8; + for (i = 0; i < 8; i++) + crc = (crc << 1) ^ ((crc & 0x8000) ? 0x8005 : 0); + } + + return crc; +} + +static uint32_t mtk_nand_header_put_ap(const struct nand_header_type *hdr_nand, + void *ptr) { - union nand_boot_header *nh = (union nand_boot_header *)ptr; int i; /* NAND device header, repeat 4 times */ - for (i = 0; i < 4; i++) - memcpy(nh + i, hdr_nand, sizeof(union nand_boot_header)); + for (i = 0; i < 4; i++) { + memcpy(ptr, hdr_nand->ap, sizeof(*hdr_nand->ap)); + ptr += sizeof(*hdr_nand->ap); + } - return le16_to_cpu(hdr_nand->pagesize); + return le16_to_cpu(hdr_nand->ap->pagesize); +} + +static uint32_t mtk_nand_header_put_hsm(const struct nand_header_type *hdr_nand, + void *ptr) +{ + memcpy(ptr, hdr_nand->hsm, sizeof(*hdr_nand->hsm)); + return 0; +} + +static uint32_t mtk_nand_header_put_hsm20(const struct nand_header_type *hdr_nand, + void *ptr) +{ + memcpy(ptr, hdr_nand->hsm20, sizeof(*hdr_nand->hsm20)); + return 0; +} + +static uint32_t mtk_nand_header_put_spim(const struct nand_header_type *hdr_nand, + void *ptr) +{ + uint16_t crc; + + memcpy(ptr, hdr_nand->spim, sizeof(*hdr_nand->spim)); + + crc = crc16(ptr, 0x4e); + memcpy(ptr + 0x4e, &crc, sizeof(uint16_t)); + + return 0; +} + +uint32_t mtk_nand_header_put(const struct nand_header_type *hdr_nand, void *ptr) +{ + switch (hdr_nand->type) { + case NAND_BOOT_HSM_HEADER: + return mtk_nand_header_put_hsm(hdr_nand, ptr); + + case NAND_BOOT_HSM20_HEADER: + return mtk_nand_header_put_hsm20(hdr_nand, ptr); + + case NAND_BOOT_SPIM_HEADER: + return mtk_nand_header_put_spim(hdr_nand, ptr); + + default: + return mtk_nand_header_put_ap(hdr_nand, ptr); + } } diff --git a/tools/mtk_nand_headers.h b/tools/mtk_nand_headers.h index 20506cab38..9b1c4bab11 100644 --- a/tools/mtk_nand_headers.h +++ b/tools/mtk_nand_headers.h @@ -16,6 +16,7 @@ struct nand_header_info { uint32_t page_size; uint32_t spare_size; uint32_t gfh_offset; + bool snfi; }; /* AP BROM Header for NAND */ @@ -39,15 +40,117 @@ union nand_boot_header { uint8_t data[0x80]; }; +/* HSM BROM Header for NAND */ +union hsm_nand_boot_header { + struct { + char id[8]; + uint32_t version; /* Header version */ + uint32_t config; /* Header config */ + uint32_t sector_size; /* ECC step size */ + uint32_t fdm_size; /* User OOB size of a step */ + uint32_t fdm_ecc_size; /* ECC parity size of a step */ + uint32_t lbs; + uint32_t page_size; /* NAND page size */ + uint32_t spare_size; /* NAND page spare size */ + uint32_t page_per_block; /* Pages of one block */ + uint32_t blocks; /* Total blocks of NAND chip */ + uint32_t plane_sel_position; /* Plane bit position */ + uint32_t pll; /* Value of pll reg */ + uint32_t acccon; /* Value of access timing reg */ + uint32_t strobe_sel; /* Value of DQS selection reg*/ + uint32_t acccon1; /* Value of access timing reg */ + uint32_t dqs_mux; /* Value of DQS mux reg */ + uint32_t dqs_ctrl; /* Value of DQS control reg */ + uint32_t delay_ctrl; /* Value of delay ctrl reg */ + uint32_t latch_lat; /* Value of latch latency reg */ + uint32_t sample_delay; /* Value of sample delay reg */ + uint32_t driving; /* Value of driving reg */ + uint32_t bl_start; /* Bootloader start addr */ + uint32_t bl_end; /* Bootloader end addr */ + uint8_t ecc_parity[42]; /* ECC parity of this header */ + }; + + uint8_t data[0x8E]; +}; + +/* HSM2.0 BROM Header for NAND */ +union hsm20_nand_boot_header { + struct { + char id[8]; + uint32_t version; /* Header version */ + uint32_t config; /* Header config */ + uint32_t sector_size; /* ECC step size */ + uint32_t fdm_size; /* User OOB size of a step */ + uint32_t fdm_ecc_size; /* ECC parity size of a step */ + uint32_t lbs; + uint32_t page_size; /* NAND page size */ + uint32_t spare_size; /* NAND page spare size */ + uint32_t page_per_block; /* Pages of one block */ + uint32_t blocks; /* Total blocks of NAND chip */ + uint32_t plane_sel_position; /* Plane bit position */ + uint32_t pll; /* Value of pll reg */ + uint32_t acccon; /* Value of access timing reg */ + uint32_t strobe_sel; /* Value of DQS selection reg*/ + uint32_t acccon1; /* Value of access timing reg */ + uint32_t dqs_mux; /* Value of DQS mux reg */ + uint32_t dqs_ctrl; /* Value of DQS control reg */ + uint32_t delay_ctrl; /* Value of delay ctrl reg */ + uint32_t latch_lat; /* Value of latch latency reg */ + uint32_t sample_delay; /* Value of sample delay reg */ + uint32_t driving; /* Value of driving reg */ + uint32_t reserved; + uint32_t bl0_start; /* Bootloader start addr */ + uint32_t bl0_end; /* Bootloader end addr */ + uint32_t bl0_type; /* Bootloader type */ + uint8_t bl_reserve[84]; + uint8_t ecc_parity[42]; /* ECC parity of this header */ + }; + + uint8_t data[0xEA]; +}; + +/* SPIM BROM Header for SPI-NAND */ +union spim_nand_boot_header { + struct { + char id[8]; + uint32_t version; /* Header version */ + uint32_t config; /* Header config */ + uint32_t page_size; /* NAND page size */ + uint32_t spare_size; /* NAND page spare size */ + uint16_t page_per_block; /* Pages of one block */ + uint16_t plane_sel_position; /* Plane bit position */ + uint16_t reserve_reg; + uint16_t reserve_val; + uint16_t ecc_error; /* ECC error reg addr */ + uint16_t ecc_mask; /* ECC error bit mask */ + uint32_t bl_start; /* Bootloader start addr */ + uint32_t bl_end; /* Bootloader end addr */ + uint8_t ecc_parity[32]; /* ECC parity of this header */ + uint32_t integrity_crc; /* CRC of this header */ + }; + + uint8_t data[0x50]; +}; + +enum nand_boot_header_type { + NAND_BOOT_AP_HEADER, + NAND_BOOT_HSM_HEADER, + NAND_BOOT_HSM20_HEADER, + NAND_BOOT_SPIM_HEADER +}; + #define NAND_BOOT_NAME "BOOTLOADER!" #define NAND_BOOT_VERSION "V006" #define NAND_BOOT_ID "NFIINFO" +#define HSM_NAND_BOOT_NAME "NANDCFG!" +#define SPIM_NAND_BOOT_NAME "SPINAND!" + /* Find nand header data by name */ -const union nand_boot_header *mtk_nand_header_find(const char *name); +const struct nand_header_type *mtk_nand_header_find(const char *name); /* Device header size using this nand header */ -uint32_t mtk_nand_header_size(const union nand_boot_header *hdr_nand); +uint32_t mtk_nand_header_size(const struct nand_header_type *hdr_nand); /* Get nand info from nand header (page size, spare size, ...) */ int mtk_nand_header_info(const void *ptr, struct nand_header_info *info); @@ -56,6 +159,7 @@ int mtk_nand_header_info(const void *ptr, struct nand_header_info *info); bool is_mtk_nand_header(const void *ptr); /* Generate Device header using give nand header */ -uint32_t mtk_nand_header_put(const union nand_boot_header *hdr_nand, void *ptr); +uint32_t mtk_nand_header_put(const struct nand_header_type *hdr_nand, + void *ptr); #endif /* _MTK_NAND_HEADERS_H */ From 812f3c4e0aef677b87858703553c97c3b5405764 Mon Sep 17 00:00:00 2001 From: Weijie Gao Date: Fri, 9 Sep 2022 20:00:27 +0800 Subject: [PATCH 272/374] MAINTAINERS: update maintainer for MediaTek ARM platform Add new files for MediaTek ARM platform Reviewed-by: Simon Glass Signed-off-by: Weijie Gao --- MAINTAINERS | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index e4fd099f87..d9f9ade7a3 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -356,20 +356,26 @@ F: doc/device-tree-bindings/phy/phy-mtk-* F: doc/device-tree-bindings/usb/mediatek,* F: doc/README.mediatek F: drivers/clk/mediatek/ +F: drivers/cpu/mtk_cpu.c +F: drivers/i2c/mtk_i2c.c F: drivers/mmc/mtk-sd.c F: drivers/phy/phy-mtk-* F: drivers/pinctrl/mediatek/ F: drivers/power/domain/mtk-power-domain.c F: drivers/ram/mediatek/ F: drivers/spi/mtk_snfi_spi.c +F: drivers/spi/mtk_spim.c F: drivers/timer/mtk_timer.c F: drivers/usb/host/xhci-mtk.c F: drivers/usb/mtu3/ F: drivers/watchdog/mtk_wdt.c F: drivers/net/mtk_eth.c +F: drivers/net/mtk_eth.h F: drivers/reset/reset-mediatek.c F: tools/mtk_image.c F: tools/mtk_image.h +F: tools/mtk_nand_headers.c +F: tools/mtk_nand_headers.h N: mediatek ARM METHODE SUPPORT From 7210e457d5d166b4409bde402fd95a99e87cdfc5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Fri, 9 Sep 2022 17:32:38 +0200 Subject: [PATCH 273/374] common/memsize.c: Fix get_effective_memsize() to always check for CONFIG_MAX_MEM_MAPPED MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CONFIG_MAX_MEM_MAPPED when defined specifies upper memory mapped limit. So check for it always, and not only when CONFIG_VERY_BIG_RAM is defined. Signed-off-by: Pali Rohár --- common/memsize.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/memsize.c b/common/memsize.c index d5d13d51bf..31884acca0 100644 --- a/common/memsize.c +++ b/common/memsize.c @@ -94,7 +94,7 @@ long get_ram_size(long *base, long maxsize) phys_size_t __weak get_effective_memsize(void) { -#ifndef CONFIG_VERY_BIG_RAM +#ifndef CONFIG_MAX_MEM_MAPPED return gd->ram_size; #else /* limit stack to what we can reasonable map */ From 777aaaa706bcfe08c284aed06886db7d482af3f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Fri, 9 Sep 2022 17:32:39 +0200 Subject: [PATCH 274/374] common/memsize.c: Fix get_effective_memsize() to check for overflow MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ensure that top of RAM can be represented by phys_size_t type. If RAM is too large or RAM base address is too upper then limit RAM size to prevent address space overflow. Signed-off-by: Pali Rohár --- common/memsize.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/common/memsize.c b/common/memsize.c index 31884acca0..3c80ad2c83 100644 --- a/common/memsize.c +++ b/common/memsize.c @@ -94,11 +94,23 @@ long get_ram_size(long *base, long maxsize) phys_size_t __weak get_effective_memsize(void) { + phys_size_t ram_size = gd->ram_size; + + /* + * Check for overflow and limit ram size to some representable value. + * It is required that ram_base + ram_size must be representable by + * phys_size_t type and must be aligned by direct access, therefore + * calculate it from last 4kB sector which should work as alignment + * on any platform. + */ + if (gd->ram_base + ram_size < gd->ram_base) + ram_size = ((phys_size_t)~0xfffULL) - gd->ram_base; + #ifndef CONFIG_MAX_MEM_MAPPED - return gd->ram_size; + return ram_size; #else /* limit stack to what we can reasonable map */ - return ((gd->ram_size > CONFIG_MAX_MEM_MAPPED) ? - CONFIG_MAX_MEM_MAPPED : gd->ram_size); + return ((ram_size > CONFIG_MAX_MEM_MAPPED) ? + CONFIG_MAX_MEM_MAPPED : ram_size); #endif } From 049704f808d5e643668a33a76e55f925d4c1b36a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Fri, 9 Sep 2022 17:32:40 +0200 Subject: [PATCH 275/374] board_f: Fix types for board_get_usable_ram_top() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit 37dc958947ed ("global_data.h: Change ram_top type to phys_addr_t") changed type of ram_top member from ulong to phys_addr_t but did not changed types in board_get_usable_ram_top() function which returns value for ram_top. So change ulong to phys_addr_t type also in board_get_usable_ram_top() signature and implementations. Fixes: 37dc958947ed ("global_data.h: Change ram_top type to phys_addr_t") Signed-off-by: Pali Rohár Reviewed-by: Simon Glass --- arch/arm/mach-imx/imx8m/soc.c | 2 +- arch/arm/mach-mvebu/arm64-common.c | 2 +- arch/arm/mach-rockchip/sdram.c | 2 +- arch/arm/mach-stm32mp/dram_init.c | 2 +- arch/arm/mach-sunxi/board.c | 2 +- arch/arm/mach-tegra/board2.c | 2 +- arch/mips/mach-jz47xx/jz4780/jz4780.c | 2 +- arch/mips/mach-octeon/dram.c | 2 +- arch/riscv/cpu/fu540/dram.c | 2 +- arch/riscv/cpu/fu740/dram.c | 2 +- arch/riscv/cpu/generic/dram.c | 2 +- arch/x86/cpu/broadwell/sdram.c | 2 +- arch/x86/cpu/coreboot/sdram.c | 2 +- arch/x86/cpu/efi/payload.c | 2 +- arch/x86/cpu/efi/sdram.c | 2 +- arch/x86/cpu/intel_common/mrc.c | 4 ++-- arch/x86/cpu/ivybridge/sdram.c | 2 +- arch/x86/cpu/qemu/dram.c | 2 +- arch/x86/cpu/quark/dram.c | 2 +- arch/x86/cpu/slimbootloader/sdram.c | 2 +- arch/x86/cpu/tangier/sdram.c | 2 +- arch/x86/include/asm/mrc_common.h | 2 +- arch/x86/include/asm/u-boot-x86.h | 2 +- arch/x86/lib/fsp1/fsp_dram.c | 2 +- arch/x86/lib/fsp2/fsp_dram.c | 2 +- board/broadcom/bcmns3/ns3.c | 2 +- board/imgtec/boston/ddr.c | 2 +- board/menlo/m53menlo/m53menlo.c | 2 +- board/raspberrypi/rpi/rpi.c | 2 +- board/ti/am65x/evm.c | 2 +- board/ti/j721e/evm.c | 2 +- board/ti/j721s2/evm.c | 2 +- board/xilinx/common/board.c | 2 +- common/board_f.c | 2 +- include/init.h | 2 +- 35 files changed, 36 insertions(+), 36 deletions(-) diff --git a/arch/arm/mach-imx/imx8m/soc.c b/arch/arm/mach-imx/imx8m/soc.c index d115b25a5b..47c0a4f5c4 100644 --- a/arch/arm/mach-imx/imx8m/soc.c +++ b/arch/arm/mach-imx/imx8m/soc.c @@ -327,7 +327,7 @@ phys_size_t get_effective_memsize(void) } } -ulong board_get_usable_ram_top(ulong total_size) +phys_size_t board_get_usable_ram_top(phys_size_t total_size) { ulong top_addr; diff --git a/arch/arm/mach-mvebu/arm64-common.c b/arch/arm/mach-mvebu/arm64-common.c index 238edbe6ba..63f6af5fe8 100644 --- a/arch/arm/mach-mvebu/arm64-common.c +++ b/arch/arm/mach-mvebu/arm64-common.c @@ -30,7 +30,7 @@ DECLARE_GLOBAL_DATA_PTR; */ #define USABLE_RAM_SIZE 0x80000000ULL -ulong board_get_usable_ram_top(ulong total_size) +phys_size_t board_get_usable_ram_top(phys_size_t total_size) { unsigned long top = CONFIG_SYS_SDRAM_BASE + min(gd->ram_size, USABLE_RAM_SIZE); diff --git a/arch/arm/mach-rockchip/sdram.c b/arch/arm/mach-rockchip/sdram.c index 705ec7ba64..12f1d7ee56 100644 --- a/arch/arm/mach-rockchip/sdram.c +++ b/arch/arm/mach-rockchip/sdram.c @@ -205,7 +205,7 @@ int dram_init(void) return 0; } -ulong board_get_usable_ram_top(ulong total_size) +phys_size_t board_get_usable_ram_top(phys_size_t total_size) { unsigned long top = CONFIG_SYS_SDRAM_BASE + SDRAM_MAX_SIZE; diff --git a/arch/arm/mach-stm32mp/dram_init.c b/arch/arm/mach-stm32mp/dram_init.c index 920b99bb68..9346fa8546 100644 --- a/arch/arm/mach-stm32mp/dram_init.c +++ b/arch/arm/mach-stm32mp/dram_init.c @@ -40,7 +40,7 @@ int dram_init(void) return 0; } -ulong board_get_usable_ram_top(ulong total_size) +phys_size_t board_get_usable_ram_top(phys_size_t total_size) { phys_size_t size; phys_addr_t reg; diff --git a/arch/arm/mach-sunxi/board.c b/arch/arm/mach-sunxi/board.c index 8f7c894286..62bb40b8c8 100644 --- a/arch/arm/mach-sunxi/board.c +++ b/arch/arm/mach-sunxi/board.c @@ -65,7 +65,7 @@ static struct mm_region sunxi_mem_map[] = { }; struct mm_region *mem_map = sunxi_mem_map; -ulong board_get_usable_ram_top(ulong total_size) +phys_size_t board_get_usable_ram_top(phys_size_t total_size) { /* Some devices (like the EMAC) have a 32-bit DMA limit. */ if (gd->ram_top > (1ULL << 32)) diff --git a/arch/arm/mach-tegra/board2.c b/arch/arm/mach-tegra/board2.c index 8950e678a6..1994db0e15 100644 --- a/arch/arm/mach-tegra/board2.c +++ b/arch/arm/mach-tegra/board2.c @@ -401,7 +401,7 @@ int dram_init_banksize(void) * This function is called before dram_init_banksize(), so we can't simply * return gd->bd->bi_dram[1].start + gd->bd->bi_dram[1].size. */ -ulong board_get_usable_ram_top(ulong total_size) +phys_size_t board_get_usable_ram_top(phys_size_t total_size) { ulong ram_top; diff --git a/arch/mips/mach-jz47xx/jz4780/jz4780.c b/arch/mips/mach-jz47xx/jz4780/jz4780.c index fefba12873..a57ec7802b 100644 --- a/arch/mips/mach-jz47xx/jz4780/jz4780.c +++ b/arch/mips/mach-jz47xx/jz4780/jz4780.c @@ -76,7 +76,7 @@ void board_init_f(ulong dummy) } #endif /* CONFIG_SPL_BUILD */ -ulong board_get_usable_ram_top(ulong total_size) +phys_size_t board_get_usable_ram_top(phys_size_t total_size) { return CONFIG_SYS_SDRAM_BASE + (256 * 1024 * 1024); } diff --git a/arch/mips/mach-octeon/dram.c b/arch/mips/mach-octeon/dram.c index 4679260f17..9c5789b1c8 100644 --- a/arch/mips/mach-octeon/dram.c +++ b/arch/mips/mach-octeon/dram.c @@ -77,7 +77,7 @@ phys_size_t get_effective_memsize(void) return UBOOT_RAM_SIZE_MAX; } -ulong board_get_usable_ram_top(ulong total_size) +phys_size_t board_get_usable_ram_top(phys_size_t total_size) { if (IS_ENABLED(CONFIG_RAM_OCTEON)) { /* Map a maximum of 256MiB - return not size but address */ diff --git a/arch/riscv/cpu/fu540/dram.c b/arch/riscv/cpu/fu540/dram.c index 1fdc7837b8..44e11bd56c 100644 --- a/arch/riscv/cpu/fu540/dram.c +++ b/arch/riscv/cpu/fu540/dram.c @@ -21,7 +21,7 @@ int dram_init_banksize(void) return fdtdec_setup_memory_banksize(); } -ulong board_get_usable_ram_top(ulong total_size) +phys_size_t board_get_usable_ram_top(phys_size_t total_size) { /* * Ensure that we run from first 4GB so that all diff --git a/arch/riscv/cpu/fu740/dram.c b/arch/riscv/cpu/fu740/dram.c index 1dc77efeca..d6d4a41d25 100644 --- a/arch/riscv/cpu/fu740/dram.c +++ b/arch/riscv/cpu/fu740/dram.c @@ -20,7 +20,7 @@ int dram_init_banksize(void) return fdtdec_setup_memory_banksize(); } -ulong board_get_usable_ram_top(ulong total_size) +phys_size_t board_get_usable_ram_top(phys_size_t total_size) { #ifdef CONFIG_64BIT /* diff --git a/arch/riscv/cpu/generic/dram.c b/arch/riscv/cpu/generic/dram.c index 1fdc7837b8..44e11bd56c 100644 --- a/arch/riscv/cpu/generic/dram.c +++ b/arch/riscv/cpu/generic/dram.c @@ -21,7 +21,7 @@ int dram_init_banksize(void) return fdtdec_setup_memory_banksize(); } -ulong board_get_usable_ram_top(ulong total_size) +phys_size_t board_get_usable_ram_top(phys_size_t total_size) { /* * Ensure that we run from first 4GB so that all diff --git a/arch/x86/cpu/broadwell/sdram.c b/arch/x86/cpu/broadwell/sdram.c index c104a849a5..1295121ae5 100644 --- a/arch/x86/cpu/broadwell/sdram.c +++ b/arch/x86/cpu/broadwell/sdram.c @@ -25,7 +25,7 @@ #include #include -ulong board_get_usable_ram_top(ulong total_size) +phys_size_t board_get_usable_ram_top(phys_size_t total_size) { return mrc_common_board_get_usable_ram_top(total_size); } diff --git a/arch/x86/cpu/coreboot/sdram.c b/arch/x86/cpu/coreboot/sdram.c index 4a256bad44..f4ee4cdf5d 100644 --- a/arch/x86/cpu/coreboot/sdram.c +++ b/arch/x86/cpu/coreboot/sdram.c @@ -27,7 +27,7 @@ unsigned int install_e820_map(unsigned int max_entries, * address, and how far U-Boot is moved by relocation are set in the global * data structure. */ -ulong board_get_usable_ram_top(ulong total_size) +phys_size_t board_get_usable_ram_top(phys_size_t total_size) { uintptr_t dest_addr = 0; int i; diff --git a/arch/x86/cpu/efi/payload.c b/arch/x86/cpu/efi/payload.c index b7778565b1..1c28a43778 100644 --- a/arch/x86/cpu/efi/payload.c +++ b/arch/x86/cpu/efi/payload.c @@ -27,7 +27,7 @@ DECLARE_GLOBAL_DATA_PTR; * the relocation address, and how far U-Boot is moved by relocation are * set in the global data structure. */ -ulong board_get_usable_ram_top(ulong total_size) +phys_size_t board_get_usable_ram_top(phys_size_t total_size) { struct efi_mem_desc *desc, *end; struct efi_entry_memmap *map; diff --git a/arch/x86/cpu/efi/sdram.c b/arch/x86/cpu/efi/sdram.c index af65982fd0..f3086db42c 100644 --- a/arch/x86/cpu/efi/sdram.c +++ b/arch/x86/cpu/efi/sdram.c @@ -11,7 +11,7 @@ DECLARE_GLOBAL_DATA_PTR; -ulong board_get_usable_ram_top(ulong total_size) +phys_size_t board_get_usable_ram_top(phys_size_t total_size) { return (ulong)efi_get_ram_base() + gd->ram_size; } diff --git a/arch/x86/cpu/intel_common/mrc.c b/arch/x86/cpu/intel_common/mrc.c index a97b0b7ceb..a4918fbad6 100644 --- a/arch/x86/cpu/intel_common/mrc.c +++ b/arch/x86/cpu/intel_common/mrc.c @@ -25,7 +25,7 @@ static const char *const ecc_decoder[] = { "active" }; -ulong mrc_common_board_get_usable_ram_top(ulong total_size) +phys_size_t mrc_common_board_get_usable_ram_top(phys_size_t total_size) { struct memory_info *info = &gd->arch.meminfo; uintptr_t dest_addr = 0; @@ -50,7 +50,7 @@ ulong mrc_common_board_get_usable_ram_top(ulong total_size) dest_addr = largest->start + largest->size; - return (ulong)dest_addr; + return (phys_size_t)dest_addr; } void mrc_common_dram_init_banksize(void) diff --git a/arch/x86/cpu/ivybridge/sdram.c b/arch/x86/cpu/ivybridge/sdram.c index dd6b8753de..1a0ec433e6 100644 --- a/arch/x86/cpu/ivybridge/sdram.c +++ b/arch/x86/cpu/ivybridge/sdram.c @@ -44,7 +44,7 @@ DECLARE_GLOBAL_DATA_PTR; #define CMOS_OFFSET_MRC_SEED_S3 156 #define CMOS_OFFSET_MRC_SEED_CHK 160 -ulong board_get_usable_ram_top(ulong total_size) +phys_size_t board_get_usable_ram_top(phys_size_t total_size) { return mrc_common_board_get_usable_ram_top(total_size); } diff --git a/arch/x86/cpu/qemu/dram.c b/arch/x86/cpu/qemu/dram.c index c174550129..595c397d4a 100644 --- a/arch/x86/cpu/qemu/dram.c +++ b/arch/x86/cpu/qemu/dram.c @@ -71,7 +71,7 @@ int dram_init_banksize(void) * the relocation address, and how far U-Boot is moved by relocation are * set in the global data structure. */ -ulong board_get_usable_ram_top(ulong total_size) +phys_size_t board_get_usable_ram_top(phys_size_t total_size) { return qemu_get_low_memory_size(); } diff --git a/arch/x86/cpu/quark/dram.c b/arch/x86/cpu/quark/dram.c index 2287dce12b..8b1ee2d5ae 100644 --- a/arch/x86/cpu/quark/dram.c +++ b/arch/x86/cpu/quark/dram.c @@ -184,7 +184,7 @@ int dram_init_banksize(void) * the relocation address, and how far U-Boot is moved by relocation are * set in the global data structure. */ -ulong board_get_usable_ram_top(ulong total_size) +phys_size_t board_get_usable_ram_top(phys_size_t total_size) { return gd->ram_size; } diff --git a/arch/x86/cpu/slimbootloader/sdram.c b/arch/x86/cpu/slimbootloader/sdram.c index c6f10e22e3..d748d5c7d4 100644 --- a/arch/x86/cpu/slimbootloader/sdram.c +++ b/arch/x86/cpu/slimbootloader/sdram.c @@ -48,7 +48,7 @@ static struct sbl_memory_map_info *get_memory_map_info(void) * @total_size: The memory size that u-boot occupies * Return: : The top available memory address lower than 4GB */ -ulong board_get_usable_ram_top(ulong total_size) +phys_size_t board_get_usable_ram_top(phys_size_t total_size) { struct sbl_memory_map_info *data; int i; diff --git a/arch/x86/cpu/tangier/sdram.c b/arch/x86/cpu/tangier/sdram.c index afb08476ed..8a4b1c5d2d 100644 --- a/arch/x86/cpu/tangier/sdram.c +++ b/arch/x86/cpu/tangier/sdram.c @@ -204,7 +204,7 @@ unsigned int install_e820_map(unsigned int max_entries, * address, and how far U-Boot is moved by relocation are set in the global * data structure. */ -ulong board_get_usable_ram_top(ulong total_size) +phys_size_t board_get_usable_ram_top(phys_size_t total_size) { struct sfi_table_simple *sb; struct sfi_mem_entry *mentry; diff --git a/arch/x86/include/asm/mrc_common.h b/arch/x86/include/asm/mrc_common.h index 3d7f00c9f9..a7f260a707 100644 --- a/arch/x86/include/asm/mrc_common.h +++ b/arch/x86/include/asm/mrc_common.h @@ -47,7 +47,7 @@ int mrc_add_memory_area(struct memory_info *info, uint64_t start, * the relocation address, and how far U-Boot is moved by relocation are * set in the global data structure. */ -ulong mrc_common_board_get_usable_ram_top(ulong total_size); +phys_size_t mrc_common_board_get_usable_ram_top(phys_size_t total_size); void mrc_common_dram_init_banksize(void); diff --git a/arch/x86/include/asm/u-boot-x86.h b/arch/x86/include/asm/u-boot-x86.h index a1655e1cea..4cf41e9354 100644 --- a/arch/x86/include/asm/u-boot-x86.h +++ b/arch/x86/include/asm/u-boot-x86.h @@ -77,7 +77,7 @@ int x86_cleanup_before_linux(void); void x86_enable_caches(void); void x86_disable_caches(void); int x86_init_cache(void); -ulong board_get_usable_ram_top(ulong total_size); +phys_size_t board_get_usable_ram_top(phys_size_t total_size); int default_print_cpuinfo(void); /* Set up a UART which can be used with printch(), printhex8(), etc. */ diff --git a/arch/x86/lib/fsp1/fsp_dram.c b/arch/x86/lib/fsp1/fsp_dram.c index cfd9b9f48c..5825221d1e 100644 --- a/arch/x86/lib/fsp1/fsp_dram.c +++ b/arch/x86/lib/fsp1/fsp_dram.c @@ -34,7 +34,7 @@ int dram_init(void) * the relocation address, and how far U-Boot is moved by relocation are * set in the global data structure. */ -ulong board_get_usable_ram_top(ulong total_size) +phys_size_t board_get_usable_ram_top(phys_size_t total_size) { return fsp_get_usable_lowmem_top(gd->arch.hob_list); } diff --git a/arch/x86/lib/fsp2/fsp_dram.c b/arch/x86/lib/fsp2/fsp_dram.c index 42d3892b76..f9ea1ab3ba 100644 --- a/arch/x86/lib/fsp2/fsp_dram.c +++ b/arch/x86/lib/fsp2/fsp_dram.c @@ -77,7 +77,7 @@ int dram_init(void) return 0; } -ulong board_get_usable_ram_top(ulong total_size) +phys_size_t board_get_usable_ram_top(phys_size_t total_size) { if (!ll_boot_init()) return gd->ram_size; diff --git a/board/broadcom/bcmns3/ns3.c b/board/broadcom/bcmns3/ns3.c index 88036c16c9..26652e8f77 100644 --- a/board/broadcom/bcmns3/ns3.c +++ b/board/broadcom/bcmns3/ns3.c @@ -183,7 +183,7 @@ int dram_init_banksize(void) } /* Limit RAM used by U-Boot to the DDR first bank End region */ -ulong board_get_usable_ram_top(ulong total_size) +phys_size_t board_get_usable_ram_top(phys_size_t total_size) { return BCM_NS3_MEM_END; } diff --git a/board/imgtec/boston/ddr.c b/board/imgtec/boston/ddr.c index 182f79b918..5b245cb447 100644 --- a/board/imgtec/boston/ddr.c +++ b/board/imgtec/boston/ddr.c @@ -23,7 +23,7 @@ int dram_init(void) return 0; } -ulong board_get_usable_ram_top(ulong total_size) +phys_size_t board_get_usable_ram_top(phys_size_t total_size) { DECLARE_GLOBAL_DATA_PTR; diff --git a/board/menlo/m53menlo/m53menlo.c b/board/menlo/m53menlo/m53menlo.c index 61ab3844b8..4afc5aaa43 100644 --- a/board/menlo/m53menlo/m53menlo.c +++ b/board/menlo/m53menlo/m53menlo.c @@ -42,7 +42,7 @@ DECLARE_GLOBAL_DATA_PTR; static u32 mx53_dram_size[2]; -ulong board_get_usable_ram_top(ulong total_size) +phys_size_t board_get_usable_ram_top(phys_size_t total_size) { /* * WARNING: We must override get_effective_memsize() function here diff --git a/board/raspberrypi/rpi/rpi.c b/board/raspberrypi/rpi/rpi.c index 17b8108cc8..00afb352bd 100644 --- a/board/raspberrypi/rpi/rpi.c +++ b/board/raspberrypi/rpi/rpi.c @@ -335,7 +335,7 @@ static void set_fdt_addr(void) /* * Prevent relocation from stomping on a firmware provided FDT blob. */ -unsigned long board_get_usable_ram_top(unsigned long total_size) +phys_size_t board_get_usable_ram_top(phys_size_t total_size) { if ((gd->ram_top - fw_dtb_pointer) > SZ_64M) return gd->ram_top; diff --git a/board/ti/am65x/evm.c b/board/ti/am65x/evm.c index 8a0a506a3e..34ec3915f3 100644 --- a/board/ti/am65x/evm.c +++ b/board/ti/am65x/evm.c @@ -61,7 +61,7 @@ int dram_init(void) return 0; } -ulong board_get_usable_ram_top(ulong total_size) +phys_size_t board_get_usable_ram_top(phys_size_t total_size) { #ifdef CONFIG_PHYS_64BIT /* Limit RAM used by U-Boot to the DDR low region */ diff --git a/board/ti/j721e/evm.c b/board/ti/j721e/evm.c index 5d090048ce..d6e431ead0 100644 --- a/board/ti/j721e/evm.c +++ b/board/ti/j721e/evm.c @@ -57,7 +57,7 @@ int dram_init(void) return 0; } -ulong board_get_usable_ram_top(ulong total_size) +phys_size_t board_get_usable_ram_top(phys_size_t total_size) { #ifdef CONFIG_PHYS_64BIT /* Limit RAM used by U-Boot to the DDR low region */ diff --git a/board/ti/j721s2/evm.c b/board/ti/j721s2/evm.c index 3c75ecfc0f..e09adc8ad3 100644 --- a/board/ti/j721s2/evm.c +++ b/board/ti/j721s2/evm.c @@ -46,7 +46,7 @@ int dram_init(void) return 0; } -ulong board_get_usable_ram_top(ulong total_size) +phys_size_t board_get_usable_ram_top(phys_size_t total_size) { #ifdef CONFIG_PHYS_64BIT /* Limit RAM used by U-Boot to the DDR low region */ diff --git a/board/xilinx/common/board.c b/board/xilinx/common/board.c index e1f7104960..391ce4dbd7 100644 --- a/board/xilinx/common/board.c +++ b/board/xilinx/common/board.c @@ -631,7 +631,7 @@ int embedded_dtb_select(void) #endif #if defined(CONFIG_LMB) -ulong board_get_usable_ram_top(ulong total_size) +phys_size_t board_get_usable_ram_top(phys_size_t total_size) { phys_size_t size; phys_addr_t reg; diff --git a/common/board_f.c b/common/board_f.c index f92d7b9faf..aee3f56d67 100644 --- a/common/board_f.c +++ b/common/board_f.c @@ -305,7 +305,7 @@ __weak int mach_cpu_init(void) } /* Get the top of usable RAM */ -__weak ulong board_get_usable_ram_top(ulong total_size) +__weak phys_size_t board_get_usable_ram_top(phys_size_t total_size) { #if defined(CONFIG_SYS_SDRAM_BASE) && CONFIG_SYS_SDRAM_BASE > 0 /* diff --git a/include/init.h b/include/init.h index 02bb4ce13e..50a8302dc5 100644 --- a/include/init.h +++ b/include/init.h @@ -291,7 +291,7 @@ int show_board_info(void); * * @param total_size Size of U-Boot (unused?) */ -ulong board_get_usable_ram_top(ulong total_size); +phys_size_t board_get_usable_ram_top(phys_size_t total_size); int board_early_init_f(void); From d92aee57eca089e6732a5c3c79c3a319819e1bfd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Fri, 9 Sep 2022 17:32:41 +0200 Subject: [PATCH 276/374] board_f: Fix printing gd->ram_size and gd->ram_top MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Members gd->ram_size and gd->ram_top are of type phys_addr_t which does not have to fit into ulong type. So cast them into unsigned long long. Fixes: 37dc958947ed ("global_data.h: Change ram_top type to phys_addr_t") Signed-off-by: Pali Rohár Reviewed-by: Simon Glass --- common/board_f.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/common/board_f.c b/common/board_f.c index aee3f56d67..970c8ff67f 100644 --- a/common/board_f.c +++ b/common/board_f.c @@ -328,7 +328,7 @@ static int setup_dest_addr(void) /* * Ram is setup, size stored in gd !! */ - debug("Ram size: %08lX\n", (ulong)gd->ram_size); + debug("Ram size: %08llX\n", (unsigned long long)gd->ram_size); #if CONFIG_VAL(SYS_MEM_TOP_HIDE) /* * Subtract specified amount of memory to hide so that it won't @@ -348,7 +348,7 @@ static int setup_dest_addr(void) gd->ram_top = gd->ram_base + get_effective_memsize(); gd->ram_top = board_get_usable_ram_top(gd->mon_len); gd->relocaddr = gd->ram_top; - debug("Ram top: %08lX\n", (ulong)gd->ram_top); + debug("Ram top: %08llX\n", (unsigned long long)gd->ram_top); #if defined(CONFIG_MP) && (defined(CONFIG_MPC86xx) || defined(CONFIG_E500)) /* * We need to make sure the location we intend to put secondary core From cf4eba4eb66dbf6102200af6ba6f1ee05fabfe3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Fri, 9 Sep 2022 17:32:42 +0200 Subject: [PATCH 277/374] ddr: fsl: Fix checking for maximal mappable memory MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Check needs to be done against CONFIG_MAX_MEM_MAPPED macro and not fixed size 4GB (as CONFIG_MAX_MEM_MAPPED can be lower and for example for e500 cores it is just 2GB). Also fix printf re-align, which should be applied only for non-SPL builds, during init_dram() call. Signed-off-by: Pali Rohár --- drivers/ddr/fsl/main.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/drivers/ddr/fsl/main.c b/drivers/ddr/fsl/main.c index 1903562ac4..020adb0abb 100644 --- a/drivers/ddr/fsl/main.c +++ b/drivers/ddr/fsl/main.c @@ -857,13 +857,22 @@ phys_size_t __fsl_ddr_sdram(fsl_ddr_info_t *pinfo) debug("total_memory by %s = %llu\n", __func__, total_memory); #if !defined(CONFIG_PHYS_64BIT) - /* Check for 4G or more. Bad. */ - if ((first_ctrl == 0) && (total_memory >= (1ull << 32))) { + /* Check for more than max memory. Bad. */ + if ((first_ctrl == 0) && (total_memory > CONFIG_MAX_MEM_MAPPED)) { puts("Detected "); print_size(total_memory, " of memory\n"); - printf(" This U-Boot only supports < 4G of DDR\n"); - printf(" You could rebuild it with CONFIG_PHYS_64BIT\n"); - printf(" "); /* re-align to match init_dram print */ +#ifndef CONFIG_SPL_BUILD + puts(" "); /* re-align to match init_dram print */ +#endif + puts("This U-Boot only supports <= "); + print_size(CONFIG_MAX_MEM_MAPPED, " of DDR\n"); +#ifndef CONFIG_SPL_BUILD + puts(" "); /* re-align to match init_dram print */ +#endif + puts("You could rebuild it with CONFIG_PHYS_64BIT\n"); +#ifndef CONFIG_SPL_BUILD + puts(" "); /* re-align to match init_dram print */ +#endif total_memory = CONFIG_MAX_MEM_MAPPED; } #endif From 922460be0b72b40cae52f5e870d38c90b609b64b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Fri, 9 Sep 2022 17:32:43 +0200 Subject: [PATCH 278/374] ddr: fsl: Fix fsl_ddr_sdram_size() for 4GB modules with 32-bit phys_size_t MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Function fsl_ddr_compute() always return size in unsigned long long type, but function fsl_ddr_sdram_size() returns size in phys_size_t type. When 36-bit addressing mode is not enabled then phys_size_t type is only 32-bit and thus it cannot store value 4GB (0x100000000). Function fsl_ddr_sdram_size() in this case returns truncated value 0x0. Fix this issue by returning the highest representable value, which is 0xffffffff (4GB - 1 byte). This change fixes crashing of proper U-Boot because it detected 4 GB module as RAM with zero size. Signed-off-by: Pali Rohár --- drivers/ddr/fsl/main.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/ddr/fsl/main.c b/drivers/ddr/fsl/main.c index 020adb0abb..d44f16cdba 100644 --- a/drivers/ddr/fsl/main.c +++ b/drivers/ddr/fsl/main.c @@ -950,5 +950,9 @@ fsl_ddr_sdram_size(void) /* Compute it once normally. */ total_memory = fsl_ddr_compute(&info, STEP_GET_SPD, 1); + /* Ensure that total_memory does not overflow on return */ + if (total_memory > (phys_size_t)~0ULL) + total_memory = (phys_size_t)~0ULL; + return total_memory; } From 272199765412182f82ff789eaeffb2d93d70a01e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Fri, 9 Sep 2022 17:32:44 +0200 Subject: [PATCH 279/374] ddr: fsl: Allow to detect 4 GB DDR modules in 32-bit mode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit U-Boot core code already handles the case when RAM size is bigger than CONFIG_MAX_MEM_MAPPED. So there is no need to do duplicate check in fsl ddr driver for CONFIG_MAX_MEM_MAPPED. Instead simplify code to just check if RAM size can be representable in phys_size_t type. And avoid printing warning if phys_size_t is just 1 byte smaller than RAM size, which is the typical situation with 4 GB DDR module. Signed-off-by: Pali Rohár --- drivers/ddr/fsl/main.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/drivers/ddr/fsl/main.c b/drivers/ddr/fsl/main.c index d44f16cdba..ed3313a531 100644 --- a/drivers/ddr/fsl/main.c +++ b/drivers/ddr/fsl/main.c @@ -857,15 +857,18 @@ phys_size_t __fsl_ddr_sdram(fsl_ddr_info_t *pinfo) debug("total_memory by %s = %llu\n", __func__, total_memory); #if !defined(CONFIG_PHYS_64BIT) - /* Check for more than max memory. Bad. */ - if ((first_ctrl == 0) && (total_memory > CONFIG_MAX_MEM_MAPPED)) { + /* + * Show warning about big DDR moodules. But avoid warning for 4 GB DDR + * modules when U-Boot supports RAM of maximal size 4 GB - 1 byte. + */ + if ((first_ctrl == 0) && (total_memory - 1 > (phys_size_t)~0ULL)) { puts("Detected "); print_size(total_memory, " of memory\n"); #ifndef CONFIG_SPL_BUILD puts(" "); /* re-align to match init_dram print */ #endif puts("This U-Boot only supports <= "); - print_size(CONFIG_MAX_MEM_MAPPED, " of DDR\n"); + print_size((unsigned long long)((phys_size_t)~0ULL)+1, " of DDR\n"); #ifndef CONFIG_SPL_BUILD puts(" "); /* re-align to match init_dram print */ #endif @@ -873,10 +876,13 @@ phys_size_t __fsl_ddr_sdram(fsl_ddr_info_t *pinfo) #ifndef CONFIG_SPL_BUILD puts(" "); /* re-align to match init_dram print */ #endif - total_memory = CONFIG_MAX_MEM_MAPPED; } #endif + /* Ensure that total_memory does not overflow on return */ + if (total_memory > (phys_size_t)~0ULL) + total_memory = (phys_size_t)~0ULL; + return total_memory; } From a86e294f9f072dd08410ef83af44258503dca1a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Fri, 9 Sep 2022 17:32:45 +0200 Subject: [PATCH 280/374] ddr: fsl: Fix re-align of verbose DRAM information for non-SPL builds MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit During init_dram() is called also compute_lowest_common_dimm_parameters() function which prints multi-line detailed output. So print also re-aligning filler after "Detected ?DIMM" line to have "DRAM: " output aligned. Signed-off-by: Pali Rohár --- drivers/ddr/fsl/lc_common_dimm_params.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/ddr/fsl/lc_common_dimm_params.c b/drivers/ddr/fsl/lc_common_dimm_params.c index d738ae3a7c..5e4ad56f07 100644 --- a/drivers/ddr/fsl/lc_common_dimm_params.c +++ b/drivers/ddr/fsl/lc_common_dimm_params.c @@ -422,6 +422,9 @@ compute_lowest_common_dimm_parameters(const unsigned int ctrl_num, dimm_params[i].mpart); #endif } +#ifndef CONFIG_SPL_BUILD + puts(" "); +#endif } } From eec715e30f4e4c6afe1bc441f9c7682e9e5bac62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Fri, 9 Sep 2022 17:32:46 +0200 Subject: [PATCH 281/374] powerpc/mpc85xx: Explain TLB unmapped memory message MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently U-Boot SPL prints just generic message "2 GiB left unmapped". Change it to more detailed "2 GiB of DDR memory left unmapped in U-Boot". This is just U-Boot configuration and operating system may map more (or also less) memory. Signed-off-by: Pali Rohár --- arch/powerpc/cpu/mpc85xx/tlb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/powerpc/cpu/mpc85xx/tlb.c b/arch/powerpc/cpu/mpc85xx/tlb.c index ab616497fa..4e4ecb4d7f 100644 --- a/arch/powerpc/cpu/mpc85xx/tlb.c +++ b/arch/powerpc/cpu/mpc85xx/tlb.c @@ -312,7 +312,7 @@ unsigned int setup_ddr_tlbs_phys(phys_addr_t p_addr, if (size || memsize > CONFIG_MAX_MEM_MAPPED) { print_size(memsize > CONFIG_MAX_MEM_MAPPED ? memsize - CONFIG_MAX_MEM_MAPPED + size : size, - " left unmapped\n"); + " of DDR memory left unmapped in U-Boot\n"); } return memsize_in_meg; From 6f915a5d24b1c8cf30a29d7edff01eb5951bef0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Sun, 11 Sep 2022 11:29:16 +0200 Subject: [PATCH 282/374] powerpc/mpc85xx: Fix re-align of unmapped DDR memory message for non-SPL builds MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit During init_dram() is called also setup_ddr_tlbs_phys() function which may print message about unmapped DDR memory. So in this case print also re-aligning filler after unmapped DDR memory message. Signed-off-by: Pali Rohár --- arch/powerpc/cpu/mpc85xx/tlb.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/powerpc/cpu/mpc85xx/tlb.c b/arch/powerpc/cpu/mpc85xx/tlb.c index 4e4ecb4d7f..e39fe14382 100644 --- a/arch/powerpc/cpu/mpc85xx/tlb.c +++ b/arch/powerpc/cpu/mpc85xx/tlb.c @@ -313,6 +313,9 @@ unsigned int setup_ddr_tlbs_phys(phys_addr_t p_addr, print_size(memsize > CONFIG_MAX_MEM_MAPPED ? memsize - CONFIG_MAX_MEM_MAPPED + size : size, " of DDR memory left unmapped in U-Boot\n"); +#ifndef CONFIG_SPL_BUILD + puts(" "); +#endif } return memsize_in_meg; From d179018e4c9561afac5ca5c8878852f1171b836b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Mon, 12 Sep 2022 21:02:27 +0200 Subject: [PATCH 283/374] display_options: print_size: Fix order overflow MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Function print_size() round size to the nearst value with one decimal fraction number. But in special cases also unit order may overflow. For example value 1073689396 is printed as "1024 MiB" and value 1073741824 as "1 GiB". Fix this issue by detecting order overflow and increasing unit order. With this change also value 1073689396 is printed as "1 GiB". Signed-off-by: Pali Rohár Reviewed-by: Simon Glass --- lib/display_options.c | 6 ++++++ test/lib/test_print.c | 3 +++ 2 files changed, 9 insertions(+) diff --git a/lib/display_options.c b/lib/display_options.c index 7feb446a55..80def5201f 100644 --- a/lib/display_options.c +++ b/lib/display_options.c @@ -127,6 +127,12 @@ void print_size(uint64_t size, const char *s) if (m >= 10) { m -= 10; n += 1; + + if (n == 1024 && i > 0) { + n = 1; + m = 0; + c = names[i - 1]; + } } } diff --git a/test/lib/test_print.c b/test/lib/test_print.c index a60a5a51f1..79b67c7793 100644 --- a/test/lib/test_print.c +++ b/test/lib/test_print.c @@ -68,6 +68,9 @@ static int lib_test_print_size(struct unit_test_state *uts) ut_assertok(test_print_size(uts, 7654321, "7.3 MiB;")); ut_assertok(test_print_size(uts, 87654321, "83.6 MiB;")); ut_assertok(test_print_size(uts, 987654321, "941.9 MiB;")); + ut_assertok(test_print_size(uts, 1073689395, "1023.9 MiB;")); + ut_assertok(test_print_size(uts, 1073689396, "1 GiB;")); + ut_assertok(test_print_size(uts, 1073741824, "1 GiB;")); ut_assertok(test_print_size(uts, 1987654321, "1.9 GiB;")); ut_assertok(test_print_size(uts, 54321987654321, "49.4 TiB;")); return 0; From 236f73962718511e801f4ec9562075e86f737ec4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Sun, 18 Sep 2022 13:23:27 +0200 Subject: [PATCH 284/374] board_f: show_dram_config: Print also real DRAM size MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 32-bit U-Boot builds cannot use more than around 2 GB of DDR memory. But on some platforms/boards it is possible to connect also 4 GB SODIMM DDR memory. U-Boot currently prints only effective size of RAM which can use, which may be misleading as somebody would expect that this line prints total size of connected DDR modules. So change show_dram_config code to prints both real and effective DRAM size if they are different. If they are same then print just one number like before. It is possible that effective size is just few bytes smaller than the real size, so print both numbers only in case function print_size() prints formats them differently. Signed-off-by: Pali Rohár --- common/board_f.c | 37 ++++++++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/common/board_f.c b/common/board_f.c index 970c8ff67f..3df4efeeff 100644 --- a/common/board_f.c +++ b/common/board_f.c @@ -57,6 +57,7 @@ #include #include #include +#include /* * Pointer to initial global data area @@ -216,6 +217,36 @@ static int announce_dram_init(void) return 0; } +/* + * From input size calculate its nearest rounded unit scale (multiply of 2^10) + * and value in calculated unit scale multiplied by 10 (as fractional fixed + * point number with one decimal digit), which is human natural format, + * same what uses print_size() function for displaying. Mathematically it is: + * round_nearest(val * 2^scale) = size * 10; where: 10 <= val < 10240. + * + * For example for size=87654321 we calculate scale=20 and val=836 which means + * that input has natural human format 83.6 M (mega = 2^20). + */ +#define compute_size_scale_val(size, scale, val) do { \ + scale = ilog2(size) / 10 * 10; \ + val = (10 * size + ((1ULL << scale) >> 1)) >> scale; \ + if (val == 10240) { val = 10; scale += 10; } \ +} while (0) + +/* + * Check if the sizes in their natural units written in decimal format with + * one fraction number are same. + */ +static int sizes_near(unsigned long long size1, unsigned long long size2) +{ + unsigned int size1_scale, size1_val, size2_scale, size2_val; + + compute_size_scale_val(size1, size1_scale, size1_val); + compute_size_scale_val(size2, size2_scale, size2_val); + + return size1_scale == size2_scale && size1_val == size2_val; +} + static int show_dram_config(void) { unsigned long long size; @@ -232,7 +263,11 @@ static int show_dram_config(void) } debug("\nDRAM: "); - print_size(size, ""); + print_size(gd->ram_size, ""); + if (!sizes_near(gd->ram_size, size)) { + printf(" (effective "); + print_size(size, ")"); + } board_add_ram_info(0); putc('\n'); From ca0f827dc78aa23d3b898856cbe2727bdec108e2 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Thu, 22 Sep 2022 15:26:43 +0200 Subject: [PATCH 285/374] efi_selftest: prefix test functions with efi_st_ An upcoming patch set creates a global function flush(). To make debugging easier we should not use the same name for a static function. Rename static functions in the LoadImage() unit test adding an efi_st_ prefix. Signed-off-by: Heinrich Schuchardt Reviewed-by: Ilias Apalodimas --- lib/efi_selftest/efi_selftest_loadimage.c | 87 ++++++++++++----------- 1 file changed, 44 insertions(+), 43 deletions(-) diff --git a/lib/efi_selftest/efi_selftest_loadimage.c b/lib/efi_selftest/efi_selftest_loadimage.c index d4c76f557c..24548f1ae6 100644 --- a/lib/efi_selftest/efi_selftest_loadimage.c +++ b/lib/efi_selftest/efi_selftest_loadimage.c @@ -142,38 +142,39 @@ static struct efi_file_system_info *file_system_info = &priv_file_system_info.info; /* Forward definitions of file and file system functions */ -static efi_status_t EFIAPI open_volume +static efi_status_t EFIAPI efi_st_open_volume (struct efi_simple_file_system_protocol *this, struct efi_file_handle **root); -static efi_status_t EFIAPI open +static efi_status_t EFIAPI efi_st_open (struct efi_file_handle *this, struct efi_file_handle **new_handle, u16 *file_name, u64 open_mode, u64 attributes); -static efi_status_t EFIAPI close(struct efi_file_handle *this); +static efi_status_t EFIAPI efi_st_close(struct efi_file_handle *this); -static efi_status_t EFIAPI delete(struct efi_file_handle *this); +static efi_status_t EFIAPI efi_st_delete(struct efi_file_handle *this); -static efi_status_t EFIAPI read +static efi_status_t EFIAPI efi_st_read (struct efi_file_handle *this, efi_uintn_t *buffer_size, void *buffer); -static efi_status_t EFIAPI write +static efi_status_t EFIAPI efi_st_write (struct efi_file_handle *this, efi_uintn_t *buffer_size, void *buffer); -static efi_status_t EFIAPI getpos(struct efi_file_handle *this, u64 *pos); +static efi_status_t EFIAPI efi_st_getpos(struct efi_file_handle *this, + u64 *pos); -static efi_status_t EFIAPI setpos(struct efi_file_handle *this, u64 pos); +static efi_status_t EFIAPI efi_st_setpos(struct efi_file_handle *this, u64 pos); -static efi_status_t EFIAPI getinfo +static efi_status_t EFIAPI efi_st_getinfo (struct efi_file_handle *this, const efi_guid_t *info_type, efi_uintn_t *buffer_size, void *buffer); -static efi_status_t EFIAPI setinfo +static efi_status_t EFIAPI efi_st_setinfo (struct efi_file_handle *this, const efi_guid_t *info_type, efi_uintn_t buffer_size, void *buffer); -static efi_status_t EFIAPI flush(struct efi_file_handle *this); +static efi_status_t EFIAPI efi_st_flush(struct efi_file_handle *this); /* Internal information about status of file system */ static struct { @@ -190,40 +191,40 @@ static struct { /* EFI_FILE_PROTOCOL for file */ static struct efi_file_handle file = { .rev = 0x00010000, - .open = open, - .close = close, - .delete = delete, - .read = read, - .write = write, - .getpos = getpos, - .setpos = setpos, - .getinfo = getinfo, - .setinfo = setinfo, - .flush = flush, + .open = efi_st_open, + .close = efi_st_close, + .delete = efi_st_delete, + .read = efi_st_read, + .write = efi_st_write, + .getpos = efi_st_getpos, + .setpos = efi_st_setpos, + .getinfo = efi_st_getinfo, + .setinfo = efi_st_setinfo, + .flush = efi_st_flush, }; /* EFI_FILE_PROTOCOL for root directory */ static struct efi_file_handle volume = { .rev = 0x00010000, - .open = open, - .close = close, - .delete = delete, - .read = read, - .write = write, - .getpos = getpos, - .setpos = setpos, - .getinfo = getinfo, - .setinfo = setinfo, - .flush = flush, + .open = efi_st_open, + .close = efi_st_close, + .delete = efi_st_delete, + .read = efi_st_read, + .write = efi_st_write, + .getpos = efi_st_getpos, + .setpos = efi_st_setpos, + .getinfo = efi_st_getinfo, + .setinfo = efi_st_setinfo, + .flush = efi_st_flush, }; /* EFI_SIMPLE_FILE_SYSTEM_PROTOCOL of the block device */ struct efi_simple_file_system_protocol file_system = { .rev = 0x00010000, - .open_volume = open_volume, + .open_volume = efi_st_open_volume, }; -static efi_status_t EFIAPI open_volume +static efi_status_t EFIAPI efi_st_open_volume (struct efi_simple_file_system_protocol *this, struct efi_file_handle **root) { @@ -236,7 +237,7 @@ static efi_status_t EFIAPI open_volume return EFI_SUCCESS; } -static efi_status_t EFIAPI open +static efi_status_t EFIAPI efi_st_open (struct efi_file_handle *this, struct efi_file_handle **new_handle, u16 *file_name, u64 open_mode, u64 attributes) @@ -251,7 +252,7 @@ static efi_status_t EFIAPI open return EFI_SUCCESS; } -static efi_status_t EFIAPI close(struct efi_file_handle *this) +static efi_status_t EFIAPI efi_st_close(struct efi_file_handle *this) { if (this == &file) priv.file_open_count--; @@ -263,7 +264,7 @@ static efi_status_t EFIAPI close(struct efi_file_handle *this) return EFI_SUCCESS; } -static efi_status_t EFIAPI delete(struct efi_file_handle *this) +static efi_status_t EFIAPI efi_st_delete(struct efi_file_handle *this) { if (this != &file) return EFI_INVALID_PARAMETER; @@ -271,7 +272,7 @@ static efi_status_t EFIAPI delete(struct efi_file_handle *this) return EFI_UNSUPPORTED; } -static efi_status_t EFIAPI read +static efi_status_t EFIAPI efi_st_read (struct efi_file_handle *this, efi_uintn_t *buffer_size, void *buffer) { if (this != &file) @@ -288,7 +289,7 @@ static efi_status_t EFIAPI read return EFI_SUCCESS; } -static efi_status_t EFIAPI write +static efi_status_t EFIAPI efi_st_write (struct efi_file_handle *this, efi_uintn_t *buffer_size, void *buffer) { if (this != &file) @@ -297,7 +298,7 @@ static efi_status_t EFIAPI write return EFI_UNSUPPORTED; } -static efi_status_t EFIAPI getpos(struct efi_file_handle *this, u64 *pos) +static efi_status_t EFIAPI efi_st_getpos(struct efi_file_handle *this, u64 *pos) { if (this != &file) return EFI_INVALID_PARAMETER; @@ -307,7 +308,7 @@ static efi_status_t EFIAPI getpos(struct efi_file_handle *this, u64 *pos) return EFI_SUCCESS; } -static efi_status_t EFIAPI setpos(struct efi_file_handle *this, u64 pos) +static efi_status_t EFIAPI efi_st_setpos(struct efi_file_handle *this, u64 pos) { if (this != &file) return EFI_INVALID_PARAMETER; @@ -317,7 +318,7 @@ static efi_status_t EFIAPI setpos(struct efi_file_handle *this, u64 pos) return EFI_SUCCESS; } -static efi_status_t EFIAPI getinfo +static efi_status_t EFIAPI efi_st_getinfo (struct efi_file_handle *this, const efi_guid_t *info_type, efi_uintn_t *buffer_size, void *buffer) { @@ -348,7 +349,7 @@ static efi_status_t EFIAPI getinfo return EFI_SUCCESS; } -static efi_status_t EFIAPI setinfo +static efi_status_t EFIAPI efi_st_setinfo (struct efi_file_handle *this, const efi_guid_t *info_type, efi_uintn_t buffer_size, void *buffer) { @@ -358,7 +359,7 @@ static efi_status_t EFIAPI setinfo return EFI_UNSUPPORTED; } -static efi_status_t EFIAPI flush(struct efi_file_handle *this) +static efi_status_t EFIAPI efi_st_flush(struct efi_file_handle *this) { if (this != &file) return EFI_INVALID_PARAMETER; From 7df5b353347621cca0eef7420ba045bf852e778a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Mon, 5 Sep 2022 11:31:16 +0200 Subject: [PATCH 286/374] sandbox: Add function os_flush() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It flushes stdout. Signed-off-by: Pali Rohár Reviewed-by: Simon Glass --- arch/sandbox/cpu/os.c | 5 +++++ include/os.h | 8 ++++++++ 2 files changed, 13 insertions(+) diff --git a/arch/sandbox/cpu/os.c b/arch/sandbox/cpu/os.c index f937991139..01845e388d 100644 --- a/arch/sandbox/cpu/os.c +++ b/arch/sandbox/cpu/os.c @@ -669,6 +669,11 @@ void os_puts(const char *str) os_putc(*str++); } +void os_flush(void) +{ + fflush(stdout); +} + int os_write_ram_buf(const char *fname) { struct sandbox_state *state = state_get_current(); diff --git a/include/os.h b/include/os.h index 148178787b..5b353ae9d9 100644 --- a/include/os.h +++ b/include/os.h @@ -295,6 +295,14 @@ void os_putc(int ch); */ void os_puts(const char *str); +/** + * os_flush() - flush controlling OS terminal + * + * This bypasses the U-Boot console support and flushes directly the OS + * stdout file descriptor. + */ +void os_flush(void); + /** * os_write_ram_buf() - write the sandbox RAM buffer to a existing file * From 974f48366f5b151f13b91961ec7721e74fb54fa9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Mon, 5 Sep 2022 11:31:17 +0200 Subject: [PATCH 287/374] console: Implement flush() function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On certain places it is required to flush output print buffers to ensure that text strings were sent to console or serial devices. For example when printing message that U-Boot is going to boot kernel or when U-Boot is going to change baudrate of terminal device. Therefore introduce a new flush() and fflush() functions into console code. These functions will call .flush callback of associated stdio_dev device. As this function may increase U-Boot side, allow to compile U-Boot without this function. For this purpose there is a new config CONSOLE_FLUSH_SUPPORT which is enabled by default and can be disabled. It is a good idea to have this option enabled for all boards which have enough space for it. When option is disabled when U-Boot defines just empty static inline function fflush() to avoid ifdefs in other code. Signed-off-by: Pali Rohár Reviewed-by: Simon Glass --- common/Kconfig | 6 +++++ common/console.c | 61 +++++++++++++++++++++++++++++++++++++++++++++ include/_exports.h | 3 +++ include/stdio.h | 15 +++++++++++ include/stdio_dev.h | 7 ++++++ 5 files changed, 92 insertions(+) diff --git a/common/Kconfig b/common/Kconfig index b776c5ca1e..6591acd2fd 100644 --- a/common/Kconfig +++ b/common/Kconfig @@ -186,6 +186,12 @@ config PRE_CON_BUF_ADDR We should consider removing this option and allocating the memory in board_init_f_init_reserve() instead. +config CONSOLE_FLUSH_SUPPORT + bool "Enable console flush support" + default y + help + This enables compilation of flush() function for console flush support. + config CONSOLE_MUX bool "Enable console multiplexing" default y if DM_VIDEO || VIDEO || LCD diff --git a/common/console.c b/common/console.c index e5be6ff44b..ce0c9b69f5 100644 --- a/common/console.c +++ b/common/console.c @@ -199,6 +199,7 @@ static int console_setfile(int file, struct stdio_dev * dev) case stdout: gd->jt->putc = putc; gd->jt->puts = puts; + STDIO_DEV_ASSIGN_FLUSH(gd->jt, flush); gd->jt->printf = printf; break; } @@ -364,6 +365,19 @@ static void console_puts(int file, const char *s) } } +#ifdef CONFIG_CONSOLE_FLUSH_SUPPORT +static void console_flush(int file) +{ + int i; + struct stdio_dev *dev; + + for_each_console_dev(i, file, dev) { + if (dev->flush != NULL) + dev->flush(dev); + } +} +#endif + #if CONFIG_IS_ENABLED(SYS_CONSOLE_IS_IN_ENV) static inline void console_doenv(int file, struct stdio_dev *dev) { @@ -413,6 +427,14 @@ static inline void console_puts(int file, const char *s) stdio_devices[file]->puts(stdio_devices[file], s); } +#ifdef CONFIG_CONSOLE_FLUSH_SUPPORT +static inline void console_flush(int file) +{ + if (stdio_devices[file]->flush) + stdio_devices[file]->flush(stdio_devices[file]); +} +#endif + #if CONFIG_IS_ENABLED(SYS_CONSOLE_IS_IN_ENV) static inline void console_doenv(int file, struct stdio_dev *dev) { @@ -526,6 +548,14 @@ void fputs(int file, const char *s) console_puts(file, s); } +#ifdef CONFIG_CONSOLE_FLUSH_SUPPORT +void fflush(int file) +{ + if (file < MAX_FILES) + console_flush(file); +} +#endif + int fprintf(int file, const char *fmt, ...) { va_list args; @@ -740,6 +770,37 @@ void puts(const char *s) } } +#ifdef CONFIG_CONSOLE_FLUSH_SUPPORT +void flush(void) +{ + if (!gd) + return; + + /* sandbox can send characters to stdout before it has a console */ + if (IS_ENABLED(CONFIG_SANDBOX) && !(gd->flags & GD_FLG_SERIAL_READY)) { + os_flush(); + return; + } + + if (IS_ENABLED(CONFIG_DEBUG_UART) && !(gd->flags & GD_FLG_SERIAL_READY)) + return; + + if (IS_ENABLED(CONFIG_SILENT_CONSOLE) && (gd->flags & GD_FLG_SILENT)) + return; + + if (IS_ENABLED(CONFIG_DISABLE_CONSOLE) && (gd->flags & GD_FLG_DISABLE_CONSOLE)) + return; + + if (!gd->have_console) + return; + + if (gd->flags & GD_FLG_DEVINIT) { + /* Send to the standard output */ + fflush(stdout); + } +} +#endif + #ifdef CONFIG_CONSOLE_RECORD int console_record_init(void) { diff --git a/include/_exports.h b/include/_exports.h index f6df8b6107..1af946fac3 100644 --- a/include/_exports.h +++ b/include/_exports.h @@ -12,6 +12,9 @@ EXPORT_FUNC(tstc, int, tstc, void) EXPORT_FUNC(putc, void, putc, const char) EXPORT_FUNC(puts, void, puts, const char *) +#ifdef CONFIG_CONSOLE_FLUSH_SUPPORT + EXPORT_FUNC(flush, void, flush, void) +#endif EXPORT_FUNC(printf, int, printf, const char*, ...) #if (defined(CONFIG_X86) && !defined(CONFIG_X86_64)) || defined(CONFIG_PPC) EXPORT_FUNC(irq_install_handler, void, install_hdlr, diff --git a/include/stdio.h b/include/stdio.h index 1939a48f0f..3241e2d493 100644 --- a/include/stdio.h +++ b/include/stdio.h @@ -15,6 +15,11 @@ int tstc(void); defined(CONFIG_SPL_SERIAL)) void putc(const char c); void puts(const char *s); +#ifdef CONFIG_CONSOLE_FLUSH_SUPPORT +void flush(void); +#else +static inline void flush(void) {} +#endif int __printf(1, 2) printf(const char *fmt, ...); int vprintf(const char *fmt, va_list args); #else @@ -26,6 +31,10 @@ static inline void puts(const char *s) { } +static inline void flush(void) +{ +} + static inline int __printf(1, 2) printf(const char *fmt, ...) { return 0; @@ -48,11 +57,17 @@ static inline int vprintf(const char *fmt, va_list args) /* stderr */ #define eputc(c) fputc(stderr, c) #define eputs(s) fputs(stderr, s) +#define eflush() fflush(stderr) #define eprintf(fmt, args...) fprintf(stderr, fmt, ##args) int __printf(2, 3) fprintf(int file, const char *fmt, ...); void fputs(int file, const char *s); void fputc(int file, const char c); +#ifdef CONFIG_CONSOLE_FLUSH_SUPPORT +void fflush(int file); +#else +static inline void fflush(int file) {} +#endif int ftstc(int file); int fgetc(int file); diff --git a/include/stdio_dev.h b/include/stdio_dev.h index 270fa2729f..3105928970 100644 --- a/include/stdio_dev.h +++ b/include/stdio_dev.h @@ -37,6 +37,13 @@ struct stdio_dev { void (*putc)(struct stdio_dev *dev, const char c); /* To put a string (accelerator) */ void (*puts)(struct stdio_dev *dev, const char *s); +#ifdef CONFIG_CONSOLE_FLUSH_SUPPORT + /* To flush output queue */ + void (*flush)(struct stdio_dev *dev); +#define STDIO_DEV_ASSIGN_FLUSH(dev, flush_func) ((dev)->flush = (flush_func)) +#else +#define STDIO_DEV_ASSIGN_FLUSH(dev, flush_func) +#endif /* INPUT functions */ From 016e2be96d4247ceacca05932f2e94d31607cc57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Mon, 5 Sep 2022 11:31:18 +0200 Subject: [PATCH 288/374] serial: Implement flush callback MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit UART drivers have putc/puts functions which just put characters into HW transmit queue and do not wait until all data are transmitted. Implement flush callback via serial driver's pending(false) callback which waits until HW transmit all characters from the queue. Signed-off-by: Pali Rohár Reviewed-by: Simon Glass --- drivers/serial/serial-uclass.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/drivers/serial/serial-uclass.c b/drivers/serial/serial-uclass.c index 0d43e9b625..1234fe0e84 100644 --- a/drivers/serial/serial-uclass.c +++ b/drivers/serial/serial-uclass.c @@ -238,6 +238,18 @@ static void _serial_puts(struct udevice *dev, const char *str) } while (*str); } +#ifdef CONFIG_CONSOLE_FLUSH_SUPPORT +static void _serial_flush(struct udevice *dev) +{ + struct dm_serial_ops *ops = serial_get_ops(dev); + + if (!ops->pending) + return; + while (ops->pending(dev, false) > 0) + ; +} +#endif + static int __serial_getc(struct udevice *dev) { struct dm_serial_ops *ops = serial_get_ops(dev); @@ -398,6 +410,13 @@ static void serial_stub_puts(struct stdio_dev *sdev, const char *str) _serial_puts(sdev->priv, str); } +#ifdef CONFIG_CONSOLE_FLUSH_SUPPORT +static void serial_stub_flush(struct stdio_dev *sdev) +{ + _serial_flush(sdev->priv); +} +#endif + static int serial_stub_getc(struct stdio_dev *sdev) { return _serial_getc(sdev->priv); @@ -520,6 +539,7 @@ static int serial_post_probe(struct udevice *dev) sdev.priv = dev; sdev.putc = serial_stub_putc; sdev.puts = serial_stub_puts; + STDIO_DEV_ASSIGN_FLUSH(&sdev, serial_stub_flush); sdev.getc = serial_stub_getc; sdev.tstc = serial_stub_tstc; From 78b5243182be8fa222f6d496e7d49675fde4d09e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Mon, 5 Sep 2022 11:31:19 +0200 Subject: [PATCH 289/374] serial: Implement serial_flush() function for console flush() fallback MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Like in all other console functions, implement also serial_flush() function as a fallback int console flush() function. Flush support is available only when config option CONSOLE_FLUSH_SUPPORT is enabled. So when it is disabled then provides just empty static inline function serial_flush(). Signed-off-by: Pali Rohár Reviewed-by: Simon Glass --- common/console.c | 3 +++ common/stdio.c | 8 ++++++++ drivers/serial/serial-uclass.c | 10 ++++++++++ include/serial.h | 5 +++++ 4 files changed, 26 insertions(+) diff --git a/common/console.c b/common/console.c index ce0c9b69f5..0c9bf66c3f 100644 --- a/common/console.c +++ b/common/console.c @@ -797,6 +797,9 @@ void flush(void) if (gd->flags & GD_FLG_DEVINIT) { /* Send to the standard output */ fflush(stdout); + } else { + /* Send directly to the handler */ + serial_flush(); } } #endif diff --git a/common/stdio.c b/common/stdio.c index 92161a0df8..13083842cb 100644 --- a/common/stdio.c +++ b/common/stdio.c @@ -87,6 +87,13 @@ static void stdio_serial_puts(struct stdio_dev *dev, const char *s) serial_puts(s); } +#ifdef CONFIG_CONSOLE_FLUSH_SUPPORT +static void stdio_serial_flush(struct stdio_dev *dev) +{ + serial_flush(); +} +#endif + static int stdio_serial_getc(struct stdio_dev *dev) { return serial_getc(); @@ -112,6 +119,7 @@ static void drv_system_init (void) dev.flags = DEV_FLAGS_OUTPUT | DEV_FLAGS_INPUT; dev.putc = stdio_serial_putc; dev.puts = stdio_serial_puts; + STDIO_DEV_ASSIGN_FLUSH(&dev, stdio_serial_flush); dev.getc = stdio_serial_getc; dev.tstc = stdio_serial_tstc; stdio_register (&dev); diff --git a/drivers/serial/serial-uclass.c b/drivers/serial/serial-uclass.c index 1234fe0e84..53df10ee85 100644 --- a/drivers/serial/serial-uclass.c +++ b/drivers/serial/serial-uclass.c @@ -327,6 +327,16 @@ void serial_puts(const char *str) _serial_puts(gd->cur_serial_dev, str); } +#ifdef CONFIG_CONSOLE_FLUSH_SUPPORT +void serial_flush(void) +{ + if (!gd->cur_serial_dev) + return; + + _serial_flush(gd->cur_serial_dev); +} +#endif + int serial_getc(void) { if (!gd->cur_serial_dev) diff --git a/include/serial.h b/include/serial.h index 8c2e7adbc3..fe01bcfadb 100644 --- a/include/serial.h +++ b/include/serial.h @@ -362,6 +362,11 @@ void serial_setbrg(void); void serial_putc(const char ch); void serial_putc_raw(const char ch); void serial_puts(const char *str); +#if defined(CONFIG_CONSOLE_FLUSH_SUPPORT) && CONFIG_IS_ENABLED(DM_SERIAL) +void serial_flush(void); +#else +static inline void serial_flush(void) {} +#endif int serial_getc(void); int serial_tstc(void); From 989cc40f806b68678e10203ec3b63d38d0fdd6eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Mon, 5 Sep 2022 11:31:20 +0200 Subject: [PATCH 290/374] serial: Call flush() before changing baudrate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Changing baudrate is a sensitive operation. To ensure that U-Boot messages printed before changing baudrate are not lost, call new U-Boot console flush() function. Signed-off-by: Pali Rohár Reviewed-by: Simon Glass --- cmd/load.c | 5 +++++ drivers/serial/serial-uclass.c | 1 + 2 files changed, 6 insertions(+) diff --git a/cmd/load.c b/cmd/load.c index e44ae0d56b..5c4f34781d 100644 --- a/cmd/load.c +++ b/cmd/load.c @@ -83,6 +83,7 @@ static int do_load_serial(struct cmd_tbl *cmdtp, int flag, int argc, printf("## Switch baudrate to %d bps and press ENTER ...\n", load_baudrate); udelay(50000); + flush(); gd->baudrate = load_baudrate; serial_setbrg(); udelay(50000); @@ -126,6 +127,7 @@ static int do_load_serial(struct cmd_tbl *cmdtp, int flag, int argc, printf("## Switch baudrate to %d bps and press ESC ...\n", current_baudrate); udelay(50000); + flush(); gd->baudrate = current_baudrate; serial_setbrg(); udelay(50000); @@ -317,6 +319,7 @@ int do_save_serial(struct cmd_tbl *cmdtp, int flag, int argc, printf("## Switch baudrate to %d bps and press ESC ...\n", (int)current_baudrate); udelay(50000); + flush(); gd->baudrate = current_baudrate; serial_setbrg(); udelay(50000); @@ -471,6 +474,7 @@ static int do_load_serial_bin(struct cmd_tbl *cmdtp, int flag, int argc, printf("## Switch baudrate to %d bps and press ENTER ...\n", load_baudrate); udelay(50000); + flush(); gd->baudrate = load_baudrate; serial_setbrg(); udelay(50000); @@ -533,6 +537,7 @@ static int do_load_serial_bin(struct cmd_tbl *cmdtp, int flag, int argc, printf("## Switch baudrate to %d bps and press ESC ...\n", current_baudrate); udelay(50000); + flush(); gd->baudrate = current_baudrate; serial_setbrg(); udelay(50000); diff --git a/drivers/serial/serial-uclass.c b/drivers/serial/serial-uclass.c index 53df10ee85..da3e1eb3ab 100644 --- a/drivers/serial/serial-uclass.c +++ b/drivers/serial/serial-uclass.c @@ -476,6 +476,7 @@ static int on_baudrate(const char *name, const char *value, enum env_op op, printf("## Switch baudrate to %d bps and press ENTER ...\n", baudrate); udelay(50000); + flush(); } gd->baudrate = baudrate; From efc3f9526f9cfcd8614668c03b9c66b209782c41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Mon, 5 Sep 2022 11:31:21 +0200 Subject: [PATCH 291/374] boot: Call flush() before booting MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In a lot of cases kernel resets UART HW. To ensure that U-Boot messages printed before booting the kernel are not lost, call new U-Boot console flush() function. Signed-off-by: Pali Rohár Reviewed-by: Simon Glass --- boot/bootm_os.c | 1 + cmd/boot.c | 1 + cmd/elf.c | 2 ++ 3 files changed, 4 insertions(+) diff --git a/boot/bootm_os.c b/boot/bootm_os.c index f31820cd07..079224ce58 100644 --- a/boot/bootm_os.c +++ b/boot/bootm_os.c @@ -303,6 +303,7 @@ static void do_bootvx_fdt(bootm_headers_t *images) #else printf("## Starting vxWorks at 0x%08lx\n", (ulong)images->ep); #endif + flush(); boot_jump_vxworks(images); diff --git a/cmd/boot.c b/cmd/boot.c index be67a5980d..14839c1ced 100644 --- a/cmd/boot.c +++ b/cmd/boot.c @@ -32,6 +32,7 @@ static int do_go(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) addr = hextoul(argv[1], NULL); printf ("## Starting application at 0x%08lX ...\n", addr); + flush(); /* * pass address parameter as argv[0] (aka command name), diff --git a/cmd/elf.c b/cmd/elf.c index ce40d3f72a..b7b9f506a5 100644 --- a/cmd/elf.c +++ b/cmd/elf.c @@ -72,6 +72,7 @@ int do_bootelf(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) return rcode; printf("## Starting application at 0x%08lx ...\n", addr); + flush(); /* * pass address parameter as argv[0] (aka command name), @@ -274,6 +275,7 @@ int do_bootvx(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) puts("## Not an ELF image, assuming binary\n"); printf("## Starting vxWorks at 0x%08lx ...\n", addr); + flush(); dcache_disable(); #if defined(CONFIG_ARM64) && defined(CONFIG_ARMV8_PSCI) From a2a9317cbc396c19baea217e091960c56c13f2c7 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Fri, 2 Sep 2022 02:32:25 +0200 Subject: [PATCH 292/374] sandbox: unblock signal before calling execv() The following faulty behavior was observed. The sandbox configured with CONFIG_SANDBOX_CRASH_RESET=y was invoked with ./u-boot -T -S After executing `exception undefined' the sandbox reboots. When executing `exception undefined' the sandbox exits with SIGSEGV. The expected behavior is that the sandbox should reboot again. If we are relaunching the sandbox in a signal handler, we have to unblock the respective signal before calling execv(). See signal(7) man-page. Signed-off-by: Heinrich Schuchardt Reviewed-by: Simon Glass --- arch/sandbox/cpu/os.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/arch/sandbox/cpu/os.c b/arch/sandbox/cpu/os.c index 01845e388d..d6170adaf5 100644 --- a/arch/sandbox/cpu/os.c +++ b/arch/sandbox/cpu/os.c @@ -1017,8 +1017,24 @@ void *os_find_text_base(void) return base; } +/** + * os_unblock_signals() - unblock all signals + * + * If we are relaunching the sandbox in a signal handler, we have to unblock + * the respective signal before calling execv(). See signal(7) man-page. + */ +static void os_unblock_signals(void) +{ + sigset_t sigs; + + sigfillset(&sigs); + sigprocmask(SIG_UNBLOCK, &sigs, NULL); +} + void os_relaunch(char *argv[]) { + os_unblock_signals(); + execv(argv[0], argv); os_exit(1); } From 8149b1500d805b56f2e3e42fb31c5554a2011745 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 17 Sep 2022 09:00:09 -0600 Subject: [PATCH 293/374] blk: Rename if_type to uclass_id Use the word 'uclass' instead of 'if_type' to complete the conversion. Signed-off-by: Simon Glass --- board/st/common/stm32mp_dfu.c | 2 +- cmd/bcb.c | 4 +- cmd/blk_common.c | 18 ++--- cmd/lsblk.c | 2 +- cmd/mmc.c | 4 +- common/spl/spl_sata.c | 2 +- common/spl/spl_usb.c | 2 +- common/usb_storage.c | 6 +- disk/disk-uclass.c | 8 +- disk/part.c | 14 ++-- doc/usage/partitions.rst | 2 +- drivers/ata/sata.c | 2 +- drivers/block/blk-uclass.c | 145 +++++++++++++++++----------------- drivers/block/blk_legacy.c | 58 +++++++------- drivers/block/ide.c | 8 +- drivers/block/sandbox.c | 8 +- drivers/mmc/mmc-uclass.c | 2 +- drivers/mmc/mmc_legacy.c | 8 +- drivers/net/fsl_enetc.c | 12 +-- drivers/net/fsl_enetc.h | 2 +- drivers/scsi/scsi.c | 6 +- drivers/virtio/virtio_blk.c | 2 +- drivers/xen/pvblock.c | 2 +- fs/fat/fat.c | 2 +- include/blk.h | 122 ++++++++++++++-------------- include/efi_loader.h | 4 +- lib/efi_loader/efi_disk.c | 12 +-- lib/efi_loader/efi_var_file.c | 4 +- 28 files changed, 231 insertions(+), 232 deletions(-) diff --git a/board/st/common/stm32mp_dfu.c b/board/st/common/stm32mp_dfu.c index fa48b2a35e..0096f71dfc 100644 --- a/board/st/common/stm32mp_dfu.c +++ b/board/st/common/stm32mp_dfu.c @@ -37,7 +37,7 @@ static void board_get_alt_info_mmc(struct udevice *dev, char *buf) if (!desc) return; - name = blk_get_if_type_name(desc->if_type); + name = blk_get_uclass_name(desc->uclass_id); devnum = desc->devnum; len = strlen(buf); diff --git a/cmd/bcb.c b/cmd/bcb.c index 8b87aa062f..1622a90c97 100644 --- a/cmd/bcb.c +++ b/cmd/bcb.c @@ -122,7 +122,7 @@ static int __bcb_load(int devnum, const char *partp) char *endp; int part, ret; - desc = blk_get_devnum_by_type(UCLASS_MMC, devnum); + desc = blk_get_devnum_by_uclass_id(UCLASS_MMC, devnum); if (!desc) { ret = -ENODEV; goto err_read_fail; @@ -287,7 +287,7 @@ static int __bcb_store(void) u64 cnt; int ret; - desc = blk_get_devnum_by_type(UCLASS_MMC, bcb_dev); + desc = blk_get_devnum_by_uclass_id(UCLASS_MMC, bcb_dev); if (!desc) { ret = -ENODEV; goto err; diff --git a/cmd/blk_common.c b/cmd/blk_common.c index 369c5ae4bb..75a072caf5 100644 --- a/cmd/blk_common.c +++ b/cmd/blk_common.c @@ -12,10 +12,10 @@ #include #include -int blk_common_cmd(int argc, char *const argv[], enum uclass_id if_type, +int blk_common_cmd(int argc, char *const argv[], enum uclass_id uclass_id, int *cur_devnump) { - const char *if_name = blk_get_if_type_name(if_type); + const char *if_name = blk_get_uclass_name(uclass_id); switch (argc) { case 0: @@ -23,16 +23,16 @@ int blk_common_cmd(int argc, char *const argv[], enum uclass_id if_type, return CMD_RET_USAGE; case 2: if (strncmp(argv[1], "inf", 3) == 0) { - blk_list_devices(if_type); + blk_list_devices(uclass_id); return 0; } else if (strncmp(argv[1], "dev", 3) == 0) { - if (blk_print_device_num(if_type, *cur_devnump)) { + if (blk_print_device_num(uclass_id, *cur_devnump)) { printf("\nno %s devices available\n", if_name); return CMD_RET_FAILURE; } return 0; } else if (strncmp(argv[1], "part", 4) == 0) { - if (blk_list_part(if_type)) + if (blk_list_part(uclass_id)) printf("\nno %s partition table available\n", if_name); return 0; @@ -42,7 +42,7 @@ int blk_common_cmd(int argc, char *const argv[], enum uclass_id if_type, if (strncmp(argv[1], "dev", 3) == 0) { int dev = (int)dectoul(argv[2], NULL); - if (!blk_show_device(if_type, dev)) { + if (!blk_show_device(uclass_id, dev)) { *cur_devnump = dev; printf("... is now current device\n"); } else { @@ -52,7 +52,7 @@ int blk_common_cmd(int argc, char *const argv[], enum uclass_id if_type, } else if (strncmp(argv[1], "part", 4) == 0) { int dev = (int)dectoul(argv[2], NULL); - if (blk_print_part_devnum(if_type, dev)) { + if (blk_print_part_devnum(uclass_id, dev)) { printf("\n%s device %d not available\n", if_name, dev); return CMD_RET_FAILURE; @@ -71,7 +71,7 @@ int blk_common_cmd(int argc, char *const argv[], enum uclass_id if_type, printf("\n%s read: device %d block # "LBAFU", count %lu ... ", if_name, *cur_devnump, blk, cnt); - n = blk_read_devnum(if_type, *cur_devnump, blk, cnt, + n = blk_read_devnum(uclass_id, *cur_devnump, blk, cnt, (ulong *)addr); printf("%ld blocks read: %s\n", n, @@ -86,7 +86,7 @@ int blk_common_cmd(int argc, char *const argv[], enum uclass_id if_type, printf("\n%s write: device %d block # "LBAFU", count %lu ... ", if_name, *cur_devnump, blk, cnt); - n = blk_write_devnum(if_type, *cur_devnump, blk, cnt, + n = blk_write_devnum(uclass_id, *cur_devnump, blk, cnt, (ulong *)addr); printf("%ld blocks written: %s\n", n, diff --git a/cmd/lsblk.c b/cmd/lsblk.c index 6a1c8f5ef4..d214dafc3b 100644 --- a/cmd/lsblk.c +++ b/cmd/lsblk.c @@ -36,7 +36,7 @@ static int do_lsblk(struct cmd_tbl *cmdtp, int flag, int argc, char * const argv continue; desc = dev_get_uclass_plat(udev); printf("%c %s %u", i ? ',' : ':', - blk_get_if_type_name(desc->if_type), + blk_get_uclass_name(desc->uclass_id), desc->devnum); i++; } diff --git a/cmd/mmc.c b/cmd/mmc.c index 0f1f4e0a71..c79d940798 100644 --- a/cmd/mmc.c +++ b/cmd/mmc.c @@ -154,7 +154,7 @@ static struct mmc *__init_mmc_device(int dev, bool force_init, #ifdef CONFIG_BLOCK_CACHE struct blk_desc *bd = mmc_get_blk_desc(mmc); - blkcache_invalidate(bd->if_type, bd->devnum); + blkcache_invalidate(bd->uclass_id, bd->devnum); #endif return mmc; @@ -530,7 +530,7 @@ static int do_mmc_part(struct cmd_tbl *cmdtp, int flag, if (!mmc) return CMD_RET_FAILURE; - mmc_dev = blk_get_devnum_by_type(UCLASS_MMC, curr_device); + mmc_dev = blk_get_devnum_by_uclass_id(UCLASS_MMC, curr_device); if (mmc_dev != NULL && mmc_dev->type != DEV_TYPE_UNKNOWN) { part_print(mmc_dev); return CMD_RET_SUCCESS; diff --git a/common/spl/spl_sata.c b/common/spl/spl_sata.c index ea9f1756c0..6c36f2ca66 100644 --- a/common/spl/spl_sata.c +++ b/common/spl/spl_sata.c @@ -71,7 +71,7 @@ static int spl_sata_load_image(struct spl_image_info *spl_image, /* try to recognize storage devices immediately */ scsi_scan(false); - stor_dev = blk_get_devnum_by_type(UCLASS_SCSI, 0); + stor_dev = blk_get_devnum_by_uclass_id(UCLASS_SCSI, 0); if (!stor_dev) return -ENODEV; diff --git a/common/spl/spl_usb.c b/common/spl/spl_usb.c index 63c00f872b..479e2dc182 100644 --- a/common/spl/spl_usb.c +++ b/common/spl/spl_usb.c @@ -41,7 +41,7 @@ int spl_usb_load(struct spl_image_info *spl_image, /* try to recognize storage devices immediately */ usb_stor_curr_dev = usb_stor_scan(1); - stor_dev = blk_get_devnum_by_type(UCLASS_USB, usb_stor_curr_dev); + stor_dev = blk_get_devnum_by_uclass_id(UCLASS_USB, usb_stor_curr_dev); if (!stor_dev) return -ENODEV; diff --git a/common/usb_storage.c b/common/usb_storage.c index 7d420160cd..e59c819bac 100644 --- a/common/usb_storage.c +++ b/common/usb_storage.c @@ -279,7 +279,7 @@ static int usb_stor_probe_device(struct usb_device *udev) blkdev = &usb_dev_desc[usb_max_devs]; memset(blkdev, '\0', sizeof(struct blk_desc)); - blkdev->if_type = UCLASS_USB; + blkdev->uclass_id = UCLASS_USB; blkdev->devnum = usb_max_devs; blkdev->part_type = PART_TYPE_UNKNOWN; blkdev->target = 0xff; @@ -1577,8 +1577,8 @@ U_BOOT_DRIVER(usb_storage_blk) = { }; #else U_BOOT_LEGACY_BLK(usb) = { - .if_typename = "usb", - .if_type = UCLASS_USB, + .uclass_idname = "usb", + .uclass_id = UCLASS_USB, .max_devs = USB_MAX_STOR_DEV, .desc = usb_dev_desc, }; diff --git a/disk/disk-uclass.c b/disk/disk-uclass.c index 9351a5cfa6..551f8b1dca 100644 --- a/disk/disk-uclass.c +++ b/disk/disk-uclass.c @@ -191,12 +191,12 @@ unsigned long dev_read(struct udevice *dev, lbaint_t start, start_in_disk += part->gpt_part_info.start; } - if (blkcache_read(block_dev->if_type, block_dev->devnum, + if (blkcache_read(block_dev->uclass_id, block_dev->devnum, start_in_disk, blkcnt, block_dev->blksz, buffer)) return blkcnt; blks_read = ops->read(dev, start, blkcnt, buffer); if (blks_read == blkcnt) - blkcache_fill(block_dev->if_type, block_dev->devnum, + blkcache_fill(block_dev->uclass_id, block_dev->devnum, start_in_disk, blkcnt, block_dev->blksz, buffer); return blks_read; @@ -216,7 +216,7 @@ unsigned long dev_write(struct udevice *dev, lbaint_t start, if (!ops->write) return -ENOSYS; - blkcache_invalidate(block_dev->if_type, block_dev->devnum); + blkcache_invalidate(block_dev->uclass_id, block_dev->devnum); return ops->write(dev, start, blkcnt, buffer); } @@ -235,7 +235,7 @@ unsigned long dev_erase(struct udevice *dev, lbaint_t start, if (!ops->erase) return -ENOSYS; - blkcache_invalidate(block_dev->if_type, block_dev->devnum); + blkcache_invalidate(block_dev->uclass_id, block_dev->devnum); return ops->erase(dev, start, blkcnt); } diff --git a/disk/part.c b/disk/part.c index 47214c0ee9..f982b30f97 100644 --- a/disk/part.c +++ b/disk/part.c @@ -61,7 +61,7 @@ static struct blk_desc *get_dev_hwpart(const char *ifname, int dev, int hwpart) if (!blk_enabled()) return NULL; - dev_desc = blk_get_devnum_by_typename(ifname, dev); + dev_desc = blk_get_devnum_by_uclass_idname(ifname, dev); if (!dev_desc) { debug("%s: No device for iface '%s', dev %d\n", __func__, ifname, dev); @@ -120,7 +120,7 @@ void dev_print(struct blk_desc *dev_desc) return; } - switch (dev_desc->if_type) { + switch (dev_desc->uclass_id) { case UCLASS_SCSI: printf ("(%d:%d) Vendor: %s Prod.: %s Rev: %s\n", dev_desc->target,dev_desc->lun, @@ -155,7 +155,7 @@ void dev_print(struct blk_desc *dev_desc) puts("device type unknown\n"); return; default: - printf("Unhandled device type: %i\n", dev_desc->if_type); + printf("Unhandled device type: %i\n", dev_desc->uclass_id); return; } puts (" Type: "); @@ -225,7 +225,7 @@ void part_init(struct blk_desc *dev_desc) const int n_ents = ll_entry_count(struct part_driver, part_driver); struct part_driver *entry; - blkcache_invalidate(dev_desc->if_type, dev_desc->devnum); + blkcache_invalidate(dev_desc->uclass_id, dev_desc->devnum); dev_desc->part_type = PART_TYPE_UNKNOWN; for (entry = drv; entry != drv + n_ents; entry++) { @@ -248,7 +248,7 @@ static void print_part_header(const char *type, struct blk_desc *dev_desc) CONFIG_IS_ENABLED(AMIGA_PARTITION) || \ CONFIG_IS_ENABLED(EFI_PARTITION) puts ("\nPartition Map for "); - switch (dev_desc->if_type) { + switch (dev_desc->uclass_id) { case UCLASS_IDE: puts ("IDE"); break; @@ -408,7 +408,7 @@ int blk_get_device_by_str(const char *ifname, const char *dev_hwpart_str, * Always should be done, otherwise hw partition 0 will return * stale data after displaying a non-zero hw partition. */ - if ((*dev_desc)->if_type == UCLASS_MMC) + if ((*dev_desc)->uclass_id == UCLASS_MMC) part_init(*dev_desc); } @@ -762,7 +762,7 @@ void part_set_generic_name(const struct blk_desc *dev_desc, { char *devtype; - switch (dev_desc->if_type) { + switch (dev_desc->uclass_id) { case UCLASS_IDE: case UCLASS_AHCI: devtype = "hd"; diff --git a/doc/usage/partitions.rst b/doc/usage/partitions.rst index 2c1a12b6bf..628469bbec 100644 --- a/doc/usage/partitions.rst +++ b/doc/usage/partitions.rst @@ -20,7 +20,7 @@ generic syntax. interface The interface used to access the partition's device, like ``mmc`` or ``scsi``. For a full list of supported interfaces, consult the - ``if_typename_str`` array in ``drivers/block/blk-uclass.c`` + ``uclass_idname_str`` array in ``drivers/block/blk-uclass.c`` devnum The device number. This defaults to 0. diff --git a/drivers/ata/sata.c b/drivers/ata/sata.c index 604c721cfd..ce3e9b5a40 100644 --- a/drivers/ata/sata.c +++ b/drivers/ata/sata.c @@ -79,7 +79,7 @@ int __sata_initialize(void) for (i = 0; i < CONFIG_SYS_SATA_MAX_DEVICE; i++) { memset(&sata_dev_desc[i], 0, sizeof(struct blk_desc)); - sata_dev_desc[i].if_type = UCLASS_AHCI; + sata_dev_desc[i].uclass_id = UCLASS_AHCI; sata_dev_desc[i].devnum = i; sata_dev_desc[i].part_type = PART_TYPE_UNKNOWN; sata_dev_desc[i].type = DEV_TYPE_HARDDISK; diff --git a/drivers/block/blk-uclass.c b/drivers/block/blk-uclass.c index a9a85aa37f..7d12d5413f 100644 --- a/drivers/block/blk-uclass.c +++ b/drivers/block/blk-uclass.c @@ -20,7 +20,7 @@ static struct { enum uclass_id id; const char *name; -} if_typename_str[] = { +} uclass_idname_str[] = { { UCLASS_IDE, "ide" }, { UCLASS_SCSI, "scsi" }, { UCLASS_USB, "usb" }, @@ -34,19 +34,19 @@ static struct { { UCLASS_PVBLOCK, "pvblock" }, }; -static enum uclass_id if_typename_to_iftype(const char *if_typename) +static enum uclass_id uclass_name_to_iftype(const char *uclass_idname) { int i; - for (i = 0; i < ARRAY_SIZE(if_typename_str); i++) { - if (!strcmp(if_typename, if_typename_str[i].name)) - return if_typename_str[i].id; + for (i = 0; i < ARRAY_SIZE(uclass_idname_str); i++) { + if (!strcmp(uclass_idname, uclass_idname_str[i].name)) + return uclass_idname_str[i].id; } return UCLASS_INVALID; } -static enum uclass_id if_type_to_uclass_id(enum uclass_id if_type) +static enum uclass_id conv_uclass_id(enum uclass_id uclass_id) { /* * This strange adjustment is used because we use UCLASS_MASS_STORAGE @@ -65,31 +65,30 @@ static enum uclass_id if_type_to_uclass_id(enum uclass_id if_type) * - rename UCLASS_USB name to "usb_ctlr" * - use UCLASS_MASS_STORAGE instead of UCLASS_USB in if_typename_str */ - if (if_type == UCLASS_USB) + if (uclass_id == UCLASS_USB) return UCLASS_MASS_STORAGE; - - return if_type; + return uclass_id; } -const char *blk_get_if_type_name(enum uclass_id if_type) +const char *blk_get_uclass_name(enum uclass_id uclass_id) { int i; - for (i = 0; i < ARRAY_SIZE(if_typename_str); i++) { - if (if_typename_str[i].id == if_type) - return if_typename_str[i].name; + for (i = 0; i < ARRAY_SIZE(uclass_idname_str); i++) { + if (uclass_idname_str[i].id == uclass_id) + return uclass_idname_str[i].name; } return "(none)"; } -struct blk_desc *blk_get_devnum_by_type(enum uclass_id if_type, int devnum) +struct blk_desc *blk_get_devnum_by_uclass_id(enum uclass_id uclass_id, int devnum) { struct blk_desc *desc; struct udevice *dev; int ret; - ret = blk_get_device(if_type, devnum, &dev); + ret = blk_get_device(uclass_id, devnum, &dev); if (ret) return NULL; desc = dev_get_uclass_plat(dev); @@ -102,7 +101,7 @@ struct blk_desc *blk_get_devnum_by_type(enum uclass_id if_type, int devnum) * name in a local table. This gives us an interface type which we can match * against the uclass of the block device's parent. */ -struct blk_desc *blk_get_devnum_by_typename(const char *if_typename, int devnum) +struct blk_desc *blk_get_devnum_by_uclass_idname(const char *uclass_idname, int devnum) { enum uclass_id uclass_id; enum uclass_id type; @@ -110,16 +109,16 @@ struct blk_desc *blk_get_devnum_by_typename(const char *if_typename, int devnum) struct uclass *uc; int ret; - type = if_typename_to_iftype(if_typename); + type = uclass_name_to_iftype(uclass_idname); if (type == UCLASS_INVALID) { debug("%s: Unknown interface type '%s'\n", __func__, - if_typename); + uclass_idname); return NULL; } - uclass_id = if_type_to_uclass_id(type); + uclass_id = conv_uclass_id(type); if (uclass_id == UCLASS_INVALID) { debug("%s: Unknown uclass for interface type'\n", - blk_get_if_type_name(type)); + blk_get_uclass_name(type)); return NULL; } @@ -129,8 +128,8 @@ struct blk_desc *blk_get_devnum_by_typename(const char *if_typename, int devnum) uclass_foreach_dev(dev, uc) { struct blk_desc *desc = dev_get_uclass_plat(dev); - debug("%s: if_type=%d, devnum=%d: %s, %d, %d\n", __func__, - type, devnum, dev->name, desc->if_type, desc->devnum); + debug("%s: uclass_id=%d, devnum=%d: %s, %d, %d\n", __func__, + type, devnum, dev->name, desc->uclass_id, desc->devnum); if (desc->devnum != devnum) continue; @@ -178,14 +177,14 @@ struct blk_desc *blk_get_by_device(struct udevice *dev) /** * get_desc() - Get the block device descriptor for the given device number * - * @if_type: Interface type + * @uclass_id: Interface type * @devnum: Device number (0 = first) * @descp: Returns block device descriptor on success * Return: 0 on success, -ENODEV if there is no such device and no device * with a higher device number, -ENOENT if there is no such device but there * is one with a higher number, or other -ve on other error. */ -static int get_desc(enum uclass_id if_type, int devnum, struct blk_desc **descp) +static int get_desc(enum uclass_id uclass_id, int devnum, struct blk_desc **descp) { bool found_more = false; struct udevice *dev; @@ -199,9 +198,9 @@ static int get_desc(enum uclass_id if_type, int devnum, struct blk_desc **descp) uclass_foreach_dev(dev, uc) { struct blk_desc *desc = dev_get_uclass_plat(dev); - debug("%s: if_type=%d, devnum=%d: %s, %d, %d\n", __func__, - if_type, devnum, dev->name, desc->if_type, desc->devnum); - if (desc->if_type == if_type) { + debug("%s: uclass_id=%d, devnum=%d: %s, %d, %d\n", __func__, + uclass_id, devnum, dev->name, desc->uclass_id, desc->devnum); + if (desc->uclass_id == uclass_id) { if (desc->devnum == devnum) { ret = device_probe(dev); if (ret) @@ -218,26 +217,26 @@ static int get_desc(enum uclass_id if_type, int devnum, struct blk_desc **descp) return found_more ? -ENOENT : -ENODEV; } -int blk_select_hwpart_devnum(enum uclass_id if_type, int devnum, int hwpart) +int blk_select_hwpart_devnum(enum uclass_id uclass_id, int devnum, int hwpart) { struct udevice *dev; int ret; - ret = blk_get_device(if_type, devnum, &dev); + ret = blk_get_device(uclass_id, devnum, &dev); if (ret) return ret; return blk_select_hwpart(dev, hwpart); } -int blk_list_part(enum uclass_id if_type) +int blk_list_part(enum uclass_id uclass_id) { struct blk_desc *desc; int devnum, ok; int ret; for (ok = 0, devnum = 0;; ++devnum) { - ret = get_desc(if_type, devnum, &desc); + ret = get_desc(uclass_id, devnum, &desc); if (ret == -ENODEV) break; else if (ret) @@ -255,12 +254,12 @@ int blk_list_part(enum uclass_id if_type) return 0; } -int blk_print_part_devnum(enum uclass_id if_type, int devnum) +int blk_print_part_devnum(enum uclass_id uclass_id, int devnum) { struct blk_desc *desc; int ret; - ret = get_desc(if_type, devnum, &desc); + ret = get_desc(uclass_id, devnum, &desc); if (ret) return ret; if (desc->type == DEV_TYPE_UNKNOWN) @@ -270,14 +269,14 @@ int blk_print_part_devnum(enum uclass_id if_type, int devnum) return 0; } -void blk_list_devices(enum uclass_id if_type) +void blk_list_devices(enum uclass_id uclass_id) { struct blk_desc *desc; int ret; int i; for (i = 0;; ++i) { - ret = get_desc(if_type, i, &desc); + ret = get_desc(uclass_id, i, &desc); if (ret == -ENODEV) break; else if (ret) @@ -289,12 +288,12 @@ void blk_list_devices(enum uclass_id if_type) } } -int blk_print_device_num(enum uclass_id if_type, int devnum) +int blk_print_device_num(enum uclass_id uclass_id, int devnum) { struct blk_desc *desc; int ret; - ret = get_desc(if_type, devnum, &desc); + ret = get_desc(uclass_id, devnum, &desc); if (ret) return ret; printf("\nIDE device %d: ", devnum); @@ -303,13 +302,13 @@ int blk_print_device_num(enum uclass_id if_type, int devnum) return 0; } -int blk_show_device(enum uclass_id if_type, int devnum) +int blk_show_device(enum uclass_id uclass_id, int devnum) { struct blk_desc *desc; int ret; printf("\nDevice %d: ", devnum); - ret = get_desc(if_type, devnum, &desc); + ret = get_desc(uclass_id, devnum, &desc); if (ret == -ENODEV || ret == -ENOENT) { printf("unknown device\n"); return -ENODEV; @@ -324,14 +323,14 @@ int blk_show_device(enum uclass_id if_type, int devnum) return 0; } -ulong blk_read_devnum(enum uclass_id if_type, int devnum, lbaint_t start, +ulong blk_read_devnum(enum uclass_id uclass_id, int devnum, lbaint_t start, lbaint_t blkcnt, void *buffer) { struct blk_desc *desc; ulong n; int ret; - ret = get_desc(if_type, devnum, &desc); + ret = get_desc(uclass_id, devnum, &desc); if (ret) return ret; n = blk_dread(desc, start, blkcnt, buffer); @@ -341,13 +340,13 @@ ulong blk_read_devnum(enum uclass_id if_type, int devnum, lbaint_t start, return n; } -ulong blk_write_devnum(enum uclass_id if_type, int devnum, lbaint_t start, +ulong blk_write_devnum(enum uclass_id uclass_id, int devnum, lbaint_t start, lbaint_t blkcnt, const void *buffer) { struct blk_desc *desc; int ret; - ret = get_desc(if_type, devnum, &desc); + ret = get_desc(uclass_id, devnum, &desc); if (ret) return ret; return blk_dwrite(desc, start, blkcnt, buffer); @@ -370,7 +369,7 @@ int blk_dselect_hwpart(struct blk_desc *desc, int hwpart) return blk_select_hwpart(desc->bdev, hwpart); } -int blk_first_device(int if_type, struct udevice **devp) +int blk_first_device(int uclass_id, struct udevice **devp) { struct blk_desc *desc; int ret; @@ -382,7 +381,7 @@ int blk_first_device(int if_type, struct udevice **devp) return -ENODEV; do { desc = dev_get_uclass_plat(*devp); - if (desc->if_type == if_type) + if (desc->uclass_id == uclass_id) return 0; ret = uclass_find_next_device(devp); if (ret) @@ -395,10 +394,10 @@ int blk_first_device(int if_type, struct udevice **devp) int blk_next_device(struct udevice **devp) { struct blk_desc *desc; - int ret, if_type; + int ret, uclass_id; desc = dev_get_uclass_plat(*devp); - if_type = desc->if_type; + uclass_id = desc->uclass_id; do { ret = uclass_find_next_device(devp); if (ret) @@ -406,12 +405,12 @@ int blk_next_device(struct udevice **devp) if (!*devp) return -ENODEV; desc = dev_get_uclass_plat(*devp); - if (desc->if_type == if_type) + if (desc->uclass_id == uclass_id) return 0; } while (1); } -int blk_find_device(int if_type, int devnum, struct udevice **devp) +int blk_find_device(int uclass_id, int devnum, struct udevice **devp) { struct uclass *uc; struct udevice *dev; @@ -423,9 +422,9 @@ int blk_find_device(int if_type, int devnum, struct udevice **devp) uclass_foreach_dev(dev, uc) { struct blk_desc *desc = dev_get_uclass_plat(dev); - debug("%s: if_type=%d, devnum=%d: %s, %d, %d\n", __func__, - if_type, devnum, dev->name, desc->if_type, desc->devnum); - if (desc->if_type == if_type && desc->devnum == devnum) { + debug("%s: uclass_id=%d, devnum=%d: %s, %d, %d\n", __func__, + uclass_id, devnum, dev->name, desc->uclass_id, desc->devnum); + if (desc->uclass_id == uclass_id && desc->devnum == devnum) { *devp = dev; return 0; } @@ -434,11 +433,11 @@ int blk_find_device(int if_type, int devnum, struct udevice **devp) return -ENODEV; } -int blk_get_device(int if_type, int devnum, struct udevice **devp) +int blk_get_device(int uclass_id, int devnum, struct udevice **devp) { int ret; - ret = blk_find_device(if_type, devnum, devp); + ret = blk_find_device(uclass_id, devnum, devp); if (ret) return ret; @@ -455,12 +454,12 @@ unsigned long blk_dread(struct blk_desc *block_dev, lbaint_t start, if (!ops->read) return -ENOSYS; - if (blkcache_read(block_dev->if_type, block_dev->devnum, + if (blkcache_read(block_dev->uclass_id, block_dev->devnum, start, blkcnt, block_dev->blksz, buffer)) return blkcnt; blks_read = ops->read(dev, start, blkcnt, buffer); if (blks_read == blkcnt) - blkcache_fill(block_dev->if_type, block_dev->devnum, + blkcache_fill(block_dev->uclass_id, block_dev->devnum, start, blkcnt, block_dev->blksz, buffer); return blks_read; @@ -475,7 +474,7 @@ unsigned long blk_dwrite(struct blk_desc *block_dev, lbaint_t start, if (!ops->write) return -ENOSYS; - blkcache_invalidate(block_dev->if_type, block_dev->devnum); + blkcache_invalidate(block_dev->uclass_id, block_dev->devnum); return ops->write(dev, start, blkcnt, buffer); } @@ -488,7 +487,7 @@ unsigned long blk_derase(struct blk_desc *block_dev, lbaint_t start, if (!ops->erase) return -ENOSYS; - blkcache_invalidate(block_dev->if_type, block_dev->devnum); + blkcache_invalidate(block_dev->uclass_id, block_dev->devnum); return ops->erase(dev, start, blkcnt); } @@ -525,7 +524,7 @@ const char *blk_get_devtype(struct udevice *dev) return uclass_get_name(device_get_uclass_id(parent)); }; -int blk_find_max_devnum(enum uclass_id if_type) +int blk_find_max_devnum(enum uclass_id uclass_id) { struct udevice *dev; int max_devnum = -ENODEV; @@ -538,18 +537,18 @@ int blk_find_max_devnum(enum uclass_id if_type) uclass_foreach_dev(dev, uc) { struct blk_desc *desc = dev_get_uclass_plat(dev); - if (desc->if_type == if_type && desc->devnum > max_devnum) + if (desc->uclass_id == uclass_id && desc->devnum > max_devnum) max_devnum = desc->devnum; } return max_devnum; } -int blk_next_free_devnum(enum uclass_id if_type) +int blk_next_free_devnum(enum uclass_id uclass_id) { int ret; - ret = blk_find_max_devnum(if_type); + ret = blk_find_max_devnum(uclass_id); if (ret == -ENODEV) return 0; if (ret < 0) @@ -631,7 +630,7 @@ int blk_count_devices(enum blk_flag_t flag) return count; } -static int blk_claim_devnum(enum uclass_id if_type, int devnum) +static int blk_claim_devnum(enum uclass_id uclass_id, int devnum) { struct udevice *dev; struct uclass *uc; @@ -643,8 +642,8 @@ static int blk_claim_devnum(enum uclass_id if_type, int devnum) uclass_foreach_dev(dev, uc) { struct blk_desc *desc = dev_get_uclass_plat(dev); - if (desc->if_type == if_type && desc->devnum == devnum) { - int next = blk_next_free_devnum(if_type); + if (desc->uclass_id == uclass_id && desc->devnum == devnum) { + int next = blk_next_free_devnum(uclass_id); if (next < 0) return next; @@ -657,7 +656,7 @@ static int blk_claim_devnum(enum uclass_id if_type, int devnum) } int blk_create_device(struct udevice *parent, const char *drv_name, - const char *name, int if_type, int devnum, int blksz, + const char *name, int uclass_id, int devnum, int blksz, lbaint_t lba, struct udevice **devp) { struct blk_desc *desc; @@ -665,9 +664,9 @@ int blk_create_device(struct udevice *parent, const char *drv_name, int ret; if (devnum == -1) { - devnum = blk_next_free_devnum(if_type); + devnum = blk_next_free_devnum(uclass_id); } else { - ret = blk_claim_devnum(if_type, devnum); + ret = blk_claim_devnum(uclass_id, devnum); if (ret < 0 && ret != -ENOENT) return ret; } @@ -677,7 +676,7 @@ int blk_create_device(struct udevice *parent, const char *drv_name, if (ret) return ret; desc = dev_get_uclass_plat(dev); - desc->if_type = if_type; + desc->uclass_id = uclass_id; desc->blksz = blksz; desc->log2blksz = LOG2(desc->blksz); desc->lba = lba; @@ -690,7 +689,7 @@ int blk_create_device(struct udevice *parent, const char *drv_name, } int blk_create_devicef(struct udevice *parent, const char *drv_name, - const char *name, int if_type, int devnum, int blksz, + const char *name, int uclass_id, int devnum, int blksz, lbaint_t lba, struct udevice **devp) { char dev_name[30], *str; @@ -701,7 +700,7 @@ int blk_create_devicef(struct udevice *parent, const char *drv_name, if (!str) return -ENOMEM; - ret = blk_create_device(parent, drv_name, str, if_type, devnum, + ret = blk_create_device(parent, drv_name, str, uclass_id, devnum, blksz, lba, devp); if (ret) { free(str); @@ -725,7 +724,7 @@ int blk_probe_or_unbind(struct udevice *dev) return ret; } -int blk_unbind_all(int if_type) +int blk_unbind_all(int uclass_id) { struct uclass *uc; struct udevice *dev, *next; @@ -737,7 +736,7 @@ int blk_unbind_all(int if_type) uclass_foreach_dev_safe(dev, next, uc) { struct blk_desc *desc = dev_get_uclass_plat(dev); - if (desc->if_type == if_type) { + if (desc->uclass_id == uclass_id) { ret = device_remove(dev, DM_REMOVE_NORMAL); if (ret) return ret; diff --git a/drivers/block/blk_legacy.c b/drivers/block/blk_legacy.c index 8c6f9cb208..5bf1d04715 100644 --- a/drivers/block/blk_legacy.c +++ b/drivers/block/blk_legacy.c @@ -9,14 +9,14 @@ #include #include -struct blk_driver *blk_driver_lookup_type(int if_type) +struct blk_driver *blk_driver_lookup_type(int uclass_id) { struct blk_driver *drv = ll_entry_start(struct blk_driver, blk_driver); const int n_ents = ll_entry_count(struct blk_driver, blk_driver); struct blk_driver *entry; for (entry = drv; entry != drv + n_ents; entry++) { - if (if_type == entry->if_type) + if (uclass_id == entry->uclass_id) return entry; } @@ -24,14 +24,14 @@ struct blk_driver *blk_driver_lookup_type(int if_type) return NULL; } -static struct blk_driver *blk_driver_lookup_typename(const char *if_typename) +static struct blk_driver *blk_driver_lookup_typename(const char *uclass_idname) { struct blk_driver *drv = ll_entry_start(struct blk_driver, blk_driver); const int n_ents = ll_entry_count(struct blk_driver, blk_driver); struct blk_driver *entry; for (entry = drv; entry != drv + n_ents; entry++) { - if (!strcmp(if_typename, entry->if_typename)) + if (!strcmp(uclass_idname, entry->uclass_idname)) return entry; } @@ -39,11 +39,11 @@ static struct blk_driver *blk_driver_lookup_typename(const char *if_typename) return NULL; } -const char *blk_get_if_type_name(enum uclass_id if_type) +const char *blk_get_uclass_name(enum uclass_id uclass_id) { - struct blk_driver *drv = blk_driver_lookup_type(if_type); + struct blk_driver *drv = blk_driver_lookup_type(uclass_id); - return drv ? drv->if_typename : NULL; + return drv ? drv->uclass_idname : NULL; } /** @@ -70,14 +70,14 @@ static int get_desc(struct blk_driver *drv, int devnum, struct blk_desc **descp) return drv->get_dev(devnum, descp); } -int blk_list_part(enum uclass_id if_type) +int blk_list_part(enum uclass_id uclass_id) { struct blk_driver *drv; struct blk_desc *desc; int devnum, ok; bool first = true; - drv = blk_driver_lookup_type(if_type); + drv = blk_driver_lookup_type(uclass_id); if (!drv) return -ENOSYS; for (ok = 0, devnum = 0; devnum < drv->max_devs; ++devnum) { @@ -97,9 +97,9 @@ int blk_list_part(enum uclass_id if_type) return 0; } -int blk_print_part_devnum(enum uclass_id if_type, int devnum) +int blk_print_part_devnum(enum uclass_id uclass_id, int devnum) { - struct blk_driver *drv = blk_driver_lookup_type(if_type); + struct blk_driver *drv = blk_driver_lookup_type(uclass_id); struct blk_desc *desc; int ret; @@ -115,9 +115,9 @@ int blk_print_part_devnum(enum uclass_id if_type, int devnum) return 0; } -void blk_list_devices(enum uclass_id if_type) +void blk_list_devices(enum uclass_id uclass_id) { - struct blk_driver *drv = blk_driver_lookup_type(if_type); + struct blk_driver *drv = blk_driver_lookup_type(uclass_id); struct blk_desc *desc; int i; @@ -133,9 +133,9 @@ void blk_list_devices(enum uclass_id if_type) } } -int blk_print_device_num(enum uclass_id if_type, int devnum) +int blk_print_device_num(enum uclass_id uclass_id, int devnum) { - struct blk_driver *drv = blk_driver_lookup_type(if_type); + struct blk_driver *drv = blk_driver_lookup_type(uclass_id); struct blk_desc *desc; int ret; @@ -144,15 +144,15 @@ int blk_print_device_num(enum uclass_id if_type, int devnum) ret = get_desc(drv, devnum, &desc); if (ret) return ret; - printf("\n%s device %d: ", drv->if_typename, devnum); + printf("\n%s device %d: ", drv->uclass_idname, devnum); dev_print(desc); return 0; } -int blk_show_device(enum uclass_id if_type, int devnum) +int blk_show_device(enum uclass_id uclass_id, int devnum) { - struct blk_driver *drv = blk_driver_lookup_type(if_type); + struct blk_driver *drv = blk_driver_lookup_type(uclass_id); struct blk_desc *desc; int ret; @@ -174,9 +174,9 @@ int blk_show_device(enum uclass_id if_type, int devnum) return 0; } -struct blk_desc *blk_get_devnum_by_type(enum uclass_id if_type, int devnum) +struct blk_desc *blk_get_devnum_by_uclass_id(enum uclass_id uclass_id, int devnum) { - struct blk_driver *drv = blk_driver_lookup_type(if_type); + struct blk_driver *drv = blk_driver_lookup_type(uclass_id); struct blk_desc *desc; if (!drv) @@ -190,7 +190,7 @@ struct blk_desc *blk_get_devnum_by_type(enum uclass_id if_type, int devnum) int blk_dselect_hwpart(struct blk_desc *desc, int hwpart) { - struct blk_driver *drv = blk_driver_lookup_type(desc->if_type); + struct blk_driver *drv = blk_driver_lookup_type(desc->uclass_id); if (!drv) return -ENOSYS; @@ -200,9 +200,9 @@ int blk_dselect_hwpart(struct blk_desc *desc, int hwpart) return 0; } -struct blk_desc *blk_get_devnum_by_typename(const char *if_typename, int devnum) +struct blk_desc *blk_get_devnum_by_uclass_idname(const char *uclass_idname, int devnum) { - struct blk_driver *drv = blk_driver_lookup_typename(if_typename); + struct blk_driver *drv = blk_driver_lookup_typename(uclass_idname); struct blk_desc *desc; if (!drv) @@ -214,10 +214,10 @@ struct blk_desc *blk_get_devnum_by_typename(const char *if_typename, int devnum) return desc; } -ulong blk_read_devnum(enum uclass_id if_type, int devnum, lbaint_t start, +ulong blk_read_devnum(enum uclass_id uclass_id, int devnum, lbaint_t start, lbaint_t blkcnt, void *buffer) { - struct blk_driver *drv = blk_driver_lookup_type(if_type); + struct blk_driver *drv = blk_driver_lookup_type(uclass_id); struct blk_desc *desc; ulong n; int ret; @@ -234,10 +234,10 @@ ulong blk_read_devnum(enum uclass_id if_type, int devnum, lbaint_t start, return n; } -ulong blk_write_devnum(enum uclass_id if_type, int devnum, lbaint_t start, +ulong blk_write_devnum(enum uclass_id uclass_id, int devnum, lbaint_t start, lbaint_t blkcnt, const void *buffer) { - struct blk_driver *drv = blk_driver_lookup_type(if_type); + struct blk_driver *drv = blk_driver_lookup_type(uclass_id); struct blk_desc *desc; int ret; @@ -249,9 +249,9 @@ ulong blk_write_devnum(enum uclass_id if_type, int devnum, lbaint_t start, return desc->block_write(desc, start, blkcnt, buffer); } -int blk_select_hwpart_devnum(enum uclass_id if_type, int devnum, int hwpart) +int blk_select_hwpart_devnum(enum uclass_id uclass_id, int devnum, int hwpart) { - struct blk_driver *drv = blk_driver_lookup_type(if_type); + struct blk_driver *drv = blk_driver_lookup_type(uclass_id); struct blk_desc *desc; int ret; diff --git a/drivers/block/ide.c b/drivers/block/ide.c index b8840d29c2..eaa58d859c 100644 --- a/drivers/block/ide.c +++ b/drivers/block/ide.c @@ -537,7 +537,7 @@ static void ide_ident(struct blk_desc *dev_desc) /* Select device */ ide_outb(device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device)); - dev_desc->if_type = UCLASS_IDE; + dev_desc->uclass_id = UCLASS_IDE; #ifdef CONFIG_ATAPI retries = 0; @@ -752,7 +752,7 @@ void ide_init(void) for (i = 0; i < CONFIG_SYS_IDE_MAXDEVICE; ++i) { ide_dev_desc[i].type = DEV_TYPE_UNKNOWN; - ide_dev_desc[i].if_type = UCLASS_IDE; + ide_dev_desc[i].uclass_id = UCLASS_IDE; ide_dev_desc[i].devnum = i; ide_dev_desc[i].part_type = PART_TYPE_UNKNOWN; ide_dev_desc[i].blksz = 0; @@ -1143,8 +1143,8 @@ UCLASS_DRIVER(ide) = { }; #else U_BOOT_LEGACY_BLK(ide) = { - .if_typename = "ide", - .if_type = UCLASS_IDE, + .uclass_idname = "ide", + .uclass_id = UCLASS_IDE, .max_devs = CONFIG_SYS_IDE_MAXDEVICE, .desc = ide_dev_desc, }; diff --git a/drivers/block/sandbox.c b/drivers/block/sandbox.c index 2de12e0a93..f2aae89716 100644 --- a/drivers/block/sandbox.c +++ b/drivers/block/sandbox.c @@ -150,7 +150,7 @@ int host_dev_bind(int devnum, char *filename, bool removable) goto err_file; } - desc = blk_get_devnum_by_type(UCLASS_ROOT, devnum); + desc = blk_get_devnum_by_uclass_id(UCLASS_ROOT, devnum); desc->removable = removable; snprintf(desc->vendor, BLK_VEN_SIZE, "U-Boot"); snprintf(desc->product, BLK_PRD_SIZE, "hostfile"); @@ -192,7 +192,7 @@ int host_dev_bind(int dev, char *filename, bool removable) } struct blk_desc *blk_dev = &host_dev->blk_dev; - blk_dev->if_type = UCLASS_ROOT; + blk_dev->uclass_id = UCLASS_ROOT; blk_dev->priv = host_dev; blk_dev->blksz = 512; blk_dev->lba = os_lseek(host_dev->fd, 0, OS_SEEK_END) / blk_dev->blksz; @@ -262,8 +262,8 @@ U_BOOT_DRIVER(sandbox_host_blk) = { }; #else U_BOOT_LEGACY_BLK(sandbox_host) = { - .if_typename = "host", - .if_type = UCLASS_ROOT, + .uclass_idname = "host", + .uclass_id = UCLASS_ROOT, .max_devs = SANDBOX_HOST_MAX_DEVICES, .get_dev = host_get_dev_err, }; diff --git a/drivers/mmc/mmc-uclass.c b/drivers/mmc/mmc-uclass.c index b1bd4ae1bc..759a6b728c 100644 --- a/drivers/mmc/mmc-uclass.c +++ b/drivers/mmc/mmc-uclass.c @@ -472,7 +472,7 @@ static int mmc_select_hwpart(struct udevice *bdev, int hwpart) ret = mmc_switch_part(mmc, hwpart); if (!ret) - blkcache_invalidate(desc->if_type, desc->devnum); + blkcache_invalidate(desc->uclass_id, desc->devnum); return ret; } diff --git a/drivers/mmc/mmc_legacy.c b/drivers/mmc/mmc_legacy.c index 4e0891e5df..a101ee43fd 100644 --- a/drivers/mmc/mmc_legacy.c +++ b/drivers/mmc/mmc_legacy.c @@ -132,7 +132,7 @@ static struct mmc mmc_static = { .dsr_imp = 0, .dsr = 0xffffffff, .block_dev = { - .if_type = UCLASS_MMC, + .uclass_id = UCLASS_MMC, .removable = 1, .devnum = 0, .block_read = mmc_bread, @@ -194,7 +194,7 @@ struct mmc *mmc_create(const struct mmc_config *cfg, void *priv) mmc->dsr = 0xffffffff; /* Setup the universal parts of the block interface just once */ bdesc = mmc_get_blk_desc(mmc); - bdesc->if_type = UCLASS_MMC; + bdesc->uclass_id = UCLASS_MMC; bdesc->removable = 1; bdesc->devnum = mmc_get_next_devnum(); bdesc->block_read = mmc_bread; @@ -253,8 +253,8 @@ static int mmc_get_dev(int dev, struct blk_desc **descp) } U_BOOT_LEGACY_BLK(mmc) = { - .if_typename = "mmc", - .if_type = UCLASS_MMC, + .uclass_idname = "mmc", + .uclass_id = UCLASS_MMC, .max_devs = -1, .get_dev = mmc_get_dev, .select_hwpart = mmc_select_hwpartp, diff --git a/drivers/net/fsl_enetc.c b/drivers/net/fsl_enetc.c index 835e5bd8bd..d43a85b498 100644 --- a/drivers/net/fsl_enetc.c +++ b/drivers/net/fsl_enetc.c @@ -146,7 +146,7 @@ static int enetc_init_sgmii(struct udevice *dev) if (!enetc_has_imdio(dev)) return 0; - if (priv->if_type == PHY_INTERFACE_MODE_2500BASEX) + if (priv->uclass_id == PHY_INTERFACE_MODE_2500BASEX) is2500 = true; /* @@ -221,7 +221,7 @@ static void enetc_setup_mac_iface(struct udevice *dev, struct enetc_priv *priv = dev_get_priv(dev); u32 if_mode; - switch (priv->if_type) { + switch (priv->uclass_id) { case PHY_INTERFACE_MODE_RGMII: case PHY_INTERFACE_MODE_RGMII_ID: case PHY_INTERFACE_MODE_RGMII_RXID: @@ -278,14 +278,14 @@ static void enetc_start_pcs(struct udevice *dev) return; } - priv->if_type = dev_read_phy_mode(dev); - if (priv->if_type == PHY_INTERFACE_MODE_NA) { + priv->uclass_id = dev_read_phy_mode(dev); + if (priv->uclass_id == PHY_INTERFACE_MODE_NA) { enetc_dbg(dev, "phy-mode property not found, defaulting to SGMII\n"); - priv->if_type = PHY_INTERFACE_MODE_SGMII; + priv->uclass_id = PHY_INTERFACE_MODE_SGMII; } - switch (priv->if_type) { + switch (priv->uclass_id) { case PHY_INTERFACE_MODE_SGMII: case PHY_INTERFACE_MODE_2500BASEX: enetc_init_sgmii(dev); diff --git a/drivers/net/fsl_enetc.h b/drivers/net/fsl_enetc.h index 69f2f4aaff..f2acf367aa 100644 --- a/drivers/net/fsl_enetc.h +++ b/drivers/net/fsl_enetc.h @@ -158,7 +158,7 @@ struct enetc_priv { struct bd_ring tx_bdr; struct bd_ring rx_bdr; - int if_type; + int uclass_id; struct mii_dev imdio; struct phy_device *phy; }; diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index 99be5aef87..3e769b0843 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c @@ -456,7 +456,7 @@ static void scsi_init_dev_desc(struct blk_desc *dev_desc, int devnum) { dev_desc->lba = 0; dev_desc->blksz = 0; - dev_desc->if_type = UCLASS_SCSI; + dev_desc->uclass_id = UCLASS_SCSI; dev_desc->devnum = devnum; dev_desc->part_type = PART_TYPE_UNKNOWN; @@ -706,8 +706,8 @@ U_BOOT_DRIVER(scsi_blk) = { }; #else U_BOOT_LEGACY_BLK(scsi) = { - .if_typename = "scsi", - .if_type = UCLASS_SCSI, + .uclass_idname = "scsi", + .uclass_id = UCLASS_SCSI, .max_devs = SCSI_MAX_DEVICE, .desc = scsi_dev_desc, }; diff --git a/drivers/virtio/virtio_blk.c b/drivers/virtio/virtio_blk.c index 9710b79117..30cfc56725 100644 --- a/drivers/virtio/virtio_blk.c +++ b/drivers/virtio/virtio_blk.c @@ -75,7 +75,7 @@ static int virtio_blk_bind(struct udevice *dev) struct blk_desc *desc = dev_get_uclass_plat(dev); int devnum; - desc->if_type = UCLASS_VIRTIO; + desc->uclass_id = UCLASS_VIRTIO; /* * Initialize the devnum to -ENODEV. This is to make sure that * blk_next_free_devnum() works as expected, since the default diff --git a/drivers/xen/pvblock.c b/drivers/xen/pvblock.c index 1090e528d0..970182cd90 100644 --- a/drivers/xen/pvblock.c +++ b/drivers/xen/pvblock.c @@ -665,7 +665,7 @@ static int pvblock_blk_bind(struct udevice *udev) struct blk_desc *desc = dev_get_uclass_plat(udev); int devnum; - desc->if_type = UCLASS_PVBLOCK; + desc->uclass_id = UCLASS_PVBLOCK; /* * Initialize the devnum to -ENODEV. This is to make sure that * blk_next_free_devnum() works as expected, since the default diff --git a/fs/fat/fat.c b/fs/fat/fat.c index c64e253abd..a945904785 100644 --- a/fs/fat/fat.c +++ b/fs/fat/fat.c @@ -1145,7 +1145,7 @@ int file_fat_detectfs(void) } if (blk_enabled()) { - printf("Interface: %s\n", blk_get_if_type_name(cur_dev->if_type)); + printf("Interface: %s\n", blk_get_uclass_name(cur_dev->uclass_id)); printf(" Device %d: ", cur_dev->devnum); dev_print(cur_dev); } diff --git a/include/blk.h b/include/blk.h index 279f9ea4a9..8806c382d4 100644 --- a/include/blk.h +++ b/include/blk.h @@ -54,7 +54,7 @@ struct blk_desc { * TODO: With driver model we should be able to use the parent * device's uclass instead. */ - enum uclass_id if_type; /* type of the interface */ + enum uclass_id uclass_id; /* type of the interface */ int devnum; /* device number */ unsigned char part_type; /* partition type */ unsigned char target; /* target SCSI ID */ @@ -114,7 +114,7 @@ int blkcache_init(void); /** * blkcache_read() - attempt to read a set of blocks from cache * - * @param iftype - IF_TYPE_x for type of device + * @param iftype - uclass_id_x for type of device * @param dev - device index of particular type * @param start - starting block number * @param blkcnt - number of blocks to read @@ -131,7 +131,7 @@ int blkcache_read(int iftype, int dev, * blkcache_fill() - make data read from a block device available * to the block cache * - * @param iftype - IF_TYPE_x for type of device + * @param iftype - uclass_id_x for type of device * @param dev - device index of particular type * @param start - starting block number * @param blkcnt - number of blocks available @@ -147,7 +147,7 @@ void blkcache_fill(int iftype, int dev, * blkcache_invalidate() - discard the cache for a set of blocks * because of a write or device (re)initialization. * - * @param iftype - IF_TYPE_x for type of device + * @param iftype - uclass_id_x for type of device * @param dev - device index of particular type */ void blkcache_invalidate(int iftype, int dev); @@ -279,22 +279,22 @@ unsigned long blk_derase(struct blk_desc *block_dev, lbaint_t start, * This function does not activate the device. The device will be returned * whether or not it is activated. * - * @if_type: Interface type (enum uclass_id_t) + * @uclass_id: Interface type (enum uclass_id_t) * @devnum: Device number (specific to each interface type) * @devp: the device, if found * Return: 0 if found, -ENODEV if no device found, or other -ve error value */ -int blk_find_device(int if_type, int devnum, struct udevice **devp); +int blk_find_device(int uclass_id, int devnum, struct udevice **devp); /** * blk_get_device() - Find and probe a block device ready for use * - * @if_type: Interface type (enum uclass_id_t) + * @uclass_id: Interface type (enum uclass_id_t) * @devnum: Device number (specific to each interface type) * @devp: the device, if found * Return: 0 if found, -ENODEV if no device found, or other -ve error value */ -int blk_get_device(int if_type, int devnum, struct udevice **devp); +int blk_get_device(int uclass_id, int devnum, struct udevice **devp); /** * blk_first_device() - Find the first device for a given interface @@ -305,7 +305,7 @@ int blk_get_device(int if_type, int devnum, struct udevice **devp); * @devp: the device, if found * Return: 0 if found, -ENODEV if no device, or other -ve error value */ -int blk_first_device(int if_type, struct udevice **devp); +int blk_first_device(int uclass_id, struct udevice **devp); /** * blk_next_device() - Find the next device for a given interface @@ -327,7 +327,7 @@ int blk_next_device(struct udevice **devp); * @parent: Parent of the new device * @drv_name: Driver name to use for the block device * @name: Name for the device - * @if_type: Interface type (enum uclass_id_t) + * @uclass_id: Interface type (enum uclass_id_t) * @devnum: Device number, specific to the interface type, or -1 to * allocate the next available number * @blksz: Block size of the device in bytes (typically 512) @@ -335,7 +335,7 @@ int blk_next_device(struct udevice **devp); * @devp: the new device (which has not been probed) */ int blk_create_device(struct udevice *parent, const char *drv_name, - const char *name, int if_type, int devnum, int blksz, + const char *name, int uclass_id, int devnum, int blksz, lbaint_t lba, struct udevice **devp); /** @@ -344,7 +344,7 @@ int blk_create_device(struct udevice *parent, const char *drv_name, * @parent: Parent of the new device * @drv_name: Driver name to use for the block device * @name: Name for the device (parent name is prepended) - * @if_type: Interface type (enum uclass_id_t) + * @uclass_id: Interface type (enum uclass_id_t) * @devnum: Device number, specific to the interface type, or -1 to * allocate the next available number * @blksz: Block size of the device in bytes (typically 512) @@ -352,7 +352,7 @@ int blk_create_device(struct udevice *parent, const char *drv_name, * @devp: the new device (which has not been probed) */ int blk_create_devicef(struct udevice *parent, const char *drv_name, - const char *name, int if_type, int devnum, int blksz, + const char *name, int uclass_id, int devnum, int blksz, lbaint_t lba, struct udevice **devp); /** @@ -372,33 +372,33 @@ int blk_probe_or_unbind(struct udevice *dev); * * The devices are removed and then unbound. * - * @if_type: Interface type to unbind + * @uclass_id: Interface type to unbind * Return: 0 if OK, -ve on error */ -int blk_unbind_all(int if_type); +int blk_unbind_all(int uclass_id); /** * blk_find_max_devnum() - find the maximum device number for an interface type * - * Finds the last allocated device number for an interface type @if_type. The + * Finds the last allocated device number for an interface type @uclass_id. The * next number is safe to use for a newly allocated device. * - * @if_type: Interface type to scan + * @uclass_id: Interface type to scan * Return: maximum device number found, or -ENODEV if none, or other -ve on * error */ -int blk_find_max_devnum(enum uclass_id if_type); +int blk_find_max_devnum(enum uclass_id uclass_id); /** * blk_next_free_devnum() - get the next device number for an interface type * * Finds the next number that is safe to use for a newly allocated device for - * an interface type @if_type. + * an interface type @uclass_id. * - * @if_type: Interface type to scan + * @uclass_id: Interface type to scan * Return: next device number safe to use, or -ve on error */ -int blk_next_free_devnum(enum uclass_id if_type); +int blk_next_free_devnum(enum uclass_id uclass_id); /** * blk_select_hwpart() - select a hardware partition @@ -447,7 +447,7 @@ static inline ulong blk_dread(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt, void *buffer) { ulong blks_read; - if (blkcache_read(block_dev->if_type, block_dev->devnum, + if (blkcache_read(block_dev->uclass_id, block_dev->devnum, start, blkcnt, block_dev->blksz, buffer)) return blkcnt; @@ -458,7 +458,7 @@ static inline ulong blk_dread(struct blk_desc *block_dev, lbaint_t start, */ blks_read = block_dev->block_read(block_dev, start, blkcnt, buffer); if (blks_read == blkcnt) - blkcache_fill(block_dev->if_type, block_dev->devnum, + blkcache_fill(block_dev->uclass_id, block_dev->devnum, start, blkcnt, block_dev->blksz, buffer); return blks_read; @@ -467,14 +467,14 @@ static inline ulong blk_dread(struct blk_desc *block_dev, lbaint_t start, static inline ulong blk_dwrite(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt, const void *buffer) { - blkcache_invalidate(block_dev->if_type, block_dev->devnum); + blkcache_invalidate(block_dev->uclass_id, block_dev->devnum); return block_dev->block_write(block_dev, start, blkcnt, buffer); } static inline ulong blk_derase(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt) { - blkcache_invalidate(block_dev->if_type, block_dev->devnum); + blkcache_invalidate(block_dev->uclass_id, block_dev->devnum); return block_dev->block_erase(block_dev, start, blkcnt); } @@ -485,15 +485,15 @@ static inline ulong blk_derase(struct blk_desc *block_dev, lbaint_t start, * driver should be provided using U_BOOT_LEGACY_BLK() for each interface * type that is to be supported. * - * @if_typename: Interface type name - * @if_type: Interface type + * @uclass_idname: Interface type name + * @uclass_id: Interface type * @max_devs: Maximum number of devices supported * @desc: Pointer to list of devices for this interface type, * or NULL to use @get_dev() instead */ struct blk_driver { - const char *if_typename; - enum uclass_id if_type; + const char *uclass_idname; + enum uclass_id uclass_id; int max_devs; struct blk_desc *desc; /** @@ -540,33 +540,33 @@ struct blk_driver { #define U_BOOT_LEGACY_BLK(__name) \ ll_entry_declare(struct blk_driver, __name, blk_driver) -struct blk_driver *blk_driver_lookup_type(int if_type); +struct blk_driver *blk_driver_lookup_type(int uclass_id); #endif /* !CONFIG_BLK */ /** - * blk_get_devnum_by_typename() - Get a block device by type and number + * blk_get_devnum_by_uclass_idname() - Get a block device by type and number * * This looks through the available block devices of the given type, returning * the one with the given @devnum. * - * @if_type: Block device type + * @uclass_id: Block device type * @devnum: Device number * Return: point to block device descriptor, or NULL if not found */ -struct blk_desc *blk_get_devnum_by_type(enum uclass_id if_type, int devnum); +struct blk_desc *blk_get_devnum_by_uclass_id(enum uclass_id uclass_id, int devnum); /** - * blk_get_devnum_by_type() - Get a block device by type name, and number + * blk_get_devnum_by_uclass_id() - Get a block device by type name, and number * - * This looks up the block device type based on @if_typename, then calls - * blk_get_devnum_by_type(). + * This looks up the block device type based on @uclass_idname, then calls + * blk_get_devnum_by_uclass_id(). * - * @if_typename: Block device type name + * @uclass_idname: Block device type name * @devnum: Device number * Return: point to block device descriptor, or NULL if not found */ -struct blk_desc *blk_get_devnum_by_typename(const char *if_typename, +struct blk_desc *blk_get_devnum_by_uclass_idname(const char *uclass_idname, int devnum); /** @@ -585,34 +585,34 @@ int blk_dselect_hwpart(struct blk_desc *desc, int hwpart); /** * blk_list_part() - list the partitions for block devices of a given type * - * This looks up the partition type for each block device of type @if_type, + * This looks up the partition type for each block device of type @uclass_id, * then displays a list of partitions. * - * @if_type: Block device type + * @uclass_id: Block device type * Return: 0 if OK, -ENODEV if there is none of that type */ -int blk_list_part(enum uclass_id if_type); +int blk_list_part(enum uclass_id uclass_id); /** * blk_list_devices() - list the block devices of a given type * - * This lists each block device of the type @if_type, showing the capacity + * This lists each block device of the type @uclass_id, showing the capacity * as well as type-specific information. * - * @if_type: Block device type + * @uclass_id: Block device type */ -void blk_list_devices(enum uclass_id if_type); +void blk_list_devices(enum uclass_id uclass_id); /** * blk_show_device() - show information about a given block device * * This shows the block device capacity as well as type-specific information. * - * @if_type: Block device type + * @uclass_id: Block device type * @devnum: Device number * Return: 0 if OK, -ENODEV for invalid device number */ -int blk_show_device(enum uclass_id if_type, int devnum); +int blk_show_device(enum uclass_id uclass_id, int devnum); /** * blk_print_device_num() - show information about a given block device @@ -620,45 +620,45 @@ int blk_show_device(enum uclass_id if_type, int devnum); * This is similar to blk_show_device() but returns an error if the block * device type is unknown. * - * @if_type: Block device type + * @uclass_id: Block device type * @devnum: Device number * Return: 0 if OK, -ENODEV for invalid device number, -ENOENT if the block * device is not connected */ -int blk_print_device_num(enum uclass_id if_type, int devnum); +int blk_print_device_num(enum uclass_id uclass_id, int devnum); /** * blk_print_part_devnum() - print the partition information for a device * - * @if_type: Block device type + * @uclass_id: Block device type * @devnum: Device number * Return: 0 if OK, -ENOENT if the block device is not connected, -ENOSYS if * the interface type is not supported, other -ve on other error */ -int blk_print_part_devnum(enum uclass_id if_type, int devnum); +int blk_print_part_devnum(enum uclass_id uclass_id, int devnum); /** * blk_read_devnum() - read blocks from a device * - * @if_type: Block device type + * @uclass_id: Block device type * @devnum: Device number * @blkcnt: Number of blocks to read * @buffer: Address to write data to * Return: number of blocks read, or -ve error number on error */ -ulong blk_read_devnum(enum uclass_id if_type, int devnum, lbaint_t start, +ulong blk_read_devnum(enum uclass_id uclass_id, int devnum, lbaint_t start, lbaint_t blkcnt, void *buffer); /** * blk_write_devnum() - write blocks to a device * - * @if_type: Block device type + * @uclass_id: Block device type * @devnum: Device number * @blkcnt: Number of blocks to write * @buffer: Address to read data from * Return: number of blocks written, or -ve error number on error */ -ulong blk_write_devnum(enum uclass_id if_type, int devnum, lbaint_t start, +ulong blk_write_devnum(enum uclass_id uclass_id, int devnum, lbaint_t start, lbaint_t blkcnt, const void *buffer); /** @@ -667,31 +667,31 @@ ulong blk_write_devnum(enum uclass_id if_type, int devnum, lbaint_t start, * This is similar to blk_dselect_hwpart() but it looks up the interface and * device number. * - * @if_type: Block device type + * @uclass_id: Block device type * @devnum: Device number * @hwpart: Partition number to select * Return: 0 if OK, -ve on error */ -int blk_select_hwpart_devnum(enum uclass_id if_type, int devnum, int hwpart); +int blk_select_hwpart_devnum(enum uclass_id uclass_id, int devnum, int hwpart); /** - * blk_get_if_type_name() - Get the name of an interface type + * blk_get_uclass_name() - Get the name of an interface type * - * @if_type: Interface type to check + * @uclass_id: Interface type to check * Return: name of interface, or NULL if none */ -const char *blk_get_if_type_name(enum uclass_id if_type); +const char *blk_get_uclass_name(enum uclass_id uclass_id); /** * blk_common_cmd() - handle common commands with block devices * * @args: Number of arguments to the command (argv[0] is the command itself) * @argv: Command arguments - * @if_type: Interface type + * @uclass_id: Interface type * @cur_devnump: Current device number for this interface type * Return: 0 if OK, CMD_RET_ERROR on error */ -int blk_common_cmd(int argc, char *const argv[], enum uclass_id if_type, +int blk_common_cmd(int argc, char *const argv[], enum uclass_id uclass_id, int *cur_devnump); enum blk_flag_t { diff --git a/include/efi_loader.h b/include/efi_loader.h index 7554f3b7db..ad01395b39 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -161,7 +161,7 @@ extern bool efi_st_keep_devices; /* EFI system partition */ extern struct efi_system_partition { - enum uclass_id if_type; + enum uclass_id uclass_id; int devnum; u8 part; } efi_system_partition; @@ -562,7 +562,7 @@ efi_status_t tcg2_measure_pe_image(void *efi, u64 efi_size, struct efi_loaded_image *loaded_image_info); /* Create handles and protocols for the partitions of a block device */ int efi_disk_create_partitions(efi_handle_t parent, struct blk_desc *desc, - const char *if_typename, int diskid, + const char *uclass_idname, int diskid, const char *pdevname); /* Called by bootefi to make GOP (graphical) interface available */ efi_status_t efi_gop_register(void); diff --git a/lib/efi_loader/efi_disk.c b/lib/efi_loader/efi_disk.c index e39968a3f3..39ea1a68a6 100644 --- a/lib/efi_loader/efi_disk.c +++ b/lib/efi_loader/efi_disk.c @@ -498,13 +498,13 @@ static efi_status_t efi_disk_add_dev( diskobj->media.last_block); /* Store first EFI system partition */ - if (part && !efi_system_partition.if_type) { + if (part && !efi_system_partition.uclass_id) { if (part_info->bootable & PART_EFI_SYSTEM_PARTITION) { - efi_system_partition.if_type = desc->if_type; + efi_system_partition.uclass_id = desc->uclass_id; efi_system_partition.devnum = desc->devnum; efi_system_partition.part = part; EFI_PRINT("EFI system partition: %s %x:%x\n", - blk_get_if_type_name(desc->if_type), + blk_get_uclass_name(desc->uclass_id), desc->devnum, part); } } @@ -640,7 +640,7 @@ static int efi_disk_probe(void *ctx, struct event *event) * has already created an efi_disk at this moment. */ desc = dev_get_uclass_plat(dev); - if (desc->if_type != UCLASS_EFI_LOADER) { + if (desc->uclass_id != UCLASS_EFI_LOADER) { ret = efi_disk_create_raw(dev); if (ret) return -1; @@ -675,7 +675,7 @@ static int efi_disk_delete_raw(struct udevice *dev) return -1; desc = dev_get_uclass_plat(dev); - if (desc->if_type != UCLASS_EFI_LOADER) { + if (desc->uclass_id != UCLASS_EFI_LOADER) { diskobj = container_of(handle, struct efi_disk_obj, header); efi_free_pool(diskobj->dp); } @@ -794,7 +794,7 @@ efi_status_t efi_disk_get_device_name(const efi_handle_t handle, char *buf, int } else { return EFI_INVALID_PARAMETER; } - if_typename = blk_get_if_type_name(desc->if_type); + if_typename = blk_get_uclass_name(desc->uclass_id); diskid = desc->devnum; if (is_partition) { diff --git a/lib/efi_loader/efi_var_file.c b/lib/efi_loader/efi_var_file.c index 994e66392f..3d58caa13d 100644 --- a/lib/efi_loader/efi_var_file.c +++ b/lib/efi_loader/efi_var_file.c @@ -38,13 +38,13 @@ static efi_status_t __maybe_unused efi_set_blk_dev_to_system_partition(void) char part_str[PART_STR_LEN]; int r; - if (efi_system_partition.if_type == UCLASS_INVALID) { + if (efi_system_partition.uclass_id == UCLASS_INVALID) { log_err("No EFI system partition\n"); return EFI_DEVICE_ERROR; } snprintf(part_str, PART_STR_LEN, "%x:%x", efi_system_partition.devnum, efi_system_partition.part); - r = fs_set_blk_dev(blk_get_if_type_name(efi_system_partition.if_type), + r = fs_set_blk_dev(blk_get_uclass_name(efi_system_partition.uclass_id), part_str, FS_TYPE_ANY); if (r) { log_err("Cannot read EFI system partition\n"); From a966fa98b55bc79ce29e09158bf77b772bc3bc33 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 21 Sep 2022 16:21:33 +0200 Subject: [PATCH 294/374] scsi: Tidy up comments for struct scsi_cmd These comments are bit of a mess. Tidy them up to match the correct coding style. Signed-off-by: Simon Glass --- include/scsi.h | 56 ++++++++++++++++++++++++++++++++++---------------- 1 file changed, 38 insertions(+), 18 deletions(-) diff --git a/include/scsi.h b/include/scsi.h index b47c7463c1..99b00e2627 100644 --- a/include/scsi.h +++ b/include/scsi.h @@ -15,27 +15,47 @@ struct udevice; +/** + * struct scsi_cmd - information about a SCSI command to be processed + * + * @cmd: command + * @sense_buf: for request sense + * @status: SCSI Status + * @target: Target ID + * @lun: Target LUN + * @cmdlen: command len + * @datalen: Total data length + * @pdata: pointer to data + * @msgout: Messge out buffer (NOT USED) + * @msgin: Message in buffer + * @sensecmdlen: Sense command len + * @sensedatalen: Sense data len + * @sensecmd: Sense command + * @contr_stat: Controller Status + * @trans_bytes: tranfered bytes + * @priv: Private value + * @dma_dir: Direction of data structure + */ struct scsi_cmd { - unsigned char cmd[16]; /* command */ - /* for request sense */ - unsigned char sense_buf[64] + unsigned char cmd[16]; + unsigned char sense_buf[64] __attribute__((aligned(ARCH_DMA_MINALIGN))); - unsigned char status; /* SCSI Status */ - unsigned char target; /* Target ID */ - unsigned char lun; /* Target LUN */ - unsigned char cmdlen; /* command len */ - unsigned long datalen; /* Total data length */ - unsigned char * pdata; /* pointer to data */ - unsigned char msgout[12]; /* Messge out buffer (NOT USED) */ - unsigned char msgin[12]; /* Message in buffer */ - unsigned char sensecmdlen; /* Sense command len */ - unsigned long sensedatalen; /* Sense data len */ - unsigned char sensecmd[6]; /* Sense command */ - unsigned long contr_stat; /* Controller Status */ - unsigned long trans_bytes; /* tranfered bytes */ + unsigned char status; + unsigned char target; + unsigned char lun; + unsigned char cmdlen; + unsigned long datalen; + unsigned char *pdata; + unsigned char msgout[12]; + unsigned char msgin[12]; + unsigned char sensecmdlen; + unsigned long sensedatalen; + unsigned char sensecmd[6]; + unsigned long contr_stat; + unsigned long trans_bytes; - unsigned int priv; - enum dma_data_direction dma_dir; + unsigned int priv; + enum dma_data_direction dma_dir; }; /*----------------------------------------------------------- From 8bae79744b39ee7725729673202477300b2f79bc Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 21 Sep 2022 16:21:34 +0200 Subject: [PATCH 295/374] sandbox: usb: Rename transfer_len in protocol struct This has the same name as a field in our local private struct, which is confusing. Change the name to xfer_len instead. Signed-off-by: Simon Glass --- drivers/usb/emul/sandbox_flash.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/usb/emul/sandbox_flash.c b/drivers/usb/emul/sandbox_flash.c index 01b2b41cce..7de752100c 100644 --- a/drivers/usb/emul/sandbox_flash.c +++ b/drivers/usb/emul/sandbox_flash.c @@ -43,7 +43,7 @@ enum { * @error: true if there is an error condition * @alloc_len: Allocation length from the last incoming command * @transfer_len: Transfer length from CBW header - * @read_len: Number of blocks of data left in the current read command + * @read_len: Number of bytes of data left in the current read command * @tag: Tag value from last command * @fd: File descriptor of backing file * @file_size: Size of file in bytes @@ -92,7 +92,7 @@ struct __packed scsi_read10_req { u8 lun_flags; u32 lba; u8 spare; - u16 transfer_len; + u16 xfer_len; u8 spare2[3]; }; @@ -282,7 +282,7 @@ static int handle_ufi_command(struct sandbox_flash_plat *plat, struct scsi_read10_req *req = (void *)buff; handle_read(priv, be32_to_cpu(req->lba), - be16_to_cpu(req->transfer_len)); + be16_to_cpu(req->xfer_len)); break; } default: From 0e0b9e94595a706d86d8a9daca572da9a7de35a0 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 21 Sep 2022 16:21:35 +0200 Subject: [PATCH 296/374] scsi: Move cmd_phase enum to the header This can be used by common files, so move it to the SCSI header and rename it. Signed-off-by: Simon Glass --- drivers/usb/emul/sandbox_flash.c | 24 +++++++++--------------- include/scsi.h | 13 +++++++++++++ 2 files changed, 22 insertions(+), 15 deletions(-) diff --git a/drivers/usb/emul/sandbox_flash.c b/drivers/usb/emul/sandbox_flash.c index 7de752100c..806aed2ef2 100644 --- a/drivers/usb/emul/sandbox_flash.c +++ b/drivers/usb/emul/sandbox_flash.c @@ -23,12 +23,6 @@ enum { SANDBOX_FLASH_BLOCK_LEN = 512, }; -enum cmd_phase { - PHASE_START, - PHASE_DATA, - PHASE_STATUS, -}; - enum { STRINGID_MANUFACTURER = 1, STRINGID_PRODUCT, @@ -56,7 +50,7 @@ struct sandbox_flash_priv { int alloc_len; int transfer_len; int read_len; - enum cmd_phase phase; + enum scsi_cmd_phase phase; u32 tag; int fd; loff_t file_size; @@ -290,7 +284,7 @@ static int handle_ufi_command(struct sandbox_flash_plat *plat, return -EPROTONOSUPPORT; } - priv->phase = priv->transfer_len ? PHASE_DATA : PHASE_STATUS; + priv->phase = priv->transfer_len ? SCSIPH_DATA : SCSIPH_STATUS; return 0; } @@ -307,7 +301,7 @@ static int sandbox_flash_bulk(struct udevice *dev, struct usb_device *udev, switch (ep) { case SANDBOX_FLASH_EP_OUT: switch (priv->phase) { - case PHASE_START: + case SCSIPH_START: priv->alloc_len = 0; priv->read_len = 0; if (priv->error || len != UMASS_BBB_CBW_SIZE || @@ -322,7 +316,7 @@ static int sandbox_flash_bulk(struct udevice *dev, struct usb_device *udev, priv->tag = cbw->dCBWTag; return handle_ufi_command(plat, priv, cbw->CBWCDB, cbw->bCDBLength); - case PHASE_DATA: + case SCSIPH_DATA: debug("data out\n"); break; default: @@ -330,7 +324,7 @@ static int sandbox_flash_bulk(struct udevice *dev, struct usb_device *udev, } case SANDBOX_FLASH_EP_IN: switch (priv->phase) { - case PHASE_DATA: + case SCSIPH_DATA: debug("data in, len=%x, alloc_len=%x, priv->read_len=%x\n", len, priv->alloc_len, priv->read_len); if (priv->read_len) { @@ -344,22 +338,22 @@ static int sandbox_flash_bulk(struct udevice *dev, struct usb_device *udev, return -EIO; priv->read_len -= len / SANDBOX_FLASH_BLOCK_LEN; if (!priv->read_len) - priv->phase = PHASE_STATUS; + priv->phase = SCSIPH_STATUS; } else { if (priv->alloc_len && len > priv->alloc_len) len = priv->alloc_len; if (len > sizeof(priv->buff)) len = sizeof(priv->buff); memcpy(buff, priv->buff, len); - priv->phase = PHASE_STATUS; + priv->phase = SCSIPH_STATUS; } return len; - case PHASE_STATUS: + case SCSIPH_STATUS: debug("status in, len=%x\n", len); if (len > sizeof(priv->status)) len = sizeof(priv->status); memcpy(buff, &priv->status, len); - priv->phase = PHASE_START; + priv->phase = SCSIPH_START; return len; default: break; diff --git a/include/scsi.h b/include/scsi.h index 99b00e2627..a4f99f0884 100644 --- a/include/scsi.h +++ b/include/scsi.h @@ -187,6 +187,19 @@ struct scsi_cmd { #define SCSI_WRITE_LONG 0x3F /* Write Long (O) */ #define SCSI_WRITE_SAME 0x41 /* Write Same (O) */ +/** + * enum scsi_cmd_phase - current phase of the SCSI protocol + * + * @SCSIPH_START: Start phase + * @SCSIPH_DATA: Data phase + * @SCSIPH_STATUS: Status phase + */ +enum scsi_cmd_phase { + SCSIPH_START, + SCSIPH_DATA, + SCSIPH_STATUS, +}; + /** * struct scsi_plat - stores information about SCSI controller * From 1377d448a26aa67907ae86a84d33c02c7c9b9dcd Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 21 Sep 2022 16:21:36 +0200 Subject: [PATCH 297/374] scsi: Move core emulation state into a new struct In preparation for sharing the emulation code between two drivers, move some of the fields into a new struct. Use a separate header file so it can be used by various drivers. Signed-off-by: Simon Glass --- drivers/usb/emul/sandbox_flash.c | 60 ++++++++++++++++---------------- include/scsi_emul.h | 32 +++++++++++++++++ 2 files changed, 62 insertions(+), 30 deletions(-) create mode 100644 include/scsi_emul.h diff --git a/drivers/usb/emul/sandbox_flash.c b/drivers/usb/emul/sandbox_flash.c index 806aed2ef2..e7abc0d5c9 100644 --- a/drivers/usb/emul/sandbox_flash.c +++ b/drivers/usb/emul/sandbox_flash.c @@ -9,6 +9,7 @@ #include #include #include +#include #include /* @@ -34,28 +35,21 @@ enum { /** * struct sandbox_flash_priv - private state for this driver * + * @eminfo: emulator state * @error: true if there is an error condition - * @alloc_len: Allocation length from the last incoming command - * @transfer_len: Transfer length from CBW header - * @read_len: Number of bytes of data left in the current read command * @tag: Tag value from last command * @fd: File descriptor of backing file * @file_size: Size of file in bytes * @status_buff: Data buffer for outgoing status - * @buff_used: Number of bytes ready to transfer back to host * @buff: Data buffer for outgoing data */ struct sandbox_flash_priv { + struct scsi_emul_info eminfo; bool error; - int alloc_len; - int transfer_len; - int read_len; - enum scsi_cmd_phase phase; u32 tag; int fd; loff_t file_size; struct umass_bbb_csw status; - int buff_used; u8 buff[512]; }; @@ -188,13 +182,14 @@ static int sandbox_flash_control(struct udevice *dev, struct usb_device *udev, static void setup_fail_response(struct sandbox_flash_priv *priv) { + struct scsi_emul_info *info = &priv->eminfo; struct umass_bbb_csw *csw = &priv->status; csw->dCSWSignature = CSWSIGNATURE; csw->dCSWTag = priv->tag; csw->dCSWDataResidue = 0; csw->bCSWStatus = CSWSTATUS_FAILED; - priv->buff_used = 0; + info->buff_used = 0; } /** @@ -207,6 +202,7 @@ static void setup_fail_response(struct sandbox_flash_priv *priv) static void setup_response(struct sandbox_flash_priv *priv, void *resp, int size) { + struct scsi_emul_info *info = &priv->eminfo; struct umass_bbb_csw *csw = &priv->status; csw->dCSWSignature = CSWSIGNATURE; @@ -215,14 +211,16 @@ static void setup_response(struct sandbox_flash_priv *priv, void *resp, csw->bCSWStatus = CSWSTATUS_GOOD; assert(!resp || resp == priv->buff); - priv->buff_used = size; + info->buff_used = size; } static void handle_read(struct sandbox_flash_priv *priv, ulong lba, ulong transfer_len) { + struct scsi_emul_info *info = &priv->eminfo; + debug("%s: lba=%lx, transfer_len=%lx\n", __func__, lba, transfer_len); - priv->read_len = transfer_len; + info->read_len = transfer_len; if (priv->fd != -1) { os_lseek(priv->fd, lba * SANDBOX_FLASH_BLOCK_LEN, OS_SEEK_SET); setup_response(priv, priv->buff, @@ -236,13 +234,14 @@ static int handle_ufi_command(struct sandbox_flash_plat *plat, struct sandbox_flash_priv *priv, const void *buff, int len) { + struct scsi_emul_info *info = &priv->eminfo; const struct scsi_cmd *req = buff; switch (*req->cmd) { case SCSI_INQUIRY: { struct scsi_inquiry_resp *resp = (void *)priv->buff; - priv->alloc_len = req->cmd[4]; + info->alloc_len = req->cmd[4]; memset(resp, '\0', sizeof(*resp)); resp->data_format = 1; resp->additional_len = 0x1f; @@ -284,7 +283,7 @@ static int handle_ufi_command(struct sandbox_flash_plat *plat, return -EPROTONOSUPPORT; } - priv->phase = priv->transfer_len ? SCSIPH_DATA : SCSIPH_STATUS; + info->phase = info->transfer_len ? SCSIPH_DATA : SCSIPH_STATUS; return 0; } @@ -293,17 +292,18 @@ static int sandbox_flash_bulk(struct udevice *dev, struct usb_device *udev, { struct sandbox_flash_plat *plat = dev_get_plat(dev); struct sandbox_flash_priv *priv = dev_get_priv(dev); + struct scsi_emul_info *info = &priv->eminfo; int ep = usb_pipeendpoint(pipe); struct umass_bbb_cbw *cbw = buff; debug("%s: dev=%s, pipe=%lx, ep=%x, len=%x, phase=%d\n", __func__, - dev->name, pipe, ep, len, priv->phase); + dev->name, pipe, ep, len, info->phase); switch (ep) { case SANDBOX_FLASH_EP_OUT: - switch (priv->phase) { + switch (info->phase) { case SCSIPH_START: - priv->alloc_len = 0; - priv->read_len = 0; + info->alloc_len = 0; + info->read_len = 0; if (priv->error || len != UMASS_BBB_CBW_SIZE || cbw->dCBWSignature != CBWSIGNATURE) goto err; @@ -312,7 +312,7 @@ static int sandbox_flash_bulk(struct udevice *dev, struct usb_device *udev, goto err; if (cbw->bCDBLength < 1 || cbw->bCDBLength >= 0x10) goto err; - priv->transfer_len = cbw->dCBWDataTransferLength; + info->transfer_len = cbw->dCBWDataTransferLength; priv->tag = cbw->dCBWTag; return handle_ufi_command(plat, priv, cbw->CBWCDB, cbw->bCDBLength); @@ -323,11 +323,11 @@ static int sandbox_flash_bulk(struct udevice *dev, struct usb_device *udev, break; } case SANDBOX_FLASH_EP_IN: - switch (priv->phase) { + switch (info->phase) { case SCSIPH_DATA: - debug("data in, len=%x, alloc_len=%x, priv->read_len=%x\n", - len, priv->alloc_len, priv->read_len); - if (priv->read_len) { + debug("data in, len=%x, alloc_len=%x, info->read_len=%x\n", + len, info->alloc_len, info->read_len); + if (info->read_len) { ulong bytes_read; if (priv->fd == -1) @@ -336,16 +336,16 @@ static int sandbox_flash_bulk(struct udevice *dev, struct usb_device *udev, bytes_read = os_read(priv->fd, buff, len); if (bytes_read != len) return -EIO; - priv->read_len -= len / SANDBOX_FLASH_BLOCK_LEN; - if (!priv->read_len) - priv->phase = SCSIPH_STATUS; + info->read_len -= len / SANDBOX_FLASH_BLOCK_LEN; + if (!info->read_len) + info->phase = SCSIPH_STATUS; } else { - if (priv->alloc_len && len > priv->alloc_len) - len = priv->alloc_len; + if (info->alloc_len && len > info->alloc_len) + len = info->alloc_len; if (len > sizeof(priv->buff)) len = sizeof(priv->buff); memcpy(buff, priv->buff, len); - priv->phase = SCSIPH_STATUS; + info->phase = SCSIPH_STATUS; } return len; case SCSIPH_STATUS: @@ -353,7 +353,7 @@ static int sandbox_flash_bulk(struct udevice *dev, struct usb_device *udev, if (len > sizeof(priv->status)) len = sizeof(priv->status); memcpy(buff, &priv->status, len); - priv->phase = SCSIPH_START; + info->phase = SCSIPH_START; return len; default: break; diff --git a/include/scsi_emul.h b/include/scsi_emul.h new file mode 100644 index 0000000000..dec78d239c --- /dev/null +++ b/include/scsi_emul.h @@ -0,0 +1,32 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Emulation of enough SCSI commands to find and read from a unit + * + * Copyright 2022 Google LLC + * Written by Simon Glass + * + * implementations of SCSI functions required so that CONFIG_SCSI can be enabled + * for sandbox + */ + +#ifndef __scsi_emul_h +#define __scsi_emul_h + +/** + * struct scsi_emul_info - information for emulating a SCSI device + * + * @phase: Current SCSI phase + * @buff_used: Number of bytes ready to transfer back to host + * @read_len: Number of bytes of data left in the current read command + * @alloc_len: Allocation length from the last incoming command + * @transfer_len: Transfer length from CBW header + */ +struct scsi_emul_info { + enum scsi_cmd_phase phase; + int buff_used; + int read_len; + int alloc_len; + uint transfer_len; +}; + +#endif From fc7a7ed3a6cd9ea03400e1356768e646ff00b043 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 21 Sep 2022 16:21:37 +0200 Subject: [PATCH 298/374] sandbox: Move buffer to scsi_emul_info Move the buffer into this struct so it can be shared between different implementations. Signed-off-by: Simon Glass --- drivers/usb/emul/sandbox_flash.c | 41 +++++++++++++++++++++++--------- include/scsi_emul.h | 5 ++++ 2 files changed, 35 insertions(+), 11 deletions(-) diff --git a/drivers/usb/emul/sandbox_flash.c b/drivers/usb/emul/sandbox_flash.c index e7abc0d5c9..3a9db835ee 100644 --- a/drivers/usb/emul/sandbox_flash.c +++ b/drivers/usb/emul/sandbox_flash.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -22,6 +23,7 @@ enum { SANDBOX_FLASH_EP_OUT = 1, /* endpoints */ SANDBOX_FLASH_EP_IN = 2, SANDBOX_FLASH_BLOCK_LEN = 512, + SANDBOX_FLASH_BUF_SIZE = 512, }; enum { @@ -41,7 +43,6 @@ enum { * @fd: File descriptor of backing file * @file_size: Size of file in bytes * @status_buff: Data buffer for outgoing status - * @buff: Data buffer for outgoing data */ struct sandbox_flash_priv { struct scsi_emul_info eminfo; @@ -50,7 +51,6 @@ struct sandbox_flash_priv { int fd; loff_t file_size; struct umass_bbb_csw status; - u8 buff[512]; }; struct sandbox_flash_plat { @@ -210,7 +210,7 @@ static void setup_response(struct sandbox_flash_priv *priv, void *resp, csw->dCSWDataResidue = 0; csw->bCSWStatus = CSWSTATUS_GOOD; - assert(!resp || resp == priv->buff); + assert(!resp || resp == info->buff); info->buff_used = size; } @@ -223,7 +223,7 @@ static void handle_read(struct sandbox_flash_priv *priv, ulong lba, info->read_len = transfer_len; if (priv->fd != -1) { os_lseek(priv->fd, lba * SANDBOX_FLASH_BLOCK_LEN, OS_SEEK_SET); - setup_response(priv, priv->buff, + setup_response(priv, info->buff, transfer_len * SANDBOX_FLASH_BLOCK_LEN); } else { setup_fail_response(priv); @@ -239,7 +239,7 @@ static int handle_ufi_command(struct sandbox_flash_plat *plat, switch (*req->cmd) { case SCSI_INQUIRY: { - struct scsi_inquiry_resp *resp = (void *)priv->buff; + struct scsi_inquiry_resp *resp = (void *)info->buff; info->alloc_len = req->cmd[4]; memset(resp, '\0', sizeof(*resp)); @@ -259,7 +259,7 @@ static int handle_ufi_command(struct sandbox_flash_plat *plat, setup_response(priv, NULL, 0); break; case SCSI_RD_CAPAC: { - struct scsi_read_capacity_resp *resp = (void *)priv->buff; + struct scsi_read_capacity_resp *resp = (void *)info->buff; uint blocks; if (priv->file_size) @@ -342,9 +342,9 @@ static int sandbox_flash_bulk(struct udevice *dev, struct usb_device *udev, } else { if (info->alloc_len && len > info->alloc_len) len = info->alloc_len; - if (len > sizeof(priv->buff)) - len = sizeof(priv->buff); - memcpy(buff, priv->buff, len); + if (len > SANDBOX_FLASH_BUF_SIZE) + len = SANDBOX_FLASH_BUF_SIZE; + memcpy(buff, info->buff, len); info->phase = SCSIPH_STATUS; } return len; @@ -394,10 +394,28 @@ static int sandbox_flash_probe(struct udevice *dev) { struct sandbox_flash_plat *plat = dev_get_plat(dev); struct sandbox_flash_priv *priv = dev_get_priv(dev); + struct scsi_emul_info *info = &priv->eminfo; + int ret; priv->fd = os_open(plat->pathname, OS_O_RDONLY); - if (priv->fd != -1) - return os_get_filesize(plat->pathname, &priv->file_size); + if (priv->fd != -1) { + ret = os_get_filesize(plat->pathname, &priv->file_size); + if (ret) + return log_msg_ret("sz", ret); + } + info->buff = malloc(SANDBOX_FLASH_BUF_SIZE); + if (!info->buff) + return log_ret(-ENOMEM); + + return 0; +} + +static int sandbox_flash_remove(struct udevice *dev) +{ + struct sandbox_flash_priv *priv = dev_get_priv(dev); + struct scsi_emul_info *info = &priv->eminfo; + + free(info->buff); return 0; } @@ -418,6 +436,7 @@ U_BOOT_DRIVER(usb_sandbox_flash) = { .of_match = sandbox_usb_flash_ids, .bind = sandbox_flash_bind, .probe = sandbox_flash_probe, + .remove = sandbox_flash_remove, .of_to_plat = sandbox_flash_of_to_plat, .ops = &sandbox_usb_flash_ops, .priv_auto = sizeof(struct sandbox_flash_priv), diff --git a/include/scsi_emul.h b/include/scsi_emul.h index dec78d239c..f27c19750b 100644 --- a/include/scsi_emul.h +++ b/include/scsi_emul.h @@ -20,8 +20,13 @@ * @read_len: Number of bytes of data left in the current read command * @alloc_len: Allocation length from the last incoming command * @transfer_len: Transfer length from CBW header + * @buff: Data buffer for outgoing data */ struct scsi_emul_info { + /* provided by the caller: */ + void *buff; + + /* state maintained by the emulator: */ enum scsi_cmd_phase phase; int buff_used; int read_len; From 0c12d9dd23a3bce38170db2bab0cc326def6a1db Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 21 Sep 2022 16:21:38 +0200 Subject: [PATCH 299/374] scsi: Move vendor/product info into the shared struct Move this information into struct scsi_emul_info so we can use it in common code. Signed-off-by: Simon Glass --- drivers/usb/emul/sandbox_flash.c | 10 ++++------ include/scsi_emul.h | 5 +++++ 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/drivers/usb/emul/sandbox_flash.c b/drivers/usb/emul/sandbox_flash.c index 3a9db835ee..eaa7f1e7ff 100644 --- a/drivers/usb/emul/sandbox_flash.c +++ b/drivers/usb/emul/sandbox_flash.c @@ -245,12 +245,8 @@ static int handle_ufi_command(struct sandbox_flash_plat *plat, memset(resp, '\0', sizeof(*resp)); resp->data_format = 1; resp->additional_len = 0x1f; - strncpy(resp->vendor, - plat->flash_strings[STRINGID_MANUFACTURER - 1].s, - sizeof(resp->vendor)); - strncpy(resp->product, - plat->flash_strings[STRINGID_PRODUCT - 1].s, - sizeof(resp->product)); + strncpy(resp->vendor, info->vendor, sizeof(resp->vendor)); + strncpy(resp->product, info->product, sizeof(resp->product)); strncpy(resp->revision, "1.0", sizeof(resp->revision)); setup_response(priv, resp, sizeof(*resp)); break; @@ -406,6 +402,8 @@ static int sandbox_flash_probe(struct udevice *dev) info->buff = malloc(SANDBOX_FLASH_BUF_SIZE); if (!info->buff) return log_ret(-ENOMEM); + info->vendor = plat->flash_strings[STRINGID_MANUFACTURER - 1].s; + info->product = plat->flash_strings[STRINGID_PRODUCT - 1].s; return 0; } diff --git a/include/scsi_emul.h b/include/scsi_emul.h index f27c19750b..b281c166f6 100644 --- a/include/scsi_emul.h +++ b/include/scsi_emul.h @@ -15,6 +15,9 @@ /** * struct scsi_emul_info - information for emulating a SCSI device * + * @vendor: Vendor name + * @product: Product name + * * @phase: Current SCSI phase * @buff_used: Number of bytes ready to transfer back to host * @read_len: Number of bytes of data left in the current read command @@ -25,6 +28,8 @@ struct scsi_emul_info { /* provided by the caller: */ void *buff; + const char *vendor; + const char *product; /* state maintained by the emulator: */ enum scsi_cmd_phase phase; From a3718f1e536c564610f23298e2c0540877ef30f8 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 21 Sep 2022 16:21:39 +0200 Subject: [PATCH 300/374] sandbox: scsi: Move block size into shared struct Move this information into struct scsi_emul_info so we can use it in common code. Signed-off-by: Simon Glass --- drivers/usb/emul/sandbox_flash.c | 11 ++++++----- include/scsi_emul.h | 2 ++ 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/drivers/usb/emul/sandbox_flash.c b/drivers/usb/emul/sandbox_flash.c index eaa7f1e7ff..e4a8eb2e98 100644 --- a/drivers/usb/emul/sandbox_flash.c +++ b/drivers/usb/emul/sandbox_flash.c @@ -222,9 +222,9 @@ static void handle_read(struct sandbox_flash_priv *priv, ulong lba, debug("%s: lba=%lx, transfer_len=%lx\n", __func__, lba, transfer_len); info->read_len = transfer_len; if (priv->fd != -1) { - os_lseek(priv->fd, lba * SANDBOX_FLASH_BLOCK_LEN, OS_SEEK_SET); + os_lseek(priv->fd, lba * info->block_size, OS_SEEK_SET); setup_response(priv, info->buff, - transfer_len * SANDBOX_FLASH_BLOCK_LEN); + transfer_len * info->block_size); } else { setup_fail_response(priv); } @@ -259,11 +259,11 @@ static int handle_ufi_command(struct sandbox_flash_plat *plat, uint blocks; if (priv->file_size) - blocks = priv->file_size / SANDBOX_FLASH_BLOCK_LEN - 1; + blocks = priv->file_size / info->block_size - 1; else blocks = 0; resp->last_block_addr = cpu_to_be32(blocks); - resp->block_len = cpu_to_be32(SANDBOX_FLASH_BLOCK_LEN); + resp->block_len = cpu_to_be32(info->block_size); setup_response(priv, resp, sizeof(*resp)); break; } @@ -332,7 +332,7 @@ static int sandbox_flash_bulk(struct udevice *dev, struct usb_device *udev, bytes_read = os_read(priv->fd, buff, len); if (bytes_read != len) return -EIO; - info->read_len -= len / SANDBOX_FLASH_BLOCK_LEN; + info->read_len -= len / info->block_size; if (!info->read_len) info->phase = SCSIPH_STATUS; } else { @@ -404,6 +404,7 @@ static int sandbox_flash_probe(struct udevice *dev) return log_ret(-ENOMEM); info->vendor = plat->flash_strings[STRINGID_MANUFACTURER - 1].s; info->product = plat->flash_strings[STRINGID_PRODUCT - 1].s; + info->block_size = SANDBOX_FLASH_BLOCK_LEN; return 0; } diff --git a/include/scsi_emul.h b/include/scsi_emul.h index b281c166f6..86c9379ca9 100644 --- a/include/scsi_emul.h +++ b/include/scsi_emul.h @@ -17,6 +17,7 @@ * * @vendor: Vendor name * @product: Product name + * @block_size: Block size of device in bytes (normally 512) * * @phase: Current SCSI phase * @buff_used: Number of bytes ready to transfer back to host @@ -30,6 +31,7 @@ struct scsi_emul_info { void *buff; const char *vendor; const char *product; + int block_size; /* state maintained by the emulator: */ enum scsi_cmd_phase phase; From f148ad1b5fb14a3295ced502647de5be69e46100 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 21 Sep 2022 16:21:40 +0200 Subject: [PATCH 301/374] sandbox: scsi: Move file size into shared struct Move this information into struct scsi_emul_info so we can use it in common code. Signed-off-by: Simon Glass --- drivers/usb/emul/sandbox_flash.c | 7 +++---- include/scsi_emul.h | 2 ++ 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/usb/emul/sandbox_flash.c b/drivers/usb/emul/sandbox_flash.c index e4a8eb2e98..3c5bc675e3 100644 --- a/drivers/usb/emul/sandbox_flash.c +++ b/drivers/usb/emul/sandbox_flash.c @@ -49,7 +49,6 @@ struct sandbox_flash_priv { bool error; u32 tag; int fd; - loff_t file_size; struct umass_bbb_csw status; }; @@ -258,8 +257,8 @@ static int handle_ufi_command(struct sandbox_flash_plat *plat, struct scsi_read_capacity_resp *resp = (void *)info->buff; uint blocks; - if (priv->file_size) - blocks = priv->file_size / info->block_size - 1; + if (info->file_size) + blocks = info->file_size / info->block_size - 1; else blocks = 0; resp->last_block_addr = cpu_to_be32(blocks); @@ -395,7 +394,7 @@ static int sandbox_flash_probe(struct udevice *dev) priv->fd = os_open(plat->pathname, OS_O_RDONLY); if (priv->fd != -1) { - ret = os_get_filesize(plat->pathname, &priv->file_size); + ret = os_get_filesize(plat->pathname, &info->file_size); if (ret) return log_msg_ret("sz", ret); } diff --git a/include/scsi_emul.h b/include/scsi_emul.h index 86c9379ca9..3c52398e3f 100644 --- a/include/scsi_emul.h +++ b/include/scsi_emul.h @@ -18,6 +18,7 @@ * @vendor: Vendor name * @product: Product name * @block_size: Block size of device in bytes (normally 512) + * @file_size: Size of the backing file for this emulator, in bytes * * @phase: Current SCSI phase * @buff_used: Number of bytes ready to transfer back to host @@ -32,6 +33,7 @@ struct scsi_emul_info { const char *vendor; const char *product; int block_size; + loff_t file_size; /* state maintained by the emulator: */ enum scsi_cmd_phase phase; From f75b6f76a484b24a346a1cd46a7e2553383a583d Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 21 Sep 2022 16:21:41 +0200 Subject: [PATCH 302/374] sandbox: scsi: Move reply setup out of helper Move this code out of the helper function so we can (later) add it as part of the shared emulation code. Set a default value of 0 for buff_used since that is what we use when there is an error. Signed-off-by: Simon Glass --- drivers/usb/emul/sandbox_flash.c | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/drivers/usb/emul/sandbox_flash.c b/drivers/usb/emul/sandbox_flash.c index 3c5bc675e3..e699f89793 100644 --- a/drivers/usb/emul/sandbox_flash.c +++ b/drivers/usb/emul/sandbox_flash.c @@ -181,14 +181,12 @@ static int sandbox_flash_control(struct udevice *dev, struct usb_device *udev, static void setup_fail_response(struct sandbox_flash_priv *priv) { - struct scsi_emul_info *info = &priv->eminfo; struct umass_bbb_csw *csw = &priv->status; csw->dCSWSignature = CSWSIGNATURE; csw->dCSWTag = priv->tag; csw->dCSWDataResidue = 0; csw->bCSWStatus = CSWSTATUS_FAILED; - info->buff_used = 0; } /** @@ -198,19 +196,14 @@ static void setup_fail_response(struct sandbox_flash_priv *priv) * @resp: Response to send, or NULL if none * @size: Size of response */ -static void setup_response(struct sandbox_flash_priv *priv, void *resp, - int size) +static void setup_response(struct sandbox_flash_priv *priv) { - struct scsi_emul_info *info = &priv->eminfo; struct umass_bbb_csw *csw = &priv->status; csw->dCSWSignature = CSWSIGNATURE; csw->dCSWTag = priv->tag; csw->dCSWDataResidue = 0; csw->bCSWStatus = CSWSTATUS_GOOD; - - assert(!resp || resp == info->buff); - info->buff_used = size; } static void handle_read(struct sandbox_flash_priv *priv, ulong lba, @@ -222,8 +215,8 @@ static void handle_read(struct sandbox_flash_priv *priv, ulong lba, info->read_len = transfer_len; if (priv->fd != -1) { os_lseek(priv->fd, lba * info->block_size, OS_SEEK_SET); - setup_response(priv, info->buff, - transfer_len * info->block_size); + info->buff_used = transfer_len * info->block_size; + setup_response(priv); } else { setup_fail_response(priv); } @@ -236,6 +229,7 @@ static int handle_ufi_command(struct sandbox_flash_plat *plat, struct scsi_emul_info *info = &priv->eminfo; const struct scsi_cmd *req = buff; + info->buff_used = 0; switch (*req->cmd) { case SCSI_INQUIRY: { struct scsi_inquiry_resp *resp = (void *)info->buff; @@ -247,11 +241,12 @@ static int handle_ufi_command(struct sandbox_flash_plat *plat, strncpy(resp->vendor, info->vendor, sizeof(resp->vendor)); strncpy(resp->product, info->product, sizeof(resp->product)); strncpy(resp->revision, "1.0", sizeof(resp->revision)); - setup_response(priv, resp, sizeof(*resp)); + info->buff_used = sizeof(*resp); + setup_response(priv); break; } case SCSI_TST_U_RDY: - setup_response(priv, NULL, 0); + setup_response(priv); break; case SCSI_RD_CAPAC: { struct scsi_read_capacity_resp *resp = (void *)info->buff; @@ -263,7 +258,8 @@ static int handle_ufi_command(struct sandbox_flash_plat *plat, blocks = 0; resp->last_block_addr = cpu_to_be32(blocks); resp->block_len = cpu_to_be32(info->block_size); - setup_response(priv, resp, sizeof(*resp)); + info->buff_used = sizeof(*resp); + setup_response(priv); break; } case SCSI_READ10: { From e074df4d23516597ce65d5056614073cc4e6bfc8 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 21 Sep 2022 16:21:42 +0200 Subject: [PATCH 303/374] sandbox: scsi: Remove setup calls from handle_read() Move the device-specific code out into the top-level function. Signed-off-by: Simon Glass --- drivers/usb/emul/sandbox_flash.c | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/drivers/usb/emul/sandbox_flash.c b/drivers/usb/emul/sandbox_flash.c index e699f89793..7b9a99c1a3 100644 --- a/drivers/usb/emul/sandbox_flash.c +++ b/drivers/usb/emul/sandbox_flash.c @@ -206,8 +206,19 @@ static void setup_response(struct sandbox_flash_priv *priv) csw->bCSWStatus = CSWSTATUS_GOOD; } -static void handle_read(struct sandbox_flash_priv *priv, ulong lba, - ulong transfer_len) +/** + * handle_read() - prepare for reading data from the backing file + * + * This seeks to the correct file position and sets info->buff_used to the + * correct size. + * + * @priv: Private information + * @lba: Start block to read from + * @transfer_length: Number of blocks to read + * @return 0 if OK, -EIO on failure + */ +static int handle_read(struct sandbox_flash_priv *priv, ulong lba, + ulong transfer_len) { struct scsi_emul_info *info = &priv->eminfo; @@ -216,10 +227,10 @@ static void handle_read(struct sandbox_flash_priv *priv, ulong lba, if (priv->fd != -1) { os_lseek(priv->fd, lba * info->block_size, OS_SEEK_SET); info->buff_used = transfer_len * info->block_size; - setup_response(priv); - } else { - setup_fail_response(priv); + return 0; } + + return -EIO; } static int handle_ufi_command(struct sandbox_flash_plat *plat, @@ -265,8 +276,12 @@ static int handle_ufi_command(struct sandbox_flash_plat *plat, case SCSI_READ10: { struct scsi_read10_req *req = (void *)buff; - handle_read(priv, be32_to_cpu(req->lba), - be16_to_cpu(req->xfer_len)); + if (!handle_read(priv, be32_to_cpu(req->lba), + be16_to_cpu(req->xfer_len))) + setup_response(priv); + else + setup_fail_response(priv); + break; } default: From 1ac42900d8de7a8989a76f2b69e6ae46784476b1 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 21 Sep 2022 16:21:43 +0200 Subject: [PATCH 304/374] sandbox: scsi: Move structs to header file Move these to the SCSI header file so we can access them from multiple emulators. Signed-off-by: Simon Glass --- drivers/usb/emul/sandbox_flash.c | 26 --------------- include/scsi.h | 55 ++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+), 26 deletions(-) diff --git a/drivers/usb/emul/sandbox_flash.c b/drivers/usb/emul/sandbox_flash.c index 7b9a99c1a3..2059fc7fe4 100644 --- a/drivers/usb/emul/sandbox_flash.c +++ b/drivers/usb/emul/sandbox_flash.c @@ -57,32 +57,6 @@ struct sandbox_flash_plat { struct usb_string flash_strings[STRINGID_COUNT]; }; -struct scsi_inquiry_resp { - u8 type; - u8 flags; - u8 version; - u8 data_format; - u8 additional_len; - u8 spare[3]; - char vendor[8]; - char product[16]; - char revision[4]; -}; - -struct scsi_read_capacity_resp { - u32 last_block_addr; - u32 block_len; -}; - -struct __packed scsi_read10_req { - u8 cmd; - u8 lun_flags; - u32 lba; - u8 spare; - u16 xfer_len; - u8 spare2[3]; -}; - static struct usb_device_descriptor flash_device_desc = { .bLength = sizeof(flash_device_desc), .bDescriptorType = USB_DT_DEVICE, diff --git a/include/scsi.h b/include/scsi.h index a4f99f0884..94e1d8ccb2 100644 --- a/include/scsi.h +++ b/include/scsi.h @@ -200,6 +200,61 @@ enum scsi_cmd_phase { SCSIPH_STATUS, }; +/** + * struct scsi_inquiry_resp - holds a SCSI inquiry command + * + * @type; command type + * @flags; command flags + * @version; command version + * @data_format; data format + * @additional_len; additional data length + * @spare[3]; spare bytes + * @vendor[8]; vendor information + * @product[16]; production information + * @revision[4]; revision information + */ +struct scsi_inquiry_resp { + u8 type; + u8 flags; + u8 version; + u8 data_format; + u8 additional_len; + u8 spare[3]; + char vendor[8]; + char product[16]; + char revision[4]; +}; + +/** + * struct scsi_read_capacity_resp - holds the response to a read-capacity cmd + * + * @last_block_addr: Logical block address of last block + * @block_len: Length of each block in bytes + */ +struct scsi_read_capacity_resp { + u32 last_block_addr; + u32 block_len; +}; + +/** + * struct scsi_read10_req - holds a SCSI READ10 request + * + * @cmd; command type + * @lun_flags; LUN flags + * @lba; Logical block address to start reading from + * @spare; spare bytes + * @xfer_len: number of blocks to read + * @spare2: more spare bytes + */ +struct __packed scsi_read10_req { + u8 cmd; + u8 lun_flags; + u32 lba; + u8 spare; + u16 xfer_len; + u8 spare2[3]; +}; + /** * struct scsi_plat - stores information about SCSI controller * From 5eff9d9c36e9e2b2437743d989f25376b981700a Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 21 Sep 2022 16:21:44 +0200 Subject: [PATCH 305/374] sandbox: Enable SCSI for all builds This will be needed to run unit tests, once the SCSI code is used for USB as well. Enable it for all sandbox builds. Signed-off-by: Simon Glass --- configs/sandbox64_defconfig | 6 +++++- configs/sandbox_flattree_defconfig | 4 ++++ configs/sandbox_noinst_defconfig | 4 ++++ configs/sandbox_spl_defconfig | 6 +++++- configs/sandbox_vpl_defconfig | 4 ++++ 5 files changed, 22 insertions(+), 2 deletions(-) diff --git a/configs/sandbox64_defconfig b/configs/sandbox64_defconfig index 9a1b6e4bbf..9dab89a999 100644 --- a/configs/sandbox64_defconfig +++ b/configs/sandbox64_defconfig @@ -52,6 +52,7 @@ CONFIG_CMD_OSD=y CONFIG_CMD_PCI=y CONFIG_CMD_READ=y CONFIG_CMD_REMOTEPROC=y +# CONFIG_CMD_SATA is not set CONFIG_CMD_SPI=y CONFIG_CMD_USB=y CONFIG_BOOTP_DNS2=y @@ -104,7 +105,6 @@ CONFIG_DEVRES=y CONFIG_DEBUG_DEVRES=y CONFIG_ADC=y CONFIG_ADC_SANDBOX=y -CONFIG_SYS_SATA_MAX_DEVICE=2 CONFIG_AXI=y CONFIG_AXI_SANDBOX=y CONFIG_SYS_IDE_MAXBUS=1 @@ -203,6 +203,10 @@ CONFIG_DM_RESET=y CONFIG_SANDBOX_RESET=y CONFIG_DM_RTC=y CONFIG_RTC_RV8803=y +CONFIG_SCSI=y +CONFIG_SCSI_AHCI_PLAT=y +CONFIG_SYS_SCSI_MAX_SCSI_ID=8 +CONFIG_SYS_SCSI_MAX_LUN=4 CONFIG_SANDBOX_SERIAL=y CONFIG_SMEM=y CONFIG_SANDBOX_SMEM=y diff --git a/configs/sandbox_flattree_defconfig b/configs/sandbox_flattree_defconfig index 4b18c240ee..a8344029f4 100644 --- a/configs/sandbox_flattree_defconfig +++ b/configs/sandbox_flattree_defconfig @@ -174,6 +174,10 @@ CONFIG_REMOTEPROC_SANDBOX=y CONFIG_DM_RESET=y CONFIG_SANDBOX_RESET=y CONFIG_DM_RTC=y +CONFIG_SCSI=y +CONFIG_SCSI_AHCI_PLAT=y +CONFIG_SYS_SCSI_MAX_SCSI_ID=8 +CONFIG_SYS_SCSI_MAX_LUN=4 CONFIG_SANDBOX_SERIAL=y CONFIG_SOUND=y CONFIG_SOUND_SANDBOX=y diff --git a/configs/sandbox_noinst_defconfig b/configs/sandbox_noinst_defconfig index 72c908f61a..da83165a4d 100644 --- a/configs/sandbox_noinst_defconfig +++ b/configs/sandbox_noinst_defconfig @@ -200,6 +200,10 @@ CONFIG_DM_RESET=y CONFIG_SANDBOX_RESET=y CONFIG_DM_RTC=y CONFIG_SPL_DM_RTC=y +CONFIG_SCSI=y +CONFIG_SCSI_AHCI_PLAT=y +CONFIG_SYS_SCSI_MAX_SCSI_ID=8 +CONFIG_SYS_SCSI_MAX_LUN=4 CONFIG_SANDBOX_SERIAL=y CONFIG_SOUND=y CONFIG_SOUND_SANDBOX=y diff --git a/configs/sandbox_spl_defconfig b/configs/sandbox_spl_defconfig index 11b9aa890b..0d7c5972d8 100644 --- a/configs/sandbox_spl_defconfig +++ b/configs/sandbox_spl_defconfig @@ -61,6 +61,7 @@ CONFIG_CMD_I2C=y CONFIG_CMD_OSD=y CONFIG_CMD_PCI=y CONFIG_CMD_REMOTEPROC=y +# CONFIG_CMD_SATA is not set CONFIG_CMD_SPI=y CONFIG_CMD_USB=y CONFIG_BOOTP_DNS2=y @@ -109,7 +110,6 @@ CONFIG_DEBUG_DEVRES=y # CONFIG_SPL_SIMPLE_BUS is not set CONFIG_ADC=y CONFIG_ADC_SANDBOX=y -CONFIG_SYS_SATA_MAX_DEVICE=2 CONFIG_AXI=y CONFIG_AXI_SANDBOX=y CONFIG_SYS_IDE_MAXBUS=1 @@ -203,6 +203,10 @@ CONFIG_DM_RESET=y CONFIG_SANDBOX_RESET=y CONFIG_DM_RTC=y CONFIG_SPL_DM_RTC=y +CONFIG_SCSI=y +CONFIG_SCSI_AHCI_PLAT=y +CONFIG_SYS_SCSI_MAX_SCSI_ID=8 +CONFIG_SYS_SCSI_MAX_LUN=4 CONFIG_SANDBOX_SERIAL=y CONFIG_SOUND=y CONFIG_SOUND_SANDBOX=y diff --git a/configs/sandbox_vpl_defconfig b/configs/sandbox_vpl_defconfig index c3856a8374..7bddac6198 100644 --- a/configs/sandbox_vpl_defconfig +++ b/configs/sandbox_vpl_defconfig @@ -209,6 +209,10 @@ CONFIG_SANDBOX_RESET=y CONFIG_DM_RTC=y CONFIG_SPL_DM_RTC=y CONFIG_TPL_DM_RTC=y +CONFIG_SCSI=y +CONFIG_SCSI_AHCI_PLAT=y +CONFIG_SYS_SCSI_MAX_SCSI_ID=8 +CONFIG_SYS_SCSI_MAX_LUN=4 CONFIG_SANDBOX_SERIAL=y CONFIG_SOUND=y CONFIG_SOUND_SANDBOX=y From 02cea1145a5ad49e400bd100b907ad763db16863 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 21 Sep 2022 16:21:45 +0200 Subject: [PATCH 306/374] sandbox: scsi: Move request-handling code to scsi_emul Move this code into the emulator file so it can be used by multiple drivers. Signed-off-by: Simon Glass --- drivers/scsi/Makefile | 1 + drivers/scsi/scsi_emul.c | 74 +++++++++++++++++++++++++++ drivers/usb/emul/sandbox_flash.c | 87 ++++---------------------------- include/scsi_emul.h | 24 +++++++++ 4 files changed, 109 insertions(+), 77 deletions(-) create mode 100644 drivers/scsi/scsi_emul.c diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile index 25194eeec1..d1b40c6140 100644 --- a/drivers/scsi/Makefile +++ b/drivers/scsi/Makefile @@ -17,4 +17,5 @@ endif ifdef CONFIG_SCSI obj-$(CONFIG_SANDBOX) += sandbox_scsi.o +obj-$(CONFIG_SANDBOX) += scsi_emul.o endif diff --git a/drivers/scsi/scsi_emul.c b/drivers/scsi/scsi_emul.c new file mode 100644 index 0000000000..5ba364bdac --- /dev/null +++ b/drivers/scsi/scsi_emul.c @@ -0,0 +1,74 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Emulation of enough SCSI commands to find and read from a unit + * + * Copyright 2022 Google LLC + * Written by Simon Glass + * + * implementation of SCSI functions required so that CONFIG_SCSI can be enabled + * for sandbox. + */ + +#define LOG_CATEGORY UCLASS_SCSI + +#include +#include +#include +#include +#include + +int sb_scsi_emul_command(struct scsi_emul_info *info, + const struct scsi_cmd *req, int len) +{ + int ret = 0; + + info->buff_used = 0; + log_debug("emul %x\n", *req->cmd); + switch (*req->cmd) { + case SCSI_INQUIRY: { + struct scsi_inquiry_resp *resp = (void *)info->buff; + + info->alloc_len = req->cmd[4]; + memset(resp, '\0', sizeof(*resp)); + resp->data_format = 1; + resp->additional_len = 0x1f; + strncpy(resp->vendor, info->vendor, sizeof(resp->vendor)); + strncpy(resp->product, info->product, sizeof(resp->product)); + strncpy(resp->revision, "1.0", sizeof(resp->revision)); + info->buff_used = sizeof(*resp); + break; + } + case SCSI_TST_U_RDY: + break; + case SCSI_RD_CAPAC: { + struct scsi_read_capacity_resp *resp = (void *)info->buff; + uint blocks; + + if (info->file_size) + blocks = info->file_size / info->block_size - 1; + else + blocks = 0; + resp->last_block_addr = cpu_to_be32(blocks); + resp->block_len = cpu_to_be32(info->block_size); + info->buff_used = sizeof(*resp); + break; + } + case SCSI_READ10: { + const struct scsi_read10_req *read_req = (void *)req; + + info->seek_block = be32_to_cpu(read_req->lba); + info->read_len = be16_to_cpu(read_req->xfer_len); + info->buff_used = info->read_len * info->block_size; + ret = SCSI_EMUL_DO_READ; + break; + } + default: + debug("Command not supported: %x\n", req->cmd[0]); + ret = -EPROTONOSUPPORT; + } + if (ret >= 0) + info->phase = info->transfer_len ? SCSIPH_DATA : SCSIPH_STATUS; + log_debug(" - done %x: ret=%d\n", *req->cmd, ret); + + return ret; +} diff --git a/drivers/usb/emul/sandbox_flash.c b/drivers/usb/emul/sandbox_flash.c index 2059fc7fe4..2589c708d8 100644 --- a/drivers/usb/emul/sandbox_flash.c +++ b/drivers/usb/emul/sandbox_flash.c @@ -180,97 +180,30 @@ static void setup_response(struct sandbox_flash_priv *priv) csw->bCSWStatus = CSWSTATUS_GOOD; } -/** - * handle_read() - prepare for reading data from the backing file - * - * This seeks to the correct file position and sets info->buff_used to the - * correct size. - * - * @priv: Private information - * @lba: Start block to read from - * @transfer_length: Number of blocks to read - * @return 0 if OK, -EIO on failure - */ -static int handle_read(struct sandbox_flash_priv *priv, ulong lba, - ulong transfer_len) -{ - struct scsi_emul_info *info = &priv->eminfo; - - debug("%s: lba=%lx, transfer_len=%lx\n", __func__, lba, transfer_len); - info->read_len = transfer_len; - if (priv->fd != -1) { - os_lseek(priv->fd, lba * info->block_size, OS_SEEK_SET); - info->buff_used = transfer_len * info->block_size; - return 0; - } - - return -EIO; -} - -static int handle_ufi_command(struct sandbox_flash_plat *plat, - struct sandbox_flash_priv *priv, const void *buff, +static int handle_ufi_command(struct sandbox_flash_priv *priv, const void *buff, int len) { struct scsi_emul_info *info = &priv->eminfo; const struct scsi_cmd *req = buff; + int ret; - info->buff_used = 0; - switch (*req->cmd) { - case SCSI_INQUIRY: { - struct scsi_inquiry_resp *resp = (void *)info->buff; - - info->alloc_len = req->cmd[4]; - memset(resp, '\0', sizeof(*resp)); - resp->data_format = 1; - resp->additional_len = 0x1f; - strncpy(resp->vendor, info->vendor, sizeof(resp->vendor)); - strncpy(resp->product, info->product, sizeof(resp->product)); - strncpy(resp->revision, "1.0", sizeof(resp->revision)); - info->buff_used = sizeof(*resp); + ret = sb_scsi_emul_command(info, req, len); + if (!ret) { setup_response(priv); - break; - } - case SCSI_TST_U_RDY: + } else if (ret == SCSI_EMUL_DO_READ && priv->fd != -1) { + os_lseek(priv->fd, info->seek_block * info->block_size, + OS_SEEK_SET); setup_response(priv); - break; - case SCSI_RD_CAPAC: { - struct scsi_read_capacity_resp *resp = (void *)info->buff; - uint blocks; - - if (info->file_size) - blocks = info->file_size / info->block_size - 1; - else - blocks = 0; - resp->last_block_addr = cpu_to_be32(blocks); - resp->block_len = cpu_to_be32(info->block_size); - info->buff_used = sizeof(*resp); - setup_response(priv); - break; - } - case SCSI_READ10: { - struct scsi_read10_req *req = (void *)buff; - - if (!handle_read(priv, be32_to_cpu(req->lba), - be16_to_cpu(req->xfer_len))) - setup_response(priv); - else - setup_fail_response(priv); - - break; - } - default: - debug("Command not supported: %x\n", req->cmd[0]); - return -EPROTONOSUPPORT; + } else { + setup_fail_response(priv); } - info->phase = info->transfer_len ? SCSIPH_DATA : SCSIPH_STATUS; return 0; } static int sandbox_flash_bulk(struct udevice *dev, struct usb_device *udev, unsigned long pipe, void *buff, int len) { - struct sandbox_flash_plat *plat = dev_get_plat(dev); struct sandbox_flash_priv *priv = dev_get_priv(dev); struct scsi_emul_info *info = &priv->eminfo; int ep = usb_pipeendpoint(pipe); @@ -294,7 +227,7 @@ static int sandbox_flash_bulk(struct udevice *dev, struct usb_device *udev, goto err; info->transfer_len = cbw->dCBWDataTransferLength; priv->tag = cbw->dCBWTag; - return handle_ufi_command(plat, priv, cbw->CBWCDB, + return handle_ufi_command(priv, cbw->CBWCDB, cbw->bCDBLength); case SCSIPH_DATA: debug("data out\n"); diff --git a/include/scsi_emul.h b/include/scsi_emul.h index 3c52398e3f..13c3f860b4 100644 --- a/include/scsi_emul.h +++ b/include/scsi_emul.h @@ -19,6 +19,7 @@ * @product: Product name * @block_size: Block size of device in bytes (normally 512) * @file_size: Size of the backing file for this emulator, in bytes + * @seek_block: Seek position for file (block number) * * @phase: Current SCSI phase * @buff_used: Number of bytes ready to transfer back to host @@ -34,13 +35,36 @@ struct scsi_emul_info { const char *product; int block_size; loff_t file_size; + int seek_block; /* state maintained by the emulator: */ enum scsi_cmd_phase phase; int buff_used; int read_len; + uint seek_pos; int alloc_len; uint transfer_len; }; +/* Indicates that a read is being started */ +#define SCSI_EMUL_DO_READ 1 + +/** + * sb_scsi_emul_command() - Process a SCSI command + * + * This sets up the response in info->buff and updates various other values + * in info. + * + * If SCSI_EMUL_DO_READ is returned then the caller should set up so that the + * backing file can be read, or return an error status if there is no file. + * + * @info: Emulation information + * @req: Request to process + * @len: Length of request in bytes + * @return SCSI_EMUL_DO_READ if a read has started, 0 if some other operation + * has started, -ve if there was an error + */ +int sb_scsi_emul_command(struct scsi_emul_info *info, + const struct scsi_cmd *req, int len); + #endif From 46df0243942f98ad5a6b57cb65b31acdc88559f8 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 21 Sep 2022 16:21:46 +0200 Subject: [PATCH 307/374] sandbox: Convert to use driver model for SCSI At present sandbox is producing a warning about SCSI migration. Drop the legacy code and replace it with a new implementation. Also drop the SATA command, which does not work with driver model. Signed-off-by: Simon Glass --- arch/Kconfig | 1 - configs/sandbox64_defconfig | 5 +- configs/sandbox_defconfig | 5 +- configs/sandbox_flattree_defconfig | 5 +- configs/sandbox_noinst_defconfig | 5 +- configs/sandbox_spl_defconfig | 5 +- configs/sandbox_vpl_defconfig | 5 +- configs/tools-only_defconfig | 1 - drivers/scsi/sandbox_scsi.c | 136 +++++++++++++++++++++++++++-- 9 files changed, 137 insertions(+), 31 deletions(-) diff --git a/arch/Kconfig b/arch/Kconfig index 994fd3b7f8..1ffd77c0f4 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -166,7 +166,6 @@ config SANDBOX imply CMD_IO imply CMD_IOTRACE imply CMD_LZMADEC - imply CMD_SATA imply CMD_SF imply CMD_SF_TEST imply CRC32_VERIFY diff --git a/configs/sandbox64_defconfig b/configs/sandbox64_defconfig index 9dab89a999..b20b181ab1 100644 --- a/configs/sandbox64_defconfig +++ b/configs/sandbox64_defconfig @@ -52,7 +52,6 @@ CONFIG_CMD_OSD=y CONFIG_CMD_PCI=y CONFIG_CMD_READ=y CONFIG_CMD_REMOTEPROC=y -# CONFIG_CMD_SATA is not set CONFIG_CMD_SPI=y CONFIG_CMD_USB=y CONFIG_BOOTP_DNS2=y @@ -204,9 +203,7 @@ CONFIG_SANDBOX_RESET=y CONFIG_DM_RTC=y CONFIG_RTC_RV8803=y CONFIG_SCSI=y -CONFIG_SCSI_AHCI_PLAT=y -CONFIG_SYS_SCSI_MAX_SCSI_ID=8 -CONFIG_SYS_SCSI_MAX_LUN=4 +CONFIG_DM_SCSI=y CONFIG_SANDBOX_SERIAL=y CONFIG_SMEM=y CONFIG_SANDBOX_SMEM=y diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig index caecb50ad9..df6a28ef24 100644 --- a/configs/sandbox_defconfig +++ b/configs/sandbox_defconfig @@ -137,7 +137,6 @@ CONFIG_DEBUG_DEVRES=y CONFIG_SIMPLE_PM_BUS=y CONFIG_ADC=y CONFIG_ADC_SANDBOX=y -CONFIG_SYS_SATA_MAX_DEVICE=2 CONFIG_AXI=y CONFIG_AXI_SANDBOX=y CONFIG_SYS_IDE_MAXBUS=1 @@ -264,9 +263,7 @@ CONFIG_RESET_SCMI=y CONFIG_DM_RTC=y CONFIG_RTC_RV8803=y CONFIG_SCSI=y -CONFIG_SCSI_AHCI_PLAT=y -CONFIG_SYS_SCSI_MAX_SCSI_ID=8 -CONFIG_SYS_SCSI_MAX_LUN=4 +CONFIG_DM_SCSI=y CONFIG_SANDBOX_SERIAL=y CONFIG_SMEM=y CONFIG_SANDBOX_SMEM=y diff --git a/configs/sandbox_flattree_defconfig b/configs/sandbox_flattree_defconfig index a8344029f4..a2eb7afcf9 100644 --- a/configs/sandbox_flattree_defconfig +++ b/configs/sandbox_flattree_defconfig @@ -85,7 +85,6 @@ CONFIG_DEVRES=y CONFIG_DEBUG_DEVRES=y CONFIG_ADC=y CONFIG_ADC_SANDBOX=y -CONFIG_SYS_SATA_MAX_DEVICE=2 CONFIG_AXI=y CONFIG_AXI_SANDBOX=y CONFIG_CLK=y @@ -175,9 +174,7 @@ CONFIG_DM_RESET=y CONFIG_SANDBOX_RESET=y CONFIG_DM_RTC=y CONFIG_SCSI=y -CONFIG_SCSI_AHCI_PLAT=y -CONFIG_SYS_SCSI_MAX_SCSI_ID=8 -CONFIG_SYS_SCSI_MAX_LUN=4 +CONFIG_DM_SCSI=y CONFIG_SANDBOX_SERIAL=y CONFIG_SOUND=y CONFIG_SOUND_SANDBOX=y diff --git a/configs/sandbox_noinst_defconfig b/configs/sandbox_noinst_defconfig index da83165a4d..8bf10bb3ee 100644 --- a/configs/sandbox_noinst_defconfig +++ b/configs/sandbox_noinst_defconfig @@ -108,7 +108,6 @@ CONFIG_DEBUG_DEVRES=y # CONFIG_SPL_SIMPLE_BUS is not set CONFIG_ADC=y CONFIG_ADC_SANDBOX=y -CONFIG_SYS_SATA_MAX_DEVICE=2 CONFIG_AXI=y CONFIG_AXI_SANDBOX=y CONFIG_SYS_IDE_MAXBUS=1 @@ -201,9 +200,7 @@ CONFIG_SANDBOX_RESET=y CONFIG_DM_RTC=y CONFIG_SPL_DM_RTC=y CONFIG_SCSI=y -CONFIG_SCSI_AHCI_PLAT=y -CONFIG_SYS_SCSI_MAX_SCSI_ID=8 -CONFIG_SYS_SCSI_MAX_LUN=4 +CONFIG_DM_SCSI=y CONFIG_SANDBOX_SERIAL=y CONFIG_SOUND=y CONFIG_SOUND_SANDBOX=y diff --git a/configs/sandbox_spl_defconfig b/configs/sandbox_spl_defconfig index 0d7c5972d8..c33f17186d 100644 --- a/configs/sandbox_spl_defconfig +++ b/configs/sandbox_spl_defconfig @@ -61,7 +61,6 @@ CONFIG_CMD_I2C=y CONFIG_CMD_OSD=y CONFIG_CMD_PCI=y CONFIG_CMD_REMOTEPROC=y -# CONFIG_CMD_SATA is not set CONFIG_CMD_SPI=y CONFIG_CMD_USB=y CONFIG_BOOTP_DNS2=y @@ -204,9 +203,7 @@ CONFIG_SANDBOX_RESET=y CONFIG_DM_RTC=y CONFIG_SPL_DM_RTC=y CONFIG_SCSI=y -CONFIG_SCSI_AHCI_PLAT=y -CONFIG_SYS_SCSI_MAX_SCSI_ID=8 -CONFIG_SYS_SCSI_MAX_LUN=4 +CONFIG_DM_SCSI=y CONFIG_SANDBOX_SERIAL=y CONFIG_SOUND=y CONFIG_SOUND_SANDBOX=y diff --git a/configs/sandbox_vpl_defconfig b/configs/sandbox_vpl_defconfig index 7bddac6198..be8186ead3 100644 --- a/configs/sandbox_vpl_defconfig +++ b/configs/sandbox_vpl_defconfig @@ -124,7 +124,6 @@ CONFIG_DEBUG_DEVRES=y # CONFIG_SPL_SIMPLE_BUS is not set CONFIG_ADC=y CONFIG_ADC_SANDBOX=y -CONFIG_SYS_SATA_MAX_DEVICE=2 CONFIG_AXI=y CONFIG_AXI_SANDBOX=y CONFIG_CLK=y @@ -210,9 +209,7 @@ CONFIG_DM_RTC=y CONFIG_SPL_DM_RTC=y CONFIG_TPL_DM_RTC=y CONFIG_SCSI=y -CONFIG_SCSI_AHCI_PLAT=y -CONFIG_SYS_SCSI_MAX_SCSI_ID=8 -CONFIG_SYS_SCSI_MAX_LUN=4 +CONFIG_DM_SCSI=y CONFIG_SANDBOX_SERIAL=y CONFIG_SOUND=y CONFIG_SOUND_SANDBOX=y diff --git a/configs/tools-only_defconfig b/configs/tools-only_defconfig index 211acc7774..2c418f5dbb 100644 --- a/configs/tools-only_defconfig +++ b/configs/tools-only_defconfig @@ -18,7 +18,6 @@ CONFIG_OF_CONTROL=y CONFIG_SYS_RELOC_GD_ENV_ADDR=y # CONFIG_NET is not set # CONFIG_ACPIGEN is not set -CONFIG_SYS_SATA_MAX_DEVICE=2 CONFIG_AXI=y CONFIG_AXI_SANDBOX=y CONFIG_SANDBOX_GPIO=y diff --git a/drivers/scsi/sandbox_scsi.c b/drivers/scsi/sandbox_scsi.c index 39b969a4b2..a7ac33cb1c 100644 --- a/drivers/scsi/sandbox_scsi.c +++ b/drivers/scsi/sandbox_scsi.c @@ -7,19 +7,145 @@ * that CONFIG_SCSI can be enabled for sandbox. */ +#define LOG_CATEGORY UCLASS_SCSI + #include +#include +#include +#include #include +#include -int scsi_bus_reset(struct udevice *dev) +enum { + SANDBOX_SCSI_BLOCK_LEN = 512, + SANDBOX_SCSI_BUF_SIZE = 512, +}; + +/** + * struct sandbox_scsi_priv + * + * @eminfo: emulator state + * @pathanme: Path to the backing file, e.g. 'scsi.img' + * @fd: File descriptor of backing file + */ +struct sandbox_scsi_priv { + struct scsi_emul_info eminfo; + const char *pathname; + int fd; +}; + +static int sandbox_scsi_exec(struct udevice *dev, struct scsi_cmd *req) { + struct sandbox_scsi_priv *priv = dev_get_priv(dev); + struct scsi_emul_info *info = &priv->eminfo; + int ret; + + if (req->lun || req->target) + return -EIO; + ret = sb_scsi_emul_command(info, req, req->cmdlen); + if (ret < 0) { + log_debug("SCSI command 0x%02x ret errno %d\n", req->cmd[0], + ret); + return ret; + } else if (ret == SCSI_EMUL_DO_READ && priv->fd != -1) { + long bytes_read; + + log_debug("read %x %x\n", info->seek_block, info->read_len); + os_lseek(priv->fd, info->seek_block * info->block_size, + OS_SEEK_SET); + bytes_read = os_read(priv->fd, req->pdata, info->buff_used); + if (bytes_read < 0) + return bytes_read; + if (bytes_read != info->buff_used) + return -EIO; + } else if (!ret) { + req->pdata = info->buff; + info->phase = SCSIPH_STATUS; + log_debug("sending buf\n"); + } else { + log_debug("error\n"); + return -EIO; + } + return 0; } -void scsi_init(void) +static int sandbox_scsi_bus_reset(struct udevice *dev) { -} + /* Not implemented */ -int scsi_exec(struct udevice *dev, struct scsi_cmd *pccb) -{ return 0; } + +static int sandbox_scsi_of_to_plat(struct udevice *dev) +{ + struct sandbox_scsi_priv *priv = dev_get_priv(dev); + + priv->pathname = dev_read_string(dev, "sandbox,filepath"); + + return 0; +} + +static int sandbox_scsi_probe(struct udevice *dev) +{ + struct scsi_plat *scsi_plat = dev_get_uclass_plat(dev); + struct sandbox_scsi_priv *priv = dev_get_priv(dev); + struct scsi_emul_info *info = &priv->eminfo; + int ret; + + scsi_plat->max_id = 2; + scsi_plat->max_lun = 3; + scsi_plat->max_bytes_per_req = 1 << 20; + + info->vendor = "SANDBOX"; + info->product = "FAKE DISK"; + info->buff = malloc(SANDBOX_SCSI_BUF_SIZE); + if (!info->buff) + return log_ret(-ENOMEM); + info->block_size = SANDBOX_SCSI_BLOCK_LEN; + + if (priv->pathname) { + priv->fd = os_open(priv->pathname, OS_O_RDONLY); + if (priv->fd != -1) { + ret = os_get_filesize(priv->pathname, &info->file_size); + if (ret) + return log_msg_ret("sz", ret); + } + } else { + priv->fd = -1; + } + log_debug("filename: %s, fd %d\n", priv->pathname, priv->fd); + + return 0; +} + +static int sandbox_scsi_remove(struct udevice *dev) +{ + struct sandbox_scsi_priv *priv = dev_get_priv(dev); + struct scsi_emul_info *info = &priv->eminfo; + + free(info->buff); + + return 0; +} + +struct scsi_ops sandbox_scsi_ops = { + .exec = sandbox_scsi_exec, + .bus_reset = sandbox_scsi_bus_reset, +}; + +static const struct udevice_id sanbox_scsi_ids[] = { + { .compatible = "sandbox,scsi" }, + { } +}; + +U_BOOT_DRIVER(sandbox_scsi) = { + .name = "sandbox_scsi", + .id = UCLASS_SCSI, + .ops = &sandbox_scsi_ops, + .of_match = sanbox_scsi_ids, + .of_to_plat = sandbox_scsi_of_to_plat, + .probe = sandbox_scsi_probe, + .remove = sandbox_scsi_remove, + .priv_auto = sizeof(struct sandbox_scsi_priv), +}; From 22c80d5603ac4c58debc8c776b8f138e76cf5f7c Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 21 Sep 2022 16:21:47 +0200 Subject: [PATCH 308/374] sandbox: Add a test for SCSI Add a simple uclass test for SCSI. It reads the partition table from a disk image and checks that it looks correct. Signed-off-by: Simon Glass --- arch/sandbox/dts/sandbox.dtsi | 4 ++++ arch/sandbox/dts/test.dts | 5 +++++ test/dm/Makefile | 1 + test/dm/scsi.c | 39 +++++++++++++++++++++++++++++++++++ test/py/tests/test_ut.py | 9 ++++++++ 5 files changed, 58 insertions(+) create mode 100644 test/dm/scsi.c diff --git a/arch/sandbox/dts/sandbox.dtsi b/arch/sandbox/dts/sandbox.dtsi index 56e6b38bfa..de7a218f45 100644 --- a/arch/sandbox/dts/sandbox.dtsi +++ b/arch/sandbox/dts/sandbox.dtsi @@ -245,6 +245,10 @@ compatible = "sandbox,sandbox-rng"; }; + scsi { + compatible = "sandbox,scsi"; + }; + sound { compatible = "sandbox,sound"; cpu { diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts index c7fffa2da2..4ee471238e 100644 --- a/arch/sandbox/dts/test.dts +++ b/arch/sandbox/dts/test.dts @@ -1158,6 +1158,11 @@ backlight = <&backlight 0 100>; }; + scsi { + compatible = "sandbox,scsi"; + sandbox,filepath = "scsi.img"; + }; + smem@0 { compatible = "sandbox,smem"; }; diff --git a/test/dm/Makefile b/test/dm/Makefile index 7543df8823..5178daa7cf 100644 --- a/test/dm/Makefile +++ b/test/dm/Makefile @@ -91,6 +91,7 @@ obj-$(CONFIG_DM_REGULATOR) += regulator.o obj-$(CONFIG_DM_RNG) += rng.o obj-$(CONFIG_DM_RTC) += rtc.o obj-$(CONFIG_SCMI_FIRMWARE) += scmi.o +obj-$(CONFIG_SCSI) += scsi.o obj-$(CONFIG_DM_SERIAL) += serial.o obj-$(CONFIG_DM_SPI_FLASH) += sf.o obj-$(CONFIG_SIMPLE_BUS) += simple-bus.o diff --git a/test/dm/scsi.c b/test/dm/scsi.c new file mode 100644 index 0000000000..380cfc88ba --- /dev/null +++ b/test/dm/scsi.c @@ -0,0 +1,39 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2015 Google, Inc + */ + +#include +#include +#include +#include +#include +#include +#include + +/* Test that sandbox SCSI works correctly */ +static int dm_test_scsi_base(struct unit_test_state *uts) +{ + const struct disk_partition *info; + const struct disk_part *part; + struct udevice *dev; + + ut_assertok(scsi_scan(false)); + + /* + * We expect some sort of partition on the disk image, created by + * test_ut_dm_init() + */ + ut_assertok(uclass_first_device_err(UCLASS_PARTITION, &dev)); + + part = dev_get_uclass_plat(dev); + ut_asserteq(1, part->partnum); + + info = &part->gpt_part_info; + ut_asserteq_str("sda1", info->name); + ut_asserteq_str("U-Boot", info->type); + ut_asserteq(0x83 /* linux */, info->sys_ind); + + return 0; +} +DM_TEST(dm_test_scsi_base, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); diff --git a/test/py/tests/test_ut.py b/test/py/tests/test_ut.py index 35fb393c1f..9d42390373 100644 --- a/test/py/tests/test_ut.py +++ b/test/py/tests/test_ut.py @@ -114,6 +114,15 @@ def test_ut_dm_init(u_boot_console): with open(fn, 'wb') as fh: fh.write(data) + # Create a file with a single partition + fn = u_boot_console.config.source_dir + '/scsi.img' + if not os.path.exists(fn): + data = b'\x00' * (2 * 1024 * 1024) + with open(fn, 'wb') as fh: + fh.write(data) + u_boot_utils.run_and_log( + u_boot_console, f'sfdisk {fn}', stdin=b'type=83') + @pytest.mark.buildconfigspec('cmd_bootflow') def test_ut_dm_init_bootstd(u_boot_console): """Initialise data for bootflow tests""" From c2bdf02c9d40da7154fea46b7d10343fe9f14209 Mon Sep 17 00:00:00 2001 From: Nikita Shubin Date: Fri, 2 Sep 2022 11:47:39 +0300 Subject: [PATCH 309/374] spl: introduce SPL_XIP to config U-Boot and SPL don't necessary share the same location, so we might end with U-Boot SPL in read-only memory (XIP) and U-Boot in read-write memory. In case of non XIP boot mode, we rely on such variables as "hart_lottery" and "available_harts_lock" which we use as atomics. The problem is that CONFIG_XIP also propagate to main U-Boot, not only SPL, so we need CONFIG_SPL_XIP to distinguish SPL XIP from other XIP modes. This adds an option special for SPL to behave it in XIP manner and we don't use hart_lottery and available_harts_lock, during start proccess. Signed-off-by: Nikita Shubin Reviewed-by: Rick Chen --- arch/riscv/Kconfig | 7 +++++++ arch/riscv/cpu/cpu.c | 2 +- arch/riscv/cpu/start.S | 4 ++-- arch/riscv/include/asm/global_data.h | 2 +- arch/riscv/lib/asm-offsets.c | 2 +- arch/riscv/lib/smp.c | 2 +- configs/ae350_rv32_spl_xip_defconfig | 2 +- configs/ae350_rv64_spl_xip_defconfig | 2 +- 8 files changed, 15 insertions(+), 8 deletions(-) diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index 78e964db12..c042506a64 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -269,6 +269,13 @@ config XIP from a NOR flash memory without copying the code to ram. Say yes here if U-Boot boots from flash directly. +config SPL_XIP + bool "Enable XIP mode for SPL" + help + If SPL starts in read-only memory (XIP for example) then we shouldn't + rely on lock variables (for example hart_lottery and available_harts_lock), + this affects only SPL, other stages should proceed as non-XIP. + config SHOW_REGS bool "Show registers on unhandled exception" diff --git a/arch/riscv/cpu/cpu.c b/arch/riscv/cpu/cpu.c index 3ffcbbd23f..0f323b26b3 100644 --- a/arch/riscv/cpu/cpu.c +++ b/arch/riscv/cpu/cpu.c @@ -19,7 +19,7 @@ * The variables here must be stored in the data section since they are used * before the bss section is available. */ -#ifndef CONFIG_XIP +#if !CONFIG_IS_ENABLED(XIP) u32 hart_lottery __section(".data") = 0; /* diff --git a/arch/riscv/cpu/start.S b/arch/riscv/cpu/start.S index b7f21ab63e..de9d078da1 100644 --- a/arch/riscv/cpu/start.S +++ b/arch/riscv/cpu/start.S @@ -122,7 +122,7 @@ call_board_init_f_0: call_harts_early_init: jal harts_early_init -#ifndef CONFIG_XIP +#if !CONFIG_IS_ENABLED(XIP) /* * Pick hart to initialize global data and run U-Boot. The other harts * wait for initialization to complete. @@ -152,7 +152,7 @@ call_harts_early_init: /* save the boot hart id to global_data */ SREG tp, GD_BOOT_HART(gp) -#ifndef CONFIG_XIP +#if !CONFIG_IS_ENABLED(XIP) la t0, available_harts_lock amoswap.w.rl zero, zero, 0(t0) diff --git a/arch/riscv/include/asm/global_data.h b/arch/riscv/include/asm/global_data.h index 095484a635..b3c79e1760 100644 --- a/arch/riscv/include/asm/global_data.h +++ b/arch/riscv/include/asm/global_data.h @@ -27,7 +27,7 @@ struct arch_global_data { #if CONFIG_IS_ENABLED(SMP) struct ipi_data ipi[CONFIG_NR_CPUS]; #endif -#ifndef CONFIG_XIP +#if !CONFIG_IS_ENABLED(XIP) ulong available_harts; #endif }; diff --git a/arch/riscv/lib/asm-offsets.c b/arch/riscv/lib/asm-offsets.c index f1fe089b3d..c4f48c8373 100644 --- a/arch/riscv/lib/asm-offsets.c +++ b/arch/riscv/lib/asm-offsets.c @@ -16,7 +16,7 @@ int main(void) { DEFINE(GD_BOOT_HART, offsetof(gd_t, arch.boot_hart)); DEFINE(GD_FIRMWARE_FDT_ADDR, offsetof(gd_t, arch.firmware_fdt_addr)); -#ifndef CONFIG_XIP +#if !CONFIG_IS_ENABLED(XIP) DEFINE(GD_AVAILABLE_HARTS, offsetof(gd_t, arch.available_harts)); #endif diff --git a/arch/riscv/lib/smp.c b/arch/riscv/lib/smp.c index ba992100ad..f8b756291f 100644 --- a/arch/riscv/lib/smp.c +++ b/arch/riscv/lib/smp.c @@ -45,7 +45,7 @@ static int send_ipi_many(struct ipi_data *ipi, int wait) continue; } -#ifndef CONFIG_XIP +#if !CONFIG_IS_ENABLED(XIP) /* skip if hart is not available */ if (!(gd->arch.available_harts & (1 << reg))) continue; diff --git a/configs/ae350_rv32_spl_xip_defconfig b/configs/ae350_rv32_spl_xip_defconfig index c7b6ea4730..67c1e35c55 100644 --- a/configs/ae350_rv32_spl_xip_defconfig +++ b/configs/ae350_rv32_spl_xip_defconfig @@ -11,7 +11,7 @@ CONFIG_SPL=y CONFIG_SYS_LOAD_ADDR=0x100000 CONFIG_TARGET_AX25_AE350=y CONFIG_RISCV_SMODE=y -CONFIG_XIP=y +CONFIG_SPL_XIP=y CONFIG_DISTRO_DEFAULTS=y CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0xffff00 diff --git a/configs/ae350_rv64_spl_xip_defconfig b/configs/ae350_rv64_spl_xip_defconfig index a197c97736..baee9bfe4a 100644 --- a/configs/ae350_rv64_spl_xip_defconfig +++ b/configs/ae350_rv64_spl_xip_defconfig @@ -12,7 +12,7 @@ CONFIG_SYS_LOAD_ADDR=0x100000 CONFIG_TARGET_AX25_AE350=y CONFIG_ARCH_RV64I=y CONFIG_RISCV_SMODE=y -CONFIG_XIP=y +CONFIG_SPL_XIP=y CONFIG_DISTRO_DEFAULTS=y CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0xfffe70 From e0465f80bd33f239612ee9f0ee7b6cf13d2f5b4d Mon Sep 17 00:00:00 2001 From: Rick Chen Date: Wed, 21 Sep 2022 14:34:54 +0800 Subject: [PATCH 310/374] riscv: Introduce AVAILABLE_HARTS In SMP all harts will register themself in available_hart during start up. Then main hart will send IPI to other harts according to this variables. But this mechanism may not guarantee that all other harts can jump to next stage. When main hart is sending IPI to other hart according to available_harts, but other harts maybe still not finish the registration. Then the SMP booting will miss some harts finally. So let it become an option and it will be enabled by default. Please refer to the discussion: https://www.mail-archive.com/u-boot@lists.denx.de/msg449997.html Signed-off-by: Rick Chen Reviewed-by: Leo Yu-Chi Liang --- arch/riscv/Kconfig | 7 +++++++ arch/riscv/cpu/cpu.c | 2 ++ arch/riscv/cpu/start.S | 13 ++++++++----- arch/riscv/include/asm/global_data.h | 2 ++ arch/riscv/lib/asm-offsets.c | 2 ++ arch/riscv/lib/smp.c | 2 ++ 6 files changed, 23 insertions(+), 5 deletions(-) diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index c042506a64..32a90b83b5 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -276,6 +276,13 @@ config SPL_XIP rely on lock variables (for example hart_lottery and available_harts_lock), this affects only SPL, other stages should proceed as non-XIP. +config AVAILABLE_HARTS + bool "Send IPI by available harts" + default y + help + By default, IPI sending mechanism will depend on available_harts. + If disable this, it will send IPI by CPUs node numbers of device tree. + config SHOW_REGS bool "Show registers on unhandled exception" diff --git a/arch/riscv/cpu/cpu.c b/arch/riscv/cpu/cpu.c index 0f323b26b3..52ab02519f 100644 --- a/arch/riscv/cpu/cpu.c +++ b/arch/riscv/cpu/cpu.c @@ -22,12 +22,14 @@ #if !CONFIG_IS_ENABLED(XIP) u32 hart_lottery __section(".data") = 0; +#ifdef CONFIG_AVAILABLE_HARTS /* * The main hart running U-Boot has acquired available_harts_lock until it has * finished initialization of global data. */ u32 available_harts_lock = 1; #endif +#endif static inline bool supports_extension(char ext) { diff --git a/arch/riscv/cpu/start.S b/arch/riscv/cpu/start.S index de9d078da1..4687bca3c9 100644 --- a/arch/riscv/cpu/start.S +++ b/arch/riscv/cpu/start.S @@ -153,21 +153,23 @@ call_harts_early_init: SREG tp, GD_BOOT_HART(gp) #if !CONFIG_IS_ENABLED(XIP) +#ifdef CONFIG_AVAILABLE_HARTS la t0, available_harts_lock amoswap.w.rl zero, zero, 0(t0) +#endif wait_for_gd_init: - la t0, available_harts_lock - li t1, 1 -1: amoswap.w.aq t1, t1, 0(t0) - bnez t1, 1b - /* * Set the global data pointer only when gd_t has been initialized. * This was already set by arch_setup_gd on the boot hart, but all other * harts' global data pointers gets set here. */ mv gp, s0 +#ifdef CONFIG_AVAILABLE_HARTS + la t0, available_harts_lock + li t1, 1 +1: amoswap.w.aq t1, t1, 0(t0) + bnez t1, 1b /* register available harts in the available_harts mask */ li t1, 1 @@ -177,6 +179,7 @@ wait_for_gd_init: SREG t2, GD_AVAILABLE_HARTS(gp) amoswap.w.rl zero, zero, 0(t0) +#endif /* * Continue on hart lottery winner, others branch to diff --git a/arch/riscv/include/asm/global_data.h b/arch/riscv/include/asm/global_data.h index b3c79e1760..858594a191 100644 --- a/arch/riscv/include/asm/global_data.h +++ b/arch/riscv/include/asm/global_data.h @@ -28,8 +28,10 @@ struct arch_global_data { struct ipi_data ipi[CONFIG_NR_CPUS]; #endif #if !CONFIG_IS_ENABLED(XIP) +#ifdef CONFIG_AVAILABLE_HARTS ulong available_harts; #endif +#endif }; #include diff --git a/arch/riscv/lib/asm-offsets.c b/arch/riscv/lib/asm-offsets.c index c4f48c8373..452dfcea97 100644 --- a/arch/riscv/lib/asm-offsets.c +++ b/arch/riscv/lib/asm-offsets.c @@ -17,7 +17,9 @@ int main(void) DEFINE(GD_BOOT_HART, offsetof(gd_t, arch.boot_hart)); DEFINE(GD_FIRMWARE_FDT_ADDR, offsetof(gd_t, arch.firmware_fdt_addr)); #if !CONFIG_IS_ENABLED(XIP) +#ifdef CONFIG_AVAILABLE_HARTS DEFINE(GD_AVAILABLE_HARTS, offsetof(gd_t, arch.available_harts)); +#endif #endif return 0; diff --git a/arch/riscv/lib/smp.c b/arch/riscv/lib/smp.c index f8b756291f..c0f65af191 100644 --- a/arch/riscv/lib/smp.c +++ b/arch/riscv/lib/smp.c @@ -46,9 +46,11 @@ static int send_ipi_many(struct ipi_data *ipi, int wait) } #if !CONFIG_IS_ENABLED(XIP) +#ifdef CONFIG_AVAILABLE_HARTS /* skip if hart is not available */ if (!(gd->arch.available_harts & (1 << reg))) continue; +#endif #endif gd->arch.ipi[reg].addr = ipi->addr; From 3c1ec13317292933fd01d9c60aae3ff1d5bc171e Mon Sep 17 00:00:00 2001 From: Rick Chen Date: Wed, 21 Sep 2022 14:34:55 +0800 Subject: [PATCH 311/374] riscv: ae350: Disable AVAILABLE_HARTS Disable AVAILABLE_HARTS mechanism to make sure that all harts can boot to Kernel shell successfully. Signed-off-by: Rick Chen Reviewed-by: Leo Yu-Chi Liang --- configs/ae350_rv32_spl_defconfig | 1 + configs/ae350_rv64_spl_defconfig | 1 + 2 files changed, 2 insertions(+) diff --git a/configs/ae350_rv32_spl_defconfig b/configs/ae350_rv32_spl_defconfig index 9b79cc41b5..1cc98a2653 100644 --- a/configs/ae350_rv32_spl_defconfig +++ b/configs/ae350_rv32_spl_defconfig @@ -48,3 +48,4 @@ CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_ATCSPI200_SPI=y # CONFIG_BINMAN_FDT is not set +# CONFIG_AVAILABLE_HARTS is not set diff --git a/configs/ae350_rv64_spl_defconfig b/configs/ae350_rv64_spl_defconfig index 4c33ca2383..4318300300 100644 --- a/configs/ae350_rv64_spl_defconfig +++ b/configs/ae350_rv64_spl_defconfig @@ -49,3 +49,4 @@ CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_ATCSPI200_SPI=y # CONFIG_BINMAN_FDT is not set +# CONFIG_AVAILABLE_HARTS is not set From f6aebdf676ed003391d158edde4ec74b41a83cb8 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Mon, 19 Sep 2022 14:21:02 +0200 Subject: [PATCH 312/374] arm64: versal-net: Add support for Versal NET platform Versal NET platform is based on Versal chip which is reusing a lot of IPs. For more information about new IPs please take a look at DT which describe currently supported devices. The patch is adding architecture and board support with soc detection algorithm. Generic setting should be very similar to Versal but it will likely diverge in longer run. Signed-off-by: Michal Simek Link: https://lore.kernel.org/r/320206853dc370ce290a4e7b6d0bb26b05206021.1663589964.git.michal.simek@amd.com --- Kconfig | 2 +- MAINTAINERS | 7 + arch/arm/Kconfig | 14 ++ arch/arm/Makefile | 1 + arch/arm/dts/Makefile | 2 + arch/arm/dts/xilinx-versal-net-virt.dts | 11 ++ arch/arm/mach-versal-net/Kconfig | 43 +++++ arch/arm/mach-versal-net/Makefile | 10 ++ arch/arm/mach-versal-net/clk.c | 35 ++++ arch/arm/mach-versal-net/cpu.c | 89 +++++++++ .../mach-versal-net/include/mach/hardware.h | 27 +++ .../mach-versal-net/include/mach/sys_proto.h | 16 ++ board/xilinx/Kconfig | 6 +- board/xilinx/versal-net/Kconfig | 9 + board/xilinx/versal-net/MAINTAINERS | 8 + board/xilinx/versal-net/Makefile | 9 + board/xilinx/versal-net/board.c | 170 ++++++++++++++++++ env/Kconfig | 6 +- include/configs/xilinx_versal_net.h | 156 ++++++++++++++++ 19 files changed, 614 insertions(+), 7 deletions(-) create mode 100644 arch/arm/dts/xilinx-versal-net-virt.dts create mode 100644 arch/arm/mach-versal-net/Kconfig create mode 100644 arch/arm/mach-versal-net/Makefile create mode 100644 arch/arm/mach-versal-net/clk.c create mode 100644 arch/arm/mach-versal-net/cpu.c create mode 100644 arch/arm/mach-versal-net/include/mach/hardware.h create mode 100644 arch/arm/mach-versal-net/include/mach/sys_proto.h create mode 100644 board/xilinx/versal-net/Kconfig create mode 100644 board/xilinx/versal-net/MAINTAINERS create mode 100644 board/xilinx/versal-net/Makefile create mode 100644 board/xilinx/versal-net/board.c create mode 100644 include/configs/xilinx_versal_net.h diff --git a/Kconfig b/Kconfig index c8c22555a9..2ea735d38e 100644 --- a/Kconfig +++ b/Kconfig @@ -540,7 +540,7 @@ config PLATFORM_ELFENTRY config STACK_SIZE hex "Define max stack size that can be used by U-Boot" - default 0x4000000 if ARCH_VERSAL || ARCH_ZYNQMP + default 0x4000000 if ARCH_VERSAL_NET || ARCH_VERSAL || ARCH_ZYNQMP default 0x200000 if MICROBLAZE default 0x1000000 help diff --git a/MAINTAINERS b/MAINTAINERS index e4fd099f87..65f26e3de9 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -629,6 +629,13 @@ F: arch/arm/mach-uniphier/ F: configs/uniphier_*_defconfig N: uniphier +ARM VERSAL NET +M: Michal Simek +S: Maintained +T: git https://source.denx.de/u-boot/custodians/u-boot-microblaze.git +F: arch/arm/mach-versal-net/ +N: (? S: Maintained diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 9a6c2e8101..2e83394052 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1251,6 +1251,18 @@ config ARCH_VERSAL imply BOARD_LATE_INIT imply ENV_VARS_UBOOT_RUNTIME_CONFIG +config ARCH_VERSAL_NET + bool "Support Xilinx Keystone Platform" + select ARM64 + select CLK + select DM + select DM_ETH if NET + select DM_MMC if MMC + select DM_SERIAL + select OF_CONTROL + imply BOARD_LATE_INIT + imply ENV_VARS_UBOOT_RUNTIME_CONFIG + config ARCH_VF610 bool "Freescale Vybrid" select CPU_V7A @@ -2300,6 +2312,8 @@ source "arch/arm/mach-zynqmp/Kconfig" source "arch/arm/mach-versal/Kconfig" +source "arch/arm/mach-versal-net/Kconfig" + source "arch/arm/mach-zynqmp-r5/Kconfig" source "arch/arm/cpu/armv7/Kconfig" diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 1f4a1d5788..ac602aed9c 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -88,6 +88,7 @@ machine-$(CONFIG_ARCH_OCTEONTX) += octeontx machine-$(CONFIG_ARCH_OCTEONTX2) += octeontx2 machine-$(CONFIG_ARCH_UNIPHIER) += uniphier machine-$(CONFIG_ARCH_VERSAL) += versal +machine-$(CONFIG_ARCH_VERSAL_NET) += versal-net machine-$(CONFIG_ARCH_ZYNQ) += zynq machine-$(CONFIG_ARCH_ZYNQMP) += zynqmp machine-$(CONFIG_ARCH_ZYNQMP_R5) += zynqmp-r5 diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index 5a42d5061c..5d4b76c6be 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -383,6 +383,8 @@ dtb-$(CONFIG_ARCH_VERSAL) += \ versal-mini-emmc0.dtb \ versal-mini-emmc1.dtb \ xilinx-versal-virt.dtb +dtb-$(CONFIG_ARCH_VERSAL_NET) += \ + xilinx-versal-net-virt.dtb dtb-$(CONFIG_ARCH_ZYNQMP_R5) += \ zynqmp-r5.dtb dtb-$(CONFIG_AM33XX) += \ diff --git a/arch/arm/dts/xilinx-versal-net-virt.dts b/arch/arm/dts/xilinx-versal-net-virt.dts new file mode 100644 index 0000000000..c99257cb08 --- /dev/null +++ b/arch/arm/dts/xilinx-versal-net-virt.dts @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Empty device tree for versal-net-virt board + * + * Copyright (C) 2022, Advanced Micro Devices, Inc. + */ + +/dts-v1/; + +/ { +}; diff --git a/arch/arm/mach-versal-net/Kconfig b/arch/arm/mach-versal-net/Kconfig new file mode 100644 index 0000000000..62825e189f --- /dev/null +++ b/arch/arm/mach-versal-net/Kconfig @@ -0,0 +1,43 @@ +# SPDX-License-Identifier: GPL-2.0 + +if ARCH_VERSAL_NET + +config SYS_BOARD + string "Board name" + default "versal-net" + +config SYS_VENDOR + string "Vendor name" + default "xilinx" + +config SYS_SOC + default "versal-net" + +config SYS_CONFIG_NAME + string "Board configuration name" + default "xilinx_versal_net" + help + This option contains information about board configuration name. + Based on this option include/configs/.h header + will be used for board configuration. + +config SYS_MEM_RSVD_FOR_MMU + bool "Reserve memory for MMU Table" + help + If defined this option is used to setup different space for + MMU table than the one which will be allocated during + relocation. + +config GICV3 + def_bool y + +config SYS_MALLOC_LEN + default 0x2000000 + +config ZYNQ_SDHCI_MAX_FREQ + default 200000000 + +source "board/xilinx/Kconfig" +source "board/xilinx/versal-net/Kconfig" + +endif diff --git a/arch/arm/mach-versal-net/Makefile b/arch/arm/mach-versal-net/Makefile new file mode 100644 index 0000000000..e12c4c0e67 --- /dev/null +++ b/arch/arm/mach-versal-net/Makefile @@ -0,0 +1,10 @@ +# SPDX-License-Identifier: GPL-2.0 +# +# Copyright (C) 2021 - 2022, Xilinx, Inc. +# Copyright (C) 2022, Advanced Micro Devices, Inc. +# +# Michal Simek +# + +obj-y += clk.o +obj-y += cpu.o diff --git a/arch/arm/mach-versal-net/clk.c b/arch/arm/mach-versal-net/clk.c new file mode 100644 index 0000000000..d097de7afa --- /dev/null +++ b/arch/arm/mach-versal-net/clk.c @@ -0,0 +1,35 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2016 - 2022, Xilinx, Inc. + * Copyright (C) 2022, Advanced Micro Devices, Inc. + * + * Michal Simek + */ + +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +#ifdef CONFIG_CLOCKS +/** + * set_cpu_clk_info - Initialize clock framework + * + * Return: 0 always. + * + * This function is called from common code after relocation and sets up the + * clock framework. The framework must not be used before this function had been + * called. + */ +int set_cpu_clk_info(void) +{ + gd->cpu_clk = get_tbclk(); + + gd->bd->bi_arm_freq = gd->cpu_clk / 1000000; + gd->bd->bi_dsp_freq = 0; + + return 0; +} +#endif diff --git a/arch/arm/mach-versal-net/cpu.c b/arch/arm/mach-versal-net/cpu.c new file mode 100644 index 0000000000..4c9b15411d --- /dev/null +++ b/arch/arm/mach-versal-net/cpu.c @@ -0,0 +1,89 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2021 - 2022, Xilinx, Inc. + * Copyright (C) 2022, Advanced Micro Devices, Inc. + * + * Michal Simek + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +#define VERSAL_NET_MEM_MAP_USED 5 + +#define DRAM_BANKS CONFIG_NR_DRAM_BANKS + +/* +1 is end of list which needs to be empty */ +#define VERSAL_NET_MEM_MAP_MAX (VERSAL_NET_MEM_MAP_USED + DRAM_BANKS + 1) + +static struct mm_region versal_mem_map[VERSAL_NET_MEM_MAP_MAX] = { + { + .virt = 0x80000000UL, + .phys = 0x80000000UL, + .size = 0x70000000UL, + .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | + PTE_BLOCK_NON_SHARE | + PTE_BLOCK_PXN | PTE_BLOCK_UXN + }, { + .virt = 0xf0000000UL, + .phys = 0xf0000000UL, + .size = 0x0fe00000UL, + .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | + PTE_BLOCK_NON_SHARE | + PTE_BLOCK_PXN | PTE_BLOCK_UXN + }, { + .virt = 0x400000000UL, + .phys = 0x400000000UL, + .size = 0x200000000UL, + .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | + PTE_BLOCK_NON_SHARE | + PTE_BLOCK_PXN | PTE_BLOCK_UXN + }, { + .virt = 0x600000000UL, + .phys = 0x600000000UL, + .size = 0x800000000UL, + .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | + PTE_BLOCK_INNER_SHARE + }, { + .virt = 0xe00000000UL, + .phys = 0xe00000000UL, + .size = 0xf200000000UL, + .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | + PTE_BLOCK_NON_SHARE | + PTE_BLOCK_PXN | PTE_BLOCK_UXN + } +}; + +void mem_map_fill(void) +{ + int banks = VERSAL_NET_MEM_MAP_USED; + + for (int i = 0; i < CONFIG_NR_DRAM_BANKS; i++) { + /* Zero size means no more DDR that's this is end */ + if (!gd->bd->bi_dram[i].size) + break; + + versal_mem_map[banks].virt = gd->bd->bi_dram[i].start; + versal_mem_map[banks].phys = gd->bd->bi_dram[i].start; + versal_mem_map[banks].size = gd->bd->bi_dram[i].size; + versal_mem_map[banks].attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | + PTE_BLOCK_INNER_SHARE; + banks = banks + 1; + } +} + +struct mm_region *mem_map = versal_mem_map; + +u64 get_page_table_size(void) +{ + return 0x14000; +} diff --git a/arch/arm/mach-versal-net/include/mach/hardware.h b/arch/arm/mach-versal-net/include/mach/hardware.h new file mode 100644 index 0000000000..2eb5498498 --- /dev/null +++ b/arch/arm/mach-versal-net/include/mach/hardware.h @@ -0,0 +1,27 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2016 - 2022, Xilinx, Inc. + * Copyright (C) 2022, Advanced Micro Devices, Inc. + */ + +#ifndef __ASSEMBLY__ +#include +#endif + +#define PMC_TAP 0xF11A0000 + +#define PMC_TAP_IDCODE (PMC_TAP + 0) +#define PMC_TAP_VERSION (PMC_TAP + 0x4) +# define PMC_VERSION_MASK GENMASK(7, 0) +# define PS_VERSION_MASK GENMASK(15, 8) +# define RTL_VERSION_MASK GENMASK(23, 16) +# define PLATFORM_MASK GENMASK(27, 24) +# define PLATFORM_VERSION_MASK GENMASK(31, 28) +#define PMC_TAP_USERCODE (PMC_TAP + 0x8) + +enum versal_net_platform { + VERSAL_NET_SILICON = 0, + VERSAL_NET_SPP = 1, + VERSAL_NET_EMU = 2, + VERSAL_NET_QEMU = 3, +}; diff --git a/arch/arm/mach-versal-net/include/mach/sys_proto.h b/arch/arm/mach-versal-net/include/mach/sys_proto.h new file mode 100644 index 0000000000..5bba9030f2 --- /dev/null +++ b/arch/arm/mach-versal-net/include/mach/sys_proto.h @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2021 - 2022, Xilinx, Inc. + * Copyright (C) 2022, Advanced Micro Devices, Inc. + */ + +#include + +void mem_map_fill(void); + +static inline int zynqmp_mmio_write(const u32 address, const u32 mask, + const u32 value) +{ + BUILD_BUG(); + return -EINVAL; +} diff --git a/board/xilinx/Kconfig b/board/xilinx/Kconfig index 1788066173..746a2332ad 100644 --- a/board/xilinx/Kconfig +++ b/board/xilinx/Kconfig @@ -42,7 +42,7 @@ endif config XILINX_OF_BOARD_DTB_ADDR hex "Default DTB pickup address" - default 0x1000 if ARCH_VERSAL + default 0x1000 if ARCH_VERSAL || ARCH_VERSAL_NET default 0x8000 if MICROBLAZE default 0x100000 if ARCH_ZYNQ || ARCH_ZYNQMP depends on OF_BOARD || OF_SEPARATE @@ -51,10 +51,10 @@ config XILINX_OF_BOARD_DTB_ADDR config BOOT_SCRIPT_OFFSET hex "Boot script offset" - depends on ARCH_ZYNQ || ARCH_ZYNQMP || ARCH_VERSAL || MICROBLAZE + depends on ARCH_ZYNQ || ARCH_ZYNQMP || ARCH_VERSAL || ARCH_VERSAL_NET || MICROBLAZE default 0xFC0000 if ARCH_ZYNQ || MICROBLAZE default 0x3E80000 if ARCH_ZYNQMP - default 0x7F80000 if ARCH_VERSAL + default 0x7F80000 if ARCH_VERSAL || ARCH_VERSAL_NET help Specifies distro boot script offset in NAND/QSPI/NOR flash. diff --git a/board/xilinx/versal-net/Kconfig b/board/xilinx/versal-net/Kconfig new file mode 100644 index 0000000000..8f94d2bb39 --- /dev/null +++ b/board/xilinx/versal-net/Kconfig @@ -0,0 +1,9 @@ +# SPDX-License-Identifier: GPL-2.0 +# +# Copyright (C) 2020 - 2022, Xilinx, Inc. +# Copyright (C) 2022, Advanced Micro Devices, Inc. +# + +if ARCH_VERSAL_NET + +endif diff --git a/board/xilinx/versal-net/MAINTAINERS b/board/xilinx/versal-net/MAINTAINERS new file mode 100644 index 0000000000..50120a88d6 --- /dev/null +++ b/board/xilinx/versal-net/MAINTAINERS @@ -0,0 +1,8 @@ +XILINX_VERSAL_NET BOARDS +M: Michal Simek +S: Maintained +T: git https://gitlab.denx.de/u-boot/custodians/u-boot-microblaze.git +F: arch/arm/dts/versal-net* +F: board/xilinx/versal-net/ +F: include/configs/xilinx_versal_net* +F: configs/xilinx_versal_net* diff --git a/board/xilinx/versal-net/Makefile b/board/xilinx/versal-net/Makefile new file mode 100644 index 0000000000..2008d4e231 --- /dev/null +++ b/board/xilinx/versal-net/Makefile @@ -0,0 +1,9 @@ +# SPDX-License-Identifier: GPL-2.0 +# +# Copyright (C) 2021 - 2022, Xilinx, Inc. +# Copyright (C) 2022, Advanced Micro Devices, Inc. +# +# Michal Simek +# + +obj-y := board.o diff --git a/board/xilinx/versal-net/board.c b/board/xilinx/versal-net/board.c new file mode 100644 index 0000000000..760031927f --- /dev/null +++ b/board/xilinx/versal-net/board.c @@ -0,0 +1,170 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2021 - 2022, Xilinx, Inc. + * Copyright (C) 2022, Advanced Micro Devices, Inc. + * + * Michal Simek + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../common/board.h" + +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +int board_init(void) +{ + printf("EL Level:\tEL%d\n", current_el()); + + return 0; +} + +static u32 platform_id, platform_version; + +char *soc_name_decode(void) +{ + char *name, *platform_name; + + switch (platform_id) { + case VERSAL_NET_SPP: + platform_name = "ipp"; + break; + case VERSAL_NET_EMU: + platform_name = "emu"; + break; + case VERSAL_NET_QEMU: + platform_name = "qemu"; + break; + default: + return NULL; + } + + /* + * --rev. are 6 chars + * max platform name is qemu which is 4 chars + * platform version number are 1+1 + * Plus 1 char for \n + */ + name = calloc(1, strlen(CONFIG_SYS_BOARD) + 13); + if (!name) + return NULL; + + sprintf(name, "%s-%s-rev%d.%d", CONFIG_SYS_BOARD, + platform_name, platform_version / 10, + platform_version % 10); + + return name; +} + +bool soc_detection(void) +{ + u32 version; + + version = readl(PMC_TAP_VERSION); + platform_id = FIELD_GET(PLATFORM_MASK, version); + + debug("idcode %x, version %x, usercode %x\n", + readl(PMC_TAP_IDCODE), version, + readl(PMC_TAP_USERCODE)); + + debug("pmc_ver %lx, ps version %lx, rtl version %lx\n", + FIELD_GET(PMC_VERSION_MASK, version), + FIELD_GET(PS_VERSION_MASK, version), + FIELD_GET(RTL_VERSION_MASK, version)); + + platform_version = FIELD_GET(PLATFORM_VERSION_MASK, version); + + if (platform_id == VERSAL_NET_SPP || + platform_id == VERSAL_NET_EMU) { + /* + * 9 is diff for + * 0 means 0.9 version + * 1 means 1.0 version + * 2 means 1.1 version + * etc, + */ + platform_version += 9; + } + + debug("Platform id: %d version: %d.%d\n", platform_id, + platform_version / 10, platform_version % 10); + + return true; +} + +int board_early_init_f(void) +{ + if (IS_ENABLED(CONFIG_DEBUG_UART)) { + /* Uart debug for sure */ + debug_uart_init(); + puts("Debug uart enabled\n"); /* or printch() */ + } + + return 0; +} + +int board_early_init_r(void) +{ + return 0; +} + +int board_late_init(void) +{ + if (!(gd->flags & GD_FLG_ENV_DEFAULT)) { + debug("Saved variables - Skipping\n"); + return 0; + } + + if (!CONFIG_IS_ENABLED(ENV_VARS_UBOOT_RUNTIME_CONFIG)) + return 0; + + return board_late_init_xilinx(); +} + +int dram_init_banksize(void) +{ + int ret; + + ret = fdtdec_setup_memory_banksize(); + if (ret) + return ret; + + mem_map_fill(); + + return 0; +} + +int dram_init(void) +{ + int ret; + + if (CONFIG_IS_ENABLED(SYS_MEM_RSVD_FOR_MMU)) + ret = fdtdec_setup_mem_size_base(); + else + ret = fdtdec_setup_mem_size_base_lowest(); + + if (ret) + return -EINVAL; + + return 0; +} + +void reset_cpu(void) +{ +} diff --git a/env/Kconfig b/env/Kconfig index 5329f7585b..24111dfaf4 100644 --- a/env/Kconfig +++ b/env/Kconfig @@ -558,7 +558,7 @@ config ENV_OFFSET default 0xF0000 if ARCH_SUNXI default 0xE0000 if ARCH_ZYNQ default 0x1E00000 if ARCH_ZYNQMP - default 0x7F40000 if ARCH_VERSAL + default 0x7F40000 if ARCH_VERSAL || ARCH_VERSAL_NET default 0 if ARC default 0x140000 if ARCH_AT91 default 0x260000 if ARCH_OMAP2PLUS @@ -583,7 +583,7 @@ config ENV_SIZE default 0x10000 if ARCH_SUNXI default 0x8000 if ARCH_ROCKCHIP && ENV_IS_IN_MMC default 0x2000 if ARCH_ROCKCHIP && ENV_IS_IN_SPI_FLASH - default 0x8000 if ARCH_ZYNQMP || ARCH_VERSAL + default 0x8000 if ARCH_ZYNQMP || ARCH_VERSAL || ARCH_VERSAL_NET default 0x4000 if ARC default 0x1f000 help @@ -593,7 +593,7 @@ config ENV_SECT_SIZE hex "Environment Sector-Size" depends on ENV_IS_IN_FLASH || ENV_IS_IN_SPI_FLASH default 0x2000 if ARCH_ROCKCHIP - default 0x40000 if ARCH_ZYNQMP || ARCH_VERSAL + default 0x40000 if ARCH_ZYNQMP || ARCH_VERSAL || ARCH_VERSAL_NET default 0x20000 if ARCH_ZYNQ || ARCH_OMAP2PLUS || ARCH_AT91 default 0x20000 if MICROBLAZE && ENV_IS_IN_SPI_FLASH default 0x10000 if ARCH_SUNXI && ENV_IS_IN_SPI_FLASH diff --git a/include/configs/xilinx_versal_net.h b/include/configs/xilinx_versal_net.h new file mode 100644 index 0000000000..d9286e7f50 --- /dev/null +++ b/include/configs/xilinx_versal_net.h @@ -0,0 +1,156 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Configuration for Xilinx Versal NET + * Copyright (C) 2016 - 2022, Xilinx, Inc. + * Copyright (C) 2022, Advanced Micro Devices, Inc. + * + * Michal Simek + * + * Based on Configuration for Xilinx ZynqMP + */ + +#ifndef __XILINX_VERSAL_NET_H +#define __XILINX_VERSAL_NET_H + +#define CONFIG_REMAKE_ELF + +/* FIXME this is causing issue at least on IPP */ +/* #define CONFIG_ARMV8_SWITCH_TO_EL1 */ + +/* Generic Interrupt Controller Definitions */ +#define GICD_BASE 0xF9000000 +#define GICR_BASE 0xF9060000 + +#define CONFIG_SYS_INIT_SP_ADDR CONFIG_SYS_TEXT_BASE + +/* Serial setup */ +#define CONFIG_CPU_ARMV8 + +#define CONFIG_SYS_BAUDRATE_TABLE \ + { 4800, 9600, 19200, 38400, 57600, 115200 } + +/* BOOTP options */ +#define CONFIG_BOOTP_BOOTFILESIZE +#define CONFIG_BOOTP_MAY_FAIL + +/* Monitor Command Prompt */ +/* Console I/O Buffer Size */ +#define CONFIG_SYS_CBSIZE 2048 +#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + \ + sizeof(CONFIG_SYS_PROMPT) + 16) +#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE +#define CONFIG_SYS_MAXARGS 64 + +#if defined(CONFIG_CMD_DFU) +#define DFU_DEFAULT_POLL_TIMEOUT 300 +#define CONFIG_THOR_RESET_OFF +#define DFU_ALT_INFO_RAM \ + "dfu_ram_info=" \ + "setenv dfu_alt_info " \ + "Image ram 80000 $kernel_size_r\\\\;" \ + "system.dtb ram $fdt_addr_r $fdt_size_r\0" \ + "dfu_ram=run dfu_ram_info && dfu 0 ram 0\0" \ + "thor_ram=run dfu_ram_info && thordown 0 ram 0\0" + +#define DFU_ALT_INFO \ + DFU_ALT_INFO_RAM +#endif + +#if !defined(DFU_ALT_INFO) +# define DFU_ALT_INFO +#endif + +/* Ethernet driver */ +#if defined(CONFIG_ZYNQ_GEM) +# define CONFIG_NET_MULTI +# define CONFIG_SYS_FAULT_ECHO_LINK_DOWN +# define PHY_ANEG_TIMEOUT 20000 +#endif + +#define CONFIG_SYS_BOOTM_LEN (60 * 1024 * 1024) + +#define CONFIG_CLOCKS + +#define ENV_MEM_LAYOUT_SETTINGS \ + "fdt_addr_r=0x40000000\0" \ + "fdt_size_r=0x400000\0" \ + "pxefile_addr_r=0x10000000\0" \ + "kernel_addr_r=0x18000000\0" \ + "kernel_size_r=0x10000000\0" \ + "scriptaddr=0x20000000\0" \ + "ramdisk_addr_r=0x02100000\0" \ + "script_size_f=0x80000\0" + +#if defined(CONFIG_MMC_SDHCI_ZYNQ) +# define BOOT_TARGET_DEVICES_MMC(func) func(MMC, mmc, 0) func(MMC, mmc, 1) +#else +# define BOOT_TARGET_DEVICES_MMC(func) +#endif + +#if defined(CONFIG_CMD_PXE) && defined(CONFIG_CMD_DHCP) +# define BOOT_TARGET_DEVICES_PXE(func) func(PXE, pxe, na) +#else +# define BOOT_TARGET_DEVICES_PXE(func) +#endif + +#if defined(CONFIG_CMD_DHCP) +# define BOOT_TARGET_DEVICES_DHCP(func) func(DHCP, dhcp, na) +#else +# define BOOT_TARGET_DEVICES_DHCP(func) +#endif + +#if defined(CONFIG_ZYNQMP_GQSPI) || defined(CONFIG_CADENCE_OSPI_VERSAL_NET) +# define BOOT_TARGET_DEVICES_XSPI(func) func(XSPI, xspi, 0) +#else +# define BOOT_TARGET_DEVICES_XSPI(func) +#endif + +#define BOOTENV_DEV_XSPI(devtypeu, devtypel, instance) \ + "bootcmd_xspi0=sf probe 0 0 0 && " \ + "sf read $scriptaddr $script_offset_f $script_size_f && " \ + "echo XSPI: Trying to boot script at ${scriptaddr} && " \ + "source ${scriptaddr}; echo XSPI: SCRIPT FAILED: continuing...;\0" + +#define BOOTENV_DEV_NAME_XSPI(devtypeu, devtypel, instance) \ + "xspi0 " + +#define BOOT_TARGET_DEVICES_JTAG(func) func(JTAG, jtag, na) + +#define BOOTENV_DEV_JTAG(devtypeu, devtypel, instance) \ + "bootcmd_jtag=echo JTAG: Trying to boot script at ${scriptaddr} && " \ + "source ${scriptaddr}; echo JTAG: SCRIPT FAILED: continuing...;\0" + +#define BOOTENV_DEV_NAME_JTAG(devtypeu, devtypel, instance) \ + "jtag " + +#define BOOT_TARGET_DEVICES_DFU_USB(func) func(DFU_USB, dfu_usb, 0) + +#define BOOTENV_DEV_DFU_USB(devtypeu, devtypel, instance) \ + "bootcmd_dfu_usb=setenv dfu_alt_info boot.scr ram $scriptaddr " \ + "$script_size_f; dfu 0 ram 0 && " \ + "echo DFU: Trying to boot script at ${scriptaddr} && " \ + "source ${scriptaddr}; " \ + "echo DFU: SCRIPT FAILED: continuing...;\0" + +#define BOOTENV_DEV_NAME_DFU_USB(devtypeu, devtypel, instance) \ + "" + +#define BOOT_TARGET_DEVICES(func) \ + BOOT_TARGET_DEVICES_JTAG(func) \ + BOOT_TARGET_DEVICES_MMC(func) \ + BOOT_TARGET_DEVICES_XSPI(func) \ + BOOT_TARGET_DEVICES_DFU_USB(func) \ + BOOT_TARGET_DEVICES_PXE(func) \ + BOOT_TARGET_DEVICES_DHCP(func) + +#include + +/* Initial environment variables */ +#ifndef CONFIG_EXTRA_ENV_SETTINGS +#define CONFIG_EXTRA_ENV_SETTINGS \ + ENV_MEM_LAYOUT_SETTINGS \ + BOOTENV \ + DFU_ALT_INFO +#endif + +#endif /* __XILINX_VERSAL_NET_H */ From 1e681448a38dcaf95a58592410382c3324c2cc00 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Mon, 19 Sep 2022 14:21:03 +0200 Subject: [PATCH 313/374] spi: cadence_qspi: Add support for Versal NET platform Trivial changes to support cadence ospi driver for Versal NET platform. Also avoid ospi flash reset for now. Signed-off-by: Michal Simek Link: https://lore.kernel.org/r/0789141f432189aab69bc496fe33e0218d1d7510.1663589964.git.michal.simek@amd.com --- arch/arm/mach-versal-net/include/mach/hardware.h | 4 ++++ drivers/spi/Kconfig | 2 +- drivers/spi/cadence_ospi_versal.c | 3 ++- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-versal-net/include/mach/hardware.h b/arch/arm/mach-versal-net/include/mach/hardware.h index 2eb5498498..808ce48fd1 100644 --- a/arch/arm/mach-versal-net/include/mach/hardware.h +++ b/arch/arm/mach-versal-net/include/mach/hardware.h @@ -25,3 +25,7 @@ enum versal_net_platform { VERSAL_NET_EMU = 2, VERSAL_NET_QEMU = 3, }; + +#define VERSAL_SLCR_BASEADDR 0xF1060000 +#define VERSAL_AXI_MUX_SEL (VERSAL_SLCR_BASEADDR + 0x504) +#define VERSAL_OSPI_LINEAR_MODE BIT(1) diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index ac91d82258..240ff212a3 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -148,7 +148,7 @@ config CQSPI_REF_CLK config CADENCE_OSPI_VERSAL bool "Configure Versal OSPI" - depends on ARCH_VERSAL && CADENCE_QSPI + depends on (ARCH_VERSAL || ARCH_VERSAL_NET) && CADENCE_QSPI imply DM_GPIO help This option is used to enable Versal OSPI DMA operations which diff --git a/drivers/spi/cadence_ospi_versal.c b/drivers/spi/cadence_ospi_versal.c index a25c50bc50..a9547a8200 100644 --- a/drivers/spi/cadence_ospi_versal.c +++ b/drivers/spi/cadence_ospi_versal.c @@ -130,6 +130,7 @@ int cadence_qspi_apb_wait_for_dma_cmplt(struct cadence_spi_priv *priv) #if defined(CONFIG_DM_GPIO) int cadence_qspi_versal_flash_reset(struct udevice *dev) { +#ifndef CONFIG_ARCH_VERSAL_NET struct gpio_desc gpio; u32 reset_gpio; int ret; @@ -165,7 +166,7 @@ int cadence_qspi_versal_flash_reset(struct udevice *dev) /* Set value 1 to pin */ dm_gpio_set_value(&gpio, 1); udelay(1); - +#endif return 0; } #else From 23896472257a0480da68cd7c6a0de061e1461f71 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Mon, 19 Sep 2022 14:21:04 +0200 Subject: [PATCH 314/374] spi: zynqmp_gqspi: Add support for Versal NET Add support for Versal NET platform. Signed-off-by: Michal Simek Link: https://lore.kernel.org/r/f374e9a81f2d85de1240029f3ba5f6423cfa0680.1663589964.git.michal.simek@amd.com --- drivers/spi/zynqmp_gqspi.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/spi/zynqmp_gqspi.c b/drivers/spi/zynqmp_gqspi.c index 4e718c545c..d3cc8554b8 100644 --- a/drivers/spi/zynqmp_gqspi.c +++ b/drivers/spi/zynqmp_gqspi.c @@ -308,7 +308,8 @@ void zynqmp_qspi_set_tapdelay(struct udevice *bus, u32 baudrateval) debug("%s, req_hz:%d, clk_rate:%d, baudrateval:%d\n", __func__, reqhz, clk_rate, baudrateval); - if (!IS_ENABLED(CONFIG_ARCH_VERSAL)) { + if (!(IS_ENABLED(CONFIG_ARCH_VERSAL) || + IS_ENABLED(CONFIG_ARCH_VERSAL_NET))) { if (reqhz <= GQSPI_FREQ_40MHZ) { tapdlybypass = TAP_DLY_BYPASS_LQSPI_RX_VALUE << TAP_DLY_BYPASS_LQSPI_RX_SHIFT; From ff33227819f579ffb963e0dac6bc6a6566b89563 Mon Sep 17 00:00:00 2001 From: Jay Buddhabhatti Date: Mon, 19 Sep 2022 14:21:05 +0200 Subject: [PATCH 315/374] clk: versal: Enable clock driver for Versal NET Add support for Versal NET compatible string in clock driver. Signed-off-by: Jay Buddhabhatti Signed-off-by: Michal Simek Link: https://lore.kernel.org/r/20a35d0c1ffcc222fbe93dd406cdd0aff92f5223.1663589964.git.michal.simek@amd.com --- drivers/clk/Kconfig | 2 +- drivers/clk/clk_versal.c | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index fd9e1a80c6..09aa97ee8c 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig @@ -184,7 +184,7 @@ config CLK_VERSACLOCK config CLK_VERSAL bool "Enable clock driver support for Versal" - depends on ARCH_VERSAL + depends on (ARCH_VERSAL || ARCH_VERSAL_NET) select ZYNQMP_FIRMWARE help This clock driver adds support for clock realted settings for diff --git a/drivers/clk/clk_versal.c b/drivers/clk/clk_versal.c index a9dd57b098..b2f62061ce 100644 --- a/drivers/clk/clk_versal.c +++ b/drivers/clk/clk_versal.c @@ -739,6 +739,7 @@ static struct clk_ops versal_clk_ops = { static const struct udevice_id versal_clk_ids[] = { { .compatible = "xlnx,versal-clk" }, + { .compatible = "xlnx,versal-net-clk" }, { } }; From 2a00cef8206480cce2d66aae3e8609e28fd67bff Mon Sep 17 00:00:00 2001 From: Jay Buddhabhatti Date: Mon, 19 Sep 2022 14:21:06 +0200 Subject: [PATCH 316/374] firmware: zynqmp: Add Versal NET compatible string Add compatible string for Versal NET. Signed-off-by: Jay Buddhabhatti Signed-off-by: Michal Simek Link: https://lore.kernel.org/r/ec73f786e1c89094752ff3693f6f0fb4536c85c5.1663589964.git.michal.simek@amd.com --- drivers/firmware/firmware-zynqmp.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/firmware/firmware-zynqmp.c b/drivers/firmware/firmware-zynqmp.c index 76ddc6b4f4..d8e0d79c57 100644 --- a/drivers/firmware/firmware-zynqmp.c +++ b/drivers/firmware/firmware-zynqmp.c @@ -370,6 +370,7 @@ int __maybe_unused xilinx_pm_request(u32 api_id, u32 arg0, u32 arg1, u32 arg2, static const struct udevice_id zynqmp_firmware_ids[] = { { .compatible = "xlnx,zynqmp-firmware" }, { .compatible = "xlnx,versal-firmware"}, + { .compatible = "xlnx,versal-net-firmware"}, { } }; From b6b2ad1cea7bf1f038875a28f2545ad70c25d0a3 Mon Sep 17 00:00:00 2001 From: Jay Buddhabhatti Date: Mon, 19 Sep 2022 14:21:07 +0200 Subject: [PATCH 317/374] mailbox: zynqmp: Enable ipi mailbox driver for Versal NET Enable mailbox configs for Versal NET. Signed-off-by: Jay Buddhabhatti Signed-off-by: Michal Simek Link: https://lore.kernel.org/r/b3a9a6a58b74d17e2ec5f60617fa42062fbab951.1663589964.git.michal.simek@amd.com --- drivers/mailbox/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig index acbdce11b7..47f24e0a02 100644 --- a/drivers/mailbox/Kconfig +++ b/drivers/mailbox/Kconfig @@ -54,7 +54,7 @@ config K3_SEC_PROXY config ZYNQMP_IPI bool "Xilinx ZynqMP IPI controller support" - depends on DM_MAILBOX && (ARCH_ZYNQMP || ARCH_VERSAL) + depends on DM_MAILBOX && (ARCH_ZYNQMP || ARCH_VERSAL || ARCH_VERSAL_NET) help This enables support for the Xilinx ZynqMP Inter Processor Interrupt communication controller. From a41c33992a89de2bcae0e361d70818def70b1783 Mon Sep 17 00:00:00 2001 From: Jay Buddhabhatti Date: Mon, 19 Sep 2022 14:21:08 +0200 Subject: [PATCH 318/374] reset: zynqmp: Enable reset driver for Versal NET Enable zynqmp reset driver for Versal NET. Signed-off-by: Jay Buddhabhatti Signed-off-by: Michal Simek Link: https://lore.kernel.org/r/c8c26618f87d8451c6ffa9487809a24718bff6a7.1663589964.git.michal.simek@amd.com --- drivers/reset/reset-zynqmp.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/reset/reset-zynqmp.c b/drivers/reset/reset-zynqmp.c index 52c08c4722..87b4df5bf8 100644 --- a/drivers/reset/reset-zynqmp.c +++ b/drivers/reset/reset-zynqmp.c @@ -80,6 +80,7 @@ const struct reset_ops zynqmp_reset_ops = { static const struct udevice_id zynqmp_reset_ids[] = { { .compatible = "xlnx,zynqmp-reset" }, { .compatible = "xlnx,versal-reset" }, + { .compatible = "xlnx,versal-net-reset" }, { } }; From ce40cbdf1f839a746996193d42abd6f3e36f07e6 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Mon, 19 Sep 2022 14:21:09 +0200 Subject: [PATCH 319/374] arm64: versal-net: Add defconfig for Versal NET Use one defconfig for supporting multiple different platforms. DTB reselection is enabled to choose DT based on SOC detection. Signed-off-by: Michal Simek Link: https://lore.kernel.org/r/82cc7c1ca8850270cc2ebc992d835a37aa3d236f.1663589964.git.michal.simek@amd.com --- configs/xilinx_versal_net_virt_defconfig | 131 +++++++++++++++++++++++ include/configs/xilinx_versal_net.h | 28 +---- 2 files changed, 134 insertions(+), 25 deletions(-) create mode 100644 configs/xilinx_versal_net_virt_defconfig diff --git a/configs/xilinx_versal_net_virt_defconfig b/configs/xilinx_versal_net_virt_defconfig new file mode 100644 index 0000000000..4a9910b7c4 --- /dev/null +++ b/configs/xilinx_versal_net_virt_defconfig @@ -0,0 +1,131 @@ +CONFIG_ARM=y +CONFIG_POSITION_INDEPENDENT=y +CONFIG_SYS_INIT_SP_BSS_OFFSET=1572864 +CONFIG_ARCH_VERSAL_NET=y +CONFIG_SYS_TEXT_BASE=0x8000000 +CONFIG_SYS_MALLOC_F_LEN=0x100000 +CONFIG_DEFAULT_DEVICE_TREE="xilinx-versal-net-virt" +CONFIG_SYS_PROMPT="Versal NET> " +CONFIG_CMD_FRU=y +CONFIG_SYS_LOAD_ADDR=0x8000000 +CONFIG_SYS_MEMTEST_START=0x00000000 +CONFIG_SYS_MEMTEST_END=0x00001000 +CONFIG_DISTRO_DEFAULTS=y +CONFIG_REMAKE_ELF=y +CONFIG_FIT=y +CONFIG_FIT_VERBOSE=y +# CONFIG_ARCH_FIXUP_FDT_MEMORY is not set +CONFIG_BOOTDELAY=5 +CONFIG_USE_PREBOOT=y +# CONFIG_DISPLAY_CPUINFO is not set +CONFIG_BOARD_EARLY_INIT_F=y +CONFIG_BOARD_EARLY_INIT_R=y +CONFIG_CLOCKS=y +CONFIG_SYS_MAXARGS=64 +CONFIG_SYS_PBSIZE=2073 +CONFIG_SYS_BOOTM_LEN=0x6400000 +CONFIG_CMD_BOOTMENU=y +CONFIG_CMD_GREPENV=y +CONFIG_CMD_NVEDIT_EFI=y +CONFIG_CMD_MEMTEST=y +CONFIG_SYS_ALT_MEMTEST=y +CONFIG_CMD_CLK=y +CONFIG_CMD_DFU=y +CONFIG_CMD_DM=y +# CONFIG_CMD_FLASH is not set +CONFIG_CMD_GPIO=y +CONFIG_CMD_I2C=y +CONFIG_CMD_MMC=y +CONFIG_CMD_MTD=y +CONFIG_CMD_SF_TEST=y +CONFIG_CMD_USB=y +CONFIG_BOOTP_MAY_FAIL=y +CONFIG_BOOTP_BOOTFILESIZE=y +CONFIG_CMD_TFTPPUT=y +CONFIG_CMD_CACHE=y +CONFIG_CMD_EFIDEBUG=y +CONFIG_CMD_TIME=y +CONFIG_CMD_TIMER=y +CONFIG_CMD_EXT4_WRITE=y +CONFIG_CMD_SQUASHFS=y +CONFIG_CMD_MTDPARTS=y +CONFIG_CMD_UBI=y +CONFIG_PARTITION_TYPE_GUID=y +CONFIG_OF_BOARD=y +CONFIG_DTB_RESELECT=y +CONFIG_MULTI_DTB_FIT=y +CONFIG_SYS_REDUNDAND_ENVIRONMENT=y +CONFIG_SYS_RELOC_GD_ENV_ADDR=y +CONFIG_NET_RANDOM_ETHADDR=y +CONFIG_NETCONSOLE=y +CONFIG_IP_DEFRAG=y +CONFIG_SYS_FAULT_ECHO_LINK_DOWN=y +CONFIG_TFTP_BLOCKSIZE=4096 +CONFIG_CLK_VERSAL=y +CONFIG_DFU_RAM=y +CONFIG_ZYNQ_GPIO=y +CONFIG_DM_I2C=y +CONFIG_SYS_I2C_CADENCE=y +CONFIG_I2C_MUX=y +CONFIG_I2C_MUX_PCA954x=y +CONFIG_DM_MAILBOX=y +CONFIG_ZYNQMP_IPI=y +CONFIG_MISC=y +CONFIG_I2C_EEPROM=y +CONFIG_SYS_I2C_EEPROM_ADDR=0x0 +CONFIG_SUPPORT_EMMC_BOOT=y +CONFIG_MMC_IO_VOLTAGE=y +CONFIG_MMC_UHS_SUPPORT=y +CONFIG_MMC_HS400_SUPPORT=y +CONFIG_MMC_SDHCI=y +CONFIG_MMC_SDHCI_ZYNQ=y +CONFIG_ZYNQ_SDHCI_MIN_FREQ=100000 +CONFIG_MTD=y +CONFIG_DM_SPI_FLASH=y +CONFIG_SPI_FLASH_GIGADEVICE=y +CONFIG_SPI_FLASH_ISSI=y +CONFIG_SPI_FLASH_MACRONIX=y +CONFIG_SPI_FLASH_SPANSION=y +CONFIG_SPI_FLASH_STMICRO=y +CONFIG_SPI_FLASH_SST=y +CONFIG_SPI_FLASH_WINBOND=y +# CONFIG_SPI_FLASH_USE_4K_SECTORS is not set +CONFIG_SPI_FLASH_MTD=y +CONFIG_PHY_MARVELL=y +CONFIG_PHY_NATSEMI=y +CONFIG_PHY_REALTEK=y +CONFIG_PHY_TI_DP83867=y +CONFIG_PHY_VITESSE=y +CONFIG_PHY_FIXED=y +CONFIG_DM_ETH_PHY=y +CONFIG_PHY_GIGE=y +CONFIG_XILINX_AXIEMAC=y +CONFIG_ZYNQ_GEM=y +CONFIG_POWER_DOMAIN=y +CONFIG_ZYNQMP_POWER_DOMAIN=y +CONFIG_DM_RESET=y +CONFIG_RESET_ZYNQMP=y +CONFIG_ARM_DCC=y +CONFIG_PL01X_SERIAL=y +CONFIG_XILINX_UARTLITE=y +CONFIG_SPI=y +CONFIG_DM_SPI=y +CONFIG_CADENCE_QSPI=y +CONFIG_CADENCE_OSPI_VERSAL=y +CONFIG_ZYNQ_SPI=y +CONFIG_ZYNQMP_GQSPI=y +CONFIG_USB=y +CONFIG_DM_USB_GADGET=y +CONFIG_USB_XHCI_HCD=y +CONFIG_USB_XHCI_DWC3=y +CONFIG_USB_DWC3=y +CONFIG_USB_DWC3_GENERIC=y +CONFIG_USB_ULPI_VIEWPORT=y +CONFIG_USB_ULPI=y +CONFIG_USB_GADGET=y +CONFIG_USB_GADGET_MANUFACTURER="Xilinx" +CONFIG_USB_GADGET_VENDOR_NUM=0x03FD +CONFIG_USB_GADGET_PRODUCT_NUM=0x0300 +CONFIG_USB_GADGET_DOWNLOAD=y +CONFIG_USB_FUNCTION_THOR=y +CONFIG_OF_LIBFDT_OVERLAY=y diff --git a/include/configs/xilinx_versal_net.h b/include/configs/xilinx_versal_net.h index d9286e7f50..0ccd38b7e6 100644 --- a/include/configs/xilinx_versal_net.h +++ b/include/configs/xilinx_versal_net.h @@ -12,8 +12,6 @@ #ifndef __XILINX_VERSAL_NET_H #define __XILINX_VERSAL_NET_H -#define CONFIG_REMAKE_ELF - /* FIXME this is causing issue at least on IPP */ /* #define CONFIG_ARMV8_SWITCH_TO_EL1 */ @@ -21,26 +19,10 @@ #define GICD_BASE 0xF9000000 #define GICR_BASE 0xF9060000 -#define CONFIG_SYS_INIT_SP_ADDR CONFIG_SYS_TEXT_BASE - /* Serial setup */ -#define CONFIG_CPU_ARMV8 - #define CONFIG_SYS_BAUDRATE_TABLE \ { 4800, 9600, 19200, 38400, 57600, 115200 } -/* BOOTP options */ -#define CONFIG_BOOTP_BOOTFILESIZE -#define CONFIG_BOOTP_MAY_FAIL - -/* Monitor Command Prompt */ -/* Console I/O Buffer Size */ -#define CONFIG_SYS_CBSIZE 2048 -#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + \ - sizeof(CONFIG_SYS_PROMPT) + 16) -#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE -#define CONFIG_SYS_MAXARGS 64 - #if defined(CONFIG_CMD_DFU) #define DFU_DEFAULT_POLL_TIMEOUT 300 #define CONFIG_THOR_RESET_OFF @@ -62,21 +44,17 @@ /* Ethernet driver */ #if defined(CONFIG_ZYNQ_GEM) -# define CONFIG_NET_MULTI -# define CONFIG_SYS_FAULT_ECHO_LINK_DOWN -# define PHY_ANEG_TIMEOUT 20000 +# define PHY_ANEG_TIMEOUT 20000 #endif -#define CONFIG_SYS_BOOTM_LEN (60 * 1024 * 1024) - -#define CONFIG_CLOCKS - #define ENV_MEM_LAYOUT_SETTINGS \ "fdt_addr_r=0x40000000\0" \ "fdt_size_r=0x400000\0" \ "pxefile_addr_r=0x10000000\0" \ "kernel_addr_r=0x18000000\0" \ "kernel_size_r=0x10000000\0" \ + "kernel_comp_addr_r=0x30000000\0" \ + "kernel_comp_size=0x3C00000\0" \ "scriptaddr=0x20000000\0" \ "ramdisk_addr_r=0x02100000\0" \ "script_size_f=0x80000\0" From f2641f066b53a2bbb933bccffd696a875fd9adf5 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Mon, 19 Sep 2022 14:21:10 +0200 Subject: [PATCH 320/374] arm64: versal-net: Add support for mini configuration Versal NET mini configuration is designed for running memory test. Current output is on DCC but changing serial0 alias to pl011 will move console to serial port. Signed-off-by: Michal Simek Link: https://lore.kernel.org/r/aec3f41a4cc48c45b8f07dd6e423d5838dbcc9d7.1663589964.git.michal.simek@amd.com --- arch/arm/dts/Makefile | 1 + arch/arm/dts/versal-net-mini.dts | 67 ++++++++++++++++++++++ configs/xilinx_versal_net_mini_defconfig | 72 ++++++++++++++++++++++++ include/configs/xilinx_versal_net_mini.h | 21 +++++++ 4 files changed, 161 insertions(+) create mode 100644 arch/arm/dts/versal-net-mini.dts create mode 100644 configs/xilinx_versal_net_mini_defconfig create mode 100644 include/configs/xilinx_versal_net_mini.h diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index 5d4b76c6be..d6832d1681 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -384,6 +384,7 @@ dtb-$(CONFIG_ARCH_VERSAL) += \ versal-mini-emmc1.dtb \ xilinx-versal-virt.dtb dtb-$(CONFIG_ARCH_VERSAL_NET) += \ + versal-net-mini.dtb \ xilinx-versal-net-virt.dtb dtb-$(CONFIG_ARCH_ZYNQMP_R5) += \ zynqmp-r5.dtb diff --git a/arch/arm/dts/versal-net-mini.dts b/arch/arm/dts/versal-net-mini.dts new file mode 100644 index 0000000000..8c29a6ed6b --- /dev/null +++ b/arch/arm/dts/versal-net-mini.dts @@ -0,0 +1,67 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * dts file for Xilinx Versal NET + * + * Copyright (C) 2021 - 2022, Xilinx, Inc. + * Copyright (C) 2022, Advanced Micro Devices, Inc. + * + * Michal Simek + */ + +/dts-v1/; + +#include + +/ { + compatible = "xlnx,versal-net-mini"; + model = "Xilinx Versal NET MINI"; + #address-cells = <2>; + #size-cells = <2>; + + memory: memory@0 { + reg = <0 0xBBF00000 0 0x100000>, <0 0 0 0x80000000>; + device_type = "memory"; + }; + + aliases { + /* serial0 = &serial0; */ + serial0 = &dcc; + }; + + chosen { + stdout-path = "serial0:115200"; + }; + + clk1: clk1 { + u-boot,dm-pre-reloc; + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <1000000>; + }; + + dcc: dcc { + compatible = "arm,dcc"; + status = "okay"; + u-boot,dm-pre-reloc; + }; + + amba: axi { + compatible = "simple-bus"; + u-boot,dm-pre-reloc; + #address-cells = <2>; + #size-cells = <2>; + ranges; + + serial0: serial@f1920000 { + u-boot,dm-pre-reloc; + compatible = "arm,pl011", "arm,primecell"; + reg = <0 0xf1920000 0 0x1000>; + reg-io-width = <4>; + clock-names = "uartclk", "apb_pclk"; + clocks = <&clk1>, <&clk1>; + clock = <1000000>; + current-speed = <115200>; + skip-init; + }; + }; +}; diff --git a/configs/xilinx_versal_net_mini_defconfig b/configs/xilinx_versal_net_mini_defconfig new file mode 100644 index 0000000000..e8fa08e3ef --- /dev/null +++ b/configs/xilinx_versal_net_mini_defconfig @@ -0,0 +1,72 @@ +CONFIG_ARM=y +CONFIG_SYS_CONFIG_NAME="xilinx_versal_net_mini" +CONFIG_SYS_ICACHE_OFF=y +# CONFIG_ARM64_CRC32 is not set +# CONFIG_ARM64_SUPPORT_AARCH32 is not set +CONFIG_ARCH_VERSAL_NET=y +CONFIG_SYS_TEXT_BASE=0xBBF10000 +CONFIG_SYS_MALLOC_LEN=0x20000 +CONFIG_SYS_MALLOC_F_LEN=0x4000 +CONFIG_NR_DRAM_BANKS=3 +CONFIG_ENV_SIZE=0x80 +CONFIG_DEFAULT_DEVICE_TREE="versal-net-mini" +CONFIG_SYS_PROMPT="Versal NET> " +CONFIG_SYS_MEM_RSVD_FOR_MMU=y +# CONFIG_PSCI_RESET is not set +CONFIG_SYS_LOAD_ADDR=0x8000000 +CONFIG_SYS_MEMTEST_START=0x00000000 +CONFIG_SYS_MEMTEST_END=0x00001000 +CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y +CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0xBBF10000 +# CONFIG_EXPERT is not set +# CONFIG_LEGACY_IMAGE_FORMAT is not set +# CONFIG_ARCH_FIXUP_FDT_MEMORY is not set +# CONFIG_AUTOBOOT is not set +CONFIG_SYS_CONSOLE_INFO_QUIET=y +# CONFIG_DISPLAY_CPUINFO is not set +CONFIG_BOARD_EARLY_INIT_R=y +# CONFIG_BOARD_LATE_INIT is not set +# CONFIG_CMDLINE_EDITING is not set +# CONFIG_AUTO_COMPLETE is not set +# CONFIG_SYS_LONGHELP is not set +# CONFIG_CMD_CONSOLE is not set +# CONFIG_CMD_BOOTD is not set +# CONFIG_CMD_BOOTM is not set +# CONFIG_CMD_BOOTI is not set +# CONFIG_CMD_ELF is not set +# CONFIG_CMD_FDT is not set +# CONFIG_CMD_GO is not set +# CONFIG_CMD_RUN is not set +# CONFIG_CMD_IMI is not set +# CONFIG_CMD_XIMG is not set +# CONFIG_CMD_EXPORTENV is not set +# CONFIG_CMD_IMPORTENV is not set +# CONFIG_CMD_EDITENV is not set +# CONFIG_CMD_SAVEENV is not set +# CONFIG_CMD_ENV_EXISTS is not set +# CONFIG_CMD_CRC32 is not set +CONFIG_CMD_MEMINFO=y +CONFIG_CMD_MX_CYCLIC=y +CONFIG_CMD_MEMTEST=y +CONFIG_SYS_ALT_MEMTEST=y +# CONFIG_CMD_LOADB is not set +# CONFIG_CMD_LOADS is not set +# CONFIG_CMD_ECHO is not set +# CONFIG_CMD_ITEST is not set +# CONFIG_CMD_SOURCE is not set +# CONFIG_CMD_SETEXPR is not set +CONFIG_CMD_CACHE=y +# CONFIG_CMD_SLEEP is not set +CONFIG_OF_EMBED=y +CONFIG_SYS_RELOC_GD_ENV_ADDR=y +# CONFIG_NET is not set +# CONFIG_DM_WARN is not set +# CONFIG_DM_DEVICE_REMOVE is not set +# CONFIG_GPIO is not set +# CONFIG_I2C is not set +# CONFIG_INPUT is not set +# CONFIG_MMC is not set +# CONFIG_POWER is not set +CONFIG_ARM_DCC=y +CONFIG_PL01X_SERIAL=y +# CONFIG_GZIP is not set diff --git a/include/configs/xilinx_versal_net_mini.h b/include/configs/xilinx_versal_net_mini.h new file mode 100644 index 0000000000..1939832a84 --- /dev/null +++ b/include/configs/xilinx_versal_net_mini.h @@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Configuration for Xilinx Versal NET MINI configuration + * + * Copyright (C) 2018 - 2022, Xilinx, Inc. + * Copyright (C) 2022, Advanced Micro Devices, Inc. + * + * Michal Simek + */ + +#ifndef __CONFIG_VERSAL_NET_MINI_H +#define __CONFIG_VERSAL_NET_MINI_H + +#define CONFIG_EXTRA_ENV_SETTINGS + +#include + +/* Undef unneeded configs */ +#undef CONFIG_EXTRA_ENV_SETTINGS + +#endif /* __CONFIG_VERSAL_NET_MINI_H */ From 9f603e2fff19507cc907faa3c5f3f2f51f1b2eaf Mon Sep 17 00:00:00 2001 From: Patrice Chotard Date: Fri, 23 Sep 2022 13:20:33 +0200 Subject: [PATCH 321/374] ARM: dts: stm32: DT sync with kernel v6.0-rc4 for MCU's boards Device tree alignment with kernel v6.0-rc4. Signed-off-by: Patrice Chotard Reviewed-by: Patrick Delaunay --- arch/arm/dts/stm32429i-eval-u-boot.dtsi | 2 +- arch/arm/dts/stm32746g-eval.dts | 18 ++++-- arch/arm/dts/stm32f4-pinctrl.dtsi | 2 +- arch/arm/dts/stm32f429-disco-u-boot.dtsi | 8 +-- arch/arm/dts/stm32f429-disco.dts | 20 +++++-- arch/arm/dts/stm32f429-pinctrl.dtsi | 72 +++++++++++------------ arch/arm/dts/stm32f429.dtsi | 69 ++++------------------ arch/arm/dts/stm32f469-disco-u-boot.dtsi | 7 +-- arch/arm/dts/stm32f469-disco.dts | 24 ++++++-- arch/arm/dts/stm32f469-pinctrl.dtsi | 74 +++++++++++------------- arch/arm/dts/stm32f7-pinctrl.dtsi | 2 +- arch/arm/dts/stm32f7-u-boot.dtsi | 2 +- arch/arm/dts/stm32f746-disco.dts | 12 ++++ arch/arm/dts/stm32f746.dtsi | 67 ++------------------- arch/arm/dts/stm32f769-disco.dts | 18 ++++-- arch/arm/dts/stm32h743.dtsi | 19 ++---- arch/arm/dts/stm32h743i-disco.dts | 8 +-- arch/arm/dts/stm32h743i-eval.dts | 8 +-- arch/arm/dts/stm32h750i-art-pi.dts | 8 +-- 19 files changed, 187 insertions(+), 253 deletions(-) diff --git a/arch/arm/dts/stm32429i-eval-u-boot.dtsi b/arch/arm/dts/stm32429i-eval-u-boot.dtsi index fcab9ae977..030da47b7a 100644 --- a/arch/arm/dts/stm32429i-eval-u-boot.dtsi +++ b/arch/arm/dts/stm32429i-eval-u-boot.dtsi @@ -218,6 +218,6 @@ }; }; -&timer5 { +&timers5 { u-boot,dm-pre-reloc; }; diff --git a/arch/arm/dts/stm32746g-eval.dts b/arch/arm/dts/stm32746g-eval.dts index 9940cf1873..0e6445a539 100644 --- a/arch/arm/dts/stm32746g-eval.dts +++ b/arch/arm/dts/stm32746g-eval.dts @@ -45,12 +45,10 @@ }; }; - gpio_keys { + gpio-keys { compatible = "gpio-keys"; - #address-cells = <1>; - #size-cells = <0>; autorepeat; - button@0 { + button-0 { label = "Wake up"; linux,code = ; gpios = <&gpioc 13 0>; @@ -160,6 +158,18 @@ bus-width = <4>; }; +&timers5 { + /* Override timer5 to act as clockevent */ + compatible = "st,stm32-timer"; + interrupts = <50>; + status = "okay"; + /delete-property/#address-cells; + /delete-property/#size-cells; + /delete-property/clock-names; + /delete-node/pwm; + /delete-node/timer@4; +}; + &usart1 { pinctrl-0 = <&usart1_pins_a>; pinctrl-names = "default"; diff --git a/arch/arm/dts/stm32f4-pinctrl.dtsi b/arch/arm/dts/stm32f4-pinctrl.dtsi index adf502694b..46815c965d 100644 --- a/arch/arm/dts/stm32f4-pinctrl.dtsi +++ b/arch/arm/dts/stm32f4-pinctrl.dtsi @@ -9,7 +9,7 @@ / { soc { - pinctrl: pin-controller { + pinctrl: pinctrl@40020000 { #address-cells = <1>; #size-cells = <1>; ranges = <0 0x40020000 0x3000>; diff --git a/arch/arm/dts/stm32f429-disco-u-boot.dtsi b/arch/arm/dts/stm32f429-disco-u-boot.dtsi index c993f86be8..45f899662d 100644 --- a/arch/arm/dts/stm32f429-disco-u-boot.dtsi +++ b/arch/arm/dts/stm32f429-disco-u-boot.dtsi @@ -27,10 +27,6 @@ soc { u-boot,dm-pre-reloc; - pin-controller { - u-boot,dm-pre-reloc; - }; - fmc: fmc@A0000000 { compatible = "st,stm32-fmc"; reg = <0xa0000000 0x1000>; @@ -123,6 +119,8 @@ }; &pinctrl { + u-boot,dm-pre-reloc; + usart1_pins_a: usart1-0 { u-boot,dm-pre-reloc; pins1 { @@ -193,6 +191,6 @@ u-boot,dm-pre-reloc; }; -&timer5 { +&timers5 { u-boot,dm-pre-reloc; }; diff --git a/arch/arm/dts/stm32f429-disco.dts b/arch/arm/dts/stm32f429-disco.dts index 42477c8d3f..30daabd10a 100644 --- a/arch/arm/dts/stm32f429-disco.dts +++ b/arch/arm/dts/stm32f429-disco.dts @@ -39,12 +39,10 @@ }; }; - gpio_keys { + gpio-keys { compatible = "gpio-keys"; - #address-cells = <1>; - #size-cells = <0>; autorepeat; - button@0 { + button-0 { label = "User"; linux,code = ; gpios = <&gpioa 0 0>; @@ -152,7 +150,7 @@ display: display@1{ /* Connect panel-ilitek-9341 to ltdc */ - compatible = "st,sf-tc240t-9370-t"; + compatible = "st,sf-tc240t-9370-t", "ilitek,ili9341"; reg = <1>; spi-3wire; spi-max-frequency = <10000000>; @@ -165,6 +163,18 @@ }; }; +&timers5 { + /* Override timer5 to act as clockevent */ + compatible = "st,stm32-timer"; + interrupts = <50>; + status = "okay"; + /delete-property/#address-cells; + /delete-property/#size-cells; + /delete-property/clock-names; + /delete-node/pwm; + /delete-node/timer@4; +}; + &usart1 { pinctrl-0 = <&usart1_pins_a>; pinctrl-names = "default"; diff --git a/arch/arm/dts/stm32f429-pinctrl.dtsi b/arch/arm/dts/stm32f429-pinctrl.dtsi index 575c7eecab..5be171eea5 100644 --- a/arch/arm/dts/stm32f429-pinctrl.dtsi +++ b/arch/arm/dts/stm32f429-pinctrl.dtsi @@ -6,54 +6,50 @@ #include "stm32f4-pinctrl.dtsi" -/ { - soc { - pinctrl: pin-controller { - compatible = "st,stm32f429-pinctrl"; +&pinctrl { + compatible = "st,stm32f429-pinctrl"; - gpioa: gpio@40020000 { - gpio-ranges = <&pinctrl 0 0 16>; - }; + gpioa: gpio@40020000 { + gpio-ranges = <&pinctrl 0 0 16>; + }; - gpiob: gpio@40020400 { - gpio-ranges = <&pinctrl 0 16 16>; - }; + gpiob: gpio@40020400 { + gpio-ranges = <&pinctrl 0 16 16>; + }; - gpioc: gpio@40020800 { - gpio-ranges = <&pinctrl 0 32 16>; - }; + gpioc: gpio@40020800 { + gpio-ranges = <&pinctrl 0 32 16>; + }; - gpiod: gpio@40020c00 { - gpio-ranges = <&pinctrl 0 48 16>; - }; + gpiod: gpio@40020c00 { + gpio-ranges = <&pinctrl 0 48 16>; + }; - gpioe: gpio@40021000 { - gpio-ranges = <&pinctrl 0 64 16>; - }; + gpioe: gpio@40021000 { + gpio-ranges = <&pinctrl 0 64 16>; + }; - gpiof: gpio@40021400 { - gpio-ranges = <&pinctrl 0 80 16>; - }; + gpiof: gpio@40021400 { + gpio-ranges = <&pinctrl 0 80 16>; + }; - gpiog: gpio@40021800 { - gpio-ranges = <&pinctrl 0 96 16>; - }; + gpiog: gpio@40021800 { + gpio-ranges = <&pinctrl 0 96 16>; + }; - gpioh: gpio@40021c00 { - gpio-ranges = <&pinctrl 0 112 16>; - }; + gpioh: gpio@40021c00 { + gpio-ranges = <&pinctrl 0 112 16>; + }; - gpioi: gpio@40022000 { - gpio-ranges = <&pinctrl 0 128 16>; - }; + gpioi: gpio@40022000 { + gpio-ranges = <&pinctrl 0 128 16>; + }; - gpioj: gpio@40022400 { - gpio-ranges = <&pinctrl 0 144 16>; - }; + gpioj: gpio@40022400 { + gpio-ranges = <&pinctrl 0 144 16>; + }; - gpiok: gpio@40022800 { - gpio-ranges = <&pinctrl 0 160 8>; - }; - }; + gpiok: gpio@40022800 { + gpio-ranges = <&pinctrl 0 160 8>; }; }; diff --git a/arch/arm/dts/stm32f429.dtsi b/arch/arm/dts/stm32f429.dtsi index a81e916064..e5b13aca40 100644 --- a/arch/arm/dts/stm32f429.dtsi +++ b/arch/arm/dts/stm32f429.dtsi @@ -52,14 +52,6 @@ }; }; - timer2: timer@40000000 { - compatible = "st,stm32-timer"; - reg = <0x40000000 0x400>; - interrupts = <28>; - clocks = <&rcc 0 STM32F4_APB1_CLOCK(TIM2)>; - status = "disabled"; - }; - timers2: timers@40000000 { #address-cells = <1>; #size-cells = <0>; @@ -82,14 +74,6 @@ }; }; - timer3: timer@40000400 { - compatible = "st,stm32-timer"; - reg = <0x40000400 0x400>; - interrupts = <29>; - clocks = <&rcc 0 STM32F4_APB1_CLOCK(TIM3)>; - status = "disabled"; - }; - timers3: timers@40000400 { #address-cells = <1>; #size-cells = <0>; @@ -112,14 +96,6 @@ }; }; - timer4: timer@40000800 { - compatible = "st,stm32-timer"; - reg = <0x40000800 0x400>; - interrupts = <30>; - clocks = <&rcc 0 STM32F4_APB1_CLOCK(TIM4)>; - status = "disabled"; - }; - timers4: timers@40000800 { #address-cells = <1>; #size-cells = <0>; @@ -142,13 +118,6 @@ }; }; - timer5: timer@40000c00 { - compatible = "st,stm32-timer"; - reg = <0x40000c00 0x400>; - interrupts = <50>; - clocks = <&rcc 0 STM32F4_APB1_CLOCK(TIM5)>; - }; - timers5: timers@40000c00 { #address-cells = <1>; #size-cells = <0>; @@ -171,14 +140,6 @@ }; }; - timer6: timer@40001000 { - compatible = "st,stm32-timer"; - reg = <0x40001000 0x400>; - interrupts = <54>; - clocks = <&rcc 0 STM32F4_APB1_CLOCK(TIM6)>; - status = "disabled"; - }; - timers6: timers@40001000 { #address-cells = <1>; #size-cells = <0>; @@ -195,14 +156,6 @@ }; }; - timer7: timer@40001400 { - compatible = "st,stm32-timer"; - reg = <0x40001400 0x400>; - interrupts = <55>; - clocks = <&rcc 0 STM32F4_APB1_CLOCK(TIM7)>; - status = "disabled"; - }; - timers7: timers@40001400 { #address-cells = <1>; #size-cells = <0>; @@ -242,8 +195,6 @@ }; timers13: timers@40001c00 { - #address-cells = <1>; - #size-cells = <0>; compatible = "st,stm32-timers"; reg = <0x40001C00 0x400>; clocks = <&rcc 0 STM32F4_APB1_CLOCK(TIM13)>; @@ -258,8 +209,6 @@ }; timers14: timers@40002000 { - #address-cells = <1>; - #size-cells = <0>; compatible = "st,stm32-timers"; reg = <0x40002000 0x400>; clocks = <&rcc 0 STM32F4_APB1_CLOCK(TIM14)>; @@ -525,7 +474,7 @@ }; }; - sdio: sdio@40012c00 { + sdio: mmc@40012c00 { compatible = "arm,pl180", "arm,primecell"; arm,primecell-periphid = <0x00880180>; reg = <0x40012c00 0x400>; @@ -592,8 +541,6 @@ }; timers10: timers@40014400 { - #address-cells = <1>; - #size-cells = <0>; compatible = "st,stm32-timers"; reg = <0x40014400 0x400>; clocks = <&rcc 0 STM32F4_APB2_CLOCK(TIM10)>; @@ -608,8 +555,6 @@ }; timers11: timers@40014800 { - #address-cells = <1>; - #size-cells = <0>; compatible = "st,stm32-timers"; reg = <0x40014800 0x400>; clocks = <&rcc 0 STM32F4_APB2_CLOCK(TIM11)>; @@ -668,7 +613,7 @@ status = "disabled"; }; - rcc: rcc@40023810 { + rcc: rcc@40023800 { #reset-cells = <1>; #clock-cells = <2>; compatible = "st,stm32f42xx-rcc", "st,stm32-rcc"; @@ -726,6 +671,16 @@ status = "disabled"; }; + dma2d: dma2d@4002b000 { + compatible = "st,stm32-dma2d"; + reg = <0x4002b000 0xc00>; + interrupts = <90>; + resets = <&rcc STM32F4_AHB1_RESET(DMA2D)>; + clocks = <&rcc 0 STM32F4_AHB1_CLOCK(DMA2D)>; + clock-names = "dma2d"; + status = "disabled"; + }; + usbotg_hs: usb@40040000 { compatible = "snps,dwc2"; reg = <0x40040000 0x40000>; diff --git a/arch/arm/dts/stm32f469-disco-u-boot.dtsi b/arch/arm/dts/stm32f469-disco-u-boot.dtsi index cd173623ef..ee0c82b53e 100644 --- a/arch/arm/dts/stm32f469-disco-u-boot.dtsi +++ b/arch/arm/dts/stm32f469-disco-u-boot.dtsi @@ -28,9 +28,6 @@ soc { u-boot,dm-pre-reloc; - pin-controller { - u-boot,dm-pre-reloc; - }; fmc: fmc@A0000000 { compatible = "st,stm32-fmc"; @@ -138,6 +135,8 @@ }; &pinctrl { + u-boot,dm-pre-reloc; + fmc_pins_d32: fmc_d32@0 { u-boot,dm-pre-reloc; pins @@ -256,6 +255,6 @@ u-boot,dm-pre-reloc; }; -&timer5 { +&timers5 { u-boot,dm-pre-reloc; }; diff --git a/arch/arm/dts/stm32f469-disco.dts b/arch/arm/dts/stm32f469-disco.dts index 23d87ee27a..6e0ffc1903 100644 --- a/arch/arm/dts/stm32f469-disco.dts +++ b/arch/arm/dts/stm32f469-disco.dts @@ -19,7 +19,7 @@ stdout-path = "serial0:115200n8"; }; - memory@00000000 { + memory@0 { device_type = "memory"; reg = <0x00000000 0x1000000>; }; @@ -63,12 +63,10 @@ }; }; - gpio_keys { + gpio-keys { compatible = "gpio-keys"; - #address-cells = <1>; - #size-cells = <0>; autorepeat; - button@0 { + button-0 { label = "User"; linux,code = ; gpios = <&gpioa 0 GPIO_ACTIVE_HIGH>; @@ -93,6 +91,10 @@ clock-frequency = <8000000>; }; +&dma2d { + status = "okay"; +}; + &dsi { #address-cells = <1>; #size-cells = <0>; @@ -185,6 +187,18 @@ bus-width = <4>; }; +&timers5 { + /* Override timer5 to act as clockevent */ + compatible = "st,stm32-timer"; + interrupts = <50>; + status = "okay"; + /delete-property/#address-cells; + /delete-property/#size-cells; + /delete-property/clock-names; + /delete-node/pwm; + /delete-node/timer@4; +}; + &usart3 { pinctrl-0 = <&usart3_pins_a>; pinctrl-names = "default"; diff --git a/arch/arm/dts/stm32f469-pinctrl.dtsi b/arch/arm/dts/stm32f469-pinctrl.dtsi index 1e2bb0191e..0610407c7b 100644 --- a/arch/arm/dts/stm32f469-pinctrl.dtsi +++ b/arch/arm/dts/stm32f469-pinctrl.dtsi @@ -5,55 +5,51 @@ #include "stm32f4-pinctrl.dtsi" -/ { - soc { - pinctrl: pin-controller { - compatible = "st,stm32f469-pinctrl"; +&pinctrl { + compatible = "st,stm32f469-pinctrl"; - gpioa: gpio@40020000 { - gpio-ranges = <&pinctrl 0 0 16>; - }; + gpioa: gpio@40020000 { + gpio-ranges = <&pinctrl 0 0 16>; + }; - gpiob: gpio@40020400 { - gpio-ranges = <&pinctrl 0 16 16>; - }; + gpiob: gpio@40020400 { + gpio-ranges = <&pinctrl 0 16 16>; + }; - gpioc: gpio@40020800 { - gpio-ranges = <&pinctrl 0 32 16>; - }; + gpioc: gpio@40020800 { + gpio-ranges = <&pinctrl 0 32 16>; + }; - gpiod: gpio@40020c00 { - gpio-ranges = <&pinctrl 0 48 16>; - }; + gpiod: gpio@40020c00 { + gpio-ranges = <&pinctrl 0 48 16>; + }; - gpioe: gpio@40021000 { - gpio-ranges = <&pinctrl 0 64 16>; - }; + gpioe: gpio@40021000 { + gpio-ranges = <&pinctrl 0 64 16>; + }; - gpiof: gpio@40021400 { - gpio-ranges = <&pinctrl 0 80 16>; - }; + gpiof: gpio@40021400 { + gpio-ranges = <&pinctrl 0 80 16>; + }; - gpiog: gpio@40021800 { - gpio-ranges = <&pinctrl 0 96 16>; - }; + gpiog: gpio@40021800 { + gpio-ranges = <&pinctrl 0 96 16>; + }; - gpioh: gpio@40021c00 { - gpio-ranges = <&pinctrl 0 112 16>; - }; + gpioh: gpio@40021c00 { + gpio-ranges = <&pinctrl 0 112 16>; + }; - gpioi: gpio@40022000 { - gpio-ranges = <&pinctrl 0 128 16>; - }; + gpioi: gpio@40022000 { + gpio-ranges = <&pinctrl 0 128 16>; + }; - gpioj: gpio@40022400 { - gpio-ranges = <&pinctrl 0 144 6>, - <&pinctrl 12 156 4>; - }; + gpioj: gpio@40022400 { + gpio-ranges = <&pinctrl 0 144 6>, + <&pinctrl 12 156 4>; + }; - gpiok: gpio@40022800 { - gpio-ranges = <&pinctrl 3 163 5>; - }; - }; + gpiok: gpio@40022800 { + gpio-ranges = <&pinctrl 3 163 5>; }; }; diff --git a/arch/arm/dts/stm32f7-pinctrl.dtsi b/arch/arm/dts/stm32f7-pinctrl.dtsi index fe4cfda72a..8f37aefa73 100644 --- a/arch/arm/dts/stm32f7-pinctrl.dtsi +++ b/arch/arm/dts/stm32f7-pinctrl.dtsi @@ -9,7 +9,7 @@ / { soc { - pinctrl: pin-controller { + pinctrl: pinctrl@40020000 { #address-cells = <1>; #size-cells = <1>; ranges = <0 0x40020000 0x3000>; diff --git a/arch/arm/dts/stm32f7-u-boot.dtsi b/arch/arm/dts/stm32f7-u-boot.dtsi index c1b2ac25c3..0ba8031c33 100644 --- a/arch/arm/dts/stm32f7-u-boot.dtsi +++ b/arch/arm/dts/stm32f7-u-boot.dtsi @@ -119,7 +119,7 @@ u-boot,dm-pre-reloc; }; -&timer5 { +&timers5 { u-boot,dm-pre-reloc; }; diff --git a/arch/arm/dts/stm32f746-disco.dts b/arch/arm/dts/stm32f746-disco.dts index 9430dc08ec..1ed58f2361 100644 --- a/arch/arm/dts/stm32f746-disco.dts +++ b/arch/arm/dts/stm32f746-disco.dts @@ -73,6 +73,18 @@ bus-width = <4>; }; +&timers5 { + /* Override timer5 to act as clockevent */ + compatible = "st,stm32-timer"; + interrupts = <50>; + status = "okay"; + /delete-property/#address-cells; + /delete-property/#size-cells; + /delete-property/clock-names; + /delete-node/pwm; + /delete-node/timer@4; +}; + &usart1 { pinctrl-0 = <&usart1_pins_b>; pinctrl-names = "default"; diff --git a/arch/arm/dts/stm32f746.dtsi b/arch/arm/dts/stm32f746.dtsi index 78facde2b5..c97b3d0d07 100644 --- a/arch/arm/dts/stm32f746.dtsi +++ b/arch/arm/dts/stm32f746.dtsi @@ -39,14 +39,6 @@ }; soc { - timer2: timer@40000000 { - compatible = "st,stm32-timer"; - reg = <0x40000000 0x400>; - interrupts = <28>; - clocks = <&rcc 0 STM32F7_APB1_CLOCK(TIM2)>; - status = "disabled"; - }; - timers2: timers@40000000 { #address-cells = <1>; #size-cells = <0>; @@ -69,14 +61,6 @@ }; }; - timer3: timer@40000400 { - compatible = "st,stm32-timer"; - reg = <0x40000400 0x400>; - interrupts = <29>; - clocks = <&rcc 0 STM32F7_APB1_CLOCK(TIM3)>; - status = "disabled"; - }; - timers3: timers@40000400 { #address-cells = <1>; #size-cells = <0>; @@ -99,14 +83,6 @@ }; }; - timer4: timer@40000800 { - compatible = "st,stm32-timer"; - reg = <0x40000800 0x400>; - interrupts = <30>; - clocks = <&rcc 0 STM32F7_APB1_CLOCK(TIM4)>; - status = "disabled"; - }; - timers4: timers@40000800 { #address-cells = <1>; #size-cells = <0>; @@ -129,13 +105,6 @@ }; }; - timer5: timer@40000c00 { - compatible = "st,stm32-timer"; - reg = <0x40000c00 0x400>; - interrupts = <50>; - clocks = <&rcc 0 STM32F7_APB1_CLOCK(TIM5)>; - }; - timers5: timers@40000c00 { #address-cells = <1>; #size-cells = <0>; @@ -158,14 +127,6 @@ }; }; - timer6: timer@40001000 { - compatible = "st,stm32-timer"; - reg = <0x40001000 0x400>; - interrupts = <54>; - clocks = <&rcc 0 STM32F7_APB1_CLOCK(TIM6)>; - status = "disabled"; - }; - timers6: timers@40001000 { #address-cells = <1>; #size-cells = <0>; @@ -182,14 +143,6 @@ }; }; - timer7: timer@40001400 { - compatible = "st,stm32-timer"; - reg = <0x40001400 0x400>; - interrupts = <55>; - clocks = <&rcc 0 STM32F7_APB1_CLOCK(TIM7)>; - status = "disabled"; - }; - timers7: timers@40001400 { #address-cells = <1>; #size-cells = <0>; @@ -229,8 +182,6 @@ }; timers13: timers@40001c00 { - #address-cells = <1>; - #size-cells = <0>; compatible = "st,stm32-timers"; reg = <0x40001C00 0x400>; clocks = <&rcc 0 STM32F7_APB1_CLOCK(TIM13)>; @@ -245,8 +196,6 @@ }; timers14: timers@40002000 { - #address-cells = <1>; - #size-cells = <0>; compatible = "st,stm32-timers"; reg = <0x40002000 0x400>; clocks = <&rcc 0 STM32F7_APB1_CLOCK(TIM14)>; @@ -313,7 +262,6 @@ clocks = <&rcc 1 CLK_I2C1>; #address-cells = <1>; #size-cells = <0>; - i2c-analog-filter; status = "disabled"; }; @@ -326,20 +274,18 @@ clocks = <&rcc 1 CLK_I2C2>; #address-cells = <1>; #size-cells = <0>; - i2c-analog-filter; status = "disabled"; }; - i2c3: i2c@40005C00 { + i2c3: i2c@40005c00 { compatible = "st,stm32f7-i2c"; - reg = <0x40005C00 0x400>; + reg = <0x40005c00 0x400>; interrupts = <72>, <73>; resets = <&rcc STM32F7_APB1_RESET(I2C3)>; clocks = <&rcc 1 CLK_I2C3>; #address-cells = <1>; #size-cells = <0>; - i2c-analog-filter; status = "disabled"; }; @@ -352,7 +298,6 @@ clocks = <&rcc 1 CLK_I2C4>; #address-cells = <1>; #size-cells = <0>; - i2c-analog-filter; status = "disabled"; }; @@ -441,7 +386,7 @@ status = "disabled"; }; - sdio2: sdio2@40011c00 { + sdio2: mmc@40011c00 { compatible = "arm,pl180", "arm,primecell"; arm,primecell-periphid = <0x00880180>; reg = <0x40011c00 0x400>; @@ -452,7 +397,7 @@ status = "disabled"; }; - sdio1: sdio1@40012c00 { + sdio1: mmc@40012c00 { compatible = "arm,pl180", "arm,primecell"; arm,primecell-periphid = <0x00880180>; reg = <0x40012c00 0x400>; @@ -499,8 +444,6 @@ }; timers10: timers@40014400 { - #address-cells = <1>; - #size-cells = <0>; compatible = "st,stm32-timers"; reg = <0x40014400 0x400>; clocks = <&rcc 0 STM32F7_APB2_CLOCK(TIM10)>; @@ -515,8 +458,6 @@ }; timers11: timers@40014800 { - #address-cells = <1>; - #size-cells = <0>; compatible = "st,stm32-timers"; reg = <0x40014800 0x400>; clocks = <&rcc 0 STM32F7_APB2_CLOCK(TIM11)>; diff --git a/arch/arm/dts/stm32f769-disco.dts b/arch/arm/dts/stm32f769-disco.dts index 03cfbd7cc2..6f93fc7bcf 100644 --- a/arch/arm/dts/stm32f769-disco.dts +++ b/arch/arm/dts/stm32f769-disco.dts @@ -39,12 +39,10 @@ }; }; - gpio_keys { + gpio-keys { compatible = "gpio-keys"; - #address-cells = <1>; - #size-cells = <0>; autorepeat; - button@0 { + button-0 { label = "User"; linux,code = ; gpios = <&gpioa 0 GPIO_ACTIVE_HIGH>; @@ -103,6 +101,18 @@ bus-width = <4>; }; +&timers5 { + /* Override timer5 to act as clockevent */ + compatible = "st,stm32-timer"; + interrupts = <50>; + status = "okay"; + /delete-property/#address-cells; + /delete-property/#size-cells; + /delete-property/clock-names; + /delete-node/pwm; + /delete-node/timer@4; +}; + &usart1 { pinctrl-0 = <&usart1_pins_a>; pinctrl-names = "default"; diff --git a/arch/arm/dts/stm32h743.dtsi b/arch/arm/dts/stm32h743.dtsi index dbfebf07f2..ceb629c4fa 100644 --- a/arch/arm/dts/stm32h743.dtsi +++ b/arch/arm/dts/stm32h743.dtsi @@ -124,7 +124,6 @@ <32>; resets = <&rcc STM32H7_APB1L_RESET(I2C1)>; clocks = <&rcc I2C1_CK>; - i2c-analog-filter; status = "disabled"; }; @@ -137,7 +136,6 @@ <34>; resets = <&rcc STM32H7_APB1L_RESET(I2C2)>; clocks = <&rcc I2C2_CK>; - i2c-analog-filter; status = "disabled"; }; @@ -150,7 +148,6 @@ <73>; resets = <&rcc STM32H7_APB1L_RESET(I2C3)>; clocks = <&rcc I2C3_CK>; - i2c-analog-filter; status = "disabled"; }; @@ -337,12 +334,12 @@ dma-requests = <32>; }; - sdmmc1: sdmmc@52007000 { + sdmmc1: mmc@52007000 { compatible = "arm,pl18x", "arm,primecell"; arm,primecell-periphid = <0x10153180>; reg = <0x52007000 0x1000>; interrupts = <49>; - interrupt-names = "cmd_irq"; + interrupt-names = "cmd_irq"; clocks = <&rcc SDMMC1_CK>; clock-names = "apb_pclk"; resets = <&rcc STM32H7_AHB3_RESET(SDMMC1)>; @@ -351,18 +348,19 @@ max-frequency = <120000000>; }; - sdmmc2: sdmmc@48022400 { + sdmmc2: mmc@48022400 { compatible = "arm,pl18x", "arm,primecell"; arm,primecell-periphid = <0x10153180>; reg = <0x48022400 0x400>; interrupts = <124>; - interrupt-names = "cmd_irq"; + interrupt-names = "cmd_irq"; clocks = <&rcc SDMMC2_CK>; clock-names = "apb_pclk"; resets = <&rcc STM32H7_AHB2_RESET(SDMMC2)>; cap-sd-highspeed; cap-mmc-highspeed; max-frequency = <120000000>; + status = "disabled"; }; exti: interrupt-controller@58000000 { @@ -398,7 +396,6 @@ <96>; resets = <&rcc STM32H7_APB4_RESET(I2C4)>; clocks = <&rcc I2C4_CK>; - i2c-analog-filter; status = "disabled"; }; @@ -452,8 +449,6 @@ }; lptimer4: timer@58002c00 { - #address-cells = <1>; - #size-cells = <0>; compatible = "st,stm32-lptimer"; reg = <0x58002c00 0x400>; clocks = <&rcc LPTIM4_CK>; @@ -468,8 +463,6 @@ }; lptimer5: timer@58003000 { - #address-cells = <1>; - #size-cells = <0>; compatible = "st,stm32-lptimer"; reg = <0x58003000 0x400>; clocks = <&rcc LPTIM5_CK>; @@ -554,7 +547,7 @@ status = "disabled"; }; - pinctrl: pin-controller@58020000 { + pinctrl: pinctrl@58020000 { #address-cells = <1>; #size-cells = <1>; compatible = "st,stm32h743-pinctrl"; diff --git a/arch/arm/dts/stm32h743i-disco.dts b/arch/arm/dts/stm32h743i-disco.dts index 3a01ebd563..b31188f8b9 100644 --- a/arch/arm/dts/stm32h743i-disco.dts +++ b/arch/arm/dts/stm32h743i-disco.dts @@ -41,10 +41,10 @@ &mac { status = "disabled"; - pinctrl-0 = <ðernet_rmii>; - pinctrl-names = "default"; - phy-mode = "rmii"; - phy-handle = <&phy0>; + pinctrl-0 = <ðernet_rmii>; + pinctrl-names = "default"; + phy-mode = "rmii"; + phy-handle = <&phy0>; mdio0 { #address-cells = <1>; diff --git a/arch/arm/dts/stm32h743i-eval.dts b/arch/arm/dts/stm32h743i-eval.dts index 38cc7faf68..5c5d8059bd 100644 --- a/arch/arm/dts/stm32h743i-eval.dts +++ b/arch/arm/dts/stm32h743i-eval.dts @@ -115,10 +115,10 @@ &mac { status = "disabled"; - pinctrl-0 = <ðernet_rmii>; - pinctrl-names = "default"; - phy-mode = "rmii"; - phy-handle = <&phy0>; + pinctrl-0 = <ðernet_rmii>; + pinctrl-names = "default"; + phy-mode = "rmii"; + phy-handle = <&phy0>; mdio0 { #address-cells = <1>; diff --git a/arch/arm/dts/stm32h750i-art-pi.dts b/arch/arm/dts/stm32h750i-art-pi.dts index 2a4d1cb496..c7c7132f22 100644 --- a/arch/arm/dts/stm32h750i-art-pi.dts +++ b/arch/arm/dts/stm32h750i-art-pi.dts @@ -87,10 +87,10 @@ &mac { status = "disabled"; - pinctrl-0 = <ðernet_rmii>; - pinctrl-names = "default"; - phy-mode = "rmii"; - phy-handle = <&phy0>; + pinctrl-0 = <ðernet_rmii>; + pinctrl-names = "default"; + phy-mode = "rmii"; + phy-handle = <&phy0>; mdio0 { #address-cells = <1>; From 6ee64732b1cc5a1a87e782d1c53dba3ec21cf6e4 Mon Sep 17 00:00:00 2001 From: Patrice Chotard Date: Tue, 20 Sep 2022 18:04:30 +0200 Subject: [PATCH 322/374] configs: stm32f746-disco: Fix SPL boot Commit 'b4b9a00ed593 ("Convert CONFIG_SYS_SPL_ARGS_ADDR to Kconfig")' replaces CONFIG_SYS_FDT_BASE by CONFIG_SYS_SPL_ARGS_ADDR. As CONFIG_SYS_SPL_ARGS_ADDR enables additional code when enable, it increases SPL size over the initial 0x8000 limit. Increase the SPL size to 0x9000 to fix SPL boot. Set SPL_SIZE_LIMIT to 0x9000 to avoid similar issue in the future. Fixes 'b4b9a00ed593 ("Convert CONFIG_SYS_SPL_ARGS_ADDR to Kconfig")' Signed-off-by: Patrice Chotard Reviewed-by: Patrick Delaunay Tested-by: Waldemar Brodkorb --- configs/stm32f746-disco_spl_defconfig | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/configs/stm32f746-disco_spl_defconfig b/configs/stm32f746-disco_spl_defconfig index e7b1acc433..5e8a8aaf3c 100644 --- a/configs/stm32f746-disco_spl_defconfig +++ b/configs/stm32f746-disco_spl_defconfig @@ -1,6 +1,6 @@ CONFIG_ARM=y CONFIG_ARCH_STM32=y -CONFIG_SYS_TEXT_BASE=0x08008000 +CONFIG_SYS_TEXT_BASE=0x08009000 CONFIG_SYS_MALLOC_LEN=0x100000 CONFIG_SYS_MALLOC_F_LEN=0xE00 CONFIG_SPL_GPIO=y @@ -13,10 +13,11 @@ CONFIG_SPL_TEXT_BASE=0x8000000 CONFIG_SYS_PROMPT="U-Boot > " CONFIG_SPL_SERIAL=y CONFIG_SPL_DRIVERS_MISC=y +CONFIG_SPL_SIZE_LIMIT=0x9000 CONFIG_STM32F7=y CONFIG_TARGET_STM32F746_DISCO=y CONFIG_SPL=y -CONFIG_SYS_LOAD_ADDR=0x8008000 +CONFIG_SYS_LOAD_ADDR=0x8009000 CONFIG_BUILD_TARGET="u-boot-with-spl.bin" CONFIG_DISTRO_DEFAULTS=y CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y @@ -29,7 +30,7 @@ CONFIG_USE_BOOTARGS=y CONFIG_BOOTARGS="console=ttyS0,115200 earlyprintk consoleblank=0 ignore_loglevel" # CONFIG_DISPLAY_CPUINFO is not set CONFIG_BOARD_LATE_INIT=y -CONFIG_SPL_PAD_TO=0x8000 +CONFIG_SPL_PAD_TO=0x9000 CONFIG_SPL_NO_BSS_LIMIT=y CONFIG_SPL_BOARD_INIT=y CONFIG_SPL_SYS_MALLOC_SIMPLE=y From c8b577ce829191ec61a785f816453de184253635 Mon Sep 17 00:00:00 2001 From: Patrice Chotard Date: Tue, 20 Sep 2022 18:04:31 +0200 Subject: [PATCH 323/374] configs: stm32f769-disco: Fix SPL boot Commit 'b4b9a00ed593 ("Convert CONFIG_SYS_SPL_ARGS_ADDR to Kconfig")' replaces CONFIG_SYS_FDT_BASE by CONFIG_SYS_SPL_ARGS_ADDR. As CONFIG_SYS_SPL_ARGS_ADDR enables additional code when enable, it increases SPL size over the initial 0x8000 limit. Increase the SPL size to 0x9000 to fix SPL boot. Set SPL_SIZE_LIMIT to 0x9000 to avoid similar issue in the future. Fixes 'b4b9a00ed593 ("Convert CONFIG_SYS_SPL_ARGS_ADDR to Kconfig")' Signed-off-by: Patrice Chotard Reviewed-by: Patrick Delaunay Tested-by: Waldemar Brodkorb --- configs/stm32f769-disco_spl_defconfig | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/configs/stm32f769-disco_spl_defconfig b/configs/stm32f769-disco_spl_defconfig index 19d2c24abb..b56d88f9f6 100644 --- a/configs/stm32f769-disco_spl_defconfig +++ b/configs/stm32f769-disco_spl_defconfig @@ -1,6 +1,6 @@ CONFIG_ARM=y CONFIG_ARCH_STM32=y -CONFIG_SYS_TEXT_BASE=0x08008000 +CONFIG_SYS_TEXT_BASE=0x08009000 CONFIG_SYS_MALLOC_LEN=0x100000 CONFIG_SYS_MALLOC_F_LEN=0xE00 CONFIG_SPL_GPIO=y @@ -13,10 +13,11 @@ CONFIG_SPL_TEXT_BASE=0x8000000 CONFIG_SYS_PROMPT="U-Boot > " CONFIG_SPL_SERIAL=y CONFIG_SPL_DRIVERS_MISC=y +CONFIG_SPL_SIZE_LIMIT=0x9000 CONFIG_STM32F7=y CONFIG_TARGET_STM32F746_DISCO=y CONFIG_SPL=y -CONFIG_SYS_LOAD_ADDR=0x8008000 +CONFIG_SYS_LOAD_ADDR=0x8009000 CONFIG_BUILD_TARGET="u-boot-with-spl.bin" CONFIG_DISTRO_DEFAULTS=y CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y @@ -28,7 +29,7 @@ CONFIG_AUTOBOOT_STOP_STR=" " CONFIG_USE_BOOTARGS=y CONFIG_BOOTARGS="console=ttyS0,115200 earlyprintk consoleblank=0 ignore_loglevel" # CONFIG_DISPLAY_CPUINFO is not set -CONFIG_SPL_PAD_TO=0x8000 +CONFIG_SPL_PAD_TO=0x9000 CONFIG_SPL_NO_BSS_LIMIT=y CONFIG_SPL_BOARD_INIT=y CONFIG_SPL_SYS_MALLOC_SIMPLE=y From 4f174e6ffab693510a9ac23c873017423f8d017e Mon Sep 17 00:00:00 2001 From: Patrice Chotard Date: Tue, 20 Sep 2022 18:04:32 +0200 Subject: [PATCH 324/374] configs: stm32746g-eval: Fix SPL boot Commit 'b4b9a00ed593 ("Convert CONFIG_SYS_SPL_ARGS_ADDR to Kconfig")' replaces CONFIG_SYS_FDT_BASE by CONFIG_SYS_SPL_ARGS_ADDR. As CONFIG_SYS_SPL_ARGS_ADDR enables additional code when enable, it increases SPL size over the initial 0x8000 limit. Increase the SPL size to 0x9000 to fix SPL boot. Set SPL_SIZE_LIMIT to 0x9000 to avoid similar issue in the future. Fixes 'b4b9a00ed593 ("Convert CONFIG_SYS_SPL_ARGS_ADDR to Kconfig")' Signed-off-by: Patrice Chotard Reviewed-by: Patrick Delaunay Tested-by: Waldemar Brodkorb --- configs/stm32746g-eval_spl_defconfig | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/configs/stm32746g-eval_spl_defconfig b/configs/stm32746g-eval_spl_defconfig index a3b7146454..d8d55c2d3c 100644 --- a/configs/stm32746g-eval_spl_defconfig +++ b/configs/stm32746g-eval_spl_defconfig @@ -1,6 +1,6 @@ CONFIG_ARM=y CONFIG_ARCH_STM32=y -CONFIG_SYS_TEXT_BASE=0x08008000 +CONFIG_SYS_TEXT_BASE=0x08009000 CONFIG_SYS_MALLOC_LEN=0x100000 CONFIG_SYS_MALLOC_F_LEN=0xE00 CONFIG_SPL_GPIO=y @@ -13,10 +13,11 @@ CONFIG_SPL_TEXT_BASE=0x8000000 CONFIG_SYS_PROMPT="U-Boot > " CONFIG_SPL_SERIAL=y CONFIG_SPL_DRIVERS_MISC=y +CONFIG_SPL_SIZE_LIMIT=0x9000 CONFIG_STM32F7=y CONFIG_TARGET_STM32F746_DISCO=y CONFIG_SPL=y -CONFIG_SYS_LOAD_ADDR=0x8008000 +CONFIG_SYS_LOAD_ADDR=0x8009000 CONFIG_BUILD_TARGET="u-boot-with-spl.bin" CONFIG_DISTRO_DEFAULTS=y CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y @@ -29,7 +30,7 @@ CONFIG_USE_BOOTARGS=y CONFIG_BOOTARGS="console=ttyS0,115200 earlyprintk consoleblank=0 ignore_loglevel" # CONFIG_DISPLAY_CPUINFO is not set CONFIG_BOARD_LATE_INIT=y -CONFIG_SPL_PAD_TO=0x8000 +CONFIG_SPL_PAD_TO=0x9000 CONFIG_SPL_NO_BSS_LIMIT=y CONFIG_SPL_BOARD_INIT=y CONFIG_SPL_SYS_MALLOC_SIMPLE=y From 4b2bcca5c37720c5c905022f4dcbb5a054267d7c Mon Sep 17 00:00:00 2001 From: Patrice Chotard Date: Tue, 20 Sep 2022 18:04:33 +0200 Subject: [PATCH 325/374] configs: stm32f746-disco: Fix CONFIG_SYS_SPL_ARGS_ADDR STM32F746 embeds 1 MB of internal flash [0x08000000-0x080fffff], fix CONFIG_SYS_SPL_ARGS_ADDR accordingly It solves hard fault when jumping from SPL to U-Boot. Signed-off-by: Patrice Chotard Reviewed-by: Patrick Delaunay Tested-by: Waldemar Brodkorb --- configs/stm32f746-disco_spl_defconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configs/stm32f746-disco_spl_defconfig b/configs/stm32f746-disco_spl_defconfig index 5e8a8aaf3c..d4a65bde24 100644 --- a/configs/stm32f746-disco_spl_defconfig +++ b/configs/stm32f746-disco_spl_defconfig @@ -36,7 +36,7 @@ CONFIG_SPL_BOARD_INIT=y CONFIG_SPL_SYS_MALLOC_SIMPLE=y CONFIG_SPL_MTD_SUPPORT=y CONFIG_SPL_XIP_SUPPORT=y -CONFIG_SYS_SPL_ARGS_ADDR=0x81c0000 +CONFIG_SYS_SPL_ARGS_ADDR=0x80c0000 CONFIG_SPL_DM_RESET=y CONFIG_SYS_PBSIZE=1050 CONFIG_CMD_GPT=y From ab5c4e5b0f34b4341dcb17c5234c08130bd251c2 Mon Sep 17 00:00:00 2001 From: Patrice Chotard Date: Tue, 20 Sep 2022 18:04:34 +0200 Subject: [PATCH 326/374] configs: stm32746g-eval: Fix CONFIG_SYS_SPL_ARGS_ADDR STM32F746 embeds 1 MB of internal flash [0x08000000-0x080fffff], fix CONFIG_SYS_SPL_ARGS_ADDR accordingly It solves hard fault when jumping from SPL to U-Boot. Signed-off-by: Patrice Chotard Reviewed-by: Patrick Delaunay Tested-by: Waldemar Brodkorb --- configs/stm32746g-eval_spl_defconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configs/stm32746g-eval_spl_defconfig b/configs/stm32746g-eval_spl_defconfig index d8d55c2d3c..28f522b15e 100644 --- a/configs/stm32746g-eval_spl_defconfig +++ b/configs/stm32746g-eval_spl_defconfig @@ -36,7 +36,7 @@ CONFIG_SPL_BOARD_INIT=y CONFIG_SPL_SYS_MALLOC_SIMPLE=y CONFIG_SPL_MTD_SUPPORT=y CONFIG_SPL_XIP_SUPPORT=y -CONFIG_SYS_SPL_ARGS_ADDR=0x81c0000 +CONFIG_SYS_SPL_ARGS_ADDR=0x80c0000 CONFIG_SPL_DM_RESET=y CONFIG_SYS_PBSIZE=1050 CONFIG_CMD_GPT=y From 3cc471d30a1f7b47f0c9d2bd9874097d4b226659 Mon Sep 17 00:00:00 2001 From: Patrice Chotard Date: Tue, 20 Sep 2022 18:04:35 +0200 Subject: [PATCH 327/374] configs: stm32f769-disco: Fix internal flash size arch-stm32f7/stm32.h file is shared between STM32F746 and STM32F769 MCUs. But STM32F769 embeds 2MB of internal flash instead of 1MB for STM32F746. The flash layout is quite similar between the 2 SoCs : STM32F746 STM32F769 4 * 32KB sectors 4 * 32KB sectors 1 * 128KB sector 1 * 128KB sector 3 * 256KB sectors 7 * 256KB sectors Update sect_sz_kb[] structure and SYS_MAX_FLASH_SECT accordingly. Signed-off-by: Patrice Chotard Reviewed-by: Patrick Delaunay Tested-by: Waldemar Brodkorb --- arch/arm/include/asm/arch-stm32f7/stm32.h | 6 +++--- configs/stm32f769-disco_defconfig | 2 +- configs/stm32f769-disco_spl_defconfig | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/arch/arm/include/asm/arch-stm32f7/stm32.h b/arch/arm/include/asm/arch-stm32f7/stm32.h index 3451e74a3d..57db839e8d 100644 --- a/arch/arm/include/asm/arch-stm32f7/stm32.h +++ b/arch/arm/include/asm/arch-stm32f7/stm32.h @@ -10,9 +10,9 @@ #include static const u32 sect_sz_kb[CONFIG_SYS_MAX_FLASH_SECT] = { - [0 ... 3] = 32 * 1024, - [4] = 128 * 1024, - [5 ... 7] = 256 * 1024 + [0 ... 3] = 32 * 1024, + [4] = 128 * 1024, + [5 ... CONFIG_SYS_MAX_FLASH_SECT - 1] = 256 * 1024 }; #endif /* _ASM_ARCH_HARDWARE_H */ diff --git a/configs/stm32f769-disco_defconfig b/configs/stm32f769-disco_defconfig index 423af7446a..5b5307ca1d 100644 --- a/configs/stm32f769-disco_defconfig +++ b/configs/stm32f769-disco_defconfig @@ -41,7 +41,7 @@ CONFIG_MTD=y CONFIG_DM_MTD=y CONFIG_MTD_NOR_FLASH=y CONFIG_STM32_FLASH=y -CONFIG_SYS_MAX_FLASH_SECT=8 +CONFIG_SYS_MAX_FLASH_SECT=12 CONFIG_DM_SPI_FLASH=y CONFIG_SPI_FLASH_MACRONIX=y CONFIG_SPI_FLASH_STMICRO=y diff --git a/configs/stm32f769-disco_spl_defconfig b/configs/stm32f769-disco_spl_defconfig index b56d88f9f6..b5d54b48ec 100644 --- a/configs/stm32f769-disco_spl_defconfig +++ b/configs/stm32f769-disco_spl_defconfig @@ -63,7 +63,7 @@ CONFIG_MTD=y CONFIG_DM_MTD=y CONFIG_MTD_NOR_FLASH=y CONFIG_STM32_FLASH=y -CONFIG_SYS_MAX_FLASH_SECT=8 +CONFIG_SYS_MAX_FLASH_SECT=12 CONFIG_DM_SPI_FLASH=y CONFIG_SPI_FLASH_MACRONIX=y CONFIG_SPI_FLASH_STMICRO=y From 2b5dee9485eb52875df801a414838d75b000604d Mon Sep 17 00:00:00 2001 From: Patrice Chotard Date: Tue, 20 Sep 2022 18:04:36 +0200 Subject: [PATCH 328/374] configs: stm32f746-disco: Remove CONFIG_SYS_UBOOT_START flag By pressing "c" key during SPL execution, we force U-boot execution instead of a kernel XIP image. This fixes a hard fault when booting stm32f746-disco in SPL with "c" key pressed during SPL execution. U-Boot SPL 2022.10-rc5-00009-g40d02baa91 (Sep 20 2022 - 17:21:21 +0200) Trying to boot from XIP Hard fault pc : 080083fc lr : 08000d1b xPSR : 21000000 r12 : 2004f108 r3 : 080083fd r2 : 00000028 r1 : 2004f0c8 r0 : 2004f0e4 Resetting CPU ... This is due to SYS_UBOOT_START flag set to 0x080083FD which is not correct. If unset, SYS_UBOOT_START is set by default to CONFIG_SYS_TEXT_BASE which match with our requirement. Signed-off-by: Patrice Chotard Reviewed-by: Patrick Delaunay Tested-by: Waldemar Brodkorb --- include/configs/stm32f746-disco.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/configs/stm32f746-disco.h b/include/configs/stm32f746-disco.h index 64c1bc7d43..b0ec226114 100644 --- a/include/configs/stm32f746-disco.h +++ b/include/configs/stm32f746-disco.h @@ -34,7 +34,6 @@ BOOTENV #define CONFIG_SYS_MONITOR_LEN (512 * 1024) -#define CONFIG_SYS_UBOOT_START 0x080083FD #define CONFIG_SYS_UBOOT_BASE (CONFIG_SYS_FLASH_BASE + \ CONFIG_SPL_PAD_TO) From 762d410e0db94c41b8d7f1ec85e47f7474655ad8 Mon Sep 17 00:00:00 2001 From: Patrice Chotard Date: Mon, 26 Sep 2022 17:59:36 +0200 Subject: [PATCH 329/374] configs: increase SYS_MALLOC_F_LEN for STM32 MCU's board Some STM32 MCU's board need their SYS_MALLOC_F_LEN value enlarged to avoid the "alloc space exhausted" error message during their boot process. Use the default SYS_MALLOC_F_LEN value which is set to 0x2000 in Kconfig. Signed-off-by: Patrice Chotard Reviewed-by: Patrick Delaunay --- configs/stm32746g-eval_defconfig | 1 - configs/stm32746g-eval_spl_defconfig | 1 - configs/stm32f429-discovery_defconfig | 1 - configs/stm32f429-evaluation_defconfig | 1 - configs/stm32f469-discovery_defconfig | 1 - configs/stm32f746-disco_defconfig | 1 - configs/stm32f746-disco_spl_defconfig | 1 - configs/stm32f769-disco_defconfig | 1 - configs/stm32f769-disco_spl_defconfig | 1 - configs/stm32h743-disco_defconfig | 1 - configs/stm32h743-eval_defconfig | 1 - configs/stm32h750-art-pi_defconfig | 1 - 12 files changed, 12 deletions(-) diff --git a/configs/stm32746g-eval_defconfig b/configs/stm32746g-eval_defconfig index 58232a7114..7200446d28 100644 --- a/configs/stm32746g-eval_defconfig +++ b/configs/stm32746g-eval_defconfig @@ -2,7 +2,6 @@ CONFIG_ARM=y CONFIG_ARCH_STM32=y CONFIG_SYS_TEXT_BASE=0x08000000 CONFIG_SYS_MALLOC_LEN=0x100000 -CONFIG_SYS_MALLOC_F_LEN=0xE00 CONFIG_NR_DRAM_BANKS=1 CONFIG_ENV_SIZE=0x2000 CONFIG_DEFAULT_DEVICE_TREE="stm32746g-eval" diff --git a/configs/stm32746g-eval_spl_defconfig b/configs/stm32746g-eval_spl_defconfig index 28f522b15e..ff42952a76 100644 --- a/configs/stm32746g-eval_spl_defconfig +++ b/configs/stm32746g-eval_spl_defconfig @@ -2,7 +2,6 @@ CONFIG_ARM=y CONFIG_ARCH_STM32=y CONFIG_SYS_TEXT_BASE=0x08009000 CONFIG_SYS_MALLOC_LEN=0x100000 -CONFIG_SYS_MALLOC_F_LEN=0xE00 CONFIG_SPL_GPIO=y CONFIG_SPL_LIBCOMMON_SUPPORT=y CONFIG_SPL_LIBGENERIC_SUPPORT=y diff --git a/configs/stm32f429-discovery_defconfig b/configs/stm32f429-discovery_defconfig index e6e595d495..914ac14641 100644 --- a/configs/stm32f429-discovery_defconfig +++ b/configs/stm32f429-discovery_defconfig @@ -2,7 +2,6 @@ CONFIG_ARM=y CONFIG_ARCH_STM32=y CONFIG_SYS_TEXT_BASE=0x08000000 CONFIG_SYS_MALLOC_LEN=0x0200000 -CONFIG_SYS_MALLOC_F_LEN=0xF00 CONFIG_NR_DRAM_BANKS=1 CONFIG_ENV_SIZE=0x2000 CONFIG_ENV_SECT_SIZE=0x20000 diff --git a/configs/stm32f429-evaluation_defconfig b/configs/stm32f429-evaluation_defconfig index 073f27168a..af7a8bf076 100644 --- a/configs/stm32f429-evaluation_defconfig +++ b/configs/stm32f429-evaluation_defconfig @@ -2,7 +2,6 @@ CONFIG_ARM=y CONFIG_ARCH_STM32=y CONFIG_SYS_TEXT_BASE=0x08000000 CONFIG_SYS_MALLOC_LEN=0x100000 -CONFIG_SYS_MALLOC_F_LEN=0xF00 CONFIG_NR_DRAM_BANKS=1 CONFIG_ENV_SIZE=0x2000 CONFIG_DEFAULT_DEVICE_TREE="stm32429i-eval" diff --git a/configs/stm32f469-discovery_defconfig b/configs/stm32f469-discovery_defconfig index bd3693275e..90680fdb05 100644 --- a/configs/stm32f469-discovery_defconfig +++ b/configs/stm32f469-discovery_defconfig @@ -2,7 +2,6 @@ CONFIG_ARM=y CONFIG_ARCH_STM32=y CONFIG_SYS_TEXT_BASE=0x08000000 CONFIG_SYS_MALLOC_LEN=0x100000 -CONFIG_SYS_MALLOC_F_LEN=0xF00 CONFIG_NR_DRAM_BANKS=1 CONFIG_ENV_SIZE=0x2000 CONFIG_DEFAULT_DEVICE_TREE="stm32f469-disco" diff --git a/configs/stm32f746-disco_defconfig b/configs/stm32f746-disco_defconfig index ed537b0578..a8edf11b40 100644 --- a/configs/stm32f746-disco_defconfig +++ b/configs/stm32f746-disco_defconfig @@ -2,7 +2,6 @@ CONFIG_ARM=y CONFIG_ARCH_STM32=y CONFIG_SYS_TEXT_BASE=0x08000000 CONFIG_SYS_MALLOC_LEN=0x100000 -CONFIG_SYS_MALLOC_F_LEN=0xE00 CONFIG_NR_DRAM_BANKS=1 CONFIG_ENV_SIZE=0x2000 CONFIG_DEFAULT_DEVICE_TREE="stm32f746-disco" diff --git a/configs/stm32f746-disco_spl_defconfig b/configs/stm32f746-disco_spl_defconfig index d4a65bde24..0e358e86ff 100644 --- a/configs/stm32f746-disco_spl_defconfig +++ b/configs/stm32f746-disco_spl_defconfig @@ -2,7 +2,6 @@ CONFIG_ARM=y CONFIG_ARCH_STM32=y CONFIG_SYS_TEXT_BASE=0x08009000 CONFIG_SYS_MALLOC_LEN=0x100000 -CONFIG_SYS_MALLOC_F_LEN=0xE00 CONFIG_SPL_GPIO=y CONFIG_SPL_LIBCOMMON_SUPPORT=y CONFIG_SPL_LIBGENERIC_SUPPORT=y diff --git a/configs/stm32f769-disco_defconfig b/configs/stm32f769-disco_defconfig index 5b5307ca1d..3e7b5bd06e 100644 --- a/configs/stm32f769-disco_defconfig +++ b/configs/stm32f769-disco_defconfig @@ -2,7 +2,6 @@ CONFIG_ARM=y CONFIG_ARCH_STM32=y CONFIG_SYS_TEXT_BASE=0x08000000 CONFIG_SYS_MALLOC_LEN=0x100000 -CONFIG_SYS_MALLOC_F_LEN=0xE00 CONFIG_NR_DRAM_BANKS=1 CONFIG_ENV_SIZE=0x2000 CONFIG_DEFAULT_DEVICE_TREE="stm32f769-disco" diff --git a/configs/stm32f769-disco_spl_defconfig b/configs/stm32f769-disco_spl_defconfig index b5d54b48ec..f0a1b667b8 100644 --- a/configs/stm32f769-disco_spl_defconfig +++ b/configs/stm32f769-disco_spl_defconfig @@ -2,7 +2,6 @@ CONFIG_ARM=y CONFIG_ARCH_STM32=y CONFIG_SYS_TEXT_BASE=0x08009000 CONFIG_SYS_MALLOC_LEN=0x100000 -CONFIG_SYS_MALLOC_F_LEN=0xE00 CONFIG_SPL_GPIO=y CONFIG_SPL_LIBCOMMON_SUPPORT=y CONFIG_SPL_LIBGENERIC_SUPPORT=y diff --git a/configs/stm32h743-disco_defconfig b/configs/stm32h743-disco_defconfig index d33da43065..8c62c70a57 100644 --- a/configs/stm32h743-disco_defconfig +++ b/configs/stm32h743-disco_defconfig @@ -2,7 +2,6 @@ CONFIG_ARM=y CONFIG_ARCH_STM32=y CONFIG_SYS_TEXT_BASE=0x08000000 CONFIG_SYS_MALLOC_LEN=0x100000 -CONFIG_SYS_MALLOC_F_LEN=0xF00 CONFIG_NR_DRAM_BANKS=1 CONFIG_ENV_SIZE=0x2000 CONFIG_DEFAULT_DEVICE_TREE="stm32h743i-disco" diff --git a/configs/stm32h743-eval_defconfig b/configs/stm32h743-eval_defconfig index a72de48690..1ff6b50819 100644 --- a/configs/stm32h743-eval_defconfig +++ b/configs/stm32h743-eval_defconfig @@ -2,7 +2,6 @@ CONFIG_ARM=y CONFIG_ARCH_STM32=y CONFIG_SYS_TEXT_BASE=0x08000000 CONFIG_SYS_MALLOC_LEN=0x100000 -CONFIG_SYS_MALLOC_F_LEN=0xF00 CONFIG_NR_DRAM_BANKS=1 CONFIG_ENV_SIZE=0x2000 CONFIG_DEFAULT_DEVICE_TREE="stm32h743i-eval" diff --git a/configs/stm32h750-art-pi_defconfig b/configs/stm32h750-art-pi_defconfig index b8296a98b4..a5fce5e866 100644 --- a/configs/stm32h750-art-pi_defconfig +++ b/configs/stm32h750-art-pi_defconfig @@ -2,7 +2,6 @@ CONFIG_ARM=y CONFIG_ARCH_STM32=y CONFIG_SYS_TEXT_BASE=0x90000000 CONFIG_SYS_MALLOC_LEN=0x100000 -CONFIG_SYS_MALLOC_F_LEN=0xF00 CONFIG_NR_DRAM_BANKS=1 CONFIG_ENV_SIZE=0x2000 CONFIG_DEFAULT_DEVICE_TREE="stm32h750i-art-pi" From c56b2bb9b9fcdd0c9ff2a76e34495b58bd98559a Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 6 Sep 2022 20:26:49 -0600 Subject: [PATCH 330/374] image: Fix BOOTM_STATE values Tidy up the code style for these. Signed-off-by: Simon Glass --- include/image.h | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/include/image.h b/include/image.h index 03424f0521..80e58559d0 100644 --- a/include/image.h +++ b/include/image.h @@ -341,18 +341,18 @@ typedef struct bootm_headers { int verify; /* env_get("verify")[0] != 'n' */ -#define BOOTM_STATE_START (0x00000001) -#define BOOTM_STATE_FINDOS (0x00000002) -#define BOOTM_STATE_FINDOTHER (0x00000004) -#define BOOTM_STATE_LOADOS (0x00000008) -#define BOOTM_STATE_RAMDISK (0x00000010) -#define BOOTM_STATE_FDT (0x00000020) -#define BOOTM_STATE_OS_CMDLINE (0x00000040) -#define BOOTM_STATE_OS_BD_T (0x00000080) -#define BOOTM_STATE_OS_PREP (0x00000100) -#define BOOTM_STATE_OS_FAKE_GO (0x00000200) /* 'Almost' run the OS */ -#define BOOTM_STATE_OS_GO (0x00000400) -#define BOOTM_STATE_PRE_LOAD 0x00000800 +#define BOOTM_STATE_START 0x00000001 +#define BOOTM_STATE_FINDOS 0x00000002 +#define BOOTM_STATE_FINDOTHER 0x00000004 +#define BOOTM_STATE_LOADOS 0x00000008 +#define BOOTM_STATE_RAMDISK 0x00000010 +#define BOOTM_STATE_FDT 0x00000020 +#define BOOTM_STATE_OS_CMDLINE 0x00000040 +#define BOOTM_STATE_OS_BD_T 0x00000080 +#define BOOTM_STATE_OS_PREP 0x00000100 +#define BOOTM_STATE_OS_FAKE_GO 0x00000200 /* 'Almost' run the OS */ +#define BOOTM_STATE_OS_GO 0x00000400 +#define BOOTM_STATE_PRE_LOAD 0x00000800 int state; #if defined(CONFIG_LMB) && !defined(USE_HOSTCC) From d9d7c20b731788c5c8018ce8e5c6e86bb01413df Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 6 Sep 2022 20:26:50 -0600 Subject: [PATCH 331/374] treewide: Drop bootm_headers_t typedef This is not needed and we should avoid typedefs. Use the struct instead. Signed-off-by: Simon Glass --- arch/arc/lib/bootm.c | 8 ++++---- arch/arm/lib/bootm.c | 13 +++++++------ arch/arm/mach-k3/common.c | 2 +- arch/arm/mach-socfpga/board.c | 2 +- arch/m68k/lib/bootm.c | 2 +- arch/microblaze/lib/bootm.c | 6 +++--- arch/mips/lib/bootm.c | 16 ++++++++-------- arch/nios2/lib/bootm.c | 2 +- arch/powerpc/lib/bootm.c | 16 ++++++++-------- arch/riscv/lib/bootm.c | 8 ++++---- arch/sandbox/lib/bootm.c | 2 +- arch/sh/lib/bootm.c | 2 +- arch/x86/lib/bootm.c | 6 +++--- arch/xtensa/lib/bootm.c | 2 +- board/synopsys/hsdk/hsdk.c | 2 +- boot/bootm.c | 16 ++++++++-------- boot/bootm_os.c | 28 +++++++++++++-------------- boot/image-board.c | 14 +++++++------- boot/image-fdt.c | 6 +++--- boot/image-fit.c | 16 ++++++++-------- cmd/bootefi.c | 2 +- cmd/booti.c | 2 +- cmd/bootz.c | 2 +- common/spl/spl.c | 2 +- include/bootm.h | 6 +++--- include/image.h | 36 +++++++++++++++++------------------ lib/efi_loader/efi_dt_fixup.c | 2 +- 27 files changed, 111 insertions(+), 110 deletions(-) diff --git a/arch/arc/lib/bootm.c b/arch/arc/lib/bootm.c index 628addd87e..07b2c1540d 100644 --- a/arch/arc/lib/bootm.c +++ b/arch/arc/lib/bootm.c @@ -22,10 +22,10 @@ static int cleanup_before_linux(void) return 0; } -__weak int board_prep_linux(bootm_headers_t *images) { return 0; } +__weak int board_prep_linux(struct bootm_headers *images) { return 0; } /* Subcommand: PREP */ -static int boot_prep_linux(bootm_headers_t *images) +static int boot_prep_linux(struct bootm_headers *images) { int ret; @@ -49,7 +49,7 @@ __weak void board_jump_and_run(ulong entry, int zero, int arch, uint params) } /* Subcommand: GO */ -static void boot_jump_linux(bootm_headers_t *images, int flag) +static void boot_jump_linux(struct bootm_headers *images, int flag) { ulong kernel_entry; unsigned int r0, r2; @@ -79,7 +79,7 @@ static void boot_jump_linux(bootm_headers_t *images, int flag) board_jump_and_run(kernel_entry, r0, 0, r2); } -int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images) +int do_bootm_linux(int flag, int argc, char *argv[], struct bootm_headers *images) { /* No need for those on ARC */ if ((flag & BOOTM_STATE_OS_BD_T) || (flag & BOOTM_STATE_OS_CMDLINE)) diff --git a/arch/arm/lib/bootm.c b/arch/arm/lib/bootm.c index 9f086f3b90..e414ef8267 100644 --- a/arch/arm/lib/bootm.c +++ b/arch/arm/lib/bootm.c @@ -192,10 +192,10 @@ static void do_nonsec_virt_switch(void) } #endif -__weak void board_prep_linux(bootm_headers_t *images) { } +__weak void board_prep_linux(struct bootm_headers *images) { } /* Subcommand: PREP */ -static void boot_prep_linux(bootm_headers_t *images) +static void boot_prep_linux(struct bootm_headers *images) { char *commandline = env_get("bootargs"); @@ -288,7 +288,7 @@ static void switch_to_el1(void) #endif /* Subcommand: GO */ -static void boot_jump_linux(bootm_headers_t *images, int flag) +static void boot_jump_linux(struct bootm_headers *images, int flag) { #ifdef CONFIG_ARM64 void (*kernel_entry)(void *fdt_addr, void *res0, void *res1, @@ -379,7 +379,7 @@ static void boot_jump_linux(bootm_headers_t *images, int flag) * they are called if subcommand is equal 0. */ int do_bootm_linux(int flag, int argc, char *const argv[], - bootm_headers_t *images) + struct bootm_headers *images) { /* No need for those on ARM */ if (flag & BOOTM_STATE_OS_BD_T || flag & BOOTM_STATE_OS_CMDLINE) @@ -401,7 +401,7 @@ int do_bootm_linux(int flag, int argc, char *const argv[], } #if defined(CONFIG_BOOTM_VXWORKS) -void boot_prep_vxworks(bootm_headers_t *images) +void boot_prep_vxworks(struct bootm_headers *images) { #if defined(CONFIG_OF_LIBFDT) int off; @@ -416,7 +416,8 @@ void boot_prep_vxworks(bootm_headers_t *images) #endif cleanup_before_linux(); } -void boot_jump_vxworks(bootm_headers_t *images) + +void boot_jump_vxworks(struct bootm_headers *images) { #if defined(CONFIG_ARM64) && defined(CONFIG_ARMV8_PSCI) armv8_setup_psci(); diff --git a/arch/arm/mach-k3/common.c b/arch/arm/mach-k3/common.c index 3962f2800f..14c37acbce 100644 --- a/arch/arm/mach-k3/common.c +++ b/arch/arm/mach-k3/common.c @@ -493,7 +493,7 @@ bool soc_is_j7200(void) } #ifdef CONFIG_ARM64 -void board_prep_linux(bootm_headers_t *images) +void board_prep_linux(struct bootm_headers *images) { debug("Linux kernel Image start = 0x%lx end = 0x%lx\n", images->os.start, images->os.end); diff --git a/arch/arm/mach-socfpga/board.c b/arch/arm/mach-socfpga/board.c index 7267163222..b49006c6c8 100644 --- a/arch/arm/mach-socfpga/board.c +++ b/arch/arm/mach-socfpga/board.c @@ -114,7 +114,7 @@ void board_fit_image_post_process(const void *fit, int node, void **p_image, #endif #if !IS_ENABLED(CONFIG_SPL_BUILD) && IS_ENABLED(CONFIG_FIT) -void board_prep_linux(bootm_headers_t *images) +void board_prep_linux(struct bootm_headers *images) { if (!images->fit_uname_cfg) { if (IS_ENABLED(CONFIG_SOCFPGA_SECURE_VAB_AUTH) && diff --git a/arch/m68k/lib/bootm.c b/arch/m68k/lib/bootm.c index 9cade92954..c1c9bdceb5 100644 --- a/arch/m68k/lib/bootm.c +++ b/arch/m68k/lib/bootm.c @@ -36,7 +36,7 @@ void arch_lmb_reserve(struct lmb *lmb) } int do_bootm_linux(int flag, int argc, char *const argv[], - bootm_headers_t *images) + struct bootm_headers *images) { int ret; struct bd_info *kbd; diff --git a/arch/microblaze/lib/bootm.c b/arch/microblaze/lib/bootm.c index 31b6659cdf..4a5421497e 100644 --- a/arch/microblaze/lib/bootm.c +++ b/arch/microblaze/lib/bootm.c @@ -37,7 +37,7 @@ void arch_lmb_reserve(struct lmb *lmb) arch_lmb_reserve_generic(lmb, get_sp(), gd->ram_top, 4096); } -static void boot_jump_linux(bootm_headers_t *images, int flag) +static void boot_jump_linux(struct bootm_headers *images, int flag) { void (*thekernel)(char *cmdline, ulong rd, ulong dt); ulong dt = (ulong)images->ft_addr; @@ -71,7 +71,7 @@ static void boot_jump_linux(bootm_headers_t *images, int flag) } } -static void boot_prep_linux(bootm_headers_t *images) +static void boot_prep_linux(struct bootm_headers *images) { if (CONFIG_IS_ENABLED(OF_LIBFDT) && CONFIG_IS_ENABLED(LMB) && images->ft_len) { debug("using: FDT\n"); @@ -83,7 +83,7 @@ static void boot_prep_linux(bootm_headers_t *images) } int do_bootm_linux(int flag, int argc, char *const argv[], - bootm_headers_t *images) + struct bootm_headers *images) { images->cmdline_start = (ulong)env_get("bootargs"); diff --git a/arch/mips/lib/bootm.c b/arch/mips/lib/bootm.c index cab8da4860..5fda914e6b 100644 --- a/arch/mips/lib/bootm.c +++ b/arch/mips/lib/bootm.c @@ -71,7 +71,7 @@ static void linux_cmdline_dump(void) debug(" arg %03d: %s\n", i, linux_argv[i]); } -static void linux_cmdline_legacy(bootm_headers_t *images) +static void linux_cmdline_legacy(struct bootm_headers *images) { const char *bootargs, *next, *quote; @@ -111,7 +111,7 @@ static void linux_cmdline_legacy(bootm_headers_t *images) } } -static void linux_cmdline_append(bootm_headers_t *images) +static void linux_cmdline_append(struct bootm_headers *images) { char buf[24]; ulong mem, rd_start, rd_size; @@ -164,7 +164,7 @@ static void linux_env_set(const char *env_name, const char *env_val) } } -static void linux_env_legacy(bootm_headers_t *images) +static void linux_env_legacy(struct bootm_headers *images) { char env_buf[12]; const char *cp; @@ -213,7 +213,7 @@ static void linux_env_legacy(bootm_headers_t *images) } } -static int boot_reloc_fdt(bootm_headers_t *images) +static int boot_reloc_fdt(struct bootm_headers *images) { /* * In case of legacy uImage's, relocation of FDT is already done @@ -243,7 +243,7 @@ int arch_fixup_fdt(void *blob) } #endif -static int boot_setup_fdt(bootm_headers_t *images) +static int boot_setup_fdt(struct bootm_headers *images) { images->initrd_start = virt_to_phys((void *)images->initrd_start); images->initrd_end = virt_to_phys((void *)images->initrd_end); @@ -251,7 +251,7 @@ static int boot_setup_fdt(bootm_headers_t *images) &images->lmb); } -static void boot_prep_linux(bootm_headers_t *images) +static void boot_prep_linux(struct bootm_headers *images) { if (CONFIG_IS_ENABLED(MIPS_BOOT_FDT) && images->ft_len) { boot_reloc_fdt(images); @@ -271,7 +271,7 @@ static void boot_prep_linux(bootm_headers_t *images) } } -static void boot_jump_linux(bootm_headers_t *images) +static void boot_jump_linux(struct bootm_headers *images) { typedef void __noreturn (*kernel_entry_t)(int, ulong, ulong, ulong); kernel_entry_t kernel = (kernel_entry_t) images->ep; @@ -302,7 +302,7 @@ static void boot_jump_linux(bootm_headers_t *images) } int do_bootm_linux(int flag, int argc, char *const argv[], - bootm_headers_t *images) + struct bootm_headers *images) { /* No need for those on MIPS */ if (flag & BOOTM_STATE_OS_BD_T) diff --git a/arch/nios2/lib/bootm.c b/arch/nios2/lib/bootm.c index 3cb59bd977..06c094d0f1 100644 --- a/arch/nios2/lib/bootm.c +++ b/arch/nios2/lib/bootm.c @@ -17,7 +17,7 @@ DECLARE_GLOBAL_DATA_PTR; #define NIOS_MAGIC 0x534f494e /* enable command line and initrd passing */ int do_bootm_linux(int flag, int argc, char *const argv[], - bootm_headers_t *images) + struct bootm_headers *images) { void (*kernel)(int, int, int, char *) = (void *)images->ep; char *commandline = env_get("bootargs"); diff --git a/arch/powerpc/lib/bootm.c b/arch/powerpc/lib/bootm.c index b92df9543e..512787854c 100644 --- a/arch/powerpc/lib/bootm.c +++ b/arch/powerpc/lib/bootm.c @@ -45,7 +45,7 @@ static void set_clocks_in_mhz (struct bd_info *kbd); #define CONFIG_SYS_LINUX_LOWMEM_MAX_SIZE (768*1024*1024) #endif -static void boot_jump_linux(bootm_headers_t *images) +static void boot_jump_linux(struct bootm_headers *images) { void (*kernel)(struct bd_info *, ulong r4, ulong r5, ulong r6, ulong r7, ulong r8, ulong r9); @@ -151,7 +151,7 @@ void arch_lmb_reserve(struct lmb *lmb) return ; } -static void boot_prep_linux(bootm_headers_t *images) +static void boot_prep_linux(struct bootm_headers *images) { #ifdef CONFIG_MP /* @@ -163,7 +163,7 @@ static void boot_prep_linux(bootm_headers_t *images) #endif } -static int boot_cmdline_linux(bootm_headers_t *images) +static int boot_cmdline_linux(struct bootm_headers *images) { ulong of_size = images->ft_len; struct lmb *lmb = &images->lmb; @@ -184,7 +184,7 @@ static int boot_cmdline_linux(bootm_headers_t *images) return ret; } -static int boot_bd_t_linux(bootm_headers_t *images) +static int boot_bd_t_linux(struct bootm_headers *images) { ulong of_size = images->ft_len; struct lmb *lmb = &images->lmb; @@ -205,7 +205,7 @@ static int boot_bd_t_linux(bootm_headers_t *images) return ret; } -static int boot_body_linux(bootm_headers_t *images) +static int boot_body_linux(struct bootm_headers *images) { int ret; @@ -224,7 +224,7 @@ static int boot_body_linux(bootm_headers_t *images) } noinline int do_bootm_linux(int flag, int argc, char *const argv[], - bootm_headers_t *images) + struct bootm_headers *images) { int ret; @@ -273,7 +273,7 @@ static void set_clocks_in_mhz (struct bd_info *kbd) } #if defined(CONFIG_BOOTM_VXWORKS) -void boot_prep_vxworks(bootm_headers_t *images) +void boot_prep_vxworks(struct bootm_headers *images) { #if defined(CONFIG_OF_LIBFDT) int off; @@ -305,7 +305,7 @@ void boot_prep_vxworks(bootm_headers_t *images) #endif } -void boot_jump_vxworks(bootm_headers_t *images) +void boot_jump_vxworks(struct bootm_headers *images) { /* PowerPC VxWorks boot interface conforms to the ePAPR standard * general purpuse registers: diff --git a/arch/riscv/lib/bootm.c b/arch/riscv/lib/bootm.c index 670d9c9ebc..f5f8b4c733 100644 --- a/arch/riscv/lib/bootm.c +++ b/arch/riscv/lib/bootm.c @@ -62,7 +62,7 @@ static void announce_and_cleanup(int fake) cleanup_before_linux(); } -static void boot_prep_linux(bootm_headers_t *images) +static void boot_prep_linux(struct bootm_headers *images) { if (CONFIG_IS_ENABLED(OF_LIBFDT) && CONFIG_IS_ENABLED(LMB) && images->ft_len) { debug("using: FDT\n"); @@ -76,7 +76,7 @@ static void boot_prep_linux(bootm_headers_t *images) } } -static void boot_jump_linux(bootm_headers_t *images, int flag) +static void boot_jump_linux(struct bootm_headers *images, int flag) { void (*kernel)(ulong hart, void *dtb); int fake = (flag & BOOTM_STATE_OS_FAKE_GO); @@ -107,7 +107,7 @@ static void boot_jump_linux(bootm_headers_t *images, int flag) } int do_bootm_linux(int flag, int argc, char *const argv[], - bootm_headers_t *images) + struct bootm_headers *images) { /* No need for those on RISC-V */ if (flag & BOOTM_STATE_OS_BD_T || flag & BOOTM_STATE_OS_CMDLINE) @@ -129,7 +129,7 @@ int do_bootm_linux(int flag, int argc, char *const argv[], } int do_bootm_vxworks(int flag, int argc, char *const argv[], - bootm_headers_t *images) + struct bootm_headers *images) { return do_bootm_linux(flag, argc, argv, images); } diff --git a/arch/sandbox/lib/bootm.c b/arch/sandbox/lib/bootm.c index d1d460b84a..c1742f94de 100644 --- a/arch/sandbox/lib/bootm.c +++ b/arch/sandbox/lib/bootm.c @@ -50,7 +50,7 @@ int bootz_setup(ulong image, ulong *start, ulong *end) return ret; } -int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images) +int do_bootm_linux(int flag, int argc, char *argv[], struct bootm_headers *images) { if (flag & (BOOTM_STATE_OS_GO | BOOTM_STATE_OS_FAKE_GO)) { bootstage_mark(BOOTSTAGE_ID_RUN_OS); diff --git a/arch/sh/lib/bootm.c b/arch/sh/lib/bootm.c index 7ea04442b8..a5fad6c46c 100644 --- a/arch/sh/lib/bootm.c +++ b/arch/sh/lib/bootm.c @@ -40,7 +40,7 @@ static unsigned long sh_check_cmd_arg(char *cmdline, char *key, int base) } int do_bootm_linux(int flag, int argc, char *const argv[], - bootm_headers_t *images) + struct bootm_headers *images) { /* Linux kernel load address */ void (*kernel) (void) = (void (*)(void))images->ep; diff --git a/arch/x86/lib/bootm.c b/arch/x86/lib/bootm.c index 1bcdb3e30d..4fdf1b2365 100644 --- a/arch/x86/lib/bootm.c +++ b/arch/x86/lib/bootm.c @@ -69,7 +69,7 @@ int arch_fixup_memory_node(void *blob) #endif /* Subcommand: PREP */ -static int boot_prep_linux(bootm_headers_t *images) +static int boot_prep_linux(struct bootm_headers *images) { char *cmd_line_dest = NULL; image_header_t *hdr; @@ -201,7 +201,7 @@ int boot_linux_kernel(ulong setup_base, ulong load_address, bool image_64bit) } /* Subcommand: GO */ -static int boot_jump_linux(bootm_headers_t *images) +static int boot_jump_linux(struct bootm_headers *images) { debug("## Transferring control to Linux (at address %08lx, kernel %08lx) ...\n", images->ep, images->os.load); @@ -211,7 +211,7 @@ static int boot_jump_linux(bootm_headers_t *images) } int do_bootm_linux(int flag, int argc, char *const argv[], - bootm_headers_t *images) + struct bootm_headers *images) { /* No need for those on x86 */ if (flag & BOOTM_STATE_OS_BD_T || flag & BOOTM_STATE_OS_CMDLINE) diff --git a/arch/xtensa/lib/bootm.c b/arch/xtensa/lib/bootm.c index 277af18168..fee3392815 100644 --- a/arch/xtensa/lib/bootm.c +++ b/arch/xtensa/lib/bootm.c @@ -134,7 +134,7 @@ static struct bp_tag *setup_fdt_tag(struct bp_tag *params, void *fdt_start) * Boot Linux. */ -int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images) +int do_bootm_linux(int flag, int argc, char *argv[], struct bootm_headers *images) { struct bp_tag *params, *params_start; ulong initrd_start, initrd_end; diff --git a/board/synopsys/hsdk/hsdk.c b/board/synopsys/hsdk/hsdk.c index 226fbba629..4308c7e440 100644 --- a/board/synopsys/hsdk/hsdk.c +++ b/board/synopsys/hsdk/hsdk.c @@ -844,7 +844,7 @@ static int hsdk_go_run(u32 cpu_start_reg) return 0; } -int board_prep_linux(bootm_headers_t *images) +int board_prep_linux(struct bootm_headers *images) { int ret, ofst; char mask[15]; diff --git a/boot/bootm.c b/boot/bootm.c index e3233fdf89..2b0dc0b36b 100644 --- a/boot/bootm.c +++ b/boot/bootm.c @@ -41,10 +41,10 @@ DECLARE_GLOBAL_DATA_PTR; -bootm_headers_t images; /* pointers to os/initrd/fdt images */ +struct bootm_headers images; /* pointers to os/initrd/fdt images */ static const void *boot_get_kernel(struct cmd_tbl *cmdtp, int flag, int argc, - char *const argv[], bootm_headers_t *images, + char *const argv[], struct bootm_headers *images, ulong *os_data, ulong *os_len); __weak void board_quiesce_devices(void) @@ -52,7 +52,7 @@ __weak void board_quiesce_devices(void) } #ifdef CONFIG_LMB -static void boot_start_lmb(bootm_headers_t *images) +static void boot_start_lmb(struct bootm_headers *images) { ulong mem_start; phys_size_t mem_size; @@ -65,7 +65,7 @@ static void boot_start_lmb(bootm_headers_t *images) } #else #define lmb_reserve(lmb, base, size) -static inline void boot_start_lmb(bootm_headers_t *images) { } +static inline void boot_start_lmb(struct bootm_headers *images) { } #endif static int bootm_start(struct cmd_tbl *cmdtp, int flag, int argc, @@ -397,7 +397,7 @@ static int handle_decomp_error(int comp_type, size_t uncomp_size, #endif #ifndef USE_HOSTCC -static int bootm_load_os(bootm_headers_t *images, int boot_progress) +static int bootm_load_os(struct bootm_headers *images, int boot_progress) { image_info_t os = images->os; ulong load = os.load; @@ -688,7 +688,7 @@ int bootm_process_cmdline_env(int flags) * unless the image type is standalone. */ int do_bootm_states(struct cmd_tbl *cmdtp, int flag, int argc, - char *const argv[], int states, bootm_headers_t *images, + char *const argv[], int states, struct bootm_headers *images, int boot_progress) { boot_os_fn *boot_fn; @@ -878,7 +878,7 @@ static image_header_t *image_get_kernel(ulong img_addr, int verify) * address and length, otherwise NULL */ static const void *boot_get_kernel(struct cmd_tbl *cmdtp, int flag, int argc, - char *const argv[], bootm_headers_t *images, + char *const argv[], struct bootm_headers *images, ulong *os_data, ulong *os_len) { #if CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT) @@ -1002,7 +1002,7 @@ static int bootm_host_load_image(const void *fit, int req_image_type, { const char *fit_uname_config = NULL; ulong data, len; - bootm_headers_t images; + struct bootm_headers images; int noffset; ulong load_end, buf_size; uint8_t image_type; diff --git a/boot/bootm_os.c b/boot/bootm_os.c index 079224ce58..649f92a75b 100644 --- a/boot/bootm_os.c +++ b/boot/bootm_os.c @@ -24,7 +24,7 @@ DECLARE_GLOBAL_DATA_PTR; static int do_bootm_standalone(int flag, int argc, char *const argv[], - bootm_headers_t *images) + struct bootm_headers *images) { int (*appl)(int, char *const[]); @@ -65,7 +65,7 @@ static void __maybe_unused fit_unsupported_reset(const char *msg) #ifdef CONFIG_BOOTM_NETBSD static int do_bootm_netbsd(int flag, int argc, char *const argv[], - bootm_headers_t *images) + struct bootm_headers *images) { void (*loader)(struct bd_info *, image_header_t *, char *, char *); image_header_t *os_hdr, *hdr; @@ -137,7 +137,7 @@ static int do_bootm_netbsd(int flag, int argc, char *const argv[], #ifdef CONFIG_BOOTM_RTEMS static int do_bootm_rtems(int flag, int argc, char *const argv[], - bootm_headers_t *images) + struct bootm_headers *images) { void (*entry_point)(struct bd_info *); @@ -170,7 +170,7 @@ static int do_bootm_rtems(int flag, int argc, char *const argv[], #if defined(CONFIG_BOOTM_OSE) static int do_bootm_ose(int flag, int argc, char *const argv[], - bootm_headers_t *images) + struct bootm_headers *images) { void (*entry_point)(void); @@ -203,7 +203,7 @@ static int do_bootm_ose(int flag, int argc, char *const argv[], #if defined(CONFIG_BOOTM_PLAN9) static int do_bootm_plan9(int flag, int argc, char *const argv[], - bootm_headers_t *images) + struct bootm_headers *images) { void (*entry_point)(void); char *s; @@ -252,7 +252,7 @@ static int do_bootm_plan9(int flag, int argc, char *const argv[], #if defined(CONFIG_BOOTM_VXWORKS) && \ (defined(CONFIG_PPC) || defined(CONFIG_ARM)) -static void do_bootvx_fdt(bootm_headers_t *images) +static void do_bootvx_fdt(struct bootm_headers *images) { #if defined(CONFIG_OF_LIBFDT) int ret; @@ -311,7 +311,7 @@ static void do_bootvx_fdt(bootm_headers_t *images) } static int do_bootm_vxworks_legacy(int flag, int argc, char *const argv[], - bootm_headers_t *images) + struct bootm_headers *images) { if (flag != BOOTM_STATE_OS_GO) return 0; @@ -329,7 +329,7 @@ static int do_bootm_vxworks_legacy(int flag, int argc, char *const argv[], } int do_bootm_vxworks(int flag, int argc, char *const argv[], - bootm_headers_t *images) + struct bootm_headers *images) { char *bootargs; int pos; @@ -365,7 +365,7 @@ int do_bootm_vxworks(int flag, int argc, char *const argv[], #if defined(CONFIG_CMD_ELF) static int do_bootm_qnxelf(int flag, int argc, char *const argv[], - bootm_headers_t *images) + struct bootm_headers *images) { char *local_args[2]; char str[16]; @@ -403,7 +403,7 @@ static int do_bootm_qnxelf(int flag, int argc, char *const argv[], #ifdef CONFIG_INTEGRITY static int do_bootm_integrity(int flag, int argc, char *const argv[], - bootm_headers_t *images) + struct bootm_headers *images) { void (*entry_point)(void); @@ -436,7 +436,7 @@ static int do_bootm_integrity(int flag, int argc, char *const argv[], #ifdef CONFIG_BOOTM_OPENRTOS static int do_bootm_openrtos(int flag, int argc, char *const argv[], - bootm_headers_t *images) + struct bootm_headers *images) { void (*entry_point)(void); @@ -462,7 +462,7 @@ static int do_bootm_openrtos(int flag, int argc, char *const argv[], #ifdef CONFIG_BOOTM_OPTEE static int do_bootm_tee(int flag, int argc, char *const argv[], - bootm_headers_t *images) + struct bootm_headers *images) { int ret; @@ -490,7 +490,7 @@ static int do_bootm_tee(int flag, int argc, char *const argv[], #ifdef CONFIG_BOOTM_EFI static int do_bootm_efi(int flag, int argc, char *const argv[], - bootm_headers_t *images) + struct bootm_headers *images) { int ret; efi_status_t efi_ret; @@ -589,7 +589,7 @@ __weak void board_preboot_os(void) } int boot_selected_os(int argc, char *const argv[], int state, - bootm_headers_t *images, boot_os_fn *boot_fn) + struct bootm_headers *images, boot_os_fn *boot_fn) { arch_preboot_os(); board_preboot_os(); diff --git a/boot/image-board.c b/boot/image-board.c index 98f903f93f..fe4455778a 100644 --- a/boot/image-board.c +++ b/boot/image-board.c @@ -301,7 +301,7 @@ int genimg_get_format(const void *img_addr) * 0, no FIT support or no configuration found * 1, configuration found */ -int genimg_has_config(bootm_headers_t *images) +int genimg_has_config(struct bootm_headers *images) { if (CONFIG_IS_ENABLED(FIT) && images->fit_uname_cfg) return 1; @@ -320,7 +320,7 @@ int genimg_has_config(bootm_headers_t *images) * Return: 0 if OK, -ENOPKG if no ramdisk (but an error should not be reported), * other -ve value on other error */ -static int select_ramdisk(bootm_headers_t *images, const char *select, u8 arch, +static int select_ramdisk(struct bootm_headers *images, const char *select, u8 arch, ulong *rd_datap, ulong *rd_lenp) { const char *fit_uname_config; @@ -482,7 +482,7 @@ static int select_ramdisk(bootm_headers_t *images, const char *select, u8 arch, * 1, if ramdisk image is found but corrupted, or invalid * rd_start and rd_end are set to 0 if no ramdisk exists */ -int boot_get_ramdisk(int argc, char *const argv[], bootm_headers_t *images, +int boot_get_ramdisk(int argc, char *const argv[], struct bootm_headers *images, u8 arch, ulong *rd_start, ulong *rd_end) { ulong rd_data, rd_len; @@ -646,7 +646,7 @@ error: return -1; } -int boot_get_setup(bootm_headers_t *images, u8 arch, +int boot_get_setup(struct bootm_headers *images, u8 arch, ulong *setup_start, ulong *setup_len) { if (!CONFIG_IS_ENABLED(FIT)) @@ -655,7 +655,7 @@ int boot_get_setup(bootm_headers_t *images, u8 arch, return boot_get_setup_fit(images, arch, setup_start, setup_len); } -int boot_get_fpga(int argc, char *const argv[], bootm_headers_t *images, +int boot_get_fpga(int argc, char *const argv[], struct bootm_headers *images, u8 arch, const ulong *ld_start, ulong * const ld_len) { ulong tmp_img_addr, img_data, img_len; @@ -758,7 +758,7 @@ static void fit_loadable_process(u8 img_type, fit_loadable_handler->handler(img_data, img_len); } -int boot_get_loadable(int argc, char *const argv[], bootm_headers_t *images, +int boot_get_loadable(int argc, char *const argv[], struct bootm_headers *images, u8 arch, const ulong *ld_start, ulong * const ld_len) { /* @@ -919,7 +919,7 @@ int boot_get_kbd(struct lmb *lmb, struct bd_info **kbd) return 0; } -int image_setup_linux(bootm_headers_t *images) +int image_setup_linux(struct bootm_headers *images) { ulong of_size = images->ft_len; char **of_flat_tree = &images->ft_addr; diff --git a/boot/image-fdt.c b/boot/image-fdt.c index e75d051c87..78417bd889 100644 --- a/boot/image-fdt.c +++ b/boot/image-fdt.c @@ -291,7 +291,7 @@ error: * other -ve value on other error */ -static int select_fdt(bootm_headers_t *images, const char *select, u8 arch, +static int select_fdt(struct bootm_headers *images, const char *select, u8 arch, ulong *fdt_addrp) { const char *buf; @@ -470,7 +470,7 @@ static int select_fdt(bootm_headers_t *images, const char *select, u8 arch, * of_flat_tree and of_size are set to 0 if no fdt exists */ int boot_get_fdt(int flag, int argc, char *const argv[], uint8_t arch, - bootm_headers_t *images, char **of_flat_tree, ulong *of_size) + struct bootm_headers *images, char **of_flat_tree, ulong *of_size) { ulong img_addr; ulong fdt_addr; @@ -602,7 +602,7 @@ __weak int arch_fixup_fdt(void *blob) return 0; } -int image_setup_libfdt(bootm_headers_t *images, void *blob, +int image_setup_libfdt(struct bootm_headers *images, void *blob, int of_size, struct lmb *lmb) { ulong *initrd_start = &images->initrd_start; diff --git a/boot/image-fit.c b/boot/image-fit.c index f16eab9df3..6e503f827d 100644 --- a/boot/image-fit.c +++ b/boot/image-fit.c @@ -1969,8 +1969,8 @@ static int fit_image_select(const void *fit, int rd_noffset, int verify) return 0; } -int fit_get_node_from_config(bootm_headers_t *images, const char *prop_name, - ulong addr) +int fit_get_node_from_config(struct bootm_headers *images, + const char *prop_name, ulong addr) { int cfg_noffset; void *fit_hdr; @@ -2031,7 +2031,7 @@ static const char *fit_get_image_type_property(int type) return "unknown"; } -int fit_image_load(bootm_headers_t *images, ulong addr, +int fit_image_load(struct bootm_headers *images, ulong addr, const char **fit_unamep, const char **fit_uname_configp, int arch, int image_type, int bootstage_id, enum fit_load_op load_op, ulong *datap, ulong *lenp) @@ -2289,8 +2289,8 @@ int fit_image_load(bootm_headers_t *images, ulong addr, return noffset; } -int boot_get_setup_fit(bootm_headers_t *images, uint8_t arch, - ulong *setup_start, ulong *setup_len) +int boot_get_setup_fit(struct bootm_headers *images, uint8_t arch, + ulong *setup_start, ulong *setup_len) { int noffset; ulong addr; @@ -2310,9 +2310,9 @@ int boot_get_setup_fit(bootm_headers_t *images, uint8_t arch, } #ifndef USE_HOSTCC -int boot_get_fdt_fit(bootm_headers_t *images, ulong addr, - const char **fit_unamep, const char **fit_uname_configp, - int arch, ulong *datap, ulong *lenp) +int boot_get_fdt_fit(struct bootm_headers *images, ulong addr, + const char **fit_unamep, const char **fit_uname_configp, + int arch, ulong *datap, ulong *lenp) { int fdt_noffset, cfg_noffset, count; const void *fit; diff --git a/cmd/bootefi.c b/cmd/bootefi.c index 8ab0ff5a64..3041873afb 100644 --- a/cmd/bootefi.c +++ b/cmd/bootefi.c @@ -281,7 +281,7 @@ efi_status_t efi_install_fdt(void *fdt) return EFI_SUCCESS; } #else - bootm_headers_t img = { 0 }; + struct bootm_headers img = { 0 }; efi_status_t ret; if (fdt == EFI_FDT_USE_INTERNAL) { diff --git a/cmd/booti.c b/cmd/booti.c index 397d4b8323..6ac39193db 100644 --- a/cmd/booti.c +++ b/cmd/booti.c @@ -21,7 +21,7 @@ DECLARE_GLOBAL_DATA_PTR; * Image booting support */ static int booti_start(struct cmd_tbl *cmdtp, int flag, int argc, - char *const argv[], bootm_headers_t *images) + char *const argv[], struct bootm_headers *images) { int ret; ulong ld; diff --git a/cmd/bootz.c b/cmd/bootz.c index 4f024bde5f..f1423573d2 100644 --- a/cmd/bootz.c +++ b/cmd/bootz.c @@ -25,7 +25,7 @@ int __weak bootz_setup(ulong image, ulong *start, ulong *end) * zImage booting support */ static int bootz_start(struct cmd_tbl *cmdtp, int flag, int argc, - char *const argv[], bootm_headers_t *images) + char *const argv[], struct bootm_headers *images) { int ret; ulong zi_start, zi_end; diff --git a/common/spl/spl.c b/common/spl/spl.c index 828f72f30b..1283f9ec37 100644 --- a/common/spl/spl.c +++ b/common/spl/spl.c @@ -260,7 +260,7 @@ void spl_set_header_raw_uboot(struct spl_image_info *spl_image) static int spl_load_fit_image(struct spl_image_info *spl_image, const struct image_header *header) { - bootm_headers_t images; + struct bootm_headers images; const char *fit_uname_config = NULL; uintptr_t fdt_hack; const char *uname; diff --git a/include/bootm.h b/include/bootm.h index 7ed5650fca..044a4797ed 100644 --- a/include/bootm.h +++ b/include/bootm.h @@ -33,7 +33,7 @@ struct cmd_tbl; * not return. */ typedef int boot_os_fn(int flag, int argc, char *const argv[], - bootm_headers_t *images); + struct bootm_headers *images); extern boot_os_fn do_bootm_linux; extern boot_os_fn do_bootm_vxworks; @@ -47,7 +47,7 @@ int bootm_host_load_images(const void *fit, int cfg_noffset); #endif int boot_selected_os(int argc, char *const argv[], int state, - bootm_headers_t *images, boot_os_fn *boot_fn); + struct bootm_headers *images, boot_os_fn *boot_fn); ulong bootm_disable_interrupts(void); @@ -56,7 +56,7 @@ int bootm_find_images(int flag, int argc, char *const argv[], ulong start, ulong size); int do_bootm_states(struct cmd_tbl *cmdtp, int flag, int argc, - char *const argv[], int states, bootm_headers_t *images, + char *const argv[], int states, struct bootm_headers *images, int boot_progress); void arch_preboot_os(void); diff --git a/include/image.h b/include/image.h index 80e58559d0..b337478c29 100644 --- a/include/image.h +++ b/include/image.h @@ -290,7 +290,7 @@ typedef struct image_info { * Legacy and FIT format headers used by do_bootm() and do_bootm_() * routines. */ -typedef struct bootm_headers { +struct bootm_headers { /* * Legacy os image header, if it is a multi component image * then boot_get_ramdisk() and get_fdt() will attempt to get @@ -358,7 +358,7 @@ typedef struct bootm_headers { #if defined(CONFIG_LMB) && !defined(USE_HOSTCC) struct lmb lmb; /* for memory mgmt */ #endif -} bootm_headers_t; +}; #ifdef CONFIG_LMB #define images_lmb(_images) (&(_images)->lmb) @@ -366,7 +366,7 @@ typedef struct bootm_headers { #define images_lmb(_images) NULL #endif -extern bootm_headers_t images; +extern struct bootm_headers images; /* * Some systems (for example LWMON) have very short watchdog periods; @@ -530,7 +530,7 @@ enum fit_load_op { FIT_LOAD_REQUIRED, /* Must be provided */ }; -int boot_get_setup(bootm_headers_t *images, uint8_t arch, ulong *setup_start, +int boot_get_setup(struct bootm_headers *images, uint8_t arch, ulong *setup_start, ulong *setup_len); /* Image format types, returned by _get_format() routine */ @@ -544,11 +544,11 @@ ulong genimg_get_kernel_addr_fit(char * const img_addr, const char **fit_uname_kernel); ulong genimg_get_kernel_addr(char * const img_addr); int genimg_get_format(const void *img_addr); -int genimg_has_config(bootm_headers_t *images); +int genimg_has_config(struct bootm_headers *images); -int boot_get_fpga(int argc, char *const argv[], bootm_headers_t *images, +int boot_get_fpga(int argc, char *const argv[], struct bootm_headers *images, uint8_t arch, const ulong *ld_start, ulong * const ld_len); -int boot_get_ramdisk(int argc, char *const argv[], bootm_headers_t *images, +int boot_get_ramdisk(int argc, char *const argv[], struct bootm_headers *images, uint8_t arch, ulong *rd_start, ulong *rd_end); /** @@ -572,10 +572,10 @@ int boot_get_ramdisk(int argc, char *const argv[], bootm_headers_t *images, * 0, if only valid images or no images are found * error code, if an error occurs during fit_image_load */ -int boot_get_loadable(int argc, char *const argv[], bootm_headers_t *images, +int boot_get_loadable(int argc, char *const argv[], struct bootm_headers *images, uint8_t arch, const ulong *ld_start, ulong *const ld_len); -int boot_get_setup_fit(bootm_headers_t *images, uint8_t arch, +int boot_get_setup_fit(struct bootm_headers *images, uint8_t arch, ulong *setup_start, ulong *setup_len); /** @@ -599,9 +599,9 @@ int boot_get_setup_fit(bootm_headers_t *images, uint8_t arch, * * Return: node offset of base image, or -ve error code on error */ -int boot_get_fdt_fit(bootm_headers_t *images, ulong addr, - const char **fit_unamep, const char **fit_uname_configp, - int arch, ulong *datap, ulong *lenp); +int boot_get_fdt_fit(struct bootm_headers *images, ulong addr, + const char **fit_unamep, const char **fit_uname_configp, + int arch, ulong *datap, ulong *lenp); /** * fit_image_load() - load an image from a FIT @@ -633,7 +633,7 @@ int boot_get_fdt_fit(bootm_headers_t *images, ulong addr, * @param lenp Returns length of loaded image * Return: node offset of image, or -ve error code on error */ -int fit_image_load(bootm_headers_t *images, ulong addr, +int fit_image_load(struct bootm_headers *images, ulong addr, const char **fit_unamep, const char **fit_uname_configp, int arch, int image_type, int bootstage_id, enum fit_load_op load_op, ulong *datap, ulong *lenp); @@ -677,11 +677,11 @@ int image_source_script(ulong addr, const char *fit_uname); * @param prop_name Property name to look up (FIT_..._PROP) * @param addr Address of FIT in memory */ -int fit_get_node_from_config(bootm_headers_t *images, const char *prop_name, - ulong addr); +int fit_get_node_from_config(struct bootm_headers *images, + const char *prop_name, ulong addr); int boot_get_fdt(int flag, int argc, char *const argv[], uint8_t arch, - bootm_headers_t *images, + struct bootm_headers *images, char **of_flat_tree, ulong *of_size); void boot_fdt_add_mem_rsv_regions(struct lmb *lmb, void *fdt_blob); int boot_relocate_fdt(struct lmb *lmb, char **of_flat_tree, ulong *of_size); @@ -871,7 +871,7 @@ int image_decomp(int comp, ulong load, ulong image_start, int type, * @lmb: Points to logical memory block structure * Return: 0 if ok, <0 on failure */ -int image_setup_libfdt(bootm_headers_t *images, void *blob, +int image_setup_libfdt(struct bootm_headers *images, void *blob, int of_size, struct lmb *lmb); /** @@ -883,7 +883,7 @@ int image_setup_libfdt(bootm_headers_t *images, void *blob, * @param images Images information * Return: 0 if ok, <0 on failure */ -int image_setup_linux(bootm_headers_t *images); +int image_setup_linux(struct bootm_headers *images); /** * bootz_setup() - Extract stat and size of a Linux xImage diff --git a/lib/efi_loader/efi_dt_fixup.c b/lib/efi_loader/efi_dt_fixup.c index d3923e5dba..838023c78f 100644 --- a/lib/efi_loader/efi_dt_fixup.c +++ b/lib/efi_loader/efi_dt_fixup.c @@ -145,7 +145,7 @@ efi_dt_fixup(struct efi_dt_fixup_protocol *this, void *dtb, efi_status_t ret; size_t required_size; size_t total_size; - bootm_headers_t img = { 0 }; + struct bootm_headers img = { 0 }; EFI_ENTRY("%p, %p, %p, %d", this, dtb, buffer_size, flags); From da79b2f25e5352a8e09b96ecef56df009f03c0b5 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 6 Sep 2022 20:26:51 -0600 Subject: [PATCH 332/374] treewide: Drop image_info_t typedef This is not needed and we should avoid typedefs. Use the struct instead. Signed-off-by: Simon Glass --- boot/bootm.c | 2 +- include/image.h | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/boot/bootm.c b/boot/bootm.c index 2b0dc0b36b..2e41d78372 100644 --- a/boot/bootm.c +++ b/boot/bootm.c @@ -399,7 +399,7 @@ static int handle_decomp_error(int comp_type, size_t uncomp_size, #ifndef USE_HOSTCC static int bootm_load_os(struct bootm_headers *images, int boot_progress) { - image_info_t os = images->os; + struct image_info os = images->os; ulong load = os.load; ulong load_end; ulong blob_start = os.start; diff --git a/include/image.h b/include/image.h index b337478c29..b58550fd64 100644 --- a/include/image.h +++ b/include/image.h @@ -278,13 +278,13 @@ typedef struct image_header { uint8_t ih_name[IH_NMLEN]; /* Image Name */ } image_header_t; -typedef struct image_info { +struct image_info { ulong start, end; /* start/end of blob */ ulong image_start, image_len; /* start of image within blob, len of image */ ulong load; /* load addr for the image */ uint8_t comp, type, os; /* compression, type of image, os type */ uint8_t arch; /* CPU architecture */ -} image_info_t; +}; /* * Legacy and FIT format headers used by do_bootm() and do_bootm_() @@ -324,7 +324,7 @@ struct bootm_headers { int fit_noffset_setup;/* x86 setup subimage node offset */ #ifndef USE_HOSTCC - image_info_t os; /* os image info */ + struct image_info os; /* os image info */ ulong ep; /* entry point of OS */ ulong rd_start, rd_end;/* ramdisk start/end */ From f3543e69442ca393e52df253d9c5d45bc189d471 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 6 Sep 2022 20:26:52 -0600 Subject: [PATCH 333/374] treewide: Drop image_header_t typedef This is not needed and we should avoid typedefs. Use the struct instead and rename it to indicate that it really is a legacy struct. Signed-off-by: Simon Glass --- arch/arm/mach-aspeed/ast2600/spl.c | 4 +- arch/arm/mach-imx/hab.c | 2 +- arch/arm/mach-imx/spl_imx_romapi.c | 6 +-- arch/arm/mach-k3/sysfw-loader.c | 6 +-- arch/arm/mach-keystone/cmd_mon.c | 6 +-- arch/arm/mach-sunxi/spl_spi_sunxi.c | 4 +- arch/mips/mach-jz47xx/jz4780/jz4780.c | 6 +-- arch/mips/mach-mtmips/mt7621/spl/spl.c | 4 +- arch/mips/mach-mtmips/mt7621/tpl/tpl.c | 4 +- arch/x86/lib/bootm.c | 2 +- board/ti/ks2_evm/board.c | 4 +- boot/boot_fit.c | 4 +- boot/bootm.c | 8 ++-- boot/bootm_os.c | 7 ++-- boot/image-android.c | 6 +-- boot/image-board.c | 12 +++--- boot/image-fdt.c | 6 +-- boot/image.c | 14 +++---- cmd/bootm.c | 4 +- cmd/disk.c | 4 +- cmd/fpga.c | 2 +- cmd/nand.c | 4 +- cmd/source.c | 2 +- cmd/ximg.c | 4 +- common/spl/spl.c | 8 ++-- common/spl/spl_ext.c | 4 +- common/spl/spl_fat.c | 6 +-- common/spl/spl_legacy.c | 8 ++-- common/spl/spl_mmc.c | 4 +- common/spl/spl_nand.c | 4 +- common/spl/spl_net.c | 2 +- common/spl/spl_nor.c | 8 ++-- common/spl/spl_onenand.c | 2 +- common/spl/spl_ram.c | 8 ++-- common/spl/spl_sata.c | 2 +- common/spl/spl_semihosting.c | 4 +- common/spl/spl_spi.c | 6 +-- common/spl/spl_ubi.c | 4 +- common/spl/spl_xip.c | 2 +- common/spl/spl_ymodem.c | 14 +++---- common/splash_source.c | 6 +-- doc/uImage.FIT/source_file_format.txt | 2 +- drivers/fpga/socfpga_arria10.c | 4 +- drivers/usb/gadget/f_sdp.c | 2 +- include/configs/uniphier.h | 2 +- include/image.h | 52 ++++++++++++++------------ include/spl.h | 8 ++-- include/tee/optee.h | 4 +- test/image/spl_load.c | 4 +- tools/binman/ftest.py | 4 +- tools/default_image.c | 31 ++++++++------- tools/fit_image.c | 4 +- tools/imx8mimage.c | 8 ++-- tools/mkimage.c | 2 +- tools/mtk_image.c | 10 ++--- 55 files changed, 179 insertions(+), 175 deletions(-) diff --git a/arch/arm/mach-aspeed/ast2600/spl.c b/arch/arm/mach-aspeed/ast2600/spl.c index 53c8a15bf9..0952e73a45 100644 --- a/arch/arm/mach-aspeed/ast2600/spl.c +++ b/arch/arm/mach-aspeed/ast2600/spl.c @@ -56,9 +56,9 @@ out: return BOOT_DEVICE_RAM; } -struct image_header *spl_get_load_buffer(ssize_t offset, size_t size) +struct legacy_img_hdr *spl_get_load_buffer(ssize_t offset, size_t size) { - return (struct image_header *)(CONFIG_SYS_LOAD_ADDR); + return (struct legacy_img_hdr *)(CONFIG_SYS_LOAD_ADDR); } #ifdef CONFIG_SPL_OS_BOOT diff --git a/arch/arm/mach-imx/hab.c b/arch/arm/mach-imx/hab.c index 0d1a7766be..c6747b257c 100644 --- a/arch/arm/mach-imx/hab.c +++ b/arch/arm/mach-imx/hab.c @@ -589,7 +589,7 @@ static ulong get_image_ivt_offset(ulong img_addr) switch (genimg_get_format(buf)) { #if CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT) case IMAGE_FORMAT_LEGACY: - return (image_get_image_size((image_header_t *)img_addr) + return (image_get_image_size((struct legacy_img_hdr *)img_addr) + 0x1000 - 1) & ~(0x1000 - 1); #endif #if CONFIG_IS_ENABLED(FIT) diff --git a/arch/arm/mach-imx/spl_imx_romapi.c b/arch/arm/mach-imx/spl_imx_romapi.c index 07bf07beee..aa5d23a6fb 100644 --- a/arch/arm/mach-imx/spl_imx_romapi.c +++ b/arch/arm/mach-imx/spl_imx_romapi.c @@ -72,7 +72,7 @@ static int spl_romapi_load_image_seekable(struct spl_image_info *spl_image, int ret; u32 offset; u32 pagesize, size; - struct image_header *header; + struct legacy_img_hdr *header; u32 image_offset; ret = rom_api_query_boot_infor(QUERY_IVT_OFF, &offset); @@ -84,14 +84,14 @@ static int spl_romapi_load_image_seekable(struct spl_image_info *spl_image, return -1; } - header = (struct image_header *)(CONFIG_SPL_IMX_ROMAPI_LOADADDR); + header = (struct legacy_img_hdr *)(CONFIG_SPL_IMX_ROMAPI_LOADADDR); printf("image offset 0x%x, pagesize 0x%x, ivt offset 0x%x\n", image_offset, pagesize, offset); offset = spl_romapi_get_uboot_base(image_offset, rom_bt_dev); - size = ALIGN(sizeof(struct image_header), pagesize); + size = ALIGN(sizeof(struct legacy_img_hdr), pagesize); ret = rom_api_download_image((u8 *)header, offset, size); if (ret != ROM_API_OKAY) { diff --git a/arch/arm/mach-k3/sysfw-loader.c b/arch/arm/mach-k3/sysfw-loader.c index b3beeca947..aea640b570 100644 --- a/arch/arm/mach-k3/sysfw-loader.c +++ b/arch/arm/mach-k3/sysfw-loader.c @@ -88,10 +88,10 @@ static void *sysfw_load_address; * Populate SPL hook to override the default load address used by the SPL * loader function with a custom address for SYSFW loading. */ -struct image_header *spl_get_load_buffer(ssize_t offset, size_t size) +struct legacy_img_hdr *spl_get_load_buffer(ssize_t offset, size_t size) { if (sysfw_loaded) - return (struct image_header *)(CONFIG_SYS_TEXT_BASE + offset); + return (struct legacy_img_hdr *)(CONFIG_SYS_TEXT_BASE + offset); else if (sysfw_load_address) return sysfw_load_address; else @@ -490,7 +490,7 @@ void k3_sysfw_loader(bool rom_loaded_sysfw, sysfw_loaded = true; /* Ensure the SYSFW image is in FIT format */ - if (image_get_magic((const image_header_t *)sysfw_load_address) != + if (image_get_magic((const struct legacy_img_hdr *)sysfw_load_address) != FDT_MAGIC) panic("SYSFW image not in FIT format!\n"); diff --git a/arch/arm/mach-keystone/cmd_mon.c b/arch/arm/mach-keystone/cmd_mon.c index e26296b6da..4734e4c714 100644 --- a/arch/arm/mach-keystone/cmd_mon.c +++ b/arch/arm/mach-keystone/cmd_mon.c @@ -17,7 +17,7 @@ static int do_mon_install(struct cmd_tbl *cmdtp, int flag, int argc, { u32 addr, dpsc_base = 0x1E80000, freq, load_addr, size; int rcode = 0; - struct image_header *header; + struct legacy_img_hdr *header; u32 ecrypt_bm_addr = 0; if (argc < 2) @@ -27,7 +27,7 @@ static int do_mon_install(struct cmd_tbl *cmdtp, int flag, int argc, addr = hextoul(argv[1], NULL); - header = (struct image_header *)addr; + header = (struct legacy_img_hdr *)addr; if (image_get_magic(header) != IH_MAGIC) { printf("## Please update monitor image\n"); @@ -36,7 +36,7 @@ static int do_mon_install(struct cmd_tbl *cmdtp, int flag, int argc, load_addr = image_get_load(header); size = image_get_data_size(header); - memcpy((void *)load_addr, (void *)(addr + sizeof(struct image_header)), + memcpy((void *)load_addr, (void *)(addr + sizeof(struct legacy_img_hdr)), size); if (argc >= 3) diff --git a/arch/arm/mach-sunxi/spl_spi_sunxi.c b/arch/arm/mach-sunxi/spl_spi_sunxi.c index de9aa68c4a..925bf85f2d 100644 --- a/arch/arm/mach-sunxi/spl_spi_sunxi.c +++ b/arch/arm/mach-sunxi/spl_spi_sunxi.c @@ -335,10 +335,10 @@ static int spl_spi_load_image(struct spl_image_info *spl_image, struct spl_boot_device *bootdev) { int ret = 0; - struct image_header *header; - header = (struct image_header *)(CONFIG_SYS_TEXT_BASE); + struct legacy_img_hdr *header; uint32_t load_offset = sunxi_get_spl_size(); + header = (struct legacy_img_hdr *)CONFIG_SYS_TEXT_BASE; load_offset = max_t(uint32_t, load_offset, CONFIG_SYS_SPI_U_BOOT_OFFS); spi0_init(); diff --git a/arch/mips/mach-jz47xx/jz4780/jz4780.c b/arch/mips/mach-jz47xx/jz4780/jz4780.c index a57ec7802b..4c40bd86fd 100644 --- a/arch/mips/mach-jz47xx/jz4780/jz4780.c +++ b/arch/mips/mach-jz47xx/jz4780/jz4780.c @@ -30,7 +30,7 @@ void board_init_f(ulong dummy) typedef void __noreturn (*image_entry_noargs_t)(void); struct mmc *mmc; unsigned long count; - struct image_header *header; + struct legacy_img_hdr *header; int ret; /* Set global data pointer */ @@ -58,8 +58,8 @@ void board_init_f(ulong dummy) if (ret) hang(); - header = (struct image_header *)(CONFIG_SYS_TEXT_BASE - - sizeof(struct image_header)); + header = (struct legacy_img_hdr *)(CONFIG_SYS_TEXT_BASE - + sizeof(struct legacy_img_hdr)); count = blk_dread(mmc_get_blk_desc(mmc), CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR, diff --git a/arch/mips/mach-mtmips/mt7621/spl/spl.c b/arch/mips/mach-mtmips/mt7621/spl/spl.c index 91eebc6c1f..aa5b267bb9 100644 --- a/arch/mips/mach-mtmips/mt7621/spl/spl.c +++ b/arch/mips/mach-mtmips/mt7621/spl/spl.c @@ -64,7 +64,7 @@ void board_boot_order(u32 *spl_boot_list) unsigned long spl_nor_get_uboot_base(void) { const struct tpl_info *tpli; - const image_header_t *hdr; + const struct legacy_img_hdr *hdr; u32 addr; addr = FLASH_MMAP_BASE + TPL_INFO_OFFSET; @@ -72,7 +72,7 @@ unsigned long spl_nor_get_uboot_base(void) if (tpli->magic == TPL_INFO_MAGIC) { addr = FLASH_MMAP_BASE + tpli->size; - hdr = (const image_header_t *)KSEG1ADDR(addr); + hdr = (const struct legacy_img_hdr *)KSEG1ADDR(addr); if (image_get_magic(hdr) == IH_MAGIC) { addr += sizeof(*hdr) + image_get_size(hdr); diff --git a/arch/mips/mach-mtmips/mt7621/tpl/tpl.c b/arch/mips/mach-mtmips/mt7621/tpl/tpl.c index 2a828907a3..d77592da5f 100644 --- a/arch/mips/mach-mtmips/mt7621/tpl/tpl.c +++ b/arch/mips/mach-mtmips/mt7621/tpl/tpl.c @@ -116,7 +116,7 @@ static void mt7621_cache_init(void) void __noreturn tpl_main(void) { - const image_header_t *hdr = (const image_header_t *)__image_copy_end; + const struct legacy_img_hdr *hdr = (const struct legacy_img_hdr *)__image_copy_end; image_entry_noargs_t image_entry; u32 loadaddr, size; uintptr_t data; @@ -132,7 +132,7 @@ void __noreturn tpl_main(void) image_entry = (image_entry_noargs_t)image_get_ep(hdr); /* Load TPL image to L2 cache */ - data = (uintptr_t)__image_copy_end + sizeof(struct image_header); + data = (uintptr_t)__image_copy_end + sizeof(struct legacy_img_hdr); fill_lock_l2cache(data, loadaddr, size); /* Jump to SPL */ diff --git a/arch/x86/lib/bootm.c b/arch/x86/lib/bootm.c index 4fdf1b2365..eafcddfa24 100644 --- a/arch/x86/lib/bootm.c +++ b/arch/x86/lib/bootm.c @@ -72,7 +72,7 @@ int arch_fixup_memory_node(void *blob) static int boot_prep_linux(struct bootm_headers *images) { char *cmd_line_dest = NULL; - image_header_t *hdr; + struct legacy_img_hdr *hdr; int is_zimage = 0; void *data = NULL; size_t len; diff --git a/board/ti/ks2_evm/board.c b/board/ti/ks2_evm/board.c index 0c5c2c9146..5ba3aa35a9 100644 --- a/board/ti/ks2_evm/board.c +++ b/board/ti/ks2_evm/board.c @@ -64,9 +64,9 @@ int dram_init(void) return 0; } -struct image_header *spl_get_load_buffer(ssize_t offset, size_t size) +struct legacy_img_hdr *spl_get_load_buffer(ssize_t offset, size_t size) { - return (struct image_header *)(CONFIG_SYS_TEXT_BASE); + return (struct legacy_img_hdr *)(CONFIG_SYS_TEXT_BASE); } int board_init(void) diff --git a/boot/boot_fit.c b/boot/boot_fit.c index dfc2a3117d..4a493b3684 100644 --- a/boot/boot_fit.c +++ b/boot/boot_fit.c @@ -57,14 +57,14 @@ static int fdt_offset(const void *fit) void *locate_dtb_in_fit(const void *fit) { - struct image_header *header; + struct legacy_img_hdr *header; int size; int ret; size = fdt_totalsize(fit); size = (size + 3) & ~3; - header = (struct image_header *)fit; + header = (struct legacy_img_hdr *)fit; if (image_get_magic(header) != FDT_MAGIC) { debug("No FIT image appended to U-boot\n"); diff --git a/boot/bootm.c b/boot/bootm.c index 2e41d78372..5b20b418db 100644 --- a/boot/bootm.c +++ b/boot/bootm.c @@ -825,9 +825,9 @@ err: * pointer to a legacy image header if valid image was found * otherwise return NULL */ -static image_header_t *image_get_kernel(ulong img_addr, int verify) +static struct legacy_img_hdr *image_get_kernel(ulong img_addr, int verify) { - image_header_t *hdr = (image_header_t *)img_addr; + struct legacy_img_hdr *hdr = (struct legacy_img_hdr *)img_addr; if (!image_check_magic(hdr)) { puts("Bad Magic Number\n"); @@ -882,7 +882,7 @@ static const void *boot_get_kernel(struct cmd_tbl *cmdtp, int flag, int argc, ulong *os_data, ulong *os_len) { #if CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT) - image_header_t *hdr; + struct legacy_img_hdr *hdr; #endif ulong img_addr; const void *buf; @@ -940,7 +940,7 @@ static const void *boot_get_kernel(struct cmd_tbl *cmdtp, int flag, int argc, * kernel decompression. */ memmove(&images->legacy_hdr_os_copy, hdr, - sizeof(image_header_t)); + sizeof(struct legacy_img_hdr)); /* save pointer to image header */ images->legacy_hdr_os = hdr; diff --git a/boot/bootm_os.c b/boot/bootm_os.c index 649f92a75b..99ff0e6c02 100644 --- a/boot/bootm_os.c +++ b/boot/bootm_os.c @@ -67,8 +67,9 @@ static void __maybe_unused fit_unsupported_reset(const char *msg) static int do_bootm_netbsd(int flag, int argc, char *const argv[], struct bootm_headers *images) { - void (*loader)(struct bd_info *, image_header_t *, char *, char *); - image_header_t *os_hdr, *hdr; + void (*loader)(struct bd_info *bd, struct legacy_img_hdr *hdr, + char *console, char *cmdline); + struct legacy_img_hdr *os_hdr, *hdr; ulong kernel_data, kernel_len; char *cmdline; @@ -115,7 +116,7 @@ static int do_bootm_netbsd(int flag, int argc, char *const argv[], cmdline = ""; } - loader = (void (*)(struct bd_info *, image_header_t *, char *, char *))images->ep; + loader = (void (*)(struct bd_info *, struct legacy_img_hdr *, char *, char *))images->ep; printf("## Transferring control to NetBSD stage-2 loader (at address %08lx) ...\n", (ulong)loader); diff --git a/boot/image-android.c b/boot/image-android.c index 1fbbbba1eb..2628db3741 100644 --- a/boot/image-android.c +++ b/boot/image-android.c @@ -63,7 +63,7 @@ int android_image_get_kernel(const struct andr_img_hdr *hdr, int verify, ulong *os_data, ulong *os_len) { u32 kernel_addr = android_image_get_kernel_addr(hdr); - const struct image_header *ihdr = (const struct image_header *) + const struct legacy_img_hdr *ihdr = (const struct legacy_img_hdr *) ((uintptr_t)hdr + hdr->page_size); /* @@ -159,8 +159,8 @@ ulong android_image_get_kcomp(const struct andr_img_hdr *hdr) { const void *p = (void *)((uintptr_t)hdr + hdr->page_size); - if (image_get_magic((image_header_t *)p) == IH_MAGIC) - return image_get_comp((image_header_t *)p); + if (image_get_magic((struct legacy_img_hdr *)p) == IH_MAGIC) + return image_get_comp((struct legacy_img_hdr *)p); else if (get_unaligned_le32(p) == LZ4F_MAGIC) return IH_COMP_LZ4; else diff --git a/boot/image-board.c b/boot/image-board.c index fe4455778a..34d1e5f18b 100644 --- a/boot/image-board.c +++ b/boot/image-board.c @@ -40,10 +40,10 @@ DECLARE_GLOBAL_DATA_PTR; * pointer to a ramdisk image header, if image was found and valid * otherwise, return NULL */ -static const image_header_t *image_get_ramdisk(ulong rd_addr, u8 arch, - int verify) +static const struct legacy_img_hdr *image_get_ramdisk(ulong rd_addr, u8 arch, + int verify) { - const image_header_t *rd_hdr = (const image_header_t *)rd_addr; + const struct legacy_img_hdr *rd_hdr = (const struct legacy_img_hdr *)rd_addr; if (!image_check_magic(rd_hdr)) { puts("Bad Magic Number\n"); @@ -273,9 +273,9 @@ ulong genimg_get_kernel_addr(char * const img_addr) int genimg_get_format(const void *img_addr) { if (CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT)) { - const image_header_t *hdr; + const struct legacy_img_hdr *hdr; - hdr = (const image_header_t *)img_addr; + hdr = (const struct legacy_img_hdr *)img_addr; if (image_check_magic(hdr)) return IMAGE_FORMAT_LEGACY; } @@ -389,7 +389,7 @@ static int select_ramdisk(struct bootm_headers *images, const char *select, u8 a switch (genimg_get_format(buf)) { case IMAGE_FORMAT_LEGACY: if (CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT)) { - const image_header_t *rd_hdr; + const struct legacy_img_hdr *rd_hdr; printf("## Loading init Ramdisk from Legacy Image at %08lx ...\n", rd_addr); diff --git a/boot/image-fdt.c b/boot/image-fdt.c index 78417bd889..ca51796322 100644 --- a/boot/image-fdt.c +++ b/boot/image-fdt.c @@ -37,9 +37,9 @@ static void fdt_error(const char *msg) } #if CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT) -static const image_header_t *image_get_fdt(ulong fdt_addr) +static const struct legacy_img_hdr *image_get_fdt(ulong fdt_addr) { - const image_header_t *fdt_hdr = map_sysmem(fdt_addr, 0); + const struct legacy_img_hdr *fdt_hdr = map_sysmem(fdt_addr, 0); image_print_contents(fdt_hdr); @@ -358,7 +358,7 @@ static int select_fdt(struct bootm_headers *images, const char *select, u8 arch, switch (genimg_get_format(buf)) { #if CONFIG_IS_ENABLED(LEGACY_IMAGE_FORMAT) case IMAGE_FORMAT_LEGACY: { - const image_header_t *fdt_hdr; + const struct legacy_img_hdr *fdt_hdr; ulong load, load_end; ulong image_start, image_data, image_end; diff --git a/boot/image.c b/boot/image.c index a0d0cc2403..9f95b3260a 100644 --- a/boot/image.c +++ b/boot/image.c @@ -220,11 +220,11 @@ static const struct table_info table_info[IH_COUNT] = { /*****************************************************************************/ /* Legacy format routines */ /*****************************************************************************/ -int image_check_hcrc(const image_header_t *hdr) +int image_check_hcrc(const struct legacy_img_hdr *hdr) { ulong hcrc; ulong len = image_get_header_size(); - image_header_t header; + struct legacy_img_hdr header; /* Copy header so we can blank CRC field for re-calculation */ memmove(&header, (char *)hdr, image_get_header_size()); @@ -235,7 +235,7 @@ int image_check_hcrc(const image_header_t *hdr) return (hcrc == image_get_hcrc(hdr)); } -int image_check_dcrc(const image_header_t *hdr) +int image_check_dcrc(const struct legacy_img_hdr *hdr) { ulong data = image_get_data(hdr); ulong len = image_get_data_size(hdr); @@ -257,7 +257,7 @@ int image_check_dcrc(const image_header_t *hdr) * returns: * number of components */ -ulong image_multi_count(const image_header_t *hdr) +ulong image_multi_count(const struct legacy_img_hdr *hdr) { ulong i, count = 0; uint32_t *size; @@ -290,7 +290,7 @@ ulong image_multi_count(const image_header_t *hdr) * data address and size of the component, if idx is valid * 0 in data and len, if idx is out of range */ -void image_multi_getimg(const image_header_t *hdr, ulong idx, +void image_multi_getimg(const struct legacy_img_hdr *hdr, ulong idx, ulong *data, ulong *len) { int i; @@ -326,7 +326,7 @@ void image_multi_getimg(const image_header_t *hdr, ulong idx, } } -static void image_print_type(const image_header_t *hdr) +static void image_print_type(const struct legacy_img_hdr *hdr) { const char __maybe_unused *os, *arch, *type, *comp; @@ -352,7 +352,7 @@ static void image_print_type(const image_header_t *hdr) */ void image_print_contents(const void *ptr) { - const image_header_t *hdr = (const image_header_t *)ptr; + const struct legacy_img_hdr *hdr = (const struct legacy_img_hdr *)ptr; const char __maybe_unused *p; p = IMAGE_INDENT_STRING; diff --git a/cmd/bootm.c b/cmd/bootm.c index 9fe8ce4a27..d764a27002 100644 --- a/cmd/bootm.c +++ b/cmd/bootm.c @@ -511,7 +511,7 @@ static int do_imls_nand(void) continue; for (off = 0; off < mtd->size; off += mtd->erasesize) { - const image_header_t *header; + const struct legacy_img_hdr *header; int ret; if (nand_block_isbad(mtd, off)) @@ -529,7 +529,7 @@ static int do_imls_nand(void) switch (genimg_get_format(buffer)) { #if defined(CONFIG_LEGACY_IMAGE_FORMAT) case IMAGE_FORMAT_LEGACY: - header = (const image_header_t *)buffer; + header = (const struct legacy_img_hdr *)buffer; len = image_get_image_size(header); nand_imls_legacyimage(mtd, nand_dev, off, len); diff --git a/cmd/disk.c b/cmd/disk.c index cb3b990ba3..3d7bc2f601 100644 --- a/cmd/disk.c +++ b/cmd/disk.c @@ -20,7 +20,7 @@ int common_diskboot(struct cmd_tbl *cmdtp, const char *intf, int argc, ulong cnt; struct disk_partition info; #if defined(CONFIG_LEGACY_IMAGE_FORMAT) - image_header_t *hdr; + struct legacy_img_hdr *hdr; #endif struct blk_desc *dev_desc; @@ -68,7 +68,7 @@ int common_diskboot(struct cmd_tbl *cmdtp, const char *intf, int argc, switch (genimg_get_format((void *) addr)) { #if defined(CONFIG_LEGACY_IMAGE_FORMAT) case IMAGE_FORMAT_LEGACY: - hdr = (image_header_t *) addr; + hdr = (struct legacy_img_hdr *)addr; bootstage_mark(BOOTSTAGE_ID_IDE_FORMAT); diff --git a/cmd/fpga.c b/cmd/fpga.c index 9cf7651d8c..8c64e957db 100644 --- a/cmd/fpga.c +++ b/cmd/fpga.c @@ -288,7 +288,7 @@ static int do_fpga_loadmk(struct cmd_tbl *cmdtp, int flag, int argc, #if defined(CONFIG_LEGACY_IMAGE_FORMAT) case IMAGE_FORMAT_LEGACY: { - image_header_t *hdr = (image_header_t *)fpga_data; + struct legacy_img_hdr *hdr = (struct legacy_img_hdr *)fpga_data; ulong data; u8 comp; diff --git a/cmd/nand.c b/cmd/nand.c index e730484d0b..5bb43794e9 100644 --- a/cmd/nand.c +++ b/cmd/nand.c @@ -975,7 +975,7 @@ static int nand_load_image(struct cmd_tbl *cmdtp, struct mtd_info *mtd, char *s; size_t cnt; #if defined(CONFIG_LEGACY_IMAGE_FORMAT) - image_header_t *hdr; + struct legacy_img_hdr *hdr; #endif #if defined(CONFIG_FIT) const void *fit_hdr = NULL; @@ -1004,7 +1004,7 @@ static int nand_load_image(struct cmd_tbl *cmdtp, struct mtd_info *mtd, switch (genimg_get_format ((void *)addr)) { #if defined(CONFIG_LEGACY_IMAGE_FORMAT) case IMAGE_FORMAT_LEGACY: - hdr = (image_header_t *)addr; + hdr = (struct legacy_img_hdr *)addr; bootstage_mark(BOOTSTAGE_ID_NAND_TYPE); image_print_contents (hdr); diff --git a/cmd/source.c b/cmd/source.c index 81e015b64e..698d9f86d9 100644 --- a/cmd/source.c +++ b/cmd/source.c @@ -46,7 +46,7 @@ int image_source_script(ulong addr, const char *fit_uname) { ulong len; #if defined(CONFIG_LEGACY_IMAGE_FORMAT) - const image_header_t *hdr; + const struct legacy_img_hdr *hdr; #endif u32 *data; int verify; diff --git a/cmd/ximg.c b/cmd/ximg.c index 63b200430c..1c40fd27a0 100644 --- a/cmd/ximg.c +++ b/cmd/ximg.c @@ -42,7 +42,7 @@ do_imgextract(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) int part = 0; #if defined(CONFIG_LEGACY_IMAGE_FORMAT) ulong count; - image_header_t *hdr = NULL; + struct legacy_img_hdr *hdr = NULL; #endif #if defined(CONFIG_FIT) const char *uname = NULL; @@ -78,7 +78,7 @@ do_imgextract(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) printf("## Copying part %d from legacy image " "at %08lx ...\n", part, addr); - hdr = (image_header_t *)addr; + hdr = (struct legacy_img_hdr *)addr; if (!image_check_magic(hdr)) { printf("Bad Magic Number\n"); return 1; diff --git a/common/spl/spl.c b/common/spl/spl.c index 1283f9ec37..752b5b247c 100644 --- a/common/spl/spl.c +++ b/common/spl/spl.c @@ -227,7 +227,7 @@ __weak void spl_board_prepare_for_boot(void) /* Nothing to do! */ } -__weak struct image_header *spl_get_load_buffer(ssize_t offset, size_t size) +__weak struct legacy_img_hdr *spl_get_load_buffer(ssize_t offset, size_t size) { return map_sysmem(CONFIG_SYS_TEXT_BASE + offset, 0); } @@ -258,7 +258,7 @@ void spl_set_header_raw_uboot(struct spl_image_info *spl_image) #if CONFIG_IS_ENABLED(LOAD_FIT_FULL) /* Parse and load full fitImage in SPL */ static int spl_load_fit_image(struct spl_image_info *spl_image, - const struct image_header *header) + const struct legacy_img_hdr *header) { struct bootm_headers images; const char *fit_uname_config = NULL; @@ -359,7 +359,7 @@ __weak int spl_parse_board_header(struct spl_image_info *spl_image, } __weak int spl_parse_legacy_header(struct spl_image_info *spl_image, - const struct image_header *header) + const struct legacy_img_hdr *header) { /* LEGACY image not supported */ debug("Legacy boot image support not enabled, proceeding to other boot methods\n"); @@ -368,7 +368,7 @@ __weak int spl_parse_legacy_header(struct spl_image_info *spl_image, int spl_parse_image_header(struct spl_image_info *spl_image, const struct spl_boot_device *bootdev, - const struct image_header *header) + const struct legacy_img_hdr *header) { #if CONFIG_IS_ENABLED(LOAD_FIT_FULL) int ret = spl_load_fit_image(spl_image, header); diff --git a/common/spl/spl_ext.c b/common/spl/spl_ext.c index ebd914c492..f117c630bf 100644 --- a/common/spl/spl_ext.c +++ b/common/spl/spl_ext.c @@ -15,7 +15,7 @@ int spl_load_image_ext(struct spl_image_info *spl_image, const char *filename) { s32 err; - struct image_header *header; + struct legacy_img_hdr *header; loff_t filelen, actlen; struct disk_partition part_info = {}; @@ -41,7 +41,7 @@ int spl_load_image_ext(struct spl_image_info *spl_image, puts("spl: ext4fs_open failed\n"); goto end; } - err = ext4fs_read((char *)header, 0, sizeof(struct image_header), &actlen); + err = ext4fs_read((char *)header, 0, sizeof(struct legacy_img_hdr), &actlen); if (err < 0) { puts("spl: ext4fs_read failed\n"); goto end; diff --git a/common/spl/spl_fat.c b/common/spl/spl_fat.c index 5b270541fc..f8a5b80a3b 100644 --- a/common/spl/spl_fat.c +++ b/common/spl/spl_fat.c @@ -60,7 +60,7 @@ int spl_load_image_fat(struct spl_image_info *spl_image, const char *filename) { int err; - struct image_header *header; + struct legacy_img_hdr *header; err = spl_register_fat_device(block_dev, partition); if (err) @@ -68,7 +68,7 @@ int spl_load_image_fat(struct spl_image_info *spl_image, header = spl_get_load_buffer(-sizeof(*header), sizeof(*header)); - err = file_fat_read(filename, header, sizeof(struct image_header)); + err = file_fat_read(filename, header, sizeof(struct legacy_img_hdr)); if (err <= 0) goto end; @@ -78,7 +78,7 @@ int spl_load_image_fat(struct spl_image_info *spl_image, if (err <= 0) goto end; err = spl_parse_image_header(spl_image, bootdev, - (struct image_header *)CONFIG_SYS_LOAD_ADDR); + (struct legacy_img_hdr *)CONFIG_SYS_LOAD_ADDR); if (err == -EAGAIN) return err; if (err == 0) diff --git a/common/spl/spl_legacy.c b/common/spl/spl_legacy.c index ae8731c782..b3624dfbb7 100644 --- a/common/spl/spl_legacy.c +++ b/common/spl/spl_legacy.c @@ -16,9 +16,9 @@ #define LZMA_LEN (1 << 20) int spl_parse_legacy_header(struct spl_image_info *spl_image, - const struct image_header *header) + const struct legacy_img_hdr *header) { - u32 header_size = sizeof(struct image_header); + u32 header_size = sizeof(struct legacy_img_hdr); /* check uImage header CRC */ if (IS_ENABLED(CONFIG_SPL_LEGACY_IMAGE_CRC_CHECK) && @@ -67,7 +67,7 @@ int spl_parse_legacy_header(struct spl_image_info *spl_image, * following switch/case statement in spl_load_legacy_img() away due to * Dead Code Elimination. */ -static inline int spl_image_get_comp(const struct image_header *hdr) +static inline int spl_image_get_comp(const struct legacy_img_hdr *hdr) { if (IS_ENABLED(CONFIG_SPL_LZMA)) return image_get_comp(hdr); @@ -81,7 +81,7 @@ int spl_load_legacy_img(struct spl_image_info *spl_image, { __maybe_unused SizeT lzma_len; __maybe_unused void *src; - struct image_header hdr; + struct legacy_img_hdr hdr; ulong dataptr; int ret; diff --git a/common/spl/spl_mmc.c b/common/spl/spl_mmc.c index 23a395e63d..e4135b2048 100644 --- a/common/spl/spl_mmc.c +++ b/common/spl/spl_mmc.c @@ -20,7 +20,7 @@ static int mmc_load_legacy(struct spl_image_info *spl_image, struct spl_boot_device *bootdev, struct mmc *mmc, - ulong sector, struct image_header *header) + ulong sector, struct legacy_img_hdr *header) { u32 image_offset_sectors; u32 image_size_sectors; @@ -83,7 +83,7 @@ int mmc_load_image_raw_sector(struct spl_image_info *spl_image, struct mmc *mmc, unsigned long sector) { unsigned long count; - struct image_header *header; + struct legacy_img_hdr *header; struct blk_desc *bd = mmc_get_blk_desc(mmc); int ret = 0; diff --git a/common/spl/spl_nand.c b/common/spl/spl_nand.c index 7b7579a2df..a16738818c 100644 --- a/common/spl/spl_nand.c +++ b/common/spl/spl_nand.c @@ -78,7 +78,7 @@ struct mtd_info * __weak nand_get_mtd(void) static int spl_nand_load_element(struct spl_image_info *spl_image, struct spl_boot_device *bootdev, - int offset, struct image_header *header) + int offset, struct legacy_img_hdr *header) { struct mtd_info *mtd = nand_get_mtd(); int bl_len = mtd ? mtd->writesize : 1; @@ -133,7 +133,7 @@ static int spl_nand_load_image(struct spl_image_info *spl_image, struct spl_boot_device *bootdev) { int err; - struct image_header *header; + struct legacy_img_hdr *header; int *src __attribute__((unused)); int *dst __attribute__((unused)); diff --git a/common/spl/spl_net.c b/common/spl/spl_net.c index a853e6aead..b2c901b554 100644 --- a/common/spl/spl_net.c +++ b/common/spl/spl_net.c @@ -28,7 +28,7 @@ static ulong spl_net_load_read(struct spl_load_info *load, ulong sector, static int spl_net_load_image(struct spl_image_info *spl_image, struct spl_boot_device *bootdev) { - struct image_header *header = (struct image_header *)image_load_addr; + struct legacy_img_hdr *header = (struct legacy_img_hdr *)image_load_addr; int rv; env_init(); diff --git a/common/spl/spl_nor.c b/common/spl/spl_nor.c index 7986e930d2..281c6136f5 100644 --- a/common/spl/spl_nor.c +++ b/common/spl/spl_nor.c @@ -26,7 +26,7 @@ unsigned long __weak spl_nor_get_uboot_base(void) static int spl_nor_load_image(struct spl_image_info *spl_image, struct spl_boot_device *bootdev) { - __maybe_unused const struct image_header *header; + __maybe_unused const struct legacy_img_hdr *header; __maybe_unused struct spl_load_info load; /* @@ -41,7 +41,7 @@ static int spl_nor_load_image(struct spl_image_info *spl_image, * Load Linux from its location in NOR flash to its defined * location in SDRAM */ - header = (const struct image_header *)CONFIG_SYS_OS_BASE; + header = (const struct legacy_img_hdr *)CONFIG_SYS_OS_BASE; #ifdef CONFIG_SPL_LOAD_FIT if (image_get_magic(header) == FDT_MAGIC) { int ret; @@ -72,7 +72,7 @@ static int spl_nor_load_image(struct spl_image_info *spl_image, memcpy((void *)spl_image->load_addr, (void *)(CONFIG_SYS_OS_BASE + - sizeof(struct image_header)), + sizeof(struct legacy_img_hdr)), spl_image->size); #ifdef CONFIG_SYS_SPL_ARGS_ADDR spl_image->arg = (void *)CONFIG_SYS_SPL_ARGS_ADDR; @@ -92,7 +92,7 @@ static int spl_nor_load_image(struct spl_image_info *spl_image, * defined location in SDRAM */ #ifdef CONFIG_SPL_LOAD_FIT - header = (const struct image_header *)spl_nor_get_uboot_base(); + header = (const struct legacy_img_hdr *)spl_nor_get_uboot_base(); if (image_get_magic(header) == FDT_MAGIC) { debug("Found FIT format U-Boot\n"); load.bl_len = 1; diff --git a/common/spl/spl_onenand.c b/common/spl/spl_onenand.c index f80769a027..53a8c6de89 100644 --- a/common/spl/spl_onenand.c +++ b/common/spl/spl_onenand.c @@ -18,7 +18,7 @@ static int spl_onenand_load_image(struct spl_image_info *spl_image, struct spl_boot_device *bootdev) { - struct image_header *header; + struct legacy_img_hdr *header; int ret; debug("spl: onenand\n"); diff --git a/common/spl/spl_ram.c b/common/spl/spl_ram.c index d64710878c..2b1ac19152 100644 --- a/common/spl/spl_ram.c +++ b/common/spl/spl_ram.c @@ -41,9 +41,9 @@ static ulong spl_ram_load_read(struct spl_load_info *load, ulong sector, static int spl_ram_load_image(struct spl_image_info *spl_image, struct spl_boot_device *bootdev) { - struct image_header *header; + struct legacy_img_hdr *header; - header = (struct image_header *)CONFIG_SPL_LOAD_FIT_ADDRESS; + header = (struct legacy_img_hdr *)CONFIG_SPL_LOAD_FIT_ADDRESS; if (CONFIG_IS_ENABLED(IMAGE_PRE_LOAD)) { unsigned long addr = (unsigned long)header; @@ -53,7 +53,7 @@ static int spl_ram_load_image(struct spl_image_info *spl_image, return ret; addr += image_load_offset; - header = (struct image_header *)addr; + header = (struct legacy_img_hdr *)addr; } #if CONFIG_IS_ENABLED(DFU) @@ -87,7 +87,7 @@ static int spl_ram_load_image(struct spl_image_info *spl_image, u_boot_pos = (ulong)spl_get_load_buffer(-sizeof(*header), sizeof(*header)); } - header = (struct image_header *)map_sysmem(u_boot_pos, 0); + header = (struct legacy_img_hdr *)map_sysmem(u_boot_pos, 0); spl_parse_image_header(spl_image, bootdev, header); } diff --git a/common/spl/spl_sata.c b/common/spl/spl_sata.c index 6c36f2ca66..9ae0273068 100644 --- a/common/spl/spl_sata.c +++ b/common/spl/spl_sata.c @@ -30,7 +30,7 @@ static int spl_sata_load_image_raw(struct spl_image_info *spl_image, struct spl_boot_device *bootdev, struct blk_desc *stor_dev, unsigned long sector) { - struct image_header *header; + struct legacy_img_hdr *header; unsigned long count; u32 image_size_sectors; u32 image_offset_sectors; diff --git a/common/spl/spl_semihosting.c b/common/spl/spl_semihosting.c index df6aeb2951..5b5e842a11 100644 --- a/common/spl/spl_semihosting.c +++ b/common/spl/spl_semihosting.c @@ -27,7 +27,7 @@ static int spl_smh_load_image(struct spl_image_info *spl_image, const char *filename = CONFIG_SPL_FS_LOAD_PAYLOAD_NAME; int ret; long fd, len; - struct image_header *header = + struct legacy_img_hdr *header = spl_get_load_buffer(-sizeof(*header), sizeof(*header)); fd = smh_open(filename, MODE_READ | MODE_BINARY); @@ -43,7 +43,7 @@ static int spl_smh_load_image(struct spl_image_info *spl_image, } len = ret; - ret = smh_read_full(fd, header, sizeof(struct image_header)); + ret = smh_read_full(fd, header, sizeof(struct legacy_img_hdr)); if (ret) { log_debug("could not read image header: %d\n", ret); goto out; diff --git a/common/spl/spl_spi.c b/common/spl/spl_spi.c index d959ad1145..da6742416e 100644 --- a/common/spl/spl_spi.c +++ b/common/spl/spl_spi.c @@ -26,7 +26,7 @@ static int spi_load_image_os(struct spl_image_info *spl_image, struct spl_boot_device *bootdev, struct spi_flash *flash, - struct image_header *header) + struct legacy_img_hdr *header) { int err; @@ -92,7 +92,7 @@ static int spl_spi_load_image(struct spl_image_info *spl_image, int err = 0; unsigned int payload_offs; struct spi_flash *flash; - struct image_header *header; + struct legacy_img_hdr *header; unsigned int sf_bus = spl_spi_boot_bus(); unsigned int sf_cs = spl_spi_boot_cs(); @@ -139,7 +139,7 @@ static int spl_spi_load_image(struct spl_image_info *spl_image, if (err) return err; err = spl_parse_image_header(spl_image, bootdev, - (struct image_header *)CONFIG_SYS_LOAD_ADDR); + (struct legacy_img_hdr *)CONFIG_SYS_LOAD_ADDR); } else if (IS_ENABLED(CONFIG_SPL_LOAD_FIT) && image_get_magic(header) == FDT_MAGIC) { struct spl_load_info load; diff --git a/common/spl/spl_ubi.c b/common/spl/spl_ubi.c index bdf5cc4c38..fb804f0208 100644 --- a/common/spl/spl_ubi.c +++ b/common/spl/spl_ubi.c @@ -15,7 +15,7 @@ int spl_ubi_load_image(struct spl_image_info *spl_image, struct spl_boot_device *bootdev) { - struct image_header *header; + struct legacy_img_hdr *header; struct ubispl_info info; struct ubispl_load volumes[2]; int ret = 1; @@ -54,7 +54,7 @@ int spl_ubi_load_image(struct spl_image_info *spl_image, ret = ubispl_load_volumes(&info, volumes, 2); if (!ret) { - header = (struct image_header *)volumes[0].load_addr; + header = (struct legacy_img_hdr *)volumes[0].load_addr; spl_parse_image_header(spl_image, bootdev, header); puts("Linux loaded.\n"); goto out; diff --git a/common/spl/spl_xip.c b/common/spl/spl_xip.c index e9a40b0ec7..1258d85e63 100644 --- a/common/spl/spl_xip.c +++ b/common/spl/spl_xip.c @@ -25,6 +25,6 @@ static int spl_xip(struct spl_image_info *spl_image, } #endif return(spl_parse_image_header(spl_image, bootdev, - (const struct image_header *)CONFIG_SYS_UBOOT_BASE)); + (const struct legacy_img_hdr *)CONFIG_SYS_UBOOT_BASE)); } SPL_LOAD_IMAGE_METHOD("XIP", 0, BOOT_DEVICE_XIP, spl_xip); diff --git a/common/spl/spl_ymodem.c b/common/spl/spl_ymodem.c index fdd5261042..038b443845 100644 --- a/common/spl/spl_ymodem.c +++ b/common/spl/spl_ymodem.c @@ -96,7 +96,7 @@ int spl_ymodem_load_image(struct spl_image_info *spl_image, int ret; connection_info_t info; char buf[BUF_SIZE]; - struct image_header *ih = NULL; + struct legacy_img_hdr *ih = NULL; ulong addr = 0; info.mode = xyzModem_ymodem; @@ -111,9 +111,9 @@ int spl_ymodem_load_image(struct spl_image_info *spl_image, goto end_stream; if (IS_ENABLED(CONFIG_SPL_LOAD_FIT_FULL) && - image_get_magic((struct image_header *)buf) == FDT_MAGIC) { + image_get_magic((struct legacy_img_hdr *)buf) == FDT_MAGIC) { addr = CONFIG_SYS_LOAD_ADDR; - ih = (struct image_header *)addr; + ih = (struct legacy_img_hdr *)addr; memcpy((void *)addr, buf, res); size += res; @@ -129,7 +129,7 @@ int spl_ymodem_load_image(struct spl_image_info *spl_image, if (ret) return ret; } else if (IS_ENABLED(CONFIG_SPL_LOAD_FIT) && - image_get_magic((struct image_header *)buf) == FDT_MAGIC) { + image_get_magic((struct legacy_img_hdr *)buf) == FDT_MAGIC) { struct spl_load_info load; struct ymodem_fit_info info; @@ -147,7 +147,7 @@ int spl_ymodem_load_image(struct spl_image_info *spl_image, while ((res = xyzModem_stream_read(buf, BUF_SIZE, &err)) > 0) size += res; } else { - ih = (struct image_header *)buf; + ih = (struct legacy_img_hdr *)buf; ret = spl_parse_image_header(spl_image, bootdev, ih); if (ret) goto end_stream; @@ -158,7 +158,7 @@ int spl_ymodem_load_image(struct spl_image_info *spl_image, #endif addr = spl_image->load_addr; memcpy((void *)addr, buf, res); - ih = (struct image_header *)addr; + ih = (struct legacy_img_hdr *)addr; size += res; addr += res; @@ -177,7 +177,7 @@ end_stream: #ifdef CONFIG_SPL_GZIP if (!(IS_ENABLED(CONFIG_SPL_LOAD_FIT) && - image_get_magic((struct image_header *)buf) == FDT_MAGIC) && + image_get_magic((struct legacy_img_hdr *)buf) == FDT_MAGIC) && (ih->ih_comp == IH_COMP_GZIP)) { if (gunzip((void *)(spl_image->load_addr + sizeof(*ih)), CONFIG_SYS_BOOTM_LEN, diff --git a/common/splash_source.c b/common/splash_source.c index 2c03cbdf92..87e55a54f8 100644 --- a/common/splash_source.c +++ b/common/splash_source.c @@ -327,17 +327,17 @@ static int splash_load_fit(struct splash_location *location, u32 bmp_load_addr) int external_splash_addr; int external_splash_size; bool is_splash_external = false; - struct image_header *img_header; + struct legacy_img_hdr *img_header; const u32 *fit_header; u32 fit_size; - const size_t header_size = sizeof(struct image_header); + const size_t header_size = sizeof(struct legacy_img_hdr); /* Read in image header */ res = splash_storage_read_raw(location, bmp_load_addr, header_size); if (res < 0) return res; - img_header = (struct image_header *)bmp_load_addr; + img_header = (struct legacy_img_hdr *)bmp_load_addr; if (image_get_magic(img_header) != FDT_MAGIC) { printf("Could not find FDT magic\n"); return -EINVAL; diff --git a/doc/uImage.FIT/source_file_format.txt b/doc/uImage.FIT/source_file_format.txt index 6870111840..0a03c942bd 100644 --- a/doc/uImage.FIT/source_file_format.txt +++ b/doc/uImage.FIT/source_file_format.txt @@ -23,7 +23,7 @@ in the system memory and passed to bootm as a arguments. Some of them may be missing: FDT is not present for legacy platforms, ramdisk is always optional. Additionally, old uImage format has been extended to support multi sub-images but the support is limited by simple format of the legacy uImage structure. -Single binary header 'struct image_header' is not flexible enough to cover all +Single binary header 'struct legacy_img_hdr' is not flexible enough to cover all possible scenarios. All those factors combined clearly show that there is a need for new, more diff --git a/drivers/fpga/socfpga_arria10.c b/drivers/fpga/socfpga_arria10.c index e86e3b7431..3b785e67d0 100644 --- a/drivers/fpga/socfpga_arria10.c +++ b/drivers/fpga/socfpga_arria10.c @@ -555,14 +555,14 @@ static int first_loading_rbf_to_buffer(struct udevice *dev, /* Load image header into buffer */ ret = request_firmware_into_buf(dev, fpga_loadfs->fpga_fsinfo->filename, - buffer_p, sizeof(struct image_header), + buffer_p, sizeof(struct legacy_img_hdr), 0); if (ret < 0) { debug("FPGA: Failed to read image header from flash.\n"); return -ENOENT; } - if (image_get_magic((struct image_header *)buffer_p) != FDT_MAGIC) { + if (image_get_magic((struct legacy_img_hdr *)buffer_p) != FDT_MAGIC) { debug("FPGA: No FDT magic was found.\n"); return -EBADF; } diff --git a/drivers/usb/gadget/f_sdp.c b/drivers/usb/gadget/f_sdp.c index 74548ab603..af4b167e17 100644 --- a/drivers/usb/gadget/f_sdp.c +++ b/drivers/usb/gadget/f_sdp.c @@ -835,7 +835,7 @@ static int sdp_handle_in_ep(struct spl_image_info *spl_image, printf("Found header at 0x%08x\n", sdp_func->jmp_address); - image_header_t *header = + struct legacy_img_hdr *header = sdp_ptr(sdp_func->jmp_address); #ifdef CONFIG_SPL_LOAD_FIT if (image_get_magic(header) == FDT_MAGIC) { diff --git a/include/configs/uniphier.h b/include/configs/uniphier.h index 15ae0844c1..d9e95abcc1 100644 --- a/include/configs/uniphier.h +++ b/include/configs/uniphier.h @@ -169,7 +169,7 @@ /* only for SPL */ -/* subtract sizeof(struct image_header) */ +/* subtract sizeof(struct legacy_img_hdr) */ #define CONFIG_SYS_UBOOT_BASE (0x130000 - 0x40) #endif /* __CONFIG_UNIPHIER_H__ */ diff --git a/include/image.h b/include/image.h index b58550fd64..eb2513c5b7 100644 --- a/include/image.h +++ b/include/image.h @@ -263,7 +263,7 @@ enum { * Legacy format image header, * all data in network byte order (aka natural aka bigendian). */ -typedef struct image_header { +struct legacy_img_hdr { uint32_t ih_magic; /* Image Header Magic Number */ uint32_t ih_hcrc; /* Image Header CRC Checksum */ uint32_t ih_time; /* Image Creation Timestamp */ @@ -276,7 +276,7 @@ typedef struct image_header { uint8_t ih_type; /* Image Type */ uint8_t ih_comp; /* Compression Type */ uint8_t ih_name[IH_NMLEN]; /* Image Name */ -} image_header_t; +}; struct image_info { ulong start, end; /* start/end of blob */ @@ -296,8 +296,8 @@ struct bootm_headers { * then boot_get_ramdisk() and get_fdt() will attempt to get * data from second and third component accordingly. */ - image_header_t *legacy_hdr_os; /* image header pointer */ - image_header_t legacy_hdr_os_copy; /* header copy */ + struct legacy_img_hdr *legacy_hdr_os; /* image header pointer */ + struct legacy_img_hdr legacy_hdr_os_copy; /* header copy */ ulong legacy_hdr_valid; /* @@ -696,11 +696,11 @@ int boot_get_kbd(struct lmb *lmb, struct bd_info **kbd); /*******************************************************************/ static inline uint32_t image_get_header_size(void) { - return (sizeof(image_header_t)); + return sizeof(struct legacy_img_hdr); } #define image_get_hdr_l(f) \ - static inline uint32_t image_get_##f(const image_header_t *hdr) \ + static inline uint32_t image_get_##f(const struct legacy_img_hdr *hdr) \ { \ return uimage_to_cpu(hdr->ih_##f); \ } @@ -713,7 +713,7 @@ image_get_hdr_l(ep) /* image_get_ep */ image_get_hdr_l(dcrc) /* image_get_dcrc */ #define image_get_hdr_b(f) \ - static inline uint8_t image_get_##f(const image_header_t *hdr) \ + static inline uint8_t image_get_##f(const struct legacy_img_hdr *hdr) \ { \ return hdr->ih_##f; \ } @@ -722,12 +722,12 @@ image_get_hdr_b(arch) /* image_get_arch */ image_get_hdr_b(type) /* image_get_type */ image_get_hdr_b(comp) /* image_get_comp */ -static inline char *image_get_name(const image_header_t *hdr) +static inline char *image_get_name(const struct legacy_img_hdr *hdr) { return (char *)hdr->ih_name; } -static inline uint32_t image_get_data_size(const image_header_t *hdr) +static inline uint32_t image_get_data_size(const struct legacy_img_hdr *hdr) { return image_get_size(hdr); } @@ -743,22 +743,23 @@ static inline uint32_t image_get_data_size(const image_header_t *hdr) * returns: * image payload data start address */ -static inline ulong image_get_data(const image_header_t *hdr) +static inline ulong image_get_data(const struct legacy_img_hdr *hdr) { return ((ulong)hdr + image_get_header_size()); } -static inline uint32_t image_get_image_size(const image_header_t *hdr) +static inline uint32_t image_get_image_size(const struct legacy_img_hdr *hdr) { return (image_get_size(hdr) + image_get_header_size()); } -static inline ulong image_get_image_end(const image_header_t *hdr) + +static inline ulong image_get_image_end(const struct legacy_img_hdr *hdr) { return ((ulong)hdr + image_get_image_size(hdr)); } #define image_set_hdr_l(f) \ - static inline void image_set_##f(image_header_t *hdr, uint32_t val) \ + static inline void image_set_##f(struct legacy_img_hdr *hdr, uint32_t val) \ { \ hdr->ih_##f = cpu_to_uimage(val); \ } @@ -771,7 +772,7 @@ image_set_hdr_l(ep) /* image_set_ep */ image_set_hdr_l(dcrc) /* image_set_dcrc */ #define image_set_hdr_b(f) \ - static inline void image_set_##f(image_header_t *hdr, uint8_t val) \ + static inline void image_set_##f(struct legacy_img_hdr *hdr, uint8_t val) \ { \ hdr->ih_##f = val; \ } @@ -780,13 +781,13 @@ image_set_hdr_b(arch) /* image_set_arch */ image_set_hdr_b(type) /* image_set_type */ image_set_hdr_b(comp) /* image_set_comp */ -static inline void image_set_name(image_header_t *hdr, const char *name) +static inline void image_set_name(struct legacy_img_hdr *hdr, const char *name) { strncpy(image_get_name(hdr), name, IH_NMLEN); } -int image_check_hcrc(const image_header_t *hdr); -int image_check_dcrc(const image_header_t *hdr); +int image_check_hcrc(const struct legacy_img_hdr *hdr); +int image_check_dcrc(const struct legacy_img_hdr *hdr); #ifndef USE_HOSTCC ulong env_get_bootm_low(void); phys_size_t env_get_bootm_size(void); @@ -794,15 +795,17 @@ phys_size_t env_get_bootm_mapsize(void); #endif void memmove_wd(void *to, void *from, size_t len, ulong chunksz); -static inline int image_check_magic(const image_header_t *hdr) +static inline int image_check_magic(const struct legacy_img_hdr *hdr) { return (image_get_magic(hdr) == IH_MAGIC); } -static inline int image_check_type(const image_header_t *hdr, uint8_t type) + +static inline int image_check_type(const struct legacy_img_hdr *hdr, uint8_t type) { return (image_get_type(hdr) == type); } -static inline int image_check_arch(const image_header_t *hdr, uint8_t arch) + +static inline int image_check_arch(const struct legacy_img_hdr *hdr, uint8_t arch) { /* Let's assume that sandbox can load any architecture */ if (!tools_build() && IS_ENABLED(CONFIG_SANDBOX)) @@ -810,19 +813,20 @@ static inline int image_check_arch(const image_header_t *hdr, uint8_t arch) return (image_get_arch(hdr) == arch) || (image_get_arch(hdr) == IH_ARCH_ARM && arch == IH_ARCH_ARM64); } -static inline int image_check_os(const image_header_t *hdr, uint8_t os) + +static inline int image_check_os(const struct legacy_img_hdr *hdr, uint8_t os) { return (image_get_os(hdr) == os); } -ulong image_multi_count(const image_header_t *hdr); -void image_multi_getimg(const image_header_t *hdr, ulong idx, +ulong image_multi_count(const struct legacy_img_hdr *hdr); +void image_multi_getimg(const struct legacy_img_hdr *hdr, ulong idx, ulong *data, ulong *len); void image_print_contents(const void *hdr); #ifndef USE_HOSTCC -static inline int image_check_target_arch(const image_header_t *hdr) +static inline int image_check_target_arch(const struct legacy_img_hdr *hdr) { #ifndef IH_ARCH_DEFAULT # error "please define IH_ARCH_DEFAULT in your arch asm/u-boot.h" diff --git a/include/spl.h b/include/spl.h index aac6648f94..0fc3686bbc 100644 --- a/include/spl.h +++ b/include/spl.h @@ -17,7 +17,7 @@ #include struct blk_desc; -struct image_header; +struct legacy_img_hdr; /* Value in r0 indicates we booted from U-Boot */ #define UBOOT_NOT_LOADED_FROM_SPL 0x13578642 @@ -29,7 +29,7 @@ struct image_header; #define MMCSD_MODE_EMMCBOOT 3 struct blk_desc; -struct image_header; +struct legacy_img_hdr; struct spl_boot_device; /* @@ -476,7 +476,7 @@ void spl_set_header_raw_uboot(struct spl_image_info *spl_image); */ int spl_parse_image_header(struct spl_image_info *spl_image, const struct spl_boot_device *bootdev, - const struct image_header *header); + const struct legacy_img_hdr *header); void spl_board_prepare_for_linux(void); @@ -865,7 +865,7 @@ void spl_perform_fixups(struct spl_image_info *spl_image); * Returns memory area which can be populated by partial image data, * ie. uImage or fitImage header. */ -struct image_header *spl_get_load_buffer(ssize_t offset, size_t size); +struct legacy_img_hdr *spl_get_load_buffer(ssize_t offset, size_t size); void spl_save_restore_data(void); #endif diff --git a/include/tee/optee.h b/include/tee/optee.h index 5412bc7386..77729450bb 100644 --- a/include/tee/optee.h +++ b/include/tee/optee.h @@ -30,7 +30,7 @@ struct optee_header { }; static inline uint32_t -optee_image_get_entry_point(const struct image_header *hdr) +optee_image_get_entry_point(const struct legacy_img_hdr *hdr) { struct optee_header *optee_hdr = (struct optee_header *)(hdr + 1); @@ -38,7 +38,7 @@ optee_image_get_entry_point(const struct image_header *hdr) } static inline uint32_t -optee_image_get_load_addr(const struct image_header *hdr) +optee_image_get_load_addr(const struct legacy_img_hdr *hdr) { return optee_image_get_entry_point(hdr) - sizeof(struct optee_header); } diff --git a/test/image/spl_load.c b/test/image/spl_load.c index df389e26f9..4e27ff460a 100644 --- a/test/image/spl_load.c +++ b/test/image/spl_load.c @@ -49,7 +49,7 @@ int board_fit_config_name_match(const char *name) return 0; } -struct image_header *spl_get_load_buffer(ssize_t offset, size_t size) +struct legacy_img_hdr *spl_get_load_buffer(ssize_t offset, size_t size) { return map_sysmem(0x100000, 0); } @@ -57,7 +57,7 @@ struct image_header *spl_get_load_buffer(ssize_t offset, size_t size) static int spl_test_load(struct unit_test_state *uts) { struct spl_image_info image; - struct image_header *header; + struct legacy_img_hdr *header; struct text_ctx text_ctx; struct spl_load_info load; char fname[256]; diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py index ecb3595603..261107b335 100644 --- a/tools/binman/ftest.py +++ b/tools/binman/ftest.py @@ -5782,7 +5782,7 @@ fdt fdtmap Extract the devicetree blob from the fdtmap # Check that the data appears in the file somewhere self.assertIn(U_BOOT_SPL_DATA, data) - # Get struct image_header -> ih_name + # Get struct legacy_img_hdr -> ih_name name = data[0x20:0x40] # Build the filename that we expect to be placed in there, by virtue of @@ -5799,7 +5799,7 @@ fdt fdtmap Extract the devicetree blob from the fdtmap # Check that the data appears in the file somewhere self.assertIn(U_BOOT_SPL_DATA, data) - # Get struct image_header -> ih_name + # Get struct legacy_img_hdr -> ih_name name = data[0x20:0x40] # Build the filename that we expect to be placed in there, by virtue of diff --git a/tools/default_image.c b/tools/default_image.c index e164c0c27d..4a067e6586 100644 --- a/tools/default_image.c +++ b/tools/default_image.c @@ -22,7 +22,7 @@ #include #include -static image_header_t header; +static struct legacy_img_hdr header; static int image_check_image_types(uint8_t type) { @@ -46,15 +46,15 @@ static int image_verify_header(unsigned char *ptr, int image_size, uint32_t len; const unsigned char *data; uint32_t checksum; - image_header_t header; - image_header_t *hdr = &header; + struct legacy_img_hdr header; + struct legacy_img_hdr *hdr = &header; /* * create copy of header so that we can blank out the * checksum field for checking - this can't be done * on the PROT_READ mapped data. */ - memcpy(hdr, ptr, sizeof(image_header_t)); + memcpy(hdr, ptr, sizeof(struct legacy_img_hdr)); if (be32_to_cpu(hdr->ih_magic) != IH_MAGIC) { debug("%s: Bad Magic Number: \"%s\" is no valid image\n", @@ -63,7 +63,7 @@ static int image_verify_header(unsigned char *ptr, int image_size, } data = (const unsigned char *)hdr; - len = sizeof(image_header_t); + len = sizeof(struct legacy_img_hdr); checksum = be32_to_cpu(hdr->ih_hcrc); hdr->ih_hcrc = cpu_to_be32(0); /* clear for re-calculation */ @@ -74,8 +74,8 @@ static int image_verify_header(unsigned char *ptr, int image_size, return -FDT_ERR_BADSTATE; } - data = (const unsigned char *)ptr + sizeof(image_header_t); - len = image_size - sizeof(image_header_t) ; + data = (const unsigned char *)ptr + sizeof(struct legacy_img_hdr); + len = image_size - sizeof(struct legacy_img_hdr); checksum = be32_to_cpu(hdr->ih_dcrc); if (crc32(0, data, len) != checksum) { @@ -94,13 +94,12 @@ static void image_set_header(void *ptr, struct stat *sbuf, int ifd, uint32_t imagesize; uint32_t ep; uint32_t addr; - - image_header_t * hdr = (image_header_t *)ptr; + struct legacy_img_hdr *hdr = (struct legacy_img_hdr *)ptr; checksum = crc32(0, (const unsigned char *)(ptr + - sizeof(image_header_t)), - sbuf->st_size - sizeof(image_header_t)); + sizeof(struct legacy_img_hdr)), + sbuf->st_size - sizeof(struct legacy_img_hdr)); time = imagetool_get_source_date(params->cmdname, sbuf->st_mtime); ep = params->ep; @@ -108,11 +107,11 @@ static void image_set_header(void *ptr, struct stat *sbuf, int ifd, if (params->type == IH_TYPE_FIRMWARE_IVT) /* Add size of CSF minus IVT */ - imagesize = sbuf->st_size - sizeof(image_header_t) + imagesize = sbuf->st_size - sizeof(struct legacy_img_hdr) + 0x2060 - sizeof(flash_header_v2_t); else - imagesize = sbuf->st_size - sizeof(image_header_t); + imagesize = sbuf->st_size - sizeof(struct legacy_img_hdr); if (params->os == IH_OS_TEE) { addr = optee_image_get_load_addr(hdr); @@ -134,14 +133,14 @@ static void image_set_header(void *ptr, struct stat *sbuf, int ifd, image_set_name(hdr, params->imagename); checksum = crc32(0, (const unsigned char *)hdr, - sizeof(image_header_t)); + sizeof(struct legacy_img_hdr)); image_set_hcrc(hdr, checksum); } static int image_extract_subimage(void *ptr, struct image_tool_params *params) { - const image_header_t *hdr = (const image_header_t *)ptr; + const struct legacy_img_hdr *hdr = (const struct legacy_img_hdr *)ptr; ulong file_data; ulong file_len; @@ -175,7 +174,7 @@ static int image_extract_subimage(void *ptr, struct image_tool_params *params) U_BOOT_IMAGE_TYPE( defimage, "Default Image support", - sizeof(image_header_t), + sizeof(struct legacy_img_hdr), (void *)&header, image_check_params, image_verify_header, diff --git a/tools/fit_image.c b/tools/fit_image.c index 979f2411ee..923a9755b7 100644 --- a/tools/fit_image.c +++ b/tools/fit_image.c @@ -22,7 +22,7 @@ #include #include -static image_header_t header; +static struct legacy_img_hdr header; static int fit_add_file_data(struct image_tool_params *params, size_t size_inc, const char *tmpfile) @@ -915,7 +915,7 @@ static int fit_check_params(struct image_tool_params *params) U_BOOT_IMAGE_TYPE( fitimage, "FIT Image support", - sizeof(image_header_t), + sizeof(struct legacy_img_hdr), (void *)&header, fit_check_params, fit_verify_header, diff --git a/tools/imx8mimage.c b/tools/imx8mimage.c index a4699decf9..35d0a92bfd 100644 --- a/tools/imx8mimage.c +++ b/tools/imx8mimage.c @@ -318,7 +318,7 @@ err_mmap: static int generate_ivt_for_fit(int fd, int fit_offset, uint32_t ep, uint32_t *fit_load_addr) { - image_header_t image_header; + struct legacy_img_hdr image_header; int ret; uint32_t fit_size, load_addr; @@ -330,8 +330,8 @@ static int generate_ivt_for_fit(int fd, int fit_offset, uint32_t ep, exit(EXIT_FAILURE); } - if (read(fd, (char *)&image_header, sizeof(image_header_t)) != - sizeof(image_header_t)) { + if (read(fd, (char *)&image_header, sizeof(struct legacy_img_hdr)) != + sizeof(struct legacy_img_hdr)) { fprintf(stderr, "generate_ivt_for_fit read failed: %s\n", strerror(errno)); exit(EXIT_FAILURE); @@ -600,7 +600,7 @@ void build_image(int ofd) close(sld_fd); file_off = sld_header_off; - file_off += sbuf.st_size + sizeof(image_header_t); + file_off += sbuf.st_size + sizeof(struct legacy_img_hdr); } } diff --git a/tools/mkimage.c b/tools/mkimage.c index 597cb3a5ce..30c6df7708 100644 --- a/tools/mkimage.c +++ b/tools/mkimage.c @@ -845,7 +845,7 @@ copy_file (int ifd, const char *datafile, int pad) if (params.xflag) { unsigned char *p = NULL; /* - * XIP: do not append the image_header_t at the + * XIP: do not append the struct legacy_img_hdr at the * beginning of the file, but consume the space * reserved for it. */ diff --git a/tools/mtk_image.c b/tools/mtk_image.c index 9b3136afa3..5ef9334163 100644 --- a/tools/mtk_image.c +++ b/tools/mtk_image.c @@ -427,10 +427,10 @@ static uint32_t crc32be_cal(const void *data, size_t length) static int mtk_image_verify_mt7621_header(const uint8_t *ptr, int print) { - const image_header_t *hdr = (const image_header_t *)ptr; + const struct legacy_img_hdr *hdr = (const struct legacy_img_hdr *)ptr; struct mt7621_nand_header *nhdr; uint32_t spl_size, crcval; - image_header_t header; + struct legacy_img_hdr header; int ret; spl_size = image_get_size(hdr); @@ -490,7 +490,7 @@ static int mtk_image_verify_mt7621_header(const uint8_t *ptr, int print) static int mtk_image_verify_header(unsigned char *ptr, int image_size, struct image_tool_params *params) { - image_header_t *hdr = (image_header_t *)ptr; + struct legacy_img_hdr *hdr = (struct legacy_img_hdr *)ptr; union lk_hdr *lk = (union lk_hdr *)ptr; /* nothing to verify for LK image header */ @@ -512,7 +512,7 @@ static int mtk_image_verify_header(unsigned char *ptr, int image_size, static void mtk_image_print_header(const void *ptr) { - image_header_t *hdr = (image_header_t *)ptr; + struct legacy_img_hdr *hdr = (struct legacy_img_hdr *)ptr; union lk_hdr *lk = (union lk_hdr *)ptr; if (le32_to_cpu(lk->magic) == LK_PART_MAGIC) { @@ -691,7 +691,7 @@ static void mtk_image_set_nand_header(void *ptr, off_t filesize, static void mtk_image_set_mt7621_header(void *ptr, off_t filesize, uint32_t loadaddr) { - image_header_t *hdr = (image_header_t *)ptr; + struct legacy_img_hdr *hdr = (struct legacy_img_hdr *)ptr; struct mt7621_stage1_header *shdr; struct mt7621_nand_header *nhdr; uint32_t datasize, crcval; From b7f134eeceb51c9bfe7ab82e0e5f751ddcb74976 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 6 Sep 2022 20:26:53 -0600 Subject: [PATCH 334/374] log: update the comment for log_msg_ret() Add some advice on string size here. Signed-off-by: Simon Glass --- include/log.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/include/log.h b/include/log.h index df497bad18..8a7b961bbf 100644 --- a/include/log.h +++ b/include/log.h @@ -322,7 +322,10 @@ void __assert_fail(const char *assertion, const char *file, unsigned int line, * * or: * - * return log_msg_ret("fred failed", fred_call()); + * return log_msg_ret("get", fred_call()); + * + * It is recommended to use <= 3 characters for the name since this will only + * use 4 bytes in rodata */ #define log_ret(_ret) ({ \ int __ret = (_ret); \ From 96d0c4514fdf3ec46c7fba718d4c8c84f51c6574 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 6 Sep 2022 20:26:54 -0600 Subject: [PATCH 335/374] sandbox: power: Update PMIC driver to use log Use the log functions instead of pr_...() so we can avoid using __func__. Signed-off-by: Simon Glass Reviewed-by: Jaehoon Chung --- drivers/power/pmic/sandbox.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/power/pmic/sandbox.c b/drivers/power/pmic/sandbox.c index d7870915de..acfeae2df9 100644 --- a/drivers/power/pmic/sandbox.c +++ b/drivers/power/pmic/sandbox.c @@ -4,11 +4,14 @@ * Przemyslaw Marczak */ +#define LOG_CATEGORY UCLASS_PMIC + #include #include #include #include #include +#include #include #include #include @@ -28,7 +31,7 @@ static int sandbox_pmic_write(struct udevice *dev, uint reg, const uint8_t *buff, int len) { if (dm_i2c_write(dev, reg, buff, len)) { - pr_err("write error to device: %p register: %#x!\n", dev, reg); + log_err("write error to device: %p register: %#x!\n", dev, reg); return -EIO; } @@ -39,7 +42,7 @@ static int sandbox_pmic_read(struct udevice *dev, uint reg, uint8_t *buff, int len) { if (dm_i2c_read(dev, reg, buff, len)) { - pr_err("read error from device: %p register: %#x!\n", dev, reg); + log_err("read error from device: %p register: %#x!\n", dev, reg); return -EIO; } @@ -49,8 +52,7 @@ static int sandbox_pmic_read(struct udevice *dev, uint reg, static int sandbox_pmic_bind(struct udevice *dev) { if (!pmic_bind_children(dev, dev_ofnode(dev), pmic_children_info)) - pr_err("%s:%d PMIC: %s - no child found!", __func__, __LINE__, - dev->name); + log_err("PMIC: %s - no child found!\n", dev->name); /* Always return success for this device - allows for PMIC I/O */ return 0; From f39e5b802aa486a038a0cbe54c2b6f72aa551f9f Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 6 Sep 2022 20:26:55 -0600 Subject: [PATCH 336/374] event: Fix a typo in the EVENT help Fix the help message. Signed-off-by: Simon Glass --- common/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/Kconfig b/common/Kconfig index 6591acd2fd..6608a4f0fc 100644 --- a/common/Kconfig +++ b/common/Kconfig @@ -577,7 +577,7 @@ config EVENT help This enables sending and processing of events, to allow interested parties to be alerted when something happens. This is an attempt to - step the flow of weak functions, hooks, functions in board_f.c + stem the flow of weak functions, hooks, functions in board_f.c and board_r.c and the Kconfig options below. See doc/develop/event.rst for more information. From b5001cb4bdfed678877840776c15b1e9a358dacf Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 6 Sep 2022 20:26:56 -0600 Subject: [PATCH 337/374] event: Allow multiple spy declarations for each event At present only one spy is allowed per event. Update the naming to allow more than one, since some need this flexibility, e.g. the EVT_FT_FIXUP event. Signed-off-by: Simon Glass --- include/event.h | 4 ++-- scripts/event_dump.py | 4 +++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/include/event.h b/include/event.h index e8f2f55c63..ff883ca064 100644 --- a/include/event.h +++ b/include/event.h @@ -143,8 +143,8 @@ static inline const char *event_spy_id(struct evspy_info *spy) * vbe_simple.c - so for now, make it global. */ #define EVENT_SPY(_type, _func) \ - __used ll_entry_declare(struct evspy_info, _type, evspy_info) = \ - _ESPY_REC(_type, _func) + __used ll_entry_declare(struct evspy_info, _type ## _3_ ## _func, \ + evspy_info) = _ESPY_REC(_type, _func) /** * event_register - register a new spy diff --git a/scripts/event_dump.py b/scripts/event_dump.py index 751f41b183..6aadddf28d 100755 --- a/scripts/event_dump.py +++ b/scripts/event_dump.py @@ -17,8 +17,10 @@ sys.path.insert(1, os.path.join(our_path, '../tools')) from binman import elf from patman import tools +# A typical symbol looks like this: +# _u_boot_list_2_evspy_info_2_EVT_MISC_INIT_F_3_sandbox_misc_init_f PREFIX = '_u_boot_list_2_evspy_info_2_' -RE_EVTYPE = re.compile('%s(.*)' % PREFIX) +RE_EVTYPE = re.compile('%s(.*)_3_.*' % PREFIX) def show_sym(fname, data, endian, evtype, sym): """Show information about an evspy entry From 829d51246fda25655b64224f2a19976797cf1897 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 6 Sep 2022 20:26:57 -0600 Subject: [PATCH 338/374] dm: core: Pass a root node to of_find_node_by_phandle() This function currently assumes that the control FDT is used. Update it to allow a root node to be passed, so it can work with any tree. Also add a comment to ofnode_get_by_phandle() so that its purpose is clear. Signed-off-by: Simon Glass --- drivers/core/of_access.c | 7 ++++--- drivers/core/ofnode.c | 2 +- include/dm/of_access.h | 4 +++- include/dm/ofnode.h | 2 ++ 4 files changed, 10 insertions(+), 5 deletions(-) diff --git a/drivers/core/of_access.c b/drivers/core/of_access.c index df007e642b..f7743d4066 100644 --- a/drivers/core/of_access.c +++ b/drivers/core/of_access.c @@ -445,14 +445,15 @@ struct device_node *of_find_node_by_prop_value(struct device_node *from, return np; } -struct device_node *of_find_node_by_phandle(phandle handle) +struct device_node *of_find_node_by_phandle(struct device_node *root, + phandle handle) { struct device_node *np; if (!handle) return NULL; - for_each_of_allnodes(np) + for_each_of_allnodes_from(root, np) if (np->phandle == handle) break; (void)of_node_get(np); @@ -697,7 +698,7 @@ static int __of_parse_phandle_with_args(const struct device_node *np, * below. */ if (cells_name || cur_index == index) { - node = of_find_node_by_phandle(phandle); + node = of_find_node_by_phandle(NULL, phandle); if (!node) { debug("%s: could not find phandle\n", np->full_name); diff --git a/drivers/core/ofnode.c b/drivers/core/ofnode.c index 42f3c09a51..b241be3b9f 100644 --- a/drivers/core/ofnode.c +++ b/drivers/core/ofnode.c @@ -391,7 +391,7 @@ ofnode ofnode_get_by_phandle(uint phandle) ofnode node; if (of_live_active()) - node = np_to_ofnode(of_find_node_by_phandle(phandle)); + node = np_to_ofnode(of_find_node_by_phandle(NULL, phandle)); else node.of_offset = fdt_node_offset_by_phandle(gd->fdt_blob, phandle); diff --git a/include/dm/of_access.h b/include/dm/of_access.h index 83f34f0d2a..d8c6d11643 100644 --- a/include/dm/of_access.h +++ b/include/dm/of_access.h @@ -258,11 +258,13 @@ struct device_node *of_find_node_by_prop_value(struct device_node *from, /** * of_find_node_by_phandle() - Find a node given a phandle * + * @root: root node to start from (NULL for default device tree) * @handle: phandle of the node to find * * Return: node pointer, or NULL if not found */ -struct device_node *of_find_node_by_phandle(phandle handle); +struct device_node *of_find_node_by_phandle(struct device_node *root, + phandle handle); /** * of_read_u8() - Find and read a 8-bit integer from a property diff --git a/include/dm/ofnode.h b/include/dm/ofnode.h index f6085231bb..6414b4648f 100644 --- a/include/dm/ofnode.h +++ b/include/dm/ofnode.h @@ -501,6 +501,8 @@ int ofnode_get_path(ofnode node, char *buf, int buflen); /** * ofnode_get_by_phandle() - get ofnode from phandle * + * This uses the default (control) device tree + * * @phandle: phandle to look up * Return: ofnode reference to the phandle */ From b215b6034c4e75d8eb0a958574b7ec3d7754b180 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 6 Sep 2022 20:26:58 -0600 Subject: [PATCH 339/374] event: Pass the images to EVT_FT_FIXUP Pass the boot images along as well, in case the fixups need to look at them. Signed-off-by: Simon Glass --- boot/image-fdt.c | 1 + include/event.h | 2 ++ 2 files changed, 3 insertions(+) diff --git a/boot/image-fdt.c b/boot/image-fdt.c index ca51796322..884e089f2d 100644 --- a/boot/image-fdt.c +++ b/boot/image-fdt.c @@ -669,6 +669,7 @@ int image_setup_libfdt(struct bootm_headers *images, void *blob, struct event_ft_fixup fixup; fixup.tree = oftree_default(); + fixup.images = images; ret = event_notify(EVT_FT_FIXUP, &fixup, sizeof(fixup)); if (ret) { printf("ERROR: fdt fixup event failed: %d\n", ret); diff --git a/include/event.h b/include/event.h index ff883ca064..3e6dcbc3dd 100644 --- a/include/event.h +++ b/include/event.h @@ -60,9 +60,11 @@ union event_data { * struct event_ft_fixup - FDT fixup before booting * * @tree: tree to update + * @images: images which are being booted */ struct event_ft_fixup { oftree tree; + struct bootm_headers *images; } ft_fixup; }; From 7c14dc7f77705f79ba49e7f0b2879986fea70fea Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 6 Sep 2022 20:26:59 -0600 Subject: [PATCH 340/374] test: Fix missing livetree test runs At present the live tree tests are not run on sandbox. This bug is in two parts, with a duplicate flag value and incorrect logic in the test runner. This was not noticed because the bug was fixed in a later commit and does not cause test failures. Fix this. Fixes: 7b1dfc9fd7e ("dm: core: Prepare for updating the device tree with ofnode") Signed-off-by: Simon Glass --- include/test/test.h | 2 +- test/dm/ofnode.c | 4 ++++ test/test-main.c | 3 +-- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/include/test/test.h b/include/test/test.h index 2b68331b54..799e918086 100644 --- a/include/test/test.h +++ b/include/test/test.h @@ -49,7 +49,7 @@ enum { /* do extra driver model init and uninit */ UT_TESTF_DM = BIT(6), /* live or flat device tree, but not both in the same executable */ - UT_TESTF_LIVE_OR_FLAT = BIT(4), + UT_TESTF_LIVE_OR_FLAT = BIT(7), }; /** diff --git a/test/dm/ofnode.c b/test/dm/ofnode.c index f80993f892..4624a08d27 100644 --- a/test/dm/ofnode.c +++ b/test/dm/ofnode.c @@ -546,6 +546,10 @@ static int dm_test_ofnode_livetree_writing(struct unit_test_state *uts) struct udevice *dev; ofnode node; + /* temporarily disable this test due to a failure fixed later */ + if (!of_live_active()) + return 0; + /* Test enabling devices */ node = ofnode_path("/usb@2"); diff --git a/test/test-main.c b/test/test-main.c index ae34002a3d..90a324bf70 100644 --- a/test/test-main.c +++ b/test/test-main.c @@ -343,8 +343,7 @@ static int ut_run_test_live_flat(struct unit_test_state *uts, /* Run with the live tree if possible */ runs = 0; if (CONFIG_IS_ENABLED(OF_LIVE)) { - if (!(test->flags & - (UT_TESTF_FLAT_TREE | UT_TESTF_LIVE_OR_FLAT))) { + if (!(test->flags & UT_TESTF_FLAT_TREE)) { uts->of_live = true; ut_assertok(ut_run_test(uts, test, test->name)); runs++; From 62d638386c17d17b929ad10956c7f60825335a4e Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 6 Sep 2022 20:27:00 -0600 Subject: [PATCH 341/374] test: Support testing malloc() failures It is helpful to test that out-of-memory checks work correctly in code that calls malloc(). Add a simple way to force failure after a given number of malloc() calls. Fix a header guard to avoid a build error on sandbox_vpl. Signed-off-by: Simon Glass Reviewed-by: Sean Anderson --- arch/sandbox/include/asm/malloc.h | 1 + common/dlmalloc.c | 19 +++++++++++++++++++ include/malloc.h | 12 ++++++++++++ test/test-main.c | 1 + 4 files changed, 33 insertions(+) diff --git a/arch/sandbox/include/asm/malloc.h b/arch/sandbox/include/asm/malloc.h index a1467b5ead..8aaaa9cb87 100644 --- a/arch/sandbox/include/asm/malloc.h +++ b/arch/sandbox/include/asm/malloc.h @@ -6,6 +6,7 @@ */ #ifndef __ASM_MALLOC_H +#define __ASM_MALLOC_H void *malloc(size_t size); void free(void *ptr); diff --git a/common/dlmalloc.c b/common/dlmalloc.c index f48cd2a333..41c7230424 100644 --- a/common/dlmalloc.c +++ b/common/dlmalloc.c @@ -596,6 +596,9 @@ ulong mem_malloc_start = 0; ulong mem_malloc_end = 0; ulong mem_malloc_brk = 0; +static bool malloc_testing; /* enable test mode */ +static int malloc_max_allocs; /* return NULL after this many calls to malloc() */ + void *sbrk(ptrdiff_t increment) { ulong old = mem_malloc_brk; @@ -1307,6 +1310,11 @@ Void_t* mALLOc(bytes) size_t bytes; return malloc_simple(bytes); #endif + if (CONFIG_IS_ENABLED(UNIT_TEST) && malloc_testing) { + if (--malloc_max_allocs < 0) + return NULL; + } + /* check if mem_malloc_init() was run */ if ((mem_malloc_start == 0) && (mem_malloc_end == 0)) { /* not initialized yet */ @@ -2470,6 +2478,17 @@ int initf_malloc(void) return 0; } +void malloc_enable_testing(int max_allocs) +{ + malloc_testing = true; + malloc_max_allocs = max_allocs; +} + +void malloc_disable_testing(void) +{ + malloc_testing = false; +} + /* History: diff --git a/include/malloc.h b/include/malloc.h index e8c8b254c0..161ccbd129 100644 --- a/include/malloc.h +++ b/include/malloc.h @@ -883,6 +883,18 @@ extern Void_t* sbrk(); void malloc_simple_info(void); +/** + * malloc_enable_testing() - Put malloc() into test mode + * + * This only works if UNIT_TESTING is enabled + * + * @max_allocs: return -ENOMEM after max_allocs calls to malloc() + */ +void malloc_enable_testing(int max_allocs); + +/** malloc_disable_testing() - Put malloc() into normal mode */ +void malloc_disable_testing(void); + #if CONFIG_IS_ENABLED(SYS_MALLOC_SIMPLE) #define malloc malloc_simple #define realloc realloc_simple diff --git a/test/test-main.c b/test/test-main.c index 90a324bf70..7a3871624c 100644 --- a/test/test-main.c +++ b/test/test-main.c @@ -47,6 +47,7 @@ static int dm_test_pre_run(struct unit_test_state *uts) uts->force_fail_alloc = false; uts->skip_post_probe = false; gd->dm_root = NULL; + malloc_disable_testing(); if (CONFIG_IS_ENABLED(UT_DM) && !CONFIG_IS_ENABLED(OF_PLATDATA)) memset(dm_testdrv_op_count, '\0', sizeof(dm_testdrv_op_count)); arch_reset_for_test(); From 5ecba3ba40cebd5e4340f6fd422683bde773689c Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 6 Sep 2022 20:27:01 -0600 Subject: [PATCH 342/374] dm: core: Document the livetree structures properly Clarify the data structure so it is easier for people to understand, particularly the corner cases. Signed-off-by: Simon Glass --- include/dm/of.h | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/include/dm/of.h b/include/dm/of.h index 9c9065b793..fce7cef0ff 100644 --- a/include/dm/of.h +++ b/include/dm/of.h @@ -31,10 +31,21 @@ struct property { /** * struct device_node: Device tree node * - * @name: Node name + * The top of this tree is typically gd->of_root which points to the root node. + * + * The head of the list of children for the root node (and any other node) is + * in @child, with @sibling providing a link to the next child. + * + * Each child has a pointer to its parent in @parent. + * + * A node may have properties in which case the head of the list of properties + * @properties pointers to the first one, with struct property->@next pointing + * to the next one. + * + * @name: Node name, "" for the root node * @type: Node type (value of device_type property) or "" if none * @phandle: Phandle value of this none, or 0 if none - * @full_name: Full path to node, e.g. "/bus@1/spi@1100" + * @full_name: Full path to node, e.g. "/bus@1/spi@1100" ("/" for the root node) * @properties: Pointer to head of list of properties, or NULL if none * @parent: Pointer to parent node, or NULL if this is the root node * @child: Pointer to head of child node list, or NULL if no children From ffe90392497898ccd8000e695901853e192a9007 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 6 Sep 2022 20:27:02 -0600 Subject: [PATCH 343/374] dm: core: Allow adding ofnode subnodes Add this feature to the ofnode interface, supporting both livetree and flattree. If the node exists it is returned, along with a -EEXIST error. Update the functions it calls to handle this too. Signed-off-by: Simon Glass --- drivers/core/of_access.c | 63 +++++++++++++++++++++++++++++++++++ drivers/core/ofnode.c | 35 ++++++++++++++++++++ include/dm/of_access.h | 15 +++++++++ include/dm/ofnode.h | 13 ++++++++ test/dm/ofnode.c | 71 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 197 insertions(+) diff --git a/drivers/core/of_access.c b/drivers/core/of_access.c index f7743d4066..de6327199a 100644 --- a/drivers/core/of_access.c +++ b/drivers/core/of_access.c @@ -969,3 +969,66 @@ int of_write_prop(struct device_node *np, const char *propname, int len, return 0; } + +int of_add_subnode(struct device_node *parent, const char *name, int len, + struct device_node **childp) +{ + struct device_node *child, *new, *last_sibling = NULL; + char *new_name, *full_name; + int parent_fnl; + + if (len == -1) + len = strlen(name); + __for_each_child_of_node(parent, child) { + /* + * make sure we don't use a child called "trevor" when we are + * searching for "trev". + */ + if (!strncmp(child->name, name, len) && strlen(name) == len) { + *childp = child; + return -EEXIST; + } + last_sibling = child; + } + + /* Subnode does not exist -> append new subnode */ + new = calloc(1, sizeof(struct device_node)); + if (!new) + return -ENOMEM; + + new_name = memdup(name, len + 1); + if (!new_name) { + free(new); + return -ENOMEM; + } + new_name[len] = '\0'; + + /* + * if the parent is the root node (named "") we don't need to prepend + * its full path + */ + parent_fnl = *parent->name ? strlen(parent->full_name) : 0; + full_name = calloc(1, parent_fnl + 1 + len + 1); + if (!full_name) { + free(new_name); + free(new); + return -ENOMEM; + } + new->name = new_name; /* assign to constant pointer */ + + strcpy(full_name, parent->full_name); /* "" for root node */ + full_name[parent_fnl] = '/'; + strlcpy(&full_name[parent_fnl + 1], name, len + 1); + new->full_name = full_name; + + /* Add as last sibling of the parent */ + if (last_sibling) + last_sibling->sibling = new; + if (!parent->child) + parent->child = new; + new->parent = parent; + + *childp = new; + + return 0; +} diff --git a/drivers/core/ofnode.c b/drivers/core/ofnode.c index b241be3b9f..8683e03c33 100644 --- a/drivers/core/ofnode.c +++ b/drivers/core/ofnode.c @@ -1289,3 +1289,38 @@ phy_interface_t ofnode_read_phy_mode(ofnode node) return PHY_INTERFACE_MODE_NA; } + +int ofnode_add_subnode(ofnode node, const char *name, ofnode *subnodep) +{ + ofnode subnode; + int ret = 0; + + assert(ofnode_valid(node)); + + if (ofnode_is_np(node)) { + struct device_node *np, *child; + + np = (struct device_node *)ofnode_to_np(node); + ret = of_add_subnode(np, name, -1, &child); + if (ret && ret != -EEXIST) + return ret; + subnode = np_to_ofnode(child); + } else { + void *fdt = (void *)gd->fdt_blob; + int poffset = ofnode_to_offset(node); + int offset; + + offset = fdt_add_subnode(fdt, poffset, name); + if (offset == -FDT_ERR_EXISTS) { + offset = fdt_subnode_offset(fdt, poffset, name); + ret = -EEXIST; + } + if (offset < 0) + return -EINVAL; + subnode = offset_to_ofnode(offset); + } + + *subnodep = subnode; + + return ret; /* 0 or -EEXIST */ +} diff --git a/include/dm/of_access.h b/include/dm/of_access.h index d8c6d11643..dd70b44344 100644 --- a/include/dm/of_access.h +++ b/include/dm/of_access.h @@ -565,4 +565,19 @@ struct device_node *of_get_stdout(void); int of_write_prop(struct device_node *np, const char *propname, int len, const void *value); +/** + * of_add_subnode() - add a new subnode to a node + * + * @node: parent node to add to + * @name: name of subnode + * @len: length of name (so the caller does not need to nul-terminate a + * partial string), or -1 for strlen(@name) + * @subnodep: returns pointer to new subnode (valid if the function returns 0 + * or -EEXIST) + * Returns 0 if OK, -EEXIST if already exists, -ENOMEM if out of memory, other + * -ve on other error + */ +int of_add_subnode(struct device_node *node, const char *name, int len, + struct device_node **subnodep); + #endif diff --git a/include/dm/ofnode.h b/include/dm/ofnode.h index 6414b4648f..ec1ab0ce15 100644 --- a/include/dm/ofnode.h +++ b/include/dm/ofnode.h @@ -1300,6 +1300,19 @@ static inline const char *ofnode_conf_read_str(const char *prop_name) { return NULL; } + #endif /* CONFIG_DM */ +/** + * of_add_subnode() - add a new subnode to a node + * + * @parent: parent node to add to + * @name: name of subnode + * @nodep: returns pointer to new subnode (valid if the function returns 0 + * or -EEXIST) + * Returns 0 if OK, -EEXIST if already exists, -ENOMEM if out of memory, other + * -ve on other error + */ +int ofnode_add_subnode(ofnode parent, const char *name, ofnode *nodep); + #endif diff --git a/test/dm/ofnode.c b/test/dm/ofnode.c index 4624a08d27..543dc546b9 100644 --- a/test/dm/ofnode.c +++ b/test/dm/ofnode.c @@ -605,3 +605,74 @@ static int dm_test_ofnode_u32(struct unit_test_state *uts) } DM_TEST(dm_test_ofnode_u32, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT | UT_TESTF_LIVE_OR_FLAT); + +static int dm_test_ofnode_add_subnode(struct unit_test_state *uts) +{ + ofnode node, check, subnode; + char buf[128]; + + /* temporarily disable this test due to a failure fixed later */ + if (!of_live_active()) + return 0; + + node = ofnode_path("/lcd"); + ut_assert(ofnode_valid(node)); + ut_assertok(ofnode_add_subnode(node, "edmund", &subnode)); + check = ofnode_path("/lcd/edmund"); + ut_asserteq(subnode.of_offset, check.of_offset); + ut_assertok(ofnode_get_path(subnode, buf, sizeof(buf))); + ut_asserteq_str("/lcd/edmund", buf); + + if (of_live_active()) { + struct device_node *child; + + ut_assertok(of_add_subnode((void *)ofnode_to_np(node), "edmund", + 2, &child)); + ut_asserteq_str("ed", child->name); + ut_asserteq_str("/lcd/ed", child->full_name); + check = ofnode_path("/lcd/ed"); + ut_asserteq_ptr(child, check.np); + ut_assertok(ofnode_get_path(np_to_ofnode(child), buf, + sizeof(buf))); + ut_asserteq_str("/lcd/ed", buf); + } + + /* An existing node should be returned with -EEXIST */ + ut_asserteq(-EEXIST, ofnode_add_subnode(node, "edmund", &check)); + ut_asserteq(subnode.of_offset, check.of_offset); + + /* add a root node */ + node = ofnode_path("/"); + ut_assert(ofnode_valid(node)); + ut_assertok(ofnode_add_subnode(node, "lcd2", &subnode)); + check = ofnode_path("/lcd2"); + ut_asserteq(subnode.of_offset, check.of_offset); + ut_assertok(ofnode_get_path(subnode, buf, sizeof(buf))); + ut_asserteq_str("/lcd2", buf); + + if (of_live_active()) { + ulong start; + int i; + + /* + * Make sure each of the three malloc()checks in + * of_add_subnode() work + */ + for (i = 0; i < 3; i++) { + malloc_enable_testing(i); + start = ut_check_free(); + ut_asserteq(-ENOMEM, ofnode_add_subnode(node, "anthony", + &check)); + ut_assertok(ut_check_delta(start)); + } + + /* This should pass since we allow 3 allocations */ + malloc_enable_testing(3); + ut_assertok(ofnode_add_subnode(node, "anthony", &check)); + malloc_disable_testing(); + } + + return 0; +} +DM_TEST(dm_test_ofnode_add_subnode, + UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT | UT_TESTF_LIVE_OR_FLAT); From c3a194dec97be3ceb74ba2c980e635aee1644d94 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 6 Sep 2022 20:27:03 -0600 Subject: [PATCH 344/374] dm: core: Support writing a property to an empty node At present this does not work with livetree. Fix it and add a test. Signed-off-by: Simon Glass --- drivers/core/of_access.c | 8 ++++---- test/dm/ofnode.c | 3 +++ 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/core/of_access.c b/drivers/core/of_access.c index de6327199a..8631e1c286 100644 --- a/drivers/core/of_access.c +++ b/drivers/core/of_access.c @@ -947,9 +947,6 @@ int of_write_prop(struct device_node *np, const char *propname, int len, pp_last = pp; } - if (!pp_last) - return -ENOENT; - /* Property does not exist -> append new property */ new = malloc(sizeof(struct property)); if (!new) @@ -965,7 +962,10 @@ int of_write_prop(struct device_node *np, const char *propname, int len, new->length = len; new->next = NULL; - pp_last->next = new; + if (pp_last) + pp_last->next = new; + else + np->properties = new; return 0; } diff --git a/test/dm/ofnode.c b/test/dm/ofnode.c index 543dc546b9..0f65ff939f 100644 --- a/test/dm/ofnode.c +++ b/test/dm/ofnode.c @@ -672,6 +672,9 @@ static int dm_test_ofnode_add_subnode(struct unit_test_state *uts) malloc_disable_testing(); } + /* write to the empty node */ + ut_assertok(ofnode_write_string(subnode, "example", "text")); + return 0; } DM_TEST(dm_test_ofnode_add_subnode, From 98306987659769607642474954b2bf9555808542 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 6 Sep 2022 20:27:04 -0600 Subject: [PATCH 345/374] dm: core: Drop the const from ofnode Now that we support writing to ofnodes, the const is not accurate. Drop it to avoid undesirable casting. Also drop the ofnode_to_npw() which is now the same as ofnode_to_np(). Signed-off-by: Simon Glass --- drivers/core/ofnode.c | 4 ++-- include/dm/ofnode.h | 22 ++-------------------- include/dm/ofnode_decl.h | 2 +- 3 files changed, 5 insertions(+), 23 deletions(-) diff --git a/drivers/core/ofnode.c b/drivers/core/ofnode.c index 8683e03c33..caf28c68c4 100644 --- a/drivers/core/ofnode.c +++ b/drivers/core/ofnode.c @@ -268,7 +268,7 @@ ofnode ofnode_find_subnode(ofnode node, const char *subnode_name) debug("%s: %s: ", __func__, subnode_name); if (ofnode_is_np(node)) { - const struct device_node *np = ofnode_to_np(node); + struct device_node *np = ofnode_to_np(node); for (np = np->child; np; np = np->sibling) { if (!strcmp(subnode_name, np->name)) @@ -1171,7 +1171,7 @@ int ofnode_write_prop(ofnode node, const char *propname, const void *value, int len) { if (of_live_active()) - return of_write_prop(ofnode_to_npw(node), propname, len, value); + return of_write_prop(ofnode_to_np(node), propname, len, value); else return fdt_setprop((void *)gd->fdt_blob, ofnode_to_offset(node), propname, value, len); diff --git a/include/dm/ofnode.h b/include/dm/ofnode.h index ec1ab0ce15..044546f005 100644 --- a/include/dm/ofnode.h +++ b/include/dm/ofnode.h @@ -35,7 +35,7 @@ struct ofnode_phandle_args { * @node: Reference containing struct device_node * (possibly invalid) * Return: pointer to device node (can be NULL) */ -static inline const struct device_node *ofnode_to_np(ofnode node) +static inline struct device_node *ofnode_to_np(ofnode node) { #ifdef OF_CHECKS if (!of_live_active()) @@ -44,24 +44,6 @@ static inline const struct device_node *ofnode_to_np(ofnode node) return node.np; } -/** - * ofnode_to_npw() - convert an ofnode to a writeable live DT node pointer - * - * This cannot be called if the reference contains an offset. - * - * @node: Reference containing struct device_node * (possibly invalid) - * Return: pointer to device node (can be NULL) - */ -static inline struct device_node *ofnode_to_npw(ofnode node) -{ -#ifdef OF_CHECKS - if (!of_live_active()) - return NULL; -#endif - /* Drop constant */ - return (struct device_node *)node.np; -} - /** * ofnode_to_offset() - convert an ofnode to a flat DT offset * @@ -117,7 +99,7 @@ static inline ofnode offset_to_ofnode(int of_offset) * @np: Live node pointer (can be NULL) * Return: reference to the associated node pointer */ -static inline ofnode np_to_ofnode(const struct device_node *np) +static inline ofnode np_to_ofnode(struct device_node *np) { ofnode node; diff --git a/include/dm/ofnode_decl.h b/include/dm/ofnode_decl.h index 266253d5e3..8d0d7885aa 100644 --- a/include/dm/ofnode_decl.h +++ b/include/dm/ofnode_decl.h @@ -39,7 +39,7 @@ * is not a really a pointer to a node: it is an offset value. See above. */ typedef union ofnode_union { - const struct device_node *np; + struct device_node *np; long of_offset; } ofnode; From 0e4b697f884d1f2190a9972b662abc8498159333 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 6 Sep 2022 20:27:05 -0600 Subject: [PATCH 346/374] test: Make a copy of the device tree before running a test When the flat device tree changes it can mess up the live tree since that uses the flat tree for its strings. This affects only a few sandbox tests which modify the device tree, but the number will grow as ofnode support for writing improves. While the control FDT is not intended to change while U-Boot is running, some tests do so. For example, the ofnode interface only supports modifying properties in the control FDT, so tests must use that. To solve this problem, keep a copy of the FDT and restore it as needed when the test is finished. The copy only happens on sandbox (except SPL builds), to reduce memory usage and because these tests are not useful on other boards. For other boards, a checksum is taken to ensure that nothing changes. It would be possible to always checksum the FDT on sandbox and only restore it if needed, but this is slightly slower than restoring it every time, at least with crc8. Move the code which checks for success to the very end, for clarity. Signed-off-by: Simon Glass --- doc/develop/driver-model/livetree.rst | 17 ++---- include/test/test.h | 6 +++ test/test-main.c | 74 +++++++++++++++++++++++++++ 3 files changed, 83 insertions(+), 14 deletions(-) diff --git a/doc/develop/driver-model/livetree.rst b/doc/develop/driver-model/livetree.rst index faf3eb5b5f..4ef8c51732 100644 --- a/doc/develop/driver-model/livetree.rst +++ b/doc/develop/driver-model/livetree.rst @@ -235,20 +235,9 @@ tree either present or absent. This is to make sure that the flat tree functions work correctly even with OF_LIVE is enabled. But if a test modifies the flat device tree, then the live tree can become invalid. Any live tree tests that run after that point will use a corrupted tree, e.g. with an incorrect property name -or worse. To deal with this we use a flag UT_TESTF_LIVE_OR_FLAT then ensures -that tests which write to the flat tree are not run if OF_LIVE is enabled. Only -the live tree version of the test is run, when OF_LIVE is enabled, with -sandbox_flattree running the flat tree version. - -This is of course a work-around, even if a reasonable one. One solution to this -problem would be to make a copy of the flat tree before the test and restore it -afterwards, in the same memory location, so that the live tree pointers work -again. Another would be to regenerate the live tree if a test modified the flat -tree. - -Neither of these solutions is currently implemented, since the situation that -causes the problem can only occur in sandbox tests, is somewhat esoteric and -the UT_TESTF_LIVE_OR_FLAT flag deals with it in a reasonable way. +or worse. To deal with this we take a copy of the device tree and restore it +after any test that modifies it. Note that this copy is not made on other +boards, only sandbox. Multiple livetrees diff --git a/include/test/test.h b/include/test/test.h index 799e918086..92215d427b 100644 --- a/include/test/test.h +++ b/include/test/test.h @@ -20,6 +20,9 @@ * @testdev: Test device * @force_fail_alloc: Force all memory allocs to fail * @skip_post_probe: Skip uclass post-probe processing + * @fdt_chksum: crc8 of the device tree contents + * @fdt_copy: Copy of the device tree + * @fdt_size: Size of the device-tree copy * @runs_per_test: Number of times to run each test (typically 1) * @expect_str: Temporary string used to hold expected string value * @actual_str: Temporary string used to hold actual string value @@ -33,6 +36,9 @@ struct unit_test_state { struct udevice *testdev; int force_fail_alloc; int skip_post_probe; + uint fdt_chksum; + void *fdt_copy; + uint fdt_size; int runs_per_test; char expect_str[512]; char actual_str[512]; diff --git a/test/test-main.c b/test/test-main.c index 7a3871624c..082821ef3e 100644 --- a/test/test-main.c +++ b/test/test-main.c @@ -9,14 +9,51 @@ #include #include #include +#include #include #include #include #include #include +#include DECLARE_GLOBAL_DATA_PTR; +/** + * enum fdtchk_t - what to do with the device tree (gd->fdt_blob) + * + * This affects what happens with the device tree before and after a test + * + * @FDTCHK_NONE: Do nothing + * @FDTCHK_CHECKSUM: Take a checksum of the FDT before the test runs and + * compare it afterwards to detect any changes + * @FDTCHK_COPY: Make a copy of the FDT and restore it afterwards + */ +enum fdtchk_t { + FDTCHK_NONE, + FDTCHK_CHECKSUM, + FDTCHK_COPY, +}; + +/** + * fdt_action() - get the required action for the FDT + * + * @return the action that should be taken for this build + */ +static enum fdtchk_t fdt_action(void) +{ + /* Do a copy for sandbox (but only the U-Boot build, not SPL) */ + if (CONFIG_IS_ENABLED(SANDBOX)) + return FDTCHK_COPY; + + /* For sandbox SPL builds, do nothing */ + if (IS_ENABLED(CONFIG_SANDBOX)) + return FDTCHK_NONE; + + /* For all other boards, do a checksum */ + return FDTCHK_CHECKSUM; +} + /* This is valid when a test is running, NULL otherwise */ static struct unit_test_state *cur_test_state; @@ -46,6 +83,9 @@ static int dm_test_pre_run(struct unit_test_state *uts) uts->testdev = NULL; uts->force_fail_alloc = false; uts->skip_post_probe = false; + if (fdt_action() == FDTCHK_CHECKSUM) + uts->fdt_chksum = crc8(0, gd->fdt_blob, + fdt_totalsize(gd->fdt_blob)); gd->dm_root = NULL; malloc_disable_testing(); if (CONFIG_IS_ENABLED(UT_DM) && !CONFIG_IS_ENABLED(OF_PLATDATA)) @@ -64,6 +104,25 @@ static int dm_test_post_run(struct unit_test_state *uts) { int id; + if (gd->fdt_blob) { + switch (fdt_action()) { + case FDTCHK_COPY: + memcpy((void *)gd->fdt_blob, uts->fdt_copy, uts->fdt_size); + break; + case FDTCHK_CHECKSUM: { + uint chksum; + + chksum = crc8(0, gd->fdt_blob, fdt_totalsize(gd->fdt_blob)); + + if (chksum != uts->fdt_chksum) + printf("Device tree changed: cannot run live tree tests\n"); + break; + } + case FDTCHK_NONE: + break; + } + } + /* * With of-platdata-inst the uclasses are created at build time. If we * destroy them we cannot get them back since uclass_add() is not @@ -443,8 +502,23 @@ int ut_run_list(const char *category, const char *prefix, uts.of_root = gd_of_root(); uts.runs_per_test = runs_per_test; + if (fdt_action() == FDTCHK_COPY && gd->fdt_blob) { + uts.fdt_size = fdt_totalsize(gd->fdt_blob); + uts.fdt_copy = os_malloc(uts.fdt_size); + if (!uts.fdt_copy) { + printf("Out of memory for device tree copy\n"); + return -ENOMEM; + } + memcpy(uts.fdt_copy, gd->fdt_blob, uts.fdt_size); + } ret = ut_run_tests(&uts, prefix, tests, count, select_name); + /* Best efforts only...ignore errors */ + if (has_dm_tests) + dm_test_restore(uts.of_root); + if (IS_ENABLED(CONFIG_SANDBOX)) + os_free(uts.fdt_copy); + if (ret == -ENOENT) printf("Test '%s' not found\n", select_name); else From eb6e903a569d35032ca3772d93c26fb1071ab3ae Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 6 Sep 2022 20:27:06 -0600 Subject: [PATCH 347/374] test: Detect a change in the device tree If the device tree changes during a test and we cannot restore it, mark it as such so that future tests which need the live tree are skipped. Signed-off-by: Simon Glass --- include/asm-generic/global_data.h | 4 ++++ test/test-main.c | 19 ++++++++++++++++--- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/include/asm-generic/global_data.h b/include/asm-generic/global_data.h index 4aeb61f08c..2d55fe2ac0 100644 --- a/include/asm-generic/global_data.h +++ b/include/asm-generic/global_data.h @@ -646,6 +646,10 @@ enum gd_flags { * @GD_FLG_SMP_READY: SMP initialization is complete */ GD_FLG_SMP_READY = 0x80000, + /** + * @GD_FLG_FDT_CHANGED: Device tree change has been detected by tests + */ + GD_FLG_FDT_CHANGED = 0x100000, }; #endif /* __ASSEMBLY__ */ diff --git a/test/test-main.c b/test/test-main.c index 082821ef3e..c12027ce68 100644 --- a/test/test-main.c +++ b/test/test-main.c @@ -79,6 +79,10 @@ static int dm_test_pre_run(struct unit_test_state *uts) { bool of_live = uts->of_live; + if (of_live && (gd->flags & GD_FLG_FDT_CHANGED)) { + printf("Cannot run live tree test as device tree changed\n"); + return -EFAULT; + } uts->root = NULL; uts->testdev = NULL; uts->force_fail_alloc = false; @@ -113,9 +117,17 @@ static int dm_test_post_run(struct unit_test_state *uts) uint chksum; chksum = crc8(0, gd->fdt_blob, fdt_totalsize(gd->fdt_blob)); - - if (chksum != uts->fdt_chksum) + if (chksum != uts->fdt_chksum) { + /* + * We cannot run any more tests that need the + * live tree, since its strings point into the + * flat tree, which has changed. This likely + * means that at least some of the pointers from + * the live tree point to different things + */ printf("Device tree changed: cannot run live tree tests\n"); + gd->flags |= GD_FLG_FDT_CHANGED; + } break; } case FDTCHK_NONE: @@ -415,7 +427,8 @@ static int ut_run_test_live_flat(struct unit_test_state *uts, * or it is a core test. */ if (!(test->flags & UT_TESTF_LIVE_TREE) && - (!runs || ut_test_run_on_flattree(test))) { + (!runs || ut_test_run_on_flattree(test)) && + !(gd->flags & GD_FLG_FDT_CHANGED)) { uts->of_live = false; ut_assertok(ut_run_test(uts, test, test->name)); runs++; From 2b90e0d54efe6e83c9313c863184b71eb811853e Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 6 Sep 2022 20:27:07 -0600 Subject: [PATCH 348/374] test: Drop the UT_TESTF_LIVE_OR_FLAT flag This was a workaround for a rare situation. Now that it will be more common and we have a proper fix, drop the flag. We can run both types of tests in the same sandbox executable, even if the flat device tree is modified. Signed-off-by: Simon Glass --- include/test/test.h | 2 -- test/dm/ofnode.c | 16 +++------------- 2 files changed, 3 insertions(+), 15 deletions(-) diff --git a/include/test/test.h b/include/test/test.h index 92215d427b..51efaecba7 100644 --- a/include/test/test.h +++ b/include/test/test.h @@ -54,8 +54,6 @@ enum { UT_TESTF_CONSOLE_REC = BIT(5), /* needs console recording */ /* do extra driver model init and uninit */ UT_TESTF_DM = BIT(6), - /* live or flat device tree, but not both in the same executable */ - UT_TESTF_LIVE_OR_FLAT = BIT(7), }; /** diff --git a/test/dm/ofnode.c b/test/dm/ofnode.c index 0f65ff939f..a421392a97 100644 --- a/test/dm/ofnode.c +++ b/test/dm/ofnode.c @@ -546,10 +546,6 @@ static int dm_test_ofnode_livetree_writing(struct unit_test_state *uts) struct udevice *dev; ofnode node; - /* temporarily disable this test due to a failure fixed later */ - if (!of_live_active()) - return 0; - /* Test enabling devices */ node = ofnode_path("/usb@2"); @@ -588,7 +584,7 @@ static int dm_test_ofnode_livetree_writing(struct unit_test_state *uts) return 0; } DM_TEST(dm_test_ofnode_livetree_writing, - UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT | UT_TESTF_LIVE_OR_FLAT); + UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); static int dm_test_ofnode_u32(struct unit_test_state *uts) { @@ -603,18 +599,13 @@ static int dm_test_ofnode_u32(struct unit_test_state *uts) return 0; } -DM_TEST(dm_test_ofnode_u32, - UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT | UT_TESTF_LIVE_OR_FLAT); +DM_TEST(dm_test_ofnode_u32, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); static int dm_test_ofnode_add_subnode(struct unit_test_state *uts) { ofnode node, check, subnode; char buf[128]; - /* temporarily disable this test due to a failure fixed later */ - if (!of_live_active()) - return 0; - node = ofnode_path("/lcd"); ut_assert(ofnode_valid(node)); ut_assertok(ofnode_add_subnode(node, "edmund", &subnode)); @@ -677,5 +668,4 @@ static int dm_test_ofnode_add_subnode(struct unit_test_state *uts) return 0; } -DM_TEST(dm_test_ofnode_add_subnode, - UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT | UT_TESTF_LIVE_OR_FLAT); +DM_TEST(dm_test_ofnode_add_subnode, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); From 73c5cb9dacbcf2e988fffa66750c4206fccc8cbc Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 6 Sep 2022 20:27:08 -0600 Subject: [PATCH 349/374] sandbox: Add a function to load a relative file path At present this implementation is specific to loading the test FDT. We plan to load others, so create a generic function to handle this. The path is now limited to 256 characters, to simplify the code. When there is an empty argv[0] (which should not happen), the function now just uses the path as is, with no prefix. Signed-off-by: Simon Glass --- arch/sandbox/cpu/start.c | 16 +++++++--------- arch/sandbox/cpu/state.c | 22 ++++++++++++++++++++++ arch/sandbox/include/asm/state.h | 14 ++++++++++++++ 3 files changed, 43 insertions(+), 9 deletions(-) diff --git a/arch/sandbox/cpu/start.c b/arch/sandbox/cpu/start.c index 90a84e93c7..642be164a3 100644 --- a/arch/sandbox/cpu/start.c +++ b/arch/sandbox/cpu/start.c @@ -205,21 +205,19 @@ SANDBOX_CMDLINE_OPT_SHORT(default_fdt, 'D', 0, static int sandbox_cmdline_cb_test_fdt(struct sandbox_state *state, const char *arg) { - const char *fmt = "/arch/sandbox/dts/test.dtb"; - char *p; + char buf[256]; char *fname; int len; - len = strlen(state->argv[0]) + strlen(fmt) + 1; + len = state_get_rel_filename("arch/sandbox/dts/test.dtb", buf, + sizeof(buf)); + if (len < 0) + return len; + fname = os_malloc(len); if (!fname) return -ENOMEM; - strcpy(fname, state->argv[0]); - p = strrchr(fname, '/'); - if (!p) - p = fname + strlen(fname); - len -= p - fname; - snprintf(p, len, fmt); + strcpy(fname, buf); state->fdt_fname = fname; return 0; diff --git a/arch/sandbox/cpu/state.c b/arch/sandbox/cpu/state.c index e0d01125bb..787e021659 100644 --- a/arch/sandbox/cpu/state.c +++ b/arch/sandbox/cpu/state.c @@ -396,6 +396,28 @@ bool autoboot_set_keyed(bool autoboot_keyed) return old_val; } +int state_get_rel_filename(const char *rel_path, char *buf, int size) +{ + struct sandbox_state *state = state_get_current(); + int rel_len, prog_len; + char *p; + int len; + + rel_len = strlen(rel_path); + p = strrchr(state->argv[0], '/'); + prog_len = p ? p - state->argv[0] : 0; + + /* allow space for a / and a terminator */ + len = prog_len + 1 + rel_len + 1; + if (len > size) + return -ENOSPC; + strncpy(buf, state->argv[0], prog_len); + buf[prog_len] = '/'; + strcpy(buf + prog_len + 1, rel_path); + + return len; +} + int state_init(void) { state = &main_state; diff --git a/arch/sandbox/include/asm/state.h b/arch/sandbox/include/asm/state.h index 07c768ae5d..12741ee064 100644 --- a/arch/sandbox/include/asm/state.h +++ b/arch/sandbox/include/asm/state.h @@ -265,6 +265,20 @@ void state_reset_for_test(struct sandbox_state *state); */ void state_show(struct sandbox_state *state); +/** + * state_get_rel_filename() - Get a filename relative to the executable + * + * This uses argv[0] to obtain a filename path + * + * @rel_path: Relative path to build, e.g. "arch/sandbox/dts/test.dtb". Must not + * have a trailing / + * @buf: Buffer to use to return the filename + * @size: Size of buffer + * @return length of filename (including terminator), -ENOSPC if @size is too + * small + */ +int state_get_rel_filename(const char *rel_path, char *buf, int size); + /** * Initialize the test system state */ From 9859d89b6e859a242d083a96950e0c05f60a5152 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 6 Sep 2022 20:27:09 -0600 Subject: [PATCH 350/374] sandbox: Support loading the other FDT We need an 'other' FDT which is different from the control FDT, so we can check that the ofnode tests correctly handle them both. Add this to the build along with a way to read it into the sandbox state. Signed-off-by: Simon Glass --- arch/sandbox/cpu/state.c | 26 ++++++++++++++++++++++++ arch/sandbox/dts/Makefile | 2 +- arch/sandbox/dts/other.dts | 35 ++++++++++++++++++++++++++++++++ arch/sandbox/include/asm/state.h | 16 +++++++++++++++ 4 files changed, 78 insertions(+), 1 deletion(-) create mode 100644 arch/sandbox/dts/other.dts diff --git a/arch/sandbox/cpu/state.c b/arch/sandbox/cpu/state.c index 787e021659..fcc4a337e5 100644 --- a/arch/sandbox/cpu/state.c +++ b/arch/sandbox/cpu/state.c @@ -418,6 +418,32 @@ int state_get_rel_filename(const char *rel_path, char *buf, int size) return len; } +int state_load_other_fdt(const char **bufp, int *sizep) +{ + struct sandbox_state *state = state_get_current(); + char fname[256]; + int len, ret; + + /* load the file if needed */ + if (!state->other_fdt_buf) { + len = state_get_rel_filename("arch/sandbox/dts/other.dtb", + fname, sizeof(fname)); + if (len < 0) + return len; + + ret = os_read_file(fname, &state->other_fdt_buf, + &state->other_size); + if (ret) { + log_err("Cannot read file '%s'\n", fname); + return ret; + } + } + *bufp = state->other_fdt_buf; + *sizep = state->other_size; + + return 0; +} + int state_init(void) { state = &main_state; diff --git a/arch/sandbox/dts/Makefile b/arch/sandbox/dts/Makefile index 6cbc9bbcaa..b6a88479b2 100644 --- a/arch/sandbox/dts/Makefile +++ b/arch/sandbox/dts/Makefile @@ -5,7 +5,7 @@ dtb-$(CONFIG_SANDBOX) += sandbox64.dtb else dtb-$(CONFIG_SANDBOX) += sandbox.dtb endif -dtb-$(CONFIG_UT_DM) += test.dtb +dtb-$(CONFIG_UT_DM) += test.dtb other.dtb dtb-$(CONFIG_CMD_EXTENSION) += overlay0.dtbo overlay1.dtbo include $(srctree)/scripts/Makefile.dts diff --git a/arch/sandbox/dts/other.dts b/arch/sandbox/dts/other.dts new file mode 100644 index 0000000000..395a792322 --- /dev/null +++ b/arch/sandbox/dts/other.dts @@ -0,0 +1,35 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Other devicetree file for running sandbox tests + * + * This used for tests which want to check they can access multiple device + * trees. This one is loaded and checks are made that it is actually visible. + */ + +/dts-v1/; + +/ { + compatible = "sandbox-other"; + #address-cells = <1>; + #size-cells = <1>; + + node { + target = <&target 3 4>; + + subnode { + compatible = "sandbox-other2"; + str-prop = "other"; + }; + + subnode2 { + }; + }; + + target: target { + compatible = "sandbox-other2"; + #gpio-cells = <2>; + str-prop = "other"; + reg = <0x8000 0x100>; + status = "disabled"; + }; +}; diff --git a/arch/sandbox/include/asm/state.h b/arch/sandbox/include/asm/state.h index 12741ee064..fd42daad51 100644 --- a/arch/sandbox/include/asm/state.h +++ b/arch/sandbox/include/asm/state.h @@ -108,6 +108,9 @@ struct sandbox_state { bool hwspinlock; /* Hardware Spinlock status */ bool allow_memio; /* Allow readl() etc. to work */ + void *other_fdt_buf; /* 'other' FDT blob used by tests */ + int other_size; /* size of other FDT blob */ + /* * This struct is getting large. * @@ -279,6 +282,19 @@ void state_show(struct sandbox_state *state); */ int state_get_rel_filename(const char *rel_path, char *buf, int size); +/** + * state_load_other_fdt() - load the 'other' FDT into a buffer + * + * This loads the other.dtb file into a buffer. This is typically used in tests. + * + * @bufp: Place to put allocated buffer pointer. The buffer is read using + * os_read_file() which calls os_malloc(), so does affect U-Boot's own malloc() + * space + * @sizep: Returns the size of the buffer + * @return 0 if OK, -ve on error + */ +int state_load_other_fdt(const char **bufp, int *sizep); + /** * Initialize the test system state */ From 756c01422dfa193097aa3d43c083b8b23e4b2301 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 6 Sep 2022 20:27:10 -0600 Subject: [PATCH 351/374] sandbox: Support setting up the other FDT for testing Provide a way to copy over the 'other' FDT when running tests. This loads it and allocates memory for the copy, if not done already, then does the copy. Avoid using U-Boot's malloc() pool for these copies, at least for now, since they are part of the test system. Tidy up the cpu.c header files while here. Signed-off-by: Simon Glass --- arch/sandbox/cpu/cpu.c | 34 ++++++++++++++++++++++++++++++--- arch/sandbox/include/asm/test.h | 19 ++++++++++++++++++ include/test/test.h | 19 ++++++++++++++++-- 3 files changed, 67 insertions(+), 5 deletions(-) diff --git a/arch/sandbox/cpu/cpu.c b/arch/sandbox/cpu/cpu.c index d077948dd7..636d3545b9 100644 --- a/arch/sandbox/cpu/cpu.c +++ b/arch/sandbox/cpu/cpu.c @@ -3,19 +3,22 @@ * Copyright (c) 2011 The Chromium OS Authors. */ +#define LOG_CATEGORY LOGC_SANDBOX + #include #include #include #include #include -#include -#include -#include #include +#include #include #include #include #include +#include +#include +#include DECLARE_GLOBAL_DATA_PTR; @@ -373,3 +376,28 @@ ulong timer_get_boot_us(void) return (count - base_count) / 1000; } + +int sandbox_load_other_fdt(void **fdtp, int *sizep) +{ + const char *orig; + int ret, size; + void *fdt = *fdtp; + + ret = state_load_other_fdt(&orig, &size); + if (ret) { + log_err("Cannot read other FDT\n"); + return log_msg_ret("ld", ret); + } + + if (!*fdtp) { + fdt = os_malloc(size); + if (!fdt) + return log_msg_ret("mem", -ENOMEM); + *sizep = size; + } + + memcpy(fdt, orig, *sizep); + *fdtp = fdt; + + return 0; +} diff --git a/arch/sandbox/include/asm/test.h b/arch/sandbox/include/asm/test.h index 53a036b3ab..0406085917 100644 --- a/arch/sandbox/include/asm/test.h +++ b/arch/sandbox/include/asm/test.h @@ -11,6 +11,8 @@ #include #include +struct unit_test_state; + /* The sandbox driver always permits an I2C device with this address */ #define SANDBOX_I2C_TEST_ADDR 0x59 @@ -315,4 +317,21 @@ int sandbox_sdl_set_bpp(struct udevice *dev, enum video_log2_bpp l2bpp); */ void sandbox_set_fake_efi_mgr_dev(struct udevice *dev, bool fake_dev); +/** + * sandbox_load_other_fdt() - load the 'other' FDT into the test state + * + * This copies the other.dtb file into the test state, so that a fresh version + * can be used for a test that is about to run. + * + * If @uts->other_fdt is NULL, as it is when first set up, this allocates a + * buffer for the other FDT and sets @uts->other_fdt_size to its size. + * + * In any case, the other FDT is copied from the sandbox state into + * @uts->other_fdt ready for use. + * + * @uts: Unit test state + * @return 0 if OK, -ve on error + */ +int sandbox_load_other_fdt(void **fdtp, int *sizep); + #endif diff --git a/include/test/test.h b/include/test/test.h index 51efaecba7..225bf45504 100644 --- a/include/test/test.h +++ b/include/test/test.h @@ -23,6 +23,8 @@ * @fdt_chksum: crc8 of the device tree contents * @fdt_copy: Copy of the device tree * @fdt_size: Size of the device-tree copy + * @other_fdt: Buffer for the other FDT (UT_TESTF_OTHER_FDT) + * @other_fdt_size: Size of the other FDT (UT_TESTF_OTHER_FDT) * @runs_per_test: Number of times to run each test (typically 1) * @expect_str: Temporary string used to hold expected string value * @actual_str: Temporary string used to hold actual string value @@ -39,6 +41,8 @@ struct unit_test_state { uint fdt_chksum; void *fdt_copy; uint fdt_size; + void *other_fdt; + int other_fdt_size; int runs_per_test; char expect_str[512]; char actual_str[512]; @@ -132,13 +136,24 @@ enum { */ struct udevice *testbus_get_clear_removed(void); +#ifdef CONFIG_SANDBOX +#include +#include +#endif + static inline void arch_reset_for_test(void) { #ifdef CONFIG_SANDBOX -#include - state_reset_for_test(state_get_current()); #endif } +static inline int test_load_other_fdt(struct unit_test_state *uts) +{ + int ret = 0; +#ifdef CONFIG_SANDBOX + ret = sandbox_load_other_fdt(&uts->other_fdt, &uts->other_fdt_size); +#endif + return ret; +} #endif /* __TEST_TEST_H */ From 8d468a188f69424b3461ba681a26b95bb9679f53 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 6 Sep 2022 20:27:11 -0600 Subject: [PATCH 352/374] sandbox: test: Provide an easy way to use the other FDT Add a test flag which indicates that the 'other' FDT should be set up ready for use. Handle this by copying in the FDT, unflattening it for livetree tests. Free the structures when the tests have run. We cannot use the other FDT unless we are using live tree or OFNODE_MULTI_TREE is enabled, since only one tree is supported by the ofnode interface in that case. Add this condition into ut_run_test_live_flat() and update the comments. Signed-off-by: Simon Glass --- include/test/test.h | 3 +++ test/test-main.c | 39 ++++++++++++++++++++++++++++++++++++--- 2 files changed, 39 insertions(+), 3 deletions(-) diff --git a/include/test/test.h b/include/test/test.h index 225bf45504..3bbd77c38b 100644 --- a/include/test/test.h +++ b/include/test/test.h @@ -25,6 +25,7 @@ * @fdt_size: Size of the device-tree copy * @other_fdt: Buffer for the other FDT (UT_TESTF_OTHER_FDT) * @other_fdt_size: Size of the other FDT (UT_TESTF_OTHER_FDT) + * @of_other: Live tree for the other FDT * @runs_per_test: Number of times to run each test (typically 1) * @expect_str: Temporary string used to hold expected string value * @actual_str: Temporary string used to hold actual string value @@ -43,6 +44,7 @@ struct unit_test_state { uint fdt_size; void *other_fdt; int other_fdt_size; + struct device_node *of_other; int runs_per_test; char expect_str[512]; char actual_str[512]; @@ -58,6 +60,7 @@ enum { UT_TESTF_CONSOLE_REC = BIT(5), /* needs console recording */ /* do extra driver model init and uninit */ UT_TESTF_DM = BIT(6), + UT_TESTF_OTHER_FDT = BIT(7), /* read in other device tree */ }; /** diff --git a/test/test-main.c b/test/test-main.c index c12027ce68..1fcbae3cd4 100644 --- a/test/test-main.c +++ b/test/test-main.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -314,6 +315,20 @@ static int test_pre_run(struct unit_test_state *uts, struct unit_test *test) (test->flags & UT_TESTF_SCAN_FDT)) ut_assertok(dm_extended_scan(false)); + if (IS_ENABLED(CONFIG_SANDBOX) && (test->flags & UT_TESTF_OTHER_FDT)) { + /* make sure the other FDT is available */ + ut_assertok(test_load_other_fdt(uts)); + + /* + * create a new live tree with it for every test, in case a + * test modifies the tree + */ + if (of_live_active()) { + ut_assertok(unflatten_device_tree(uts->other_fdt, + &uts->of_other)); + } + } + if (test->flags & UT_TESTF_CONSOLE_REC) { int ret = console_record_reset_enable(); @@ -342,6 +357,9 @@ static int test_post_run(struct unit_test_state *uts, struct unit_test *test) ut_assertok(cyclic_uninit()); ut_assertok(event_uninit()); + free(uts->of_other); + uts->of_other = NULL; + return 0; } @@ -412,6 +430,9 @@ static int ut_run_test_live_flat(struct unit_test_state *uts, { int runs; + if ((test->flags & UT_TESTF_OTHER_FDT) && !IS_ENABLED(CONFIG_SANDBOX)) + return -EAGAIN; + /* Run with the live tree if possible */ runs = 0; if (CONFIG_IS_ENABLED(OF_LIVE)) { @@ -423,10 +444,20 @@ static int ut_run_test_live_flat(struct unit_test_state *uts, } /* - * Run with the flat tree if we couldn't run it with live tree, - * or it is a core test. + * Run with the flat tree if: + * - it is not marked for live tree only + * - it doesn't require the 'other' FDT when OFNODE_MULTI_TREE_MAX is + * not enabled (since flat tree can only support a single FDT in that + * case + * - we couldn't run it with live tree, + * - it is a core test (dm tests except video) + * - the FDT is still valid and has not been updated by an earlier test + * (for sandbox we handle this by copying the tree, but not for other + * boards) */ if (!(test->flags & UT_TESTF_LIVE_TREE) && + (CONFIG_IS_ENABLED(OFNODE_MULTI_TREE) || + !(test->flags & UT_TESTF_OTHER_FDT)) && (!runs || ut_test_run_on_flattree(test)) && !(gd->flags & GD_FLG_FDT_CHANGED)) { uts->of_live = false; @@ -529,8 +560,10 @@ int ut_run_list(const char *category, const char *prefix, /* Best efforts only...ignore errors */ if (has_dm_tests) dm_test_restore(uts.of_root); - if (IS_ENABLED(CONFIG_SANDBOX)) + if (IS_ENABLED(CONFIG_SANDBOX)) { os_free(uts.fdt_copy); + os_free(uts.other_fdt); + } if (ret == -ENOENT) printf("Test '%s' not found\n", select_name); From 1701359f752b9622752df6a6c6a1326c225a5616 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 6 Sep 2022 20:27:12 -0600 Subject: [PATCH 353/374] dm: core: Reduce code size with dev_of_offset() Update the function to mark it with the const attribute. Also avoid calling it multiple times in the devfdt_get_addr_index() function. Signed-off-by: Simon Glass --- drivers/core/fdtaddr.c | 18 +++++++++--------- include/dm/device.h | 6 +++--- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/core/fdtaddr.c b/drivers/core/fdtaddr.c index c3a50a2b0c..91bcd1a2c2 100644 --- a/drivers/core/fdtaddr.c +++ b/drivers/core/fdtaddr.c @@ -21,6 +21,8 @@ DECLARE_GLOBAL_DATA_PTR; fdt_addr_t devfdt_get_addr_index(const struct udevice *dev, int index) { #if CONFIG_IS_ENABLED(OF_REAL) + int offset = dev_of_offset(dev); + int parent = dev_of_offset(dev->parent); fdt_addr_t addr; if (CONFIG_IS_ENABLED(OF_TRANSLATE)) { @@ -28,21 +30,19 @@ fdt_addr_t devfdt_get_addr_index(const struct udevice *dev, int index) int len = 0; int na, ns; - na = fdt_address_cells(gd->fdt_blob, - dev_of_offset(dev->parent)); + na = fdt_address_cells(gd->fdt_blob, parent); if (na < 1) { debug("bad #address-cells\n"); return FDT_ADDR_T_NONE; } - ns = fdt_size_cells(gd->fdt_blob, dev_of_offset(dev->parent)); + ns = fdt_size_cells(gd->fdt_blob, parent); if (ns < 0) { debug("bad #size-cells\n"); return FDT_ADDR_T_NONE; } - reg = fdt_getprop(gd->fdt_blob, dev_of_offset(dev), "reg", - &len); + reg = fdt_getprop(gd->fdt_blob, offset, "reg", &len); if (!reg || (len <= (index * sizeof(fdt32_t) * (na + ns)))) { debug("Req index out of range\n"); return FDT_ADDR_T_NONE; @@ -56,7 +56,7 @@ fdt_addr_t devfdt_get_addr_index(const struct udevice *dev, int index) * bus setups. */ addr = fdt_translate_address((void *)gd->fdt_blob, - dev_of_offset(dev), reg); + offset, reg); } else { /* Non translatable if #size-cells == 0 */ addr = fdt_read_number(reg, na); @@ -66,9 +66,9 @@ fdt_addr_t devfdt_get_addr_index(const struct udevice *dev, int index) * Use the "simple" translate function for less complex * bus setups. */ - addr = fdtdec_get_addr_size_auto_parent(gd->fdt_blob, - dev_of_offset(dev->parent), dev_of_offset(dev), - "reg", index, NULL, false); + addr = fdtdec_get_addr_size_auto_parent(gd->fdt_blob, parent, + offset, "reg", index, + NULL, false); if (CONFIG_IS_ENABLED(SIMPLE_BUS) && addr != FDT_ADDR_T_NONE) { if (device_get_uclass_id(dev->parent) == UCLASS_SIMPLE_BUS) diff --git a/include/dm/device.h b/include/dm/device.h index 12c6ba37ff..f3f953c9af 100644 --- a/include/dm/device.h +++ b/include/dm/device.h @@ -253,7 +253,7 @@ static inline void dev_bic_flags(struct udevice *dev, u32 bic) * @dev: device to check * Return: reference of the device's DT node */ -static inline ofnode dev_ofnode(const struct udevice *dev) +static inline __attribute_const__ ofnode dev_ofnode(const struct udevice *dev) { #if CONFIG_IS_ENABLED(OF_REAL) return dev->node_; @@ -273,7 +273,7 @@ static inline ofnode dev_ofnode(const struct udevice *dev) #define dev_get_dma_offset(_dev) 0 #endif -static inline int dev_of_offset(const struct udevice *dev) +static inline __attribute_const__ int dev_of_offset(const struct udevice *dev) { #if CONFIG_IS_ENABLED(OF_REAL) return ofnode_to_offset(dev_ofnode(dev)); @@ -282,7 +282,7 @@ static inline int dev_of_offset(const struct udevice *dev) #endif } -static inline bool dev_has_ofnode(const struct udevice *dev) +static inline __attribute_const__ bool dev_has_ofnode(const struct udevice *dev) { #if CONFIG_IS_ENABLED(OF_REAL) return ofnode_valid(dev_ofnode(dev)); From 4b1f5714658e98f55e9dbae58fd5000f9a3fcbd3 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 6 Sep 2022 20:27:13 -0600 Subject: [PATCH 354/374] dm: core: Rename ofnode_get_first/next_property() Drop the 'get' in these names since it does not fit with the rest of the API. Signed-off-by: Simon Glass --- drivers/core/ofnode.c | 4 ++-- drivers/core/read.c | 4 ++-- env/common.c | 4 ++-- include/dm/ofnode.h | 8 ++++---- include/dm/read.h | 6 +++--- test/dm/ofread.c | 4 ++-- 6 files changed, 15 insertions(+), 15 deletions(-) diff --git a/drivers/core/ofnode.c b/drivers/core/ofnode.c index caf28c68c4..2feca567a8 100644 --- a/drivers/core/ofnode.c +++ b/drivers/core/ofnode.c @@ -780,7 +780,7 @@ const void *ofnode_get_property(ofnode node, const char *propname, int *lenp) propname, lenp); } -int ofnode_get_first_property(ofnode node, struct ofprop *prop) +int ofnode_first_property(ofnode node, struct ofprop *prop) { prop->node = node; @@ -799,7 +799,7 @@ int ofnode_get_first_property(ofnode node, struct ofprop *prop) return 0; } -int ofnode_get_next_property(struct ofprop *prop) +int ofnode_next_property(struct ofprop *prop) { if (ofnode_is_np(prop->node)) { prop->prop = of_get_next_property(ofnode_to_np(prop->node), diff --git a/drivers/core/read.c b/drivers/core/read.c index 07ab8ab41c..df298d50cd 100644 --- a/drivers/core/read.c +++ b/drivers/core/read.c @@ -287,12 +287,12 @@ const void *dev_read_prop(const struct udevice *dev, const char *propname, int dev_read_first_prop(const struct udevice *dev, struct ofprop *prop) { - return ofnode_get_first_property(dev_ofnode(dev), prop); + return ofnode_first_property(dev_ofnode(dev), prop); } int dev_read_next_prop(struct ofprop *prop) { - return ofnode_get_next_property(prop); + return ofnode_next_property(prop); } const void *dev_read_prop_by_prop(struct ofprop *prop, diff --git a/env/common.c b/env/common.c index 8dd05ff76d..4e70baaee8 100644 --- a/env/common.c +++ b/env/common.c @@ -539,9 +539,9 @@ void env_import_fdt(void) return; } - for (res = ofnode_get_first_property(node, &prop); + for (res = ofnode_first_property(node, &prop); !res; - res = ofnode_get_next_property(&prop)) { + res = ofnode_next_property(&prop)) { const char *name, *val; val = ofnode_get_property_by_prop(&prop, &name, NULL); diff --git a/include/dm/ofnode.h b/include/dm/ofnode.h index 044546f005..d477ef1762 100644 --- a/include/dm/ofnode.h +++ b/include/dm/ofnode.h @@ -799,7 +799,7 @@ int ofnode_decode_display_timing(ofnode node, int index, const void *ofnode_get_property(ofnode node, const char *propname, int *lenp); /** - * ofnode_get_first_property()- get the reference of the first property + * ofnode_first_property()- get the reference of the first property * * Get reference to the first property of the node, it is used to iterate * and read all the property with ofnode_get_property_by_prop(). @@ -808,10 +808,10 @@ const void *ofnode_get_property(ofnode node, const char *propname, int *lenp); * @prop: place to put argument reference * Return: 0 if OK, -ve on error. -FDT_ERR_NOTFOUND if not found */ -int ofnode_get_first_property(ofnode node, struct ofprop *prop); +int ofnode_first_property(ofnode node, struct ofprop *prop); /** - * ofnode_get_next_property() - get the reference of the next property + * ofnode_next_property() - get the reference of the next property * * Get reference to the next property of the node, it is used to iterate * and read all the property with ofnode_get_property_by_prop(). @@ -819,7 +819,7 @@ int ofnode_get_first_property(ofnode node, struct ofprop *prop); * @prop: reference of current argument and place to put reference of next one * Return: 0 if OK, -ve on error. -FDT_ERR_NOTFOUND if not found */ -int ofnode_get_next_property(struct ofprop *prop); +int ofnode_next_property(struct ofprop *prop); /** * ofnode_get_property_by_prop() - get a pointer to the value of a property diff --git a/include/dm/read.h b/include/dm/read.h index 122b9cd15b..519c156e1c 100644 --- a/include/dm/read.h +++ b/include/dm/read.h @@ -569,7 +569,7 @@ const void *dev_read_prop(const struct udevice *dev, const char *propname, int dev_read_first_prop(const struct udevice *dev, struct ofprop *prop); /** - * ofnode_get_next_property() - get the reference of the next property + * ofnode_next_property() - get the reference of the next property * * Get reference to the next property of the node, it is used to iterate * and read all the property with dev_read_prop_by_prop(). @@ -1079,12 +1079,12 @@ static inline const void *dev_read_prop(const struct udevice *dev, static inline int dev_read_first_prop(const struct udevice *dev, struct ofprop *prop) { - return ofnode_get_first_property(dev_ofnode(dev), prop); + return ofnode_first_property(dev_ofnode(dev), prop); } static inline int dev_read_next_prop(struct ofprop *prop) { - return ofnode_get_next_property(prop); + return ofnode_next_property(prop); } static inline const void *dev_read_prop_by_prop(struct ofprop *prop, diff --git a/test/dm/ofread.c b/test/dm/ofread.c index 8c7dd82513..95a24c3f42 100644 --- a/test/dm/ofread.c +++ b/test/dm/ofread.c @@ -14,9 +14,9 @@ static int dm_test_ofnode_get_property_by_prop(struct unit_test_state *uts) int res, len, count = 0; node = ofnode_path("/cros-ec/flash"); - for (res = ofnode_get_first_property(node, &prop); + for (res = ofnode_first_property(node, &prop); !res; - res = ofnode_get_next_property(&prop)) { + res = ofnode_next_property(&prop)) { value = ofnode_get_property_by_prop(&prop, &propname, &len); ut_assertnonnull(value); switch (count) { From 9243224687bd92674c693546a46f849b1a54c75c Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 6 Sep 2022 20:27:14 -0600 Subject: [PATCH 355/374] dm: core: Rename ofnode_get_property_by_prop() The current name is quite unwieldy. Change it to use an ofprop_ prefix and shorten it. Fix the return-value comment while we are here. Signed-off-by: Simon Glass --- drivers/core/ofnode.c | 4 ++-- drivers/core/read.c | 2 +- env/common.c | 2 +- include/dm/ofnode.h | 14 +++++++------- include/dm/read.h | 2 +- test/dm/ofread.c | 7 +++---- 6 files changed, 15 insertions(+), 16 deletions(-) diff --git a/drivers/core/ofnode.c b/drivers/core/ofnode.c index 2feca567a8..f9c9ca14a6 100644 --- a/drivers/core/ofnode.c +++ b/drivers/core/ofnode.c @@ -816,8 +816,8 @@ int ofnode_next_property(struct ofprop *prop) return 0; } -const void *ofnode_get_property_by_prop(const struct ofprop *prop, - const char **propname, int *lenp) +const void *ofprop_get_property(const struct ofprop *prop, + const char **propname, int *lenp) { if (ofnode_is_np(prop->node)) return of_get_property_by_prop(ofnode_to_np(prop->node), diff --git a/drivers/core/read.c b/drivers/core/read.c index df298d50cd..3e5fea87d8 100644 --- a/drivers/core/read.c +++ b/drivers/core/read.c @@ -298,7 +298,7 @@ int dev_read_next_prop(struct ofprop *prop) const void *dev_read_prop_by_prop(struct ofprop *prop, const char **propname, int *lenp) { - return ofnode_get_property_by_prop(prop, propname, lenp); + return ofprop_get_property(prop, propname, lenp); } int dev_read_alias_seq(const struct udevice *dev, int *devnump) diff --git a/env/common.c b/env/common.c index 4e70baaee8..8beb8e6aa4 100644 --- a/env/common.c +++ b/env/common.c @@ -544,7 +544,7 @@ void env_import_fdt(void) res = ofnode_next_property(&prop)) { const char *name, *val; - val = ofnode_get_property_by_prop(&prop, &name, NULL); + val = ofprop_get_property(&prop, &name, NULL); env_set(name, val); } } diff --git a/include/dm/ofnode.h b/include/dm/ofnode.h index d477ef1762..9dcc1fed5b 100644 --- a/include/dm/ofnode.h +++ b/include/dm/ofnode.h @@ -802,7 +802,7 @@ const void *ofnode_get_property(ofnode node, const char *propname, int *lenp); * ofnode_first_property()- get the reference of the first property * * Get reference to the first property of the node, it is used to iterate - * and read all the property with ofnode_get_property_by_prop(). + * and read all the property with ofprop_get_property(). * * @node: node to read * @prop: place to put argument reference @@ -814,7 +814,7 @@ int ofnode_first_property(ofnode node, struct ofprop *prop); * ofnode_next_property() - get the reference of the next property * * Get reference to the next property of the node, it is used to iterate - * and read all the property with ofnode_get_property_by_prop(). + * and read all the property with ofprop_get_property(). * * @prop: reference of current argument and place to put reference of next one * Return: 0 if OK, -ve on error. -FDT_ERR_NOTFOUND if not found @@ -822,17 +822,17 @@ int ofnode_first_property(ofnode node, struct ofprop *prop); int ofnode_next_property(struct ofprop *prop); /** - * ofnode_get_property_by_prop() - get a pointer to the value of a property + * ofprop_get_property() - get a pointer to the value of a property * * Get value for the property identified by the provided reference. * * @prop: reference on property * @propname: If non-NULL, place to property name on success, - * @lenp: If non-NULL, place to put length on success - * Return: 0 if OK, -ve on error. -FDT_ERR_NOTFOUND if not found + * @lenp: If non-NULL, place to put length on success, or error code on failure + * Return: pointer to property, or NULL if not found */ -const void *ofnode_get_property_by_prop(const struct ofprop *prop, - const char **propname, int *lenp); +const void *ofprop_get_property(const struct ofprop *prop, + const char **propname, int *lenp); /** * ofnode_is_available() - check if a node is marked available diff --git a/include/dm/read.h b/include/dm/read.h index 519c156e1c..cc4f16196f 100644 --- a/include/dm/read.h +++ b/include/dm/read.h @@ -1091,7 +1091,7 @@ static inline const void *dev_read_prop_by_prop(struct ofprop *prop, const char **propname, int *lenp) { - return ofnode_get_property_by_prop(prop, propname, lenp); + return ofprop_get_property(prop, propname, lenp); } static inline int dev_read_alias_seq(const struct udevice *dev, int *devnump) diff --git a/test/dm/ofread.c b/test/dm/ofread.c index 95a24c3f42..3523860d2b 100644 --- a/test/dm/ofread.c +++ b/test/dm/ofread.c @@ -5,7 +5,7 @@ #include #include -static int dm_test_ofnode_get_property_by_prop(struct unit_test_state *uts) +static int dm_test_ofprop_get_property(struct unit_test_state *uts) { ofnode node; struct ofprop prop; @@ -17,7 +17,7 @@ static int dm_test_ofnode_get_property_by_prop(struct unit_test_state *uts) for (res = ofnode_first_property(node, &prop); !res; res = ofnode_next_property(&prop)) { - value = ofnode_get_property_by_prop(&prop, &propname, &len); + value = ofprop_get_property(&prop, &propname, &len); ut_assertnonnull(value); switch (count) { case 0: @@ -46,5 +46,4 @@ static int dm_test_ofnode_get_property_by_prop(struct unit_test_state *uts) return 0; } -DM_TEST(dm_test_ofnode_get_property_by_prop, - UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); +DM_TEST(dm_test_ofprop_get_property, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); From f46ec93ed593e7a442629a2a56fd541debc41329 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 6 Sep 2022 20:27:15 -0600 Subject: [PATCH 356/374] dm: core: Avoid creating a name property when unflattening The current implementation creates a 'name' value for every node. This is not needed for the latest device tree format, which includes a name in the node header. Adjust the code to point the name at the node header instead. Also simplify ofnode_get_name(), now that we can rely on it to set the name correctly. Update the comment to make it clear what name the root node has. Signed-off-by: Simon Glass --- drivers/core/ofnode.c | 2 +- include/dm/ofnode.h | 2 +- lib/of_live.c | 7 ++++++- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/core/ofnode.c b/drivers/core/ofnode.c index f9c9ca14a6..154c7b2667 100644 --- a/drivers/core/ofnode.c +++ b/drivers/core/ofnode.c @@ -356,7 +356,7 @@ const char *ofnode_get_name(ofnode node) } if (ofnode_is_np(node)) - return strrchr(node.np->full_name, '/') + 1; + return node.np->name; return fdt_get_name(gd->fdt_blob, ofnode_to_offset(node), NULL); } diff --git a/include/dm/ofnode.h b/include/dm/ofnode.h index 9dcc1fed5b..1e23a40c99 100644 --- a/include/dm/ofnode.h +++ b/include/dm/ofnode.h @@ -466,7 +466,7 @@ ofnode ofnode_get_parent(ofnode node); * ofnode_get_name() - get the name of a node * * @node: valid node to look up - * Return: name of node + * Return: name of node (for the root node this is "") */ const char *ofnode_get_name(ofnode node); diff --git a/lib/of_live.c b/lib/of_live.c index 30cae9ab88..1b5964d09a 100644 --- a/lib/of_live.c +++ b/lib/of_live.c @@ -97,6 +97,10 @@ static void *unflatten_dt_node(const void *blob, void *mem, int *poffset, char *fn; fn = (char *)np + sizeof(*np); + if (new_format) { + np->name = pathp; + has_name = 1; + } np->full_name = fn; if (new_format) { /* rebuild full path for new format */ @@ -202,7 +206,8 @@ static void *unflatten_dt_node(const void *blob, void *mem, int *poffset, } if (!dryrun) { *prev_pp = NULL; - np->name = of_get_property(np, "name", NULL); + if (!has_name) + np->name = of_get_property(np, "name", NULL); np->type = of_get_property(np, "device_type", NULL); if (!np->name) From 52ad21aa2cc55f53da19436f457a8590abf0d125 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 6 Sep 2022 20:27:16 -0600 Subject: [PATCH 357/374] dm: core: Add a macro to iterate through properties Add a 'for_each' macro like we have for nodes. Fix the comment for struct ofprop while we are here. Signed-off-by: Simon Glass --- include/dm/ofnode.h | 38 ++++++++++++++++++++++++++++++++++++++ include/dm/ofnode_decl.h | 2 +- test/dm/ofnode.c | 24 ++++++++++++++++++++++++ 3 files changed, 63 insertions(+), 1 deletion(-) diff --git a/include/dm/ofnode.h b/include/dm/ofnode.h index 1e23a40c99..7b0ef109b7 100644 --- a/include/dm/ofnode.h +++ b/include/dm/ofnode.h @@ -176,6 +176,20 @@ static inline ofnode ofnode_root(void) return node; } +/** + * ofprop_valid() - check if an ofprop is valid + * + * @prop: Pointer to ofprop to check + * Return: true if the reference contains a valid ofprop, false if not + */ +static inline bool ofprop_valid(struct ofprop *prop) +{ + if (of_live_active()) + return prop->prop; + else + return prop->offset >= 0; +} + /** * oftree_default() - Returns the default device tree (U-Boot's control FDT) * @@ -821,6 +835,30 @@ int ofnode_first_property(ofnode node, struct ofprop *prop); */ int ofnode_next_property(struct ofprop *prop); +/** + * ofnode_for_each_prop() - iterate over all properties of a node + * + * @prop: struct ofprop + * @node: node (lvalue, ofnode) + * + * This is a wrapper around a for loop and is used like this:: + * + * ofnode node; + * struct ofprop prop; + * + * ofnode_for_each_prop(prop, node) { + * ...use prop... + * } + * + * Note that this is implemented as a macro and @prop is used as + * iterator in the loop. The parent variable can be a constant or even a + * literal. + */ +#define ofnode_for_each_prop(prop, node) \ + for (ofnode_first_property(node, &prop); \ + ofprop_valid(&prop); \ + ofnode_next_property(&prop)) + /** * ofprop_get_property() - get a pointer to the value of a property * diff --git a/include/dm/ofnode_decl.h b/include/dm/ofnode_decl.h index 8d0d7885aa..f666a0287b 100644 --- a/include/dm/ofnode_decl.h +++ b/include/dm/ofnode_decl.h @@ -57,7 +57,7 @@ typedef union ofnode_union { * * @node: Pointer to device node * @offset: Pointer into flat device tree, used for flat tree. - * @prop: Pointer to property, used for live treee. + * @prop: Pointer to property, used for live tree. */ struct ofprop { diff --git a/test/dm/ofnode.c b/test/dm/ofnode.c index a421392a97..5ddfd0298a 100644 --- a/test/dm/ofnode.c +++ b/test/dm/ofnode.c @@ -669,3 +669,27 @@ static int dm_test_ofnode_add_subnode(struct unit_test_state *uts) return 0; } DM_TEST(dm_test_ofnode_add_subnode, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); + +static int dm_test_ofnode_for_each_prop(struct unit_test_state *uts) +{ + ofnode node, subnode; + struct ofprop prop; + int count; + + node = ofnode_path("/buttons"); + count = 0; + + /* we expect "compatible" for each node */ + ofnode_for_each_prop(prop, node) + count++; + ut_asserteq(1, count); + + /* there are two nodes, each with 2 properties */ + ofnode_for_each_subnode(subnode, node) + ofnode_for_each_prop(prop, subnode) + count++; + ut_asserteq(5, count); + + return 0; +} +DM_TEST(dm_test_ofnode_for_each_prop, UT_TESTF_SCAN_FDT); From 8909066199281b86bf4ee7673ec6d7983dd12a26 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 6 Sep 2022 20:27:17 -0600 Subject: [PATCH 358/374] dm: core: Drop ofnode_is_available() This function is also available as ofnode_is_enabled(), so use that instead. Signed-off-by: Simon Glass --- arch/arm/mach-tegra/xusb-padctl-common.c | 2 +- arch/riscv/lib/andes_plic.c | 2 +- arch/riscv/lib/smp.c | 2 +- drivers/core/ofnode.c | 9 --------- drivers/cpu/imx8_cpu.c | 2 +- drivers/cpu/riscv_cpu.c | 2 +- drivers/crypto/fsl/jr.c | 2 +- drivers/firmware/scmi/scmi_agent-uclass.c | 2 +- drivers/mtd/mtdpart.c | 4 ++-- drivers/mtd/nand/raw/zynq_nand.c | 2 +- drivers/net/fec_mxc.c | 2 +- drivers/net/fsl_enetc.c | 2 +- drivers/net/mscc_eswitch/felix_switch.c | 2 +- drivers/net/sja1105.c | 2 +- drivers/net/ti/am65-cpsw-nuss.c | 2 +- drivers/pci/pci-uclass.c | 2 +- drivers/pci/pci_mvebu.c | 2 +- drivers/pci/pci_tegra.c | 2 +- drivers/pci/pcie_mediatek.c | 4 ++-- include/dm/ofnode.h | 8 -------- lib/fdtdec.c | 2 +- net/dsa-uclass.c | 2 +- 22 files changed, 22 insertions(+), 39 deletions(-) diff --git a/arch/arm/mach-tegra/xusb-padctl-common.c b/arch/arm/mach-tegra/xusb-padctl-common.c index 8bdd44ad7a..388ec49968 100644 --- a/arch/arm/mach-tegra/xusb-padctl-common.c +++ b/arch/arm/mach-tegra/xusb-padctl-common.c @@ -282,7 +282,7 @@ int tegra_xusb_process_nodes(ofnode nodes[], unsigned int count, debug("%s: count=%d\n", __func__, count); for (i = 0; i < count; i++) { debug("%s: i=%d, node=%p\n", __func__, i, nodes[i].np); - if (!ofnode_is_available(nodes[i])) + if (!ofnode_is_enabled(nodes[i])) continue; padctl.socdata = socdata; diff --git a/arch/riscv/lib/andes_plic.c b/arch/riscv/lib/andes_plic.c index 5e113ee8c9..68514758a8 100644 --- a/arch/riscv/lib/andes_plic.c +++ b/arch/riscv/lib/andes_plic.c @@ -71,7 +71,7 @@ int riscv_init_ipi(void) continue; /* skip if hart is marked as not available */ - if (!ofnode_is_available(node)) + if (!ofnode_is_enabled(node)) continue; /* read hart ID of CPU */ diff --git a/arch/riscv/lib/smp.c b/arch/riscv/lib/smp.c index c0f65af191..4f073a016f 100644 --- a/arch/riscv/lib/smp.c +++ b/arch/riscv/lib/smp.c @@ -27,7 +27,7 @@ static int send_ipi_many(struct ipi_data *ipi, int wait) ofnode_for_each_subnode(node, cpus) { /* skip if hart is marked as not available in the device tree */ - if (!ofnode_is_available(node)) + if (!ofnode_is_enabled(node)) continue; /* read hart ID of CPU */ diff --git a/drivers/core/ofnode.c b/drivers/core/ofnode.c index 154c7b2667..4dd2aee11c 100644 --- a/drivers/core/ofnode.c +++ b/drivers/core/ofnode.c @@ -828,15 +828,6 @@ const void *ofprop_get_property(const struct ofprop *prop, propname, lenp); } -bool ofnode_is_available(ofnode node) -{ - if (ofnode_is_np(node)) - return of_device_is_available(ofnode_to_np(node)); - else - return fdtdec_get_is_enabled(gd->fdt_blob, - ofnode_to_offset(node)); -} - fdt_addr_t ofnode_get_addr_size(ofnode node, const char *property, fdt_size_t *sizep) { diff --git a/drivers/cpu/imx8_cpu.c b/drivers/cpu/imx8_cpu.c index abddbef57b..b8eb2d2800 100644 --- a/drivers/cpu/imx8_cpu.c +++ b/drivers/cpu/imx8_cpu.c @@ -144,7 +144,7 @@ static int cpu_imx_get_count(const struct udevice *dev) ofnode_for_each_subnode(node, dev_ofnode(dev->parent)) { const char *device_type; - if (!ofnode_is_available(node)) + if (!ofnode_is_enabled(node)) continue; device_type = ofnode_read_string(node, "device_type"); diff --git a/drivers/cpu/riscv_cpu.c b/drivers/cpu/riscv_cpu.c index b30dceba37..d6484d7f4b 100644 --- a/drivers/cpu/riscv_cpu.c +++ b/drivers/cpu/riscv_cpu.c @@ -77,7 +77,7 @@ static int riscv_cpu_get_count(const struct udevice *dev) const char *device_type; /* skip if hart is marked as not available in the device tree */ - if (!ofnode_is_available(node)) + if (!ofnode_is_enabled(node)) continue; device_type = ofnode_read_string(node, "device_type"); diff --git a/drivers/crypto/fsl/jr.c b/drivers/crypto/fsl/jr.c index acd29924f7..8c0fb27b53 100644 --- a/drivers/crypto/fsl/jr.c +++ b/drivers/crypto/fsl/jr.c @@ -853,7 +853,7 @@ static int caam_jr_probe(struct udevice *dev) /* Check for enabled job ring node */ ofnode_for_each_subnode(node, dev_ofnode(dev)) { - if (!ofnode_is_available(node)) + if (!ofnode_is_enabled(node)) continue; jr_node = ofnode_read_u32_default(node, "reg", -1); diff --git a/drivers/firmware/scmi/scmi_agent-uclass.c b/drivers/firmware/scmi/scmi_agent-uclass.c index 2b6211c4e6..c3f3d1f440 100644 --- a/drivers/firmware/scmi/scmi_agent-uclass.c +++ b/drivers/firmware/scmi/scmi_agent-uclass.c @@ -65,7 +65,7 @@ static int scmi_bind_protocols(struct udevice *dev) struct driver *drv = NULL; u32 protocol_id; - if (!ofnode_is_available(node)) + if (!ofnode_is_enabled(node)) continue; if (ofnode_read_u32(node, "reg", &protocol_id)) diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c index 56aa58b58b..4886392a1c 100644 --- a/drivers/mtd/mtdpart.c +++ b/drivers/mtd/mtdpart.c @@ -895,7 +895,7 @@ int add_mtd_partitions_of(struct mtd_info *master) else parts = ofnode_find_subnode(master->flash_node, "partitions"); - if (!ofnode_valid(parts) || !ofnode_is_available(parts) || + if (!ofnode_valid(parts) || !ofnode_is_enabled(parts) || !ofnode_device_is_compatible(parts, "fixed-partitions")) return 0; @@ -905,7 +905,7 @@ int add_mtd_partitions_of(struct mtd_info *master) fdt_addr_t offset; fdt_size_t size; - if (!ofnode_is_available(child)) + if (!ofnode_is_enabled(child)) continue; offset = ofnode_get_addr_size_index_notrans(child, 0, &size); diff --git a/drivers/mtd/nand/raw/zynq_nand.c b/drivers/mtd/nand/raw/zynq_nand.c index 10e9cd18b0..14cb2ba704 100644 --- a/drivers/mtd/nand/raw/zynq_nand.c +++ b/drivers/mtd/nand/raw/zynq_nand.c @@ -1095,7 +1095,7 @@ static int zynq_nand_probe(struct udevice *dev) } } - if (!ofnode_is_available(of_nand)) { + if (!ofnode_is_enabled(of_nand)) { debug("Nand node in dt disabled\n"); return dm_scan_fdt_dev(dev); } diff --git a/drivers/net/fec_mxc.c b/drivers/net/fec_mxc.c index 8bc2b46d40..bbc4434ddb 100644 --- a/drivers/net/fec_mxc.c +++ b/drivers/net/fec_mxc.c @@ -1078,7 +1078,7 @@ static int device_get_phy_addr(struct fec_priv *priv, struct udevice *dev) return ret; } - if (!ofnode_is_available(phandle_args.node)) + if (!ofnode_is_enabled(phandle_args.node)) return -ENOENT; priv->phy_of_node = phandle_args.node; diff --git a/drivers/net/fsl_enetc.c b/drivers/net/fsl_enetc.c index d43a85b498..1fd5089cc4 100644 --- a/drivers/net/fsl_enetc.c +++ b/drivers/net/fsl_enetc.c @@ -323,7 +323,7 @@ static int enetc_probe(struct udevice *dev) struct enetc_priv *priv = dev_get_priv(dev); int res; - if (ofnode_valid(dev_ofnode(dev)) && !ofnode_is_available(dev_ofnode(dev))) { + if (ofnode_valid(dev_ofnode(dev)) && !ofnode_is_enabled(dev_ofnode(dev))) { enetc_dbg(dev, "interface disabled\n"); return -ENODEV; } diff --git a/drivers/net/mscc_eswitch/felix_switch.c b/drivers/net/mscc_eswitch/felix_switch.c index 709c9e3ef5..2e5f45e574 100644 --- a/drivers/net/mscc_eswitch/felix_switch.c +++ b/drivers/net/mscc_eswitch/felix_switch.c @@ -287,7 +287,7 @@ static int felix_probe(struct udevice *dev) int err; if (ofnode_valid(dev_ofnode(dev)) && - !ofnode_is_available(dev_ofnode(dev))) { + !ofnode_is_enabled(dev_ofnode(dev))) { dev_dbg(dev, "switch disabled\n"); return -ENODEV; } diff --git a/drivers/net/sja1105.c b/drivers/net/sja1105.c index 4ca8709e34..48f044c647 100644 --- a/drivers/net/sja1105.c +++ b/drivers/net/sja1105.c @@ -3316,7 +3316,7 @@ static int sja1105_probe(struct udevice *dev) int rc; if (ofnode_valid(dev_ofnode(dev)) && - !ofnode_is_available(dev_ofnode(dev))) { + !ofnode_is_enabled(dev_ofnode(dev))) { dev_dbg(dev, "switch disabled\n"); return -ENODEV; } diff --git a/drivers/net/ti/am65-cpsw-nuss.c b/drivers/net/ti/am65-cpsw-nuss.c index 9580fa37ea..b79e06290a 100644 --- a/drivers/net/ti/am65-cpsw-nuss.c +++ b/drivers/net/ti/am65-cpsw-nuss.c @@ -719,7 +719,7 @@ static int am65_cpsw_probe_nuss(struct udevice *dev) node_name = ofnode_get_name(node); - disabled = !ofnode_is_available(node); + disabled = !ofnode_is_enabled(node); ret = ofnode_read_u32(node, "reg", &port_id); if (ret) { diff --git a/drivers/pci/pci-uclass.c b/drivers/pci/pci-uclass.c index 16a6a699f9..058b2f6359 100644 --- a/drivers/pci/pci-uclass.c +++ b/drivers/pci/pci-uclass.c @@ -766,7 +766,7 @@ static int pci_find_and_bind_driver(struct udevice *parent, if (ofnode_valid(dev_ofnode(parent))) pci_dev_find_ofnode(parent, bdf, &node); - if (ofnode_valid(node) && !ofnode_is_available(node)) { + if (ofnode_valid(node) && !ofnode_is_enabled(node)) { debug("%s: Ignoring disabled device\n", __func__); return log_msg_ret("dis", -EPERM); } diff --git a/drivers/pci/pci_mvebu.c b/drivers/pci/pci_mvebu.c index 5bd340a421..93a7508d8a 100644 --- a/drivers/pci/pci_mvebu.c +++ b/drivers/pci/pci_mvebu.c @@ -740,7 +740,7 @@ static int mvebu_pcie_bind(struct udevice *parent) /* First phase: Fill mvebu_pcie struct for each port */ ofnode_for_each_subnode(subnode, dev_ofnode(parent)) { - if (!ofnode_is_available(subnode)) + if (!ofnode_is_enabled(subnode)) continue; pcie = calloc(1, sizeof(*pcie)); diff --git a/drivers/pci/pci_tegra.c b/drivers/pci/pci_tegra.c index bc489d5ec8..29d54117e9 100644 --- a/drivers/pci/pci_tegra.c +++ b/drivers/pci/pci_tegra.c @@ -531,7 +531,7 @@ static int tegra_pcie_parse_dt(struct udevice *dev, enum tegra_pci_id id, lanes |= num_lanes << (index << 3); - if (!ofnode_is_available(subnode)) + if (!ofnode_is_enabled(subnode)) continue; port = malloc(sizeof(*port)); diff --git a/drivers/pci/pcie_mediatek.c b/drivers/pci/pcie_mediatek.c index 051a3bc969..c6e30e2462 100644 --- a/drivers/pci/pcie_mediatek.c +++ b/drivers/pci/pcie_mediatek.c @@ -657,7 +657,7 @@ static int mtk_pcie_probe(struct udevice *dev) struct fdt_pci_addr addr; u32 slot = 0; - if (!ofnode_is_available(subnode)) + if (!ofnode_is_enabled(subnode)) continue; err = ofnode_read_pci_addr(subnode, 0, "reg", &addr); @@ -696,7 +696,7 @@ static int mtk_pcie_probe_v2(struct udevice *dev) pcie->priv = dev; dev_for_each_subnode(subnode, dev) { - if (!ofnode_is_available(subnode)) + if (!ofnode_is_enabled(subnode)) continue; err = ofnode_read_pci_addr(subnode, 0, "reg", &addr); diff --git a/include/dm/ofnode.h b/include/dm/ofnode.h index 7b0ef109b7..a674d7d8fd 100644 --- a/include/dm/ofnode.h +++ b/include/dm/ofnode.h @@ -872,14 +872,6 @@ int ofnode_next_property(struct ofprop *prop); const void *ofprop_get_property(const struct ofprop *prop, const char **propname, int *lenp); -/** - * ofnode_is_available() - check if a node is marked available - * - * @node: node to check - * Return: true if node's 'status' property is "okay" (or is missing) - */ -bool ofnode_is_available(ofnode node); - /** * ofnode_get_addr_size() - get address and size from a property * diff --git a/lib/fdtdec.c b/lib/fdtdec.c index 96b6b71a60..eca01081c5 100644 --- a/lib/fdtdec.c +++ b/lib/fdtdec.c @@ -1058,7 +1058,7 @@ ofnode get_next_memory_node(ofnode mem) { do { mem = ofnode_by_prop_value(mem, "device_type", "memory", 7); - } while (!ofnode_is_available(mem)); + } while (!ofnode_is_enabled(mem)); return mem; } diff --git a/net/dsa-uclass.c b/net/dsa-uclass.c index 3bf4351c84..5b7046432f 100644 --- a/net/dsa-uclass.c +++ b/net/dsa-uclass.c @@ -432,7 +432,7 @@ static int dsa_post_bind(struct udevice *dev) * skip registration if port id not found or if the port * is explicitly disabled in DT */ - if (!ofnode_valid(pnode) || !ofnode_is_available(pnode)) + if (!ofnode_valid(pnode) || !ofnode_is_enabled(pnode)) continue; err = device_bind_driver_to_node(dev, DSA_PORT_CHILD_DRV_NAME, From 66d0d0c188db9e816c5b18e8823a8d8bf5e9cd63 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 6 Sep 2022 20:27:18 -0600 Subject: [PATCH 359/374] dm: core: Expand integer-reading tests The current tests do not cover all the behaviour. Add some more. Tidy up a few inconsistencies between livetree and flattree which come to light with these tests. Also drop the -ENODATA error since it is never actually returned. Signed-off-by: Simon Glass --- drivers/core/of_access.c | 5 +- drivers/core/ofnode.c | 17 +++++-- include/dm/of_access.h | 10 ++-- include/dm/ofnode.h | 8 +-- test/dm/ofnode.c | 102 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 125 insertions(+), 17 deletions(-) diff --git a/drivers/core/of_access.c b/drivers/core/of_access.c index 8631e1c286..85f7da5a49 100644 --- a/drivers/core/of_access.c +++ b/drivers/core/of_access.c @@ -471,8 +471,7 @@ struct device_node *of_find_node_by_phandle(struct device_node *root, * @len: requested length of property value * * Return: the property value on success, -EINVAL if the property does not - * exist, -ENODATA if property does not have a value, and -EOVERFLOW if the - * property data isn't large enough. + * exist and -EOVERFLOW if the property data isn't large enough. */ static void *of_find_property_value_of_size(const struct device_node *np, const char *propname, u32 len) @@ -481,8 +480,6 @@ static void *of_find_property_value_of_size(const struct device_node *np, if (!prop) return ERR_PTR(-EINVAL); - if (!prop->value) - return ERR_PTR(-ENODATA); if (len > prop->length) return ERR_PTR(-EOVERFLOW); diff --git a/drivers/core/ofnode.c b/drivers/core/ofnode.c index 4dd2aee11c..e4b4b352e4 100644 --- a/drivers/core/ofnode.c +++ b/drivers/core/ofnode.c @@ -296,9 +296,20 @@ int ofnode_read_u32_array(ofnode node, const char *propname, return of_read_u32_array(ofnode_to_np(node), propname, out_values, sz); } else { - return fdtdec_get_int_array(gd->fdt_blob, - ofnode_to_offset(node), propname, - out_values, sz); + int ret; + + ret = fdtdec_get_int_array(gd->fdt_blob, + ofnode_to_offset(node), propname, + out_values, sz); + + /* get the error right, but space is more important in SPL */ + if (!IS_ENABLED(CONFIG_SPL_BUILD)) { + if (ret == -FDT_ERR_NOTFOUND) + return -EINVAL; + else if (ret == -FDT_ERR_BADLAYOUT) + return -EOVERFLOW; + } + return ret; } } diff --git a/include/dm/of_access.h b/include/dm/of_access.h index dd70b44344..c556a18f7d 100644 --- a/include/dm/of_access.h +++ b/include/dm/of_access.h @@ -327,8 +327,7 @@ int of_read_u32(const struct device_node *np, const char *propname, u32 *outp); * @outp: pointer to return value, modified only if return value is 0. * * Return: - * 0 on success, -EINVAL if the property does not exist, - * -ENODATA if property does not have a value, and -EOVERFLOW if the + * 0 on success, -EINVAL if the property does not exist, or -EOVERFLOW if the * property data isn't large enough. */ int of_read_u32_index(const struct device_node *np, const char *propname, @@ -345,8 +344,7 @@ int of_read_u32_index(const struct device_node *np, const char *propname, * @outp: pointer to return value, modified only if return value is 0. * * Return: - * 0 on success, -EINVAL if the property does not exist, - * -ENODATA if property does not have a value, and -EOVERFLOW if the + * 0 on success, -EINVAL if the property does not exist, or -EOVERFLOW if the * property data isn't large enough. */ int of_read_u64(const struct device_node *np, const char *propname, u64 *outp); @@ -362,8 +360,8 @@ int of_read_u64(const struct device_node *np, const char *propname, u64 *outp); * @out_values: pointer to return value, modified only if return value is 0. * @sz: number of array elements to read * Return: - * 0 on success, -EINVAL if the property does not exist, -ENODATA - * if property does not have a value, and -EOVERFLOW is longer than sz. + * 0 on success, -EINVAL if the property does not exist, or -EOVERFLOW if + * longer than sz. */ int of_read_u32_array(const struct device_node *np, const char *propname, u32 *out_values, size_t sz); diff --git a/include/dm/ofnode.h b/include/dm/ofnode.h index a674d7d8fd..8b0a108706 100644 --- a/include/dm/ofnode.h +++ b/include/dm/ofnode.h @@ -373,12 +373,12 @@ const char *ofnode_read_string(ofnode node, const char *propname); * @propname: name of the property to read * @out_values: pointer to return value, modified only if return value is 0 * @sz: number of array elements to read - * Return: 0 if OK, -ve on error + * Return: 0 on success, -EINVAL if the property does not exist, + * -ENODATA if property does not have a value, and -EOVERFLOW if the + * property data isn't large enough * * Search for a property in a device node and read 32-bit value(s) from - * it. Returns 0 on success, -EINVAL if the property does not exist, - * -ENODATA if property does not have a value, and -EOVERFLOW if the - * property data isn't large enough. + * it. * * The out_values is modified only if a valid u32 value can be decoded. */ diff --git a/test/dm/ofnode.c b/test/dm/ofnode.c index 5ddfd0298a..eac0c50364 100644 --- a/test/dm/ofnode.c +++ b/test/dm/ofnode.c @@ -320,6 +320,9 @@ static int dm_test_ofnode_get_path(struct unit_test_state *uts) res = ofnode_get_path(node, buf, 32); ut_asserteq(-ENOSPC, res); + res = ofnode_get_path(ofnode_root(), buf, 32); + ut_asserteq_str("/", buf); + return 0; } DM_TEST(dm_test_ofnode_get_path, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); @@ -589,6 +592,7 @@ DM_TEST(dm_test_ofnode_livetree_writing, static int dm_test_ofnode_u32(struct unit_test_state *uts) { ofnode node; + u32 val; node = ofnode_path("/lcd"); ut_assert(ofnode_valid(node)); @@ -597,10 +601,62 @@ static int dm_test_ofnode_u32(struct unit_test_state *uts) ut_asserteq(1367, ofnode_read_u32_default(node, "xres", 123)); ut_assertok(ofnode_write_u32(node, "xres", 1366)); + node = ofnode_path("/backlight"); + ut_assertok(ofnode_read_u32_index(node, "brightness-levels", 0, &val)); + ut_asserteq(0, val); + ut_assertok(ofnode_read_u32_index(node, "brightness-levels", 1, &val)); + ut_asserteq(16, val); + ut_assertok(ofnode_read_u32_index(node, "brightness-levels", 8, &val)); + ut_asserteq(255, val); + ut_asserteq(-EOVERFLOW, + ofnode_read_u32_index(node, "brightness-levels", 9, &val)); + ut_asserteq(-EINVAL, ofnode_read_u32_index(node, "missing", 0, &val)); + return 0; } DM_TEST(dm_test_ofnode_u32, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); +static int dm_test_ofnode_u32_array(struct unit_test_state *uts) +{ + ofnode node; + u32 val[10]; + + node = ofnode_path("/a-test"); + ut_assert(ofnode_valid(node)); + ut_assertok(ofnode_read_u32_array(node, "int-value", val, 1)); + ut_asserteq(-EINVAL, ofnode_read_u32_array(node, "missing", val, 1)); + ut_asserteq(-EOVERFLOW, ofnode_read_u32_array(node, "bool-value", val, + 1)); + + memset(val, '\0', sizeof(val)); + ut_assertok(ofnode_read_u32_array(node, "int-array", val + 1, 3)); + ut_asserteq(0, val[0]); + ut_asserteq(5678, val[1]); + ut_asserteq(9123, val[2]); + ut_asserteq(4567, val[3]); + ut_asserteq(0, val[4]); + ut_asserteq(-EOVERFLOW, ofnode_read_u32_array(node, "int-array", val, + 4)); + + return 0; +} +DM_TEST(dm_test_ofnode_u32_array, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); + +static int dm_test_ofnode_u64(struct unit_test_state *uts) +{ + ofnode node; + u64 val; + + node = ofnode_path("/a-test"); + ut_assert(ofnode_valid(node)); + ut_assertok(ofnode_read_u64(node, "int64-value", &val)); + ut_asserteq_64(0x1111222233334444, val); + ut_asserteq(-EINVAL, ofnode_read_u64(node, "missing", &val)); + + return 0; +} +DM_TEST(dm_test_ofnode_u64, UT_TESTF_SCAN_FDT); + static int dm_test_ofnode_add_subnode(struct unit_test_state *uts) { ofnode node, check, subnode; @@ -693,3 +749,49 @@ static int dm_test_ofnode_for_each_prop(struct unit_test_state *uts) return 0; } DM_TEST(dm_test_ofnode_for_each_prop, UT_TESTF_SCAN_FDT); + +static int dm_test_ofnode_by_compatible(struct unit_test_state *uts) +{ + const char *compat = "denx,u-boot-fdt-test"; + ofnode node; + int count; + + count = 0; + for (node = ofnode_null(); + node = ofnode_by_compatible(node, compat), ofnode_valid(node);) + count++; + ut_asserteq(11, count); + + return 0; +} +DM_TEST(dm_test_ofnode_by_compatible, UT_TESTF_SCAN_FDT); + +static int dm_test_ofnode_find_subnode(struct unit_test_state *uts) +{ + ofnode node, subnode; + + node = ofnode_path("/buttons"); + + subnode = ofnode_find_subnode(node, "btn1"); + ut_assert(ofnode_valid(subnode)); + ut_asserteq_str("btn1", ofnode_get_name(subnode)); + + subnode = ofnode_find_subnode(node, "btn"); + ut_assert(!ofnode_valid(subnode)); + + return 0; +} +DM_TEST(dm_test_ofnode_find_subnode, UT_TESTF_SCAN_FDT); + +static int dm_test_ofnode_get_name(struct unit_test_state *uts) +{ + ofnode node; + + node = ofnode_path("/buttons"); + ut_assert(ofnode_valid(node)); + ut_asserteq_str("buttons", ofnode_get_name(node)); + ut_asserteq_str("", ofnode_get_name(ofnode_root())); + + return 0; +} +DM_TEST(dm_test_ofnode_get_name, UT_TESTF_SCAN_FDT); From ee88ba71acce3455aadef18c725de715e6c9af21 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 6 Sep 2022 20:27:19 -0600 Subject: [PATCH 360/374] dm: core: Provide a way to reset the device tree At present there is only one device tree used by the ofnode functions, except for some esoteric use of live tree. In preparation for supporting more than one, add a way to reset the list of device trees. For now this does nothing. Signed-off-by: Simon Glass --- common/board_r.c | 2 ++ include/dm/ofnode.h | 8 ++++++++ lib/fdtdec.c | 5 ++++- test/test-main.c | 2 ++ 4 files changed, 16 insertions(+), 1 deletion(-) diff --git a/common/board_r.c b/common/board_r.c index 50670b5615..6e1ad2bfce 100644 --- a/common/board_r.c +++ b/common/board_r.c @@ -234,6 +234,8 @@ static int initr_dm(void) { int ret; + oftree_reset(); + /* Save the pre-reloc driver model and start a new one */ gd->dm_root_f = gd->dm_root; gd->dm_root = NULL; diff --git a/include/dm/ofnode.h b/include/dm/ofnode.h index 8b0a108706..7e9d3be96a 100644 --- a/include/dm/ofnode.h +++ b/include/dm/ofnode.h @@ -27,6 +27,14 @@ struct ofnode_phandle_args { uint32_t args[OF_MAX_PHANDLE_ARGS]; }; +/** + * oftree_reset() - reset the state of the oftree list + * + * Reset the oftree list so it can be started again. This should be called + * once the control FDT is in place, but before the ofnode interface is used. + */ +static inline void oftree_reset(void) {} + /** * ofnode_to_np() - convert an ofnode to a live DT node pointer * diff --git a/lib/fdtdec.c b/lib/fdtdec.c index eca01081c5..64c5b3da15 100644 --- a/lib/fdtdec.c +++ b/lib/fdtdec.c @@ -13,7 +13,6 @@ #include #include #include -#include #include #include #include @@ -24,6 +23,8 @@ #include #include #include +#include +#include #include #include #include @@ -1668,6 +1669,8 @@ int fdtdec_setup(void) ret = fdtdec_prepare_fdt(); if (!ret) ret = fdtdec_board_setup(gd->fdt_blob); + oftree_reset(); + return ret; } diff --git a/test/test-main.c b/test/test-main.c index 1fcbae3cd4..d74df297c4 100644 --- a/test/test-main.c +++ b/test/test-main.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -99,6 +100,7 @@ static int dm_test_pre_run(struct unit_test_state *uts) /* Determine whether to make the live tree available */ gd_set_of_root(of_live ? uts->of_root : NULL); + oftree_reset(); ut_assertok(dm_init(of_live)); uts->root = dm_root(); From a3f50d038695887808497c1a15c9fcc122d964e6 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 6 Sep 2022 20:27:20 -0600 Subject: [PATCH 361/374] dm: core: Add an ofnode function to obtain the flat tree The flat device tree is assumed to be the control FDT but this is not always the case. Update the ofnode implementation to obtain the node via an function call so we can eventually add support for selecting different trees. Signed-off-by: Simon Glass --- drivers/core/ofnode.c | 91 ++++++++++++++++++++++++------------------- include/dm/ofnode.h | 19 +++++++++ 2 files changed, 69 insertions(+), 41 deletions(-) diff --git a/drivers/core/ofnode.c b/drivers/core/ofnode.c index e4b4b352e4..48d4dec1cc 100644 --- a/drivers/core/ofnode.c +++ b/drivers/core/ofnode.c @@ -119,8 +119,8 @@ int ofnode_read_u32_index(ofnode node, const char *propname, int index, return of_read_u32_index(ofnode_to_np(node), propname, index, outp); - cell = fdt_getprop(gd->fdt_blob, ofnode_to_offset(node), propname, - &len); + cell = fdt_getprop(ofnode_to_fdt(node), ofnode_to_offset(node), + propname, &len); if (!cell) { debug("(not found)\n"); return -EINVAL; @@ -165,8 +165,8 @@ int ofnode_read_u64(ofnode node, const char *propname, u64 *outp) if (ofnode_is_np(node)) return of_read_u64(ofnode_to_np(node), propname, outp); - cell = fdt_getprop(gd->fdt_blob, ofnode_to_offset(node), propname, - &len); + cell = fdt_getprop(ofnode_to_fdt(node), ofnode_to_offset(node), + propname, &len); if (!cell || len < sizeof(*cell)) { debug("(not found)\n"); return -EINVAL; @@ -217,7 +217,7 @@ const void *ofnode_read_prop(ofnode node, const char *propname, int *sizep) len = prop->length; } } else { - val = fdt_getprop(gd->fdt_blob, ofnode_to_offset(node), + val = fdt_getprop(ofnode_to_fdt(node), ofnode_to_offset(node), propname, &len); } if (!val) { @@ -276,7 +276,7 @@ ofnode ofnode_find_subnode(ofnode node, const char *subnode_name) } subnode = np_to_ofnode(np); } else { - int ooffset = fdt_subnode_offset(gd->fdt_blob, + int ooffset = fdt_subnode_offset(ofnode_to_fdt(node), ofnode_to_offset(node), subnode_name); subnode = offset_to_ofnode(ooffset); } @@ -298,7 +298,7 @@ int ofnode_read_u32_array(ofnode node, const char *propname, } else { int ret; - ret = fdtdec_get_int_array(gd->fdt_blob, + ret = fdtdec_get_int_array(ofnode_to_fdt(node), ofnode_to_offset(node), propname, out_values, sz); @@ -319,7 +319,7 @@ bool ofnode_is_enabled(ofnode node) if (ofnode_is_np(node)) { return of_device_is_available(ofnode_to_np(node)); } else { - return fdtdec_get_is_enabled(gd->fdt_blob, + return fdtdec_get_is_enabled(ofnode_to_fdt(node), ofnode_to_offset(node)); } } @@ -331,7 +331,7 @@ ofnode ofnode_first_subnode(ofnode node) return np_to_ofnode(node.np->child); return offset_to_ofnode( - fdt_first_subnode(gd->fdt_blob, ofnode_to_offset(node))); + fdt_first_subnode(ofnode_to_fdt(node), ofnode_to_offset(node))); } ofnode ofnode_next_subnode(ofnode node) @@ -341,7 +341,7 @@ ofnode ofnode_next_subnode(ofnode node) return np_to_ofnode(node.np->sibling); return offset_to_ofnode( - fdt_next_subnode(gd->fdt_blob, ofnode_to_offset(node))); + fdt_next_subnode(ofnode_to_fdt(node), ofnode_to_offset(node))); } #endif /* !DM_INLINE_OFNODE */ @@ -353,7 +353,7 @@ ofnode ofnode_get_parent(ofnode node) if (ofnode_is_np(node)) parent = np_to_ofnode(of_get_parent(ofnode_to_np(node))); else - parent.of_offset = fdt_parent_offset(gd->fdt_blob, + parent.of_offset = fdt_parent_offset(ofnode_to_fdt(node), ofnode_to_offset(node)); return parent; @@ -369,7 +369,7 @@ const char *ofnode_get_name(ofnode node) if (ofnode_is_np(node)) return node.np->name; - return fdt_get_name(gd->fdt_blob, ofnode_to_offset(node), NULL); + return fdt_get_name(ofnode_to_fdt(node), ofnode_to_offset(node), NULL); } int ofnode_get_path(ofnode node, char *buf, int buflen) @@ -386,7 +386,7 @@ int ofnode_get_path(ofnode node, char *buf, int buflen) } else { int res; - res = fdt_get_path(gd->fdt_blob, ofnode_to_offset(node), buf, + res = fdt_get_path(ofnode_to_fdt(node), ofnode_to_offset(node), buf, buflen); if (!res) return res; @@ -442,7 +442,7 @@ static fdt_addr_t __ofnode_get_addr_size_index(ofnode node, int index, } else { na = ofnode_read_simple_addr_cells(ofnode_get_parent(node)); ns = ofnode_read_simple_size_cells(ofnode_get_parent(node)); - return fdtdec_get_addr_size_fixed(gd->fdt_blob, + return fdtdec_get_addr_size_fixed(ofnode_to_fdt(node), ofnode_to_offset(node), "reg", index, na, ns, size, translate); @@ -490,7 +490,7 @@ int ofnode_stringlist_search(ofnode node, const char *property, } else { int ret; - ret = fdt_stringlist_search(gd->fdt_blob, + ret = fdt_stringlist_search(ofnode_to_fdt(node), ofnode_to_offset(node), property, string); if (ret == -FDT_ERR_NOTFOUND) @@ -511,7 +511,8 @@ int ofnode_read_string_index(ofnode node, const char *property, int index, } else { int len; - *outp = fdt_stringlist_get(gd->fdt_blob, ofnode_to_offset(node), + *outp = fdt_stringlist_get(ofnode_to_fdt(node), + ofnode_to_offset(node), property, index, &len); if (len < 0) return -EINVAL; @@ -524,7 +525,7 @@ int ofnode_read_string_count(ofnode node, const char *property) if (ofnode_is_np(node)) { return of_property_count_strings(ofnode_to_np(node), property); } else { - return fdt_stringlist_count(gd->fdt_blob, + return fdt_stringlist_count(ofnode_to_fdt(node), ofnode_to_offset(node), property); } } @@ -593,7 +594,7 @@ int ofnode_parse_phandle_with_args(ofnode node, const char *list_name, struct fdtdec_phandle_args args; int ret; - ret = fdtdec_parse_phandle_with_args(gd->fdt_blob, + ret = fdtdec_parse_phandle_with_args(ofnode_to_fdt(node), ofnode_to_offset(node), list_name, cells_name, cell_count, index, &args); @@ -612,7 +613,7 @@ int ofnode_count_phandle_with_args(ofnode node, const char *list_name, return of_count_phandle_with_args(ofnode_to_np(node), list_name, cells_name, cell_count); else - return fdtdec_parse_phandle_with_args(gd->fdt_blob, + return fdtdec_parse_phandle_with_args(ofnode_to_fdt(node), ofnode_to_offset(node), list_name, cells_name, cell_count, -1, NULL); } @@ -787,7 +788,7 @@ const void *ofnode_get_property(ofnode node, const char *propname, int *lenp) if (ofnode_is_np(node)) return of_get_property(ofnode_to_np(node), propname, lenp); else - return fdt_getprop(gd->fdt_blob, ofnode_to_offset(node), + return fdt_getprop(ofnode_to_fdt(node), ofnode_to_offset(node), propname, lenp); } @@ -801,7 +802,7 @@ int ofnode_first_property(ofnode node, struct ofprop *prop) return -FDT_ERR_NOTFOUND; } else { prop->offset = - fdt_first_property_offset(gd->fdt_blob, + fdt_first_property_offset(ofnode_to_fdt(node), ofnode_to_offset(prop->node)); if (prop->offset < 0) return prop->offset; @@ -818,8 +819,9 @@ int ofnode_next_property(struct ofprop *prop) if (!prop->prop) return -FDT_ERR_NOTFOUND; } else { - prop->offset = fdt_next_property_offset(gd->fdt_blob, - prop->offset); + prop->offset = + fdt_next_property_offset(ofnode_to_fdt(prop->node), + prop->offset); if (prop->offset < 0) return prop->offset; } @@ -834,7 +836,7 @@ const void *ofprop_get_property(const struct ofprop *prop, return of_get_property_by_prop(ofnode_to_np(prop->node), prop->prop, propname, lenp); else - return fdt_getprop_by_offset(gd->fdt_blob, + return fdt_getprop_by_offset(ofnode_to_fdt(prop->node), prop->offset, propname, lenp); } @@ -859,7 +861,7 @@ fdt_addr_t ofnode_get_addr_size(ofnode node, const char *property, else return of_read_number(prop, na); } else { - return fdtdec_get_addr_size(gd->fdt_blob, + return fdtdec_get_addr_size(ofnode_to_fdt(node), ofnode_to_offset(node), property, sizep); } @@ -878,7 +880,7 @@ const uint8_t *ofnode_read_u8_array_ptr(ofnode node, const char *propname, return (uint8_t *)prop; } else { - return fdtdec_locate_byte_array(gd->fdt_blob, + return fdtdec_locate_byte_array(ofnode_to_fdt(node), ofnode_to_offset(node), propname, sz); } } @@ -1014,10 +1016,10 @@ int ofnode_read_addr_cells(ofnode node) if (ofnode_is_np(node)) { return of_n_addr_cells(ofnode_to_np(node)); } else { - int parent = fdt_parent_offset(gd->fdt_blob, + int parent = fdt_parent_offset(ofnode_to_fdt(node), ofnode_to_offset(node)); - return fdt_address_cells(gd->fdt_blob, parent); + return fdt_address_cells(ofnode_to_fdt(node), parent); } } @@ -1026,10 +1028,10 @@ int ofnode_read_size_cells(ofnode node) if (ofnode_is_np(node)) { return of_n_size_cells(ofnode_to_np(node)); } else { - int parent = fdt_parent_offset(gd->fdt_blob, + int parent = fdt_parent_offset(ofnode_to_fdt(node), ofnode_to_offset(node)); - return fdt_size_cells(gd->fdt_blob, parent); + return fdt_size_cells(ofnode_to_fdt(node), parent); } } @@ -1038,7 +1040,8 @@ int ofnode_read_simple_addr_cells(ofnode node) if (ofnode_is_np(node)) return of_simple_addr_cells(ofnode_to_np(node)); else - return fdt_address_cells(gd->fdt_blob, ofnode_to_offset(node)); + return fdt_address_cells(ofnode_to_fdt(node), + ofnode_to_offset(node)); } int ofnode_read_simple_size_cells(ofnode node) @@ -1046,7 +1049,8 @@ int ofnode_read_simple_size_cells(ofnode node) if (ofnode_is_np(node)) return of_simple_size_cells(ofnode_to_np(node)); else - return fdt_size_cells(gd->fdt_blob, ofnode_to_offset(node)); + return fdt_size_cells(ofnode_to_fdt(node), + ofnode_to_offset(node)); } bool ofnode_pre_reloc(ofnode node) @@ -1083,7 +1087,8 @@ int ofnode_read_resource(ofnode node, uint index, struct resource *res) struct fdt_resource fres; int ret; - ret = fdt_get_resource(gd->fdt_blob, ofnode_to_offset(node), + ret = fdt_get_resource(ofnode_to_fdt(node), + ofnode_to_offset(node), "reg", index, &fres); if (ret < 0) return -EINVAL; @@ -1112,7 +1117,8 @@ u64 ofnode_translate_address(ofnode node, const fdt32_t *in_addr) if (ofnode_is_np(node)) return of_translate_address(ofnode_to_np(node), in_addr); else - return fdt_translate_address(gd->fdt_blob, ofnode_to_offset(node), in_addr); + return fdt_translate_address(ofnode_to_fdt(node), + ofnode_to_offset(node), in_addr); } u64 ofnode_translate_dma_address(ofnode node, const fdt32_t *in_addr) @@ -1120,7 +1126,8 @@ u64 ofnode_translate_dma_address(ofnode node, const fdt32_t *in_addr) if (ofnode_is_np(node)) return of_translate_dma_address(ofnode_to_np(node), in_addr); else - return fdt_translate_dma_address(gd->fdt_blob, ofnode_to_offset(node), in_addr); + return fdt_translate_dma_address(ofnode_to_fdt(node), + ofnode_to_offset(node), in_addr); } int ofnode_get_dma_range(ofnode node, phys_addr_t *cpu, dma_addr_t *bus, u64 *size) @@ -1128,7 +1135,8 @@ int ofnode_get_dma_range(ofnode node, phys_addr_t *cpu, dma_addr_t *bus, u64 *si if (ofnode_is_np(node)) return of_get_dma_range(ofnode_to_np(node), cpu, bus, size); else - return fdt_get_dma_range(gd->fdt_blob, ofnode_to_offset(node), + return fdt_get_dma_range(ofnode_to_fdt(node), + ofnode_to_offset(node), cpu, bus, size); } @@ -1138,7 +1146,7 @@ int ofnode_device_is_compatible(ofnode node, const char *compat) return of_device_is_compatible(ofnode_to_np(node), compat, NULL, NULL); else - return !fdt_node_check_compatible(gd->fdt_blob, + return !fdt_node_check_compatible(ofnode_to_fdt(node), ofnode_to_offset(node), compat); } @@ -1151,7 +1159,8 @@ ofnode ofnode_by_compatible(ofnode from, const char *compat) compat)); } else { return offset_to_ofnode(fdt_node_offset_by_compatible( - gd->fdt_blob, ofnode_to_offset(from), compat)); + ofnode_to_fdt(from), + ofnode_to_offset(from), compat)); } } @@ -1164,7 +1173,7 @@ ofnode ofnode_by_prop_value(ofnode from, const char *propname, propval, proplen)); } else { return offset_to_ofnode(fdt_node_offset_by_prop_value( - gd->fdt_blob, ofnode_to_offset(from), + ofnode_to_fdt(from), ofnode_to_offset(from), propname, propval, proplen)); } } @@ -1175,7 +1184,7 @@ int ofnode_write_prop(ofnode node, const char *propname, const void *value, if (of_live_active()) return of_write_prop(ofnode_to_np(node), propname, len, value); else - return fdt_setprop((void *)gd->fdt_blob, ofnode_to_offset(node), + return fdt_setprop(ofnode_to_fdt(node), ofnode_to_offset(node), propname, value, len); return 0; @@ -1308,7 +1317,7 @@ int ofnode_add_subnode(ofnode node, const char *name, ofnode *subnodep) return ret; subnode = np_to_ofnode(child); } else { - void *fdt = (void *)gd->fdt_blob; + void *fdt = ofnode_to_fdt(node); int poffset = ofnode_to_offset(node); int offset; diff --git a/include/dm/ofnode.h b/include/dm/ofnode.h index 7e9d3be96a..f68896711e 100644 --- a/include/dm/ofnode.h +++ b/include/dm/ofnode.h @@ -35,6 +35,25 @@ struct ofnode_phandle_args { */ static inline void oftree_reset(void) {} +/** + * ofnode_to_fdt() - convert an ofnode to a flat DT pointer + * + * This cannot be called if the reference contains a node pointer. + * + * @node: Reference containing offset (possibly invalid) + * Return: DT offset (can be NULL) + */ +static inline void *ofnode_to_fdt(ofnode node) +{ +#ifdef OF_CHECKS + if (of_live_active()) + return NULL; +#endif + + /* Use the control FDT by default */ + return (void *)gd->fdt_blob; +} + /** * ofnode_to_np() - convert an ofnode to a live DT node pointer * From 085d59411ca7cde4ca5c70beeab4fdcea209aed6 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 6 Sep 2022 20:27:21 -0600 Subject: [PATCH 362/374] dm: core: Add ofnode functions to obtain an oftree At present dm_test_ofnode_root() does this manually. Add some inline functions to handle it, so this code can be centralised. Add oftree functions to produce a null tree and to check whether a tree is valid or not. Signed-off-by: Simon Glass --- include/dm/ofnode.h | 63 +++++++++++++++++++++++++++++++++++++++++++++ test/dm/ofnode.c | 7 +++-- 2 files changed, 68 insertions(+), 2 deletions(-) diff --git a/include/dm/ofnode.h b/include/dm/ofnode.h index f68896711e..328e1edad4 100644 --- a/include/dm/ofnode.h +++ b/include/dm/ofnode.h @@ -173,6 +173,38 @@ static inline bool ofnode_equal(ofnode ref1, ofnode ref2) return ref1.of_offset == ref2.of_offset; } +/** + * oftree_valid() - check if an oftree is valid + * + * @tree: Reference containing oftree + * Return: true if the reference contains a valid oftree, false if node + */ +static inline bool oftree_valid(oftree tree) +{ + if (of_live_active()) + return tree.np; + else + return tree.fdt; +} + +/** + * oftree_null() - Obtain a null oftree + * + * This returns an oftree which points to no tree. It works both with the flat + * tree and livetree. + */ +static inline oftree oftree_null(void) +{ + oftree tree; + + if (of_live_active()) + tree.np = NULL; + else + tree.fdt = NULL; + + return tree; +} + /** * ofnode_null() - Obtain a null ofnode * @@ -234,6 +266,37 @@ static inline oftree oftree_default(void) return tree; } +/** + * oftree_from_np() - Returns an oftree from a node pointer + * + * @root: Root node of the tree + * Returns: reference to the given node + */ +static inline oftree oftree_from_np(struct device_node *root) +{ + oftree tree; + + tree.np = root; + + return tree; +} + +/** + * oftree_from_fdt() - Returns an oftree from a flat device tree pointer + * + * @fdt: Device tree to use + * + * Returns: reference to the given node + */ +static inline oftree oftree_from_fdt(void *fdt) +{ + oftree tree; + + tree.fdt = fdt; + + return tree; +} + /** * ofnode_name_eq() - Check if the node name is equivalent to a given name * ignoring the unit address diff --git a/test/dm/ofnode.c b/test/dm/ofnode.c index eac0c50364..f146b52d62 100644 --- a/test/dm/ofnode.c +++ b/test/dm/ofnode.c @@ -518,13 +518,16 @@ static int dm_test_ofnode_root(struct unit_test_state *uts) ut_assert(ofnode_valid(node)); ut_asserteq_str("sbe5", ofnode_get_name(node)); + ut_assert(!oftree_valid(oftree_null())); + ut_assertok(make_ofnode_fdt(uts, fdt, sizeof(fdt))); if (of_live_active()) { ut_assertok(unflatten_device_tree(fdt, &root)); - tree.np = root; + tree = oftree_from_np(root); } else { - tree.fdt = fdt; + tree = oftree_from_fdt(fdt); } + ut_assert(oftree_valid(tree)); /* Make sure they don't work on this new tree */ node = ofnode_path_root(tree, "mmc0"); From 928d267aeea9406497c8060c03d3a0a78a8cbaa9 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 6 Sep 2022 20:27:22 -0600 Subject: [PATCH 363/374] dm: core: Add a way to look up a phandle in an oftree When we have multiple trees, the ofnode logic needs to be told which one to use. Create a new function which takes an oftree argument, along with a helper to obtain the FDT pointer from an oftree. Signed-off-by: Simon Glass --- drivers/core/ofnode.c | 14 ++++++++++++++ include/dm/ofnode.h | 25 +++++++++++++++++++++++++ test/dm/ofnode.c | 2 ++ 3 files changed, 41 insertions(+) diff --git a/drivers/core/ofnode.c b/drivers/core/ofnode.c index 48d4dec1cc..012cb8cdda 100644 --- a/drivers/core/ofnode.c +++ b/drivers/core/ofnode.c @@ -410,6 +410,20 @@ ofnode ofnode_get_by_phandle(uint phandle) return node; } +ofnode oftree_get_by_phandle(oftree tree, uint phandle) +{ + ofnode node; + + if (of_live_active()) + node = np_to_ofnode(of_find_node_by_phandle(tree.np, phandle)); + else + node.of_offset = + fdt_node_offset_by_phandle(oftree_lookup_fdt(tree), + phandle); + + return node; +} + static fdt_addr_t __ofnode_get_addr_size_index(ofnode node, int index, fdt_size_t *size, bool translate) { diff --git a/include/dm/ofnode.h b/include/dm/ofnode.h index 328e1edad4..fa72bb9eff 100644 --- a/include/dm/ofnode.h +++ b/include/dm/ofnode.h @@ -102,6 +102,22 @@ static inline bool ofnode_valid(ofnode node) return node.of_offset >= 0; } +/** + * oftree_lookup_fdt() - obtain the FDT pointer from an oftree + * + * This can only be called when flat tree is enabled + * + * @tree: Tree to look at + * @return FDT pointer from the tree + */ +static inline void *oftree_lookup_fdt(oftree tree) +{ + if (of_live_active()) + return NULL; + else + return tree.fdt; +} + /** * offset_to_ofnode() - convert a DT offset to an ofnode * @@ -594,6 +610,15 @@ int ofnode_get_path(ofnode node, char *buf, int buflen); */ ofnode ofnode_get_by_phandle(uint phandle); +/** + * oftree_get_by_phandle() - get ofnode from phandle + * + * @tree: tree to use + * @phandle: phandle to look up + * Return: ofnode reference to the phandle + */ +ofnode oftree_get_by_phandle(oftree tree, uint phandle); + /** * ofnode_read_size() - read the size of a property * diff --git a/test/dm/ofnode.c b/test/dm/ofnode.c index f146b52d62..f6bb04642e 100644 --- a/test/dm/ofnode.c +++ b/test/dm/ofnode.c @@ -36,6 +36,8 @@ static int dm_test_ofnode_get_by_phandle(struct unit_test_state *uts) /* test unknown phandle */ ut_assert(!ofnode_valid(ofnode_get_by_phandle(0x1000000))); + ut_assert(ofnode_valid(oftree_get_by_phandle(oftree_default(), 1))); + return 0; } DM_TEST(dm_test_ofnode_get_by_phandle, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); From 2187cb7e4aaae7a4ed7318a073b26dff462cb7a1 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 6 Sep 2022 20:27:23 -0600 Subject: [PATCH 364/374] dm: core: Allow obtaining a node offset in the same tree In some cases we want to obtain an ofnode in the same tree as a different ofnode, such as when looking up a subnode. At present this is trivial, since there is only one tree. When there are multiple trees, this implementation will change. Also move the ofnode_to_offset() function up higher in the header file, since we will need to provide a different implementation with multiple trees. Signed-off-by: Simon Glass --- drivers/core/ofnode.c | 19 ++++++++++--------- include/dm/ofnode.h | 44 +++++++++++++++++++++++++++++++------------ 2 files changed, 42 insertions(+), 21 deletions(-) diff --git a/drivers/core/ofnode.c b/drivers/core/ofnode.c index 012cb8cdda..b1ba8c5ab4 100644 --- a/drivers/core/ofnode.c +++ b/drivers/core/ofnode.c @@ -278,7 +278,7 @@ ofnode ofnode_find_subnode(ofnode node, const char *subnode_name) } else { int ooffset = fdt_subnode_offset(ofnode_to_fdt(node), ofnode_to_offset(node), subnode_name); - subnode = offset_to_ofnode(ooffset); + subnode = noffset_to_ofnode(node, ooffset); } debug("%s\n", ofnode_valid(subnode) ? ofnode_get_name(subnode) : ""); @@ -330,7 +330,7 @@ ofnode ofnode_first_subnode(ofnode node) if (ofnode_is_np(node)) return np_to_ofnode(node.np->child); - return offset_to_ofnode( + return noffset_to_ofnode(node, fdt_first_subnode(ofnode_to_fdt(node), ofnode_to_offset(node))); } @@ -340,7 +340,7 @@ ofnode ofnode_next_subnode(ofnode node) if (ofnode_is_np(node)) return np_to_ofnode(node.np->sibling); - return offset_to_ofnode( + return noffset_to_ofnode(node, fdt_next_subnode(ofnode_to_fdt(node), ofnode_to_offset(node))); } #endif /* !DM_INLINE_OFNODE */ @@ -1172,8 +1172,8 @@ ofnode ofnode_by_compatible(ofnode from, const char *compat) (struct device_node *)ofnode_to_np(from), NULL, compat)); } else { - return offset_to_ofnode(fdt_node_offset_by_compatible( - ofnode_to_fdt(from), + return noffset_to_ofnode(from, + fdt_node_offset_by_compatible(ofnode_to_fdt(from), ofnode_to_offset(from), compat)); } } @@ -1186,9 +1186,10 @@ ofnode ofnode_by_prop_value(ofnode from, const char *propname, (struct device_node *)ofnode_to_np(from), propname, propval, proplen)); } else { - return offset_to_ofnode(fdt_node_offset_by_prop_value( - ofnode_to_fdt(from), ofnode_to_offset(from), - propname, propval, proplen)); + return noffset_to_ofnode(from, + fdt_node_offset_by_prop_value(ofnode_to_fdt(from), + ofnode_to_offset(from), propname, propval, + proplen)); } } @@ -1342,7 +1343,7 @@ int ofnode_add_subnode(ofnode node, const char *name, ofnode *subnodep) } if (offset < 0) return -EINVAL; - subnode = offset_to_ofnode(offset); + subnode = noffset_to_ofnode(node, offset); } *subnodep = subnode; diff --git a/include/dm/ofnode.h b/include/dm/ofnode.h index fa72bb9eff..a53cffbed9 100644 --- a/include/dm/ofnode.h +++ b/include/dm/ofnode.h @@ -54,6 +54,23 @@ static inline void *ofnode_to_fdt(ofnode node) return (void *)gd->fdt_blob; } +/** + * ofnode_to_offset() - convert an ofnode to a flat DT offset + * + * This cannot be called if the reference contains a node pointer. + * + * @node: Reference containing offset (possibly invalid) + * Return: DT offset (can be -1) + */ +static inline int ofnode_to_offset(ofnode node) +{ +#ifdef OF_CHECKS + if (of_live_active()) + return -1; +#endif + return node.of_offset; +} + /** * ofnode_to_np() - convert an ofnode to a live DT node pointer * @@ -72,20 +89,22 @@ static inline struct device_node *ofnode_to_np(ofnode node) } /** - * ofnode_to_offset() - convert an ofnode to a flat DT offset + * noffset_to_ofnode() - convert a DT offset to an ofnode * - * This cannot be called if the reference contains a node pointer. - * - * @node: Reference containing offset (possibly invalid) - * Return: DT offset (can be -1) + * @other_node: Node in the same tree to use as a reference + * @of_offset: DT offset (either valid, or -1) + * Return: reference to the associated DT offset */ -static inline int ofnode_to_offset(ofnode node) +static inline ofnode noffset_to_ofnode(ofnode other_node, int of_offset) { -#ifdef OF_CHECKS + ofnode node; + if (of_live_active()) - return -1; -#endif - return node.of_offset; + node.np = NULL; + else + node.of_offset = of_offset; + + return node; } /** @@ -1175,8 +1194,9 @@ ofnode ofnode_by_compatible(ofnode from, const char *compat); * Find the next node after @from that has a @propname with a value * @propval and a length @proplen. * - * @from: ofnode to start from (use ofnode_null() to start at the - * beginning) + * @from: ofnode to start from. Use ofnode_null() to start at the + * beginning, or the return value from oftree_root() to start at the first + * child of the root * @propname: property name to check * @propval: property value to search for * @proplen: length of the value in propval From b7bd94f1a8a63cd4f947036e0d42ee2e23852d64 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 6 Sep 2022 20:27:24 -0600 Subject: [PATCH 365/374] dm: core: Split ofnode_path_root() into two functions This function turns out to be a little confusing since it looks up a path and also registers the tree. Split it into two, one that gets the root node and one that looks up a path, so the purpose is clear. Registering the tree will happen in a function to be added in a later patch, called oftree_from_fdt(). Signed-off-by: Simon Glass --- boot/vbe_simple.c | 2 +- drivers/core/ofnode.c | 42 +++++++++++++++++++++++++++++++++++++----- include/dm/ofnode.h | 16 +++++++++++++--- test/boot/vbe_simple.c | 2 +- test/dm/ofnode.c | 6 +++--- 5 files changed, 55 insertions(+), 13 deletions(-) diff --git a/boot/vbe_simple.c b/boot/vbe_simple.c index 0fc57388f3..61b6322ebe 100644 --- a/boot/vbe_simple.c +++ b/boot/vbe_simple.c @@ -240,7 +240,7 @@ static int bootmeth_vbe_simple_ft_fixup(void *ctx, struct event *event) continue; /* Check if there is a node to fix up */ - node = ofnode_path_root(tree, "/chosen/fwupd"); + node = oftree_path(tree, "/chosen/fwupd"); if (!ofnode_valid(node)) continue; node = ofnode_find_subnode(node, dev->name); diff --git a/drivers/core/ofnode.c b/drivers/core/ofnode.c index b1ba8c5ab4..7f6c47f0c0 100644 --- a/drivers/core/ofnode.c +++ b/drivers/core/ofnode.c @@ -18,6 +18,26 @@ #include #include +/** + * ofnode_from_tree_offset() - get an ofnode from a tree offset (flat tree) + * + * Looks up the tree and returns an ofnode with the correct of_offset + * + * If @offset is < 0 then this returns an ofnode with that offset + * + * @tree: tree to check + * @offset: offset within that tree (can be < 0) + * @return node for that offset + */ +static ofnode ofnode_from_tree_offset(oftree tree, int offset) +{ + ofnode node; + + node.of_offset = offset; + + return node; +} + bool ofnode_name_eq(ofnode node, const char *name) { const char *node_name; @@ -640,15 +660,27 @@ ofnode ofnode_path(const char *path) return offset_to_ofnode(fdt_path_offset(gd->fdt_blob, path)); } -ofnode ofnode_path_root(oftree tree, const char *path) +ofnode oftree_root(oftree tree) { - if (of_live_active()) + if (of_live_active()) { + return np_to_ofnode(tree.np); + } else { + return ofnode_from_tree_offset(tree, 0); + } +} + +ofnode oftree_path(oftree tree, const char *path) +{ + if (of_live_active()) { return np_to_ofnode(of_find_node_opts_by_path(tree.np, path, NULL)); - else if (*path != '/' && tree.fdt != gd->fdt_blob) + } else if (*path != '/' && tree.fdt != gd->fdt_blob) { return ofnode_null(); /* Aliases only on control FDT */ - else - return offset_to_ofnode(fdt_path_offset(tree.fdt, path)); + } else { + int offset = fdt_path_offset(tree.fdt, path); + + return ofnode_from_tree_offset(tree, offset); + } } const void *ofnode_read_chosen_prop(const char *propname, int *sizep) diff --git a/include/dm/ofnode.h b/include/dm/ofnode.h index a53cffbed9..ad179a65e9 100644 --- a/include/dm/ofnode.h +++ b/include/dm/ofnode.h @@ -855,18 +855,28 @@ int ofnode_count_phandle_with_args(ofnode node, const char *list_name, ofnode ofnode_path(const char *path); /** - * ofnode_path_root() - find a node by full path from a root node + * oftree_path() - find a node by full path from a root node * * @tree: Device tree to use * @path: Full path to node, e.g. "/bus/spi@1" * Return: reference to the node found. Use ofnode_valid() to check if it exists */ -ofnode ofnode_path_root(oftree tree, const char *path); +ofnode oftree_path(oftree tree, const char *path); + +/** + * oftree_root() - get the root node of a tree + * + * @tree: Device tree to use + * Return: reference to the root node + */ +ofnode oftree_root(oftree tree); /** * ofnode_read_chosen_prop() - get the value of a chosen property * - * This looks for a property within the /chosen node and returns its value + * This looks for a property within the /chosen node and returns its value. + * + * This only works with the control FDT. * * @propname: Property name to look for * @sizep: Returns size of property, or `FDT_ERR_...` error code if function diff --git a/test/boot/vbe_simple.c b/test/boot/vbe_simple.c index 2f6979cafc..3f03fc3acd 100644 --- a/test/boot/vbe_simple.c +++ b/test/boot/vbe_simple.c @@ -96,7 +96,7 @@ static int vbe_simple_test_base(struct unit_test_state *uts) fixup.tree.np = np; ut_assertok(event_notify(EVT_FT_FIXUP, &fixup, sizeof(fixup))); - node = ofnode_path_root(fixup.tree, "/chosen/fwupd/firmware0"); + node = oftree_path(fixup.tree, "/chosen/fwupd/firmware0"); version = ofnode_read_string(node, "cur-version"); ut_assertnonnull(version); diff --git a/test/dm/ofnode.c b/test/dm/ofnode.c index f6bb04642e..b73ab98828 100644 --- a/test/dm/ofnode.c +++ b/test/dm/ofnode.c @@ -532,15 +532,15 @@ static int dm_test_ofnode_root(struct unit_test_state *uts) ut_assert(oftree_valid(tree)); /* Make sure they don't work on this new tree */ - node = ofnode_path_root(tree, "mmc0"); + node = oftree_path(tree, "mmc0"); ut_assert(!ofnode_valid(node)); /* It should appear in the new tree */ - node = ofnode_path_root(tree, "/new-mmc"); + node = oftree_path(tree, "/new-mmc"); ut_assert(ofnode_valid(node)); /* ...and not in the control FDT */ - node = ofnode_path_root(oftree_default(), "/new-mmc"); + node = oftree_path(oftree_default(), "/new-mmc"); ut_assert(!ofnode_valid(node)); free(root); From 41b65d68ec324d9c75dcfe6e1b34fef077b4b87a Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 6 Sep 2022 20:27:25 -0600 Subject: [PATCH 366/374] dm: core: Add definitions for multiple ofnode trees At present, unless OF_LIVE is enabled, ofnode only supports access to one device tree, the control FDT. This is because only the node offset is encoded in ofnode, with the tree being implicit. This makes ofnode (without OF_LIVE) unsuitable for device tree fixups, as implemented by ft_board_setup() and other such functions. To solve this, we can use the top bits of the node offset to hold a tree ID. Add the definitions for this. Signed-off-by: Simon Glass --- drivers/core/Kconfig | 24 ++++++++++++++++++++++++ include/dm/ofnode_decl.h | 33 +++++++++++++++++++++++++++++++-- 2 files changed, 55 insertions(+), 2 deletions(-) diff --git a/drivers/core/Kconfig b/drivers/core/Kconfig index 007dc6a1de..c9bf5de433 100644 --- a/drivers/core/Kconfig +++ b/drivers/core/Kconfig @@ -400,6 +400,30 @@ config DM_DEV_READ_INLINE bool default y if !OF_LIVE +config OFNODE_MULTI_TREE + bool "Allow the ofnode interface to access any tree" + default y if EVENT && !DM_DEV_READ_INLINE && !DM_INLINE_OFNODE + help + Normally U-Boot makes use of its control FDT, the one used to bind + devices and provide options. In some cases, U-Boot must also process + a separate FDT, e.g. one provided by the operating system, which + needs additions to the /chosen node. + + This works fine with live tree (OF_LIVE), but with flat tree the + offset provided in ofnode is only useful with the control FDT. This + option adds a 'tree ID' to the offset, so that multiple trees can + be used. Call oftree_from_fdt() to register a new tree. + +config OFNODE_MULTI_TREE_MAX + int "Maximum number of FDTs" + range 2 8 + depends on OFNODE_MULTI_TREE + default 4 + help + Sets the maximum number of device trees which can be used with the + ofnode interface when using flat trees (OF_LIVE). This is only + available in U-Boot proper and only after relocation. + config ACPIGEN bool "Support ACPI table generation in driver model" default y if SANDBOX || (GENERATE_ACPI_TABLE && !QEMU) diff --git a/include/dm/ofnode_decl.h b/include/dm/ofnode_decl.h index f666a0287b..5c2115aab0 100644 --- a/include/dm/ofnode_decl.h +++ b/include/dm/ofnode_decl.h @@ -31,8 +31,18 @@ * this increases code size slightly due to the subtraction. Since it offers no * real benefit, the approach described here seems best. * - * For now these points use constant types, since we don't allow writing - * the DT. + * Where multiple trees are in use, this works without any trouble with live + * tree, except for aliases, such as ofnode_path("mmc0"), which only work on the + * control FDT. When the flat tree is in use, the trees are registered and a + * 'tree ID' is encoded into the top bits of @of_offset - see immediately below + * for the associated macro definitions. Note that 64-bit machines use the same + * encoding, even though there is more space available. This is partly because + * the FDT format contains 32-bit values for things like the string-table + * offset, therefore 64-bit offsets cannot be supported anyway. + * + * For the multiple-tree case, an invalid offset (i.e. with of_offset < 0) is + * still invalid. It does not contain a tree ID. So there is no way of knowing + * which tree produced the invalid offset. * * @np: Pointer to device node, used for live tree * @of_offset: Pointer into flat device tree, used for flat tree. Note that this @@ -43,6 +53,25 @@ typedef union ofnode_union { long of_offset; } ofnode; +/* shift for the tree ID within of_offset */ +#define OF_TREE_SHIFT 28 + +/* mask to obtain the device tree offset from of_offset */ +#define OF_TREE_MASK ((1 << OF_TREE_SHIFT) - 1) + +/* encode a tree ID and node offset into an of_offset value */ +#define OFTREE_NODE(tree_id, offs) ((tree_id) << OF_TREE_SHIFT | (offs)) + +/* decode the node offset from an of_offset value */ +#define OFTREE_OFFSET(of_offs) ((of_offs) & OF_TREE_MASK) + +/* decode the tree ID from an of_offset value */ +#define OFTREE_TREE_ID(of_offs) ((of_offs) >> OF_TREE_SHIFT) + +/* encode a node offset in the tree given by another node's of_offset value */ +#define OFTREE_MAKE_NODE(other_of_offset, offs) \ + (((offs) & OF_TREE_MASK) | ((other_of_offset) & ~OF_TREE_MASK)) + /** * struct ofprop - reference to a property of a device tree node * From 92291652b5741647919770c29cae8a2aac56b2bf Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 6 Sep 2022 20:27:26 -0600 Subject: [PATCH 367/374] dm: core: Add the ofnode multi-tree implementation Add the logic to redirect requests for the device tree through a function which can look up the tree ID. This works by using the top bits of ofnode.of_offset to encode a tree. It is assumed that there will only be a few device trees used at runtime, typically the control FDT (always tree ID 0) and possibly a separate FDT to be passed the OS. The maximum number of device trees supported at runtime is 8, with this implementation. That would use bits 30:28 of the node-offset value, meaning that the positive offset range is limited to bits 27:0, versus 30:1 with this feature disabled. That still allows a device tree of up to 256MB, which should be enough for most FITs. Larger ones can be supported by using external data with the FIT, or by enabling OF_LIVE. Update the documentation a little and fix up the comment for ofnode_valid(). Signed-off-by: Simon Glass --- doc/develop/driver-model/livetree.rst | 11 +- drivers/core/ofnode.c | 170 +++++++++++++++++++++++++- include/dm/ofnode.h | 113 +++++++++-------- 3 files changed, 238 insertions(+), 56 deletions(-) diff --git a/doc/develop/driver-model/livetree.rst b/doc/develop/driver-model/livetree.rst index 4ef8c51732..76be89b963 100644 --- a/doc/develop/driver-model/livetree.rst +++ b/doc/develop/driver-model/livetree.rst @@ -250,11 +250,14 @@ a flat tree. It would be helpful to use livetree for fixups, since adding a lot of nodes and properties would involve less memory copying and be more efficient. As a step towards this, an `oftree` type has been introduced. It is normally set to -oftree_default() but can be set to other values. Eventually this should allow -the use of FDT fixups using the ofnode interface, instead of the low-level -libfdt one. +oftree_default() but can be set to other values using oftree_from_fdt(). +So long as OF_LIVE is disabled, it is possible to do fixups using the ofnode +interface. The OF_LIVE support required addition of the flattening step at the +end. -See dm_test_ofnode_root() for some examples. +See dm_test_ofnode_root() for some examples. The ofnode_path_root() function +causes a flat device tree to be 'registered' such that it can be used by the +ofnode interface. Internal implementation diff --git a/drivers/core/ofnode.c b/drivers/core/ofnode.c index 7f6c47f0c0..53db7b5ff0 100644 --- a/drivers/core/ofnode.c +++ b/drivers/core/ofnode.c @@ -4,6 +4,8 @@ * Written by Simon Glass */ +#define LOG_CATEGORY LOGC_DT + #include #include #include @@ -18,22 +20,182 @@ #include #include +DECLARE_GLOBAL_DATA_PTR; + +#if CONFIG_IS_ENABLED(OFNODE_MULTI_TREE) +static void *oftree_list[CONFIG_OFNODE_MULTI_TREE_MAX]; +static int oftree_count; + +void oftree_reset(void) +{ + if (gd->flags & GD_FLG_RELOC) { + oftree_count = 0; + oftree_list[oftree_count++] = (void *)gd->fdt_blob; + } +} + +static int oftree_find(const void *fdt) +{ + int i; + + for (i = 0; i < oftree_count; i++) { + if (fdt == oftree_list[i]) + return i; + } + + return -1; +} + +static oftree oftree_ensure(void *fdt) +{ + oftree tree; + int i; + + if (gd->flags & GD_FLG_RELOC) { + i = oftree_find(fdt); + if (i == -1) { + if (oftree_count == CONFIG_OFNODE_MULTI_TREE_MAX) { + log_warning("Too many registered device trees (max %d)\n", + CONFIG_OFNODE_MULTI_TREE_MAX); + return oftree_null(); + } + + /* register the new tree */ + i = oftree_count++; + oftree_list[i] = fdt; + log_debug("oftree: registered tree %d: %p\n", i, fdt); + } + } else { + if (fdt != gd->fdt_blob) { + log_debug("Cannot only access control FDT before relocation\n"); + return oftree_null(); + } + } + + tree.fdt = fdt; + + return tree; +} + +void *ofnode_lookup_fdt(ofnode node) +{ + if (gd->flags & GD_FLG_RELOC) { + uint i = OFTREE_TREE_ID(node.of_offset); + + if (i > oftree_count) { + log_debug("Invalid tree ID %x\n", i); + return NULL; + } + + return oftree_list[i]; + } else { + return (void *)gd->fdt_blob; + } +} + +void *ofnode_to_fdt(ofnode node) +{ +#ifdef OF_CHECKS + if (of_live_active()) + return NULL; +#endif + if (CONFIG_IS_ENABLED(OFNODE_MULTI_TREE) && ofnode_valid(node)) + return ofnode_lookup_fdt(node); + + /* Use the control FDT by default */ + return (void *)gd->fdt_blob; +} + +/** + * ofnode_to_offset() - convert an ofnode to a flat DT offset + * + * This cannot be called if the reference contains a node pointer. + * + * @node: Reference containing offset (possibly invalid) + * Return: DT offset (can be -1) + */ +int ofnode_to_offset(ofnode node) +{ +#ifdef OF_CHECKS + if (of_live_active()) + return -1; +#endif + if (CONFIG_IS_ENABLED(OFNODE_MULTI_TREE) && node.of_offset >= 0) + return OFTREE_OFFSET(node.of_offset); + + return node.of_offset; +} + +oftree oftree_from_fdt(void *fdt) +{ + oftree tree; + + if (CONFIG_IS_ENABLED(OFNODE_MULTI_TREE)) + return oftree_ensure(fdt); + + tree.fdt = fdt; + + return tree; +} + +/** + * noffset_to_ofnode() - convert a DT offset to an ofnode + * + * @other_node: Node in the same tree to use as a reference + * @of_offset: DT offset (either valid, or -1) + * Return: reference to the associated DT offset + */ +ofnode noffset_to_ofnode(ofnode other_node, int of_offset) +{ + ofnode node; + + if (of_live_active()) + node.np = NULL; + else if (!CONFIG_IS_ENABLED(OFNODE_MULTI_TREE) || of_offset < 0 || + !ofnode_valid(other_node)) + node.of_offset = of_offset; + else + node.of_offset = OFTREE_MAKE_NODE(other_node.of_offset, + of_offset); + + return node; +} + +#else /* !OFNODE_MULTI_TREE */ + +static inline int oftree_find(const void *fdt) +{ + return 0; +} + +#endif /* OFNODE_MULTI_TREE */ + /** * ofnode_from_tree_offset() - get an ofnode from a tree offset (flat tree) * - * Looks up the tree and returns an ofnode with the correct of_offset + * Looks up the tree and returns an ofnode with the correct of_offset (i.e. + * containing the tree ID). * - * If @offset is < 0 then this returns an ofnode with that offset + * If @offset is < 0 then this returns an ofnode with that offset and no tree + * ID. * * @tree: tree to check * @offset: offset within that tree (can be < 0) - * @return node for that offset + * @return node for that offset, with the correct ID */ static ofnode ofnode_from_tree_offset(oftree tree, int offset) { ofnode node; - node.of_offset = offset; + if (CONFIG_IS_ENABLED(OFNODE_MULTI_TREE) && offset >= 0) { + int tree_id = oftree_find(tree.fdt); + + if (tree_id == -1) + return ofnode_null(); + node.of_offset = OFTREE_NODE(tree_id, offset); + } else { + node.of_offset = offset; + } return node; } diff --git a/include/dm/ofnode.h b/include/dm/ofnode.h index ad179a65e9..3a514f71f6 100644 --- a/include/dm/ofnode.h +++ b/include/dm/ofnode.h @@ -27,13 +27,14 @@ struct ofnode_phandle_args { uint32_t args[OF_MAX_PHANDLE_ARGS]; }; +#if CONFIG_IS_ENABLED(OFNODE_MULTI_TREE) /** * oftree_reset() - reset the state of the oftree list * * Reset the oftree list so it can be started again. This should be called * once the control FDT is in place, but before the ofnode interface is used. */ -static inline void oftree_reset(void) {} +void oftree_reset(void); /** * ofnode_to_fdt() - convert an ofnode to a flat DT pointer @@ -43,16 +44,7 @@ static inline void oftree_reset(void) {} * @node: Reference containing offset (possibly invalid) * Return: DT offset (can be NULL) */ -static inline void *ofnode_to_fdt(ofnode node) -{ -#ifdef OF_CHECKS - if (of_live_active()) - return NULL; -#endif - - /* Use the control FDT by default */ - return (void *)gd->fdt_blob; -} +__attribute_const__ void *ofnode_to_fdt(ofnode node); /** * ofnode_to_offset() - convert an ofnode to a flat DT offset @@ -62,7 +54,40 @@ static inline void *ofnode_to_fdt(ofnode node) * @node: Reference containing offset (possibly invalid) * Return: DT offset (can be -1) */ -static inline int ofnode_to_offset(ofnode node) +__attribute_const__ int ofnode_to_offset(ofnode node); + +/** + * oftree_from_fdt() - Returns an oftree from a flat device tree pointer + * + * @fdt: Device tree to use + * + * Returns: reference to the given node + */ +oftree oftree_from_fdt(void *fdt); + +/** + * noffset_to_ofnode() - convert a DT offset to an ofnode + * + * @other_node: Node in the same tree to use as a reference + * @of_offset: DT offset (either valid, or -1) + * Return: reference to the associated DT offset + */ +ofnode noffset_to_ofnode(ofnode other_node, int of_offset); + +#else /* !OFNODE_MULTI_TREE */ +static inline void oftree_reset(void) {} + +static inline void *ofnode_to_fdt(ofnode node) +{ +#ifdef OF_CHECKS + if (of_live_active()) + return NULL; +#endif + /* Use the control FDT by default */ + return (void *)gd->fdt_blob; +} + +static inline __attribute_const__ int ofnode_to_offset(ofnode node) { #ifdef OF_CHECKS if (of_live_active()) @@ -71,6 +96,33 @@ static inline int ofnode_to_offset(ofnode node) return node.of_offset; } +static inline oftree oftree_from_fdt(void *fdt) +{ + oftree tree; + + /* we cannot access other trees without OFNODE_MULTI_TREE */ + if (fdt == gd->fdt_blob) + tree.fdt = fdt; + else + tree.fdt = NULL; + + return tree; +} + +static inline ofnode noffset_to_ofnode(ofnode other_node, int of_offset) +{ + ofnode node; + + if (of_live_active()) + node.np = NULL; + else + node.of_offset = of_offset; + + return node; +} + +#endif /* OFNODE_MULTI_TREE */ + /** * ofnode_to_np() - convert an ofnode to a live DT node pointer * @@ -88,30 +140,11 @@ static inline struct device_node *ofnode_to_np(ofnode node) return node.np; } -/** - * noffset_to_ofnode() - convert a DT offset to an ofnode - * - * @other_node: Node in the same tree to use as a reference - * @of_offset: DT offset (either valid, or -1) - * Return: reference to the associated DT offset - */ -static inline ofnode noffset_to_ofnode(ofnode other_node, int of_offset) -{ - ofnode node; - - if (of_live_active()) - node.np = NULL; - else - node.of_offset = of_offset; - - return node; -} - /** * ofnode_valid() - check if an ofnode is valid * * @node: Reference containing offset (possibly invalid) - * Return: true if the reference contains a valid ofnode, false if it is NULL + * Return: true if the reference contains a valid ofnode, false if not */ static inline bool ofnode_valid(ofnode node) { @@ -316,22 +349,6 @@ static inline oftree oftree_from_np(struct device_node *root) return tree; } -/** - * oftree_from_fdt() - Returns an oftree from a flat device tree pointer - * - * @fdt: Device tree to use - * - * Returns: reference to the given node - */ -static inline oftree oftree_from_fdt(void *fdt) -{ - oftree tree; - - tree.fdt = fdt; - - return tree; -} - /** * ofnode_name_eq() - Check if the node name is equivalent to a given name * ignoring the unit address From 5e96925ba5b934105a9c63f050b824f24a6dfb3d Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 6 Sep 2022 20:27:27 -0600 Subject: [PATCH 368/374] dm: core: Complete phandle implementation using the other FDT We need to be able to look up phandles in any FDT, not just the control FDT. Use the 'other' FDT to test this, with a helper function which gets this as an oftree that can then we used as needed. Add a few more tests and some comments at the top of the file, to explain what is going on. Signed-off-by: Simon Glass --- drivers/core/ofnode.c | 4 +-- include/test/ut.h | 5 +++ test/dm/ofnode.c | 80 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 87 insertions(+), 2 deletions(-) diff --git a/drivers/core/ofnode.c b/drivers/core/ofnode.c index 53db7b5ff0..2c4d521009 100644 --- a/drivers/core/ofnode.c +++ b/drivers/core/ofnode.c @@ -599,9 +599,9 @@ ofnode oftree_get_by_phandle(oftree tree, uint phandle) if (of_live_active()) node = np_to_ofnode(of_find_node_by_phandle(tree.np, phandle)); else - node.of_offset = + node = ofnode_from_tree_offset(tree, fdt_node_offset_by_phandle(oftree_lookup_fdt(tree), - phandle); + phandle)); return node; } diff --git a/include/test/ut.h b/include/test/ut.h index f7d1d18f7c..f7217aa8ac 100644 --- a/include/test/ut.h +++ b/include/test/ut.h @@ -119,6 +119,11 @@ int ut_check_console_end(struct unit_test_state *uts); */ int ut_check_console_dump(struct unit_test_state *uts, int total_bytes); +/* Report a failure, with printf() string */ +#define ut_reportf(fmt, args...) \ + ut_failf(uts, __FILE__, __LINE__, __func__, "report", \ + fmt, ##args) + /* Assert that a condition is non-zero */ #define ut_assert(cond) \ if (!(cond)) { \ diff --git a/test/dm/ofnode.c b/test/dm/ofnode.c index b73ab98828..134a307f1b 100644 --- a/test/dm/ofnode.c +++ b/test/dm/ofnode.c @@ -1,4 +1,20 @@ // SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2022 Google LLC + * + * There are two types of tests in this file: + * - normal ones which act on the control FDT (gd->fdt_blob or gd->of_root) + * - 'other' ones which act on the 'other' FDT (other.dts) + * + * The 'other' ones have an _ot suffix. + * + * The latter are used to check behaviour with multiple device trees, + * particularly with flat tree, where a tree ID is included in ofnode as part of + * the node offset. These tests are typically just for making sure that the + * offset makes it to libfdt correctly and that the resulting return value is + * correctly turned into an ofnode. The 'other' tests do not fully check the + * behaviour of each ofnode function, since that is done by the normal ones. + */ #include #include @@ -13,6 +29,28 @@ #include #include +/** + * get_other_oftree() - Convert a flat tree into an oftree object + * + * @uts: Test state + * @return: oftree object for the 'other' FDT (see sandbox' other.dts) + */ +oftree get_other_oftree(struct unit_test_state *uts) +{ + oftree tree; + + if (of_live_active()) + tree = oftree_from_np(uts->of_other); + else + tree = oftree_from_fdt(uts->other_fdt); + + /* An invalid tree may cause failure or crashes */ + if (!oftree_valid(tree)) + ut_reportf("test needs the UT_TESTF_OTHER_FDT flag"); + + return tree; +} + static int dm_test_ofnode_compatible(struct unit_test_state *uts) { ofnode root_node = ofnode_path("/"); @@ -42,6 +80,20 @@ static int dm_test_ofnode_get_by_phandle(struct unit_test_state *uts) } DM_TEST(dm_test_ofnode_get_by_phandle, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); +static int dm_test_ofnode_get_by_phandle_ot(struct unit_test_state *uts) +{ + oftree otree = get_other_oftree(uts); + ofnode node; + + ut_assert(ofnode_valid(oftree_get_by_phandle(oftree_default(), 1))); + node = oftree_get_by_phandle(otree, 1); + ut_assert(ofnode_valid(node)); + ut_asserteq_str("target", ofnode_get_name(node)); + + return 0; +} +DM_TEST(dm_test_ofnode_get_by_phandle_ot, UT_TESTF_OTHER_FDT); + static int dm_test_ofnode_by_prop_value(struct unit_test_state *uts) { const char propname[] = "compatible"; @@ -185,6 +237,34 @@ static int dm_test_ofnode_phandle(struct unit_test_state *uts) } DM_TEST(dm_test_ofnode_phandle, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); +static int dm_test_ofnode_phandle_ot(struct unit_test_state *uts) +{ + oftree otree = get_other_oftree(uts); + struct ofnode_phandle_args args; + ofnode node; + int ret; + + node = oftree_path(otree, "/node"); + + /* Test ofnode_count_phandle_with_args with cell name */ + ret = ofnode_count_phandle_with_args(node, "missing", "#gpio-cells", 0); + ut_asserteq(-ENOENT, ret); + ret = ofnode_count_phandle_with_args(node, "target", "#invalid", 0); + ut_asserteq(-EINVAL, ret); + ret = ofnode_count_phandle_with_args(node, "target", "#gpio-cells", 0); + ut_asserteq(1, ret); + + ret = ofnode_parse_phandle_with_args(node, "target", "#gpio-cells", 0, + 0, &args); + ut_assertok(ret); + ut_asserteq(2, args.args_count); + ut_asserteq(3, args.args[0]); + ut_asserteq(4, args.args[1]); + + return 0; +} +DM_TEST(dm_test_ofnode_phandle_ot, UT_TESTF_OTHER_FDT); + static int dm_test_ofnode_read_chosen(struct unit_test_state *uts) { const char *str; From 988f146855624d5549637552ca9f24bf07f088bf Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 6 Sep 2022 20:27:28 -0600 Subject: [PATCH 369/374] dm: core: Update comments for default-FDT ofnode functions Some ofnode functions can only operate on the default device tree, i.e. U-Boot's control FDT. Add comments to that effect. Fix up the reference to device tree bindings while we are here. Signed-off-by: Simon Glass --- include/dm/ofnode.h | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/include/dm/ofnode.h b/include/dm/ofnode.h index 3a514f71f6..0c5a883eaf 100644 --- a/include/dm/ofnode.h +++ b/include/dm/ofnode.h @@ -908,6 +908,8 @@ const void *ofnode_read_chosen_prop(const char *propname, int *sizep); * This looks for a property within the /chosen node and returns its value, * checking that it is a valid nul-terminated string * + * This only works with the control FDT. + * * @propname: Property name to look for * Return: string value if found, else NULL */ @@ -919,6 +921,8 @@ const char *ofnode_read_chosen_string(const char *propname); * This looks up a named property in the chosen node and uses that as a path to * look up a code. * + * This only works with the control FDT. + * * @propname: Property name to look for * Return: the referenced node if present, else ofnode_null() */ @@ -929,6 +933,8 @@ ofnode ofnode_get_chosen_node(const char *propname); * * This looks for a property within the /aliases node and returns its value * + * This only works with the control FDT. + * * @propname: Property name to look for * @sizep: Returns size of property, or `FDT_ERR_...` error code if function * returns NULL @@ -942,6 +948,8 @@ const void *ofnode_read_aliases_prop(const char *propname, int *sizep); * This looks up a named property in the aliases node and uses that as a path to * look up a code. * + * This only works with the control FDT. + * * @propname: Property name to look for * Return: the referenced node if present, else ofnode_null() */ @@ -1427,7 +1435,9 @@ phy_interface_t ofnode_read_phy_mode(ofnode mac_node); * * This reads a property from the /config node of the devicetree. * - * See doc/config.txt for bindings + * This only works with the control FDT. + * + * See doc/device-tree-bindings/config.txt for bindings * * @prop_name: property name to look up * Return: true, if it exists, false if not @@ -1439,7 +1449,7 @@ bool ofnode_conf_read_bool(const char *prop_name); * * This reads a property from the /config node of the devicetree. * - * See doc/config.txt for bindings + * See doc/device-tree-bindings/config.txt for bindings * * @prop_name: property name to look up * @default_val: default value to return if the property is not found @@ -1452,7 +1462,9 @@ int ofnode_conf_read_int(const char *prop_name, int default_val); * * This reads a property from the /config node of the devicetree. * - * See doc/config.txt for bindings + * This only works with the control FDT. + * + * See doc/device-tree-bindings/config.txt for bindings * * @prop_name: property name to look up * Return: string value, if found, or NULL if not From 88a1ae8172a847911ce699ac95f79ea17c88739c Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 6 Sep 2022 20:27:29 -0600 Subject: [PATCH 370/374] dm: core: Create a function to get a live tree in a test Move this logic out of the test into separate functions, so we can use it in other tests. Signed-off-by: Simon Glass --- test/dm/ofnode.c | 57 +++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 49 insertions(+), 8 deletions(-) diff --git a/test/dm/ofnode.c b/test/dm/ofnode.c index 134a307f1b..be5e3155e3 100644 --- a/test/dm/ofnode.c +++ b/test/dm/ofnode.c @@ -51,6 +51,46 @@ oftree get_other_oftree(struct unit_test_state *uts) return tree; } +/** + * get_oftree() - Convert a flat tree into an oftree object + * + * @uts: Test state + * @fdt: Pointer to flat tree + * @treep: Returns the tree, on success + * Return: 0 if OK, 1 if the tree failed to unflatten, -EOVERFLOW if there are + * too many flat trees to allow another one to be registers (see + * oftree_ensure()) + */ +int get_oftree(struct unit_test_state *uts, void *fdt, oftree *treep) +{ + oftree tree; + + if (of_live_active()) { + struct device_node *root; + + ut_assertok(unflatten_device_tree(fdt, &root)); + tree = oftree_from_np(root); + } else { + tree = oftree_from_fdt(fdt); + if (!oftree_valid(tree)) + return -EOVERFLOW; + } + *treep = tree; + + return 0; +} + +/** + * free_oftree() - Free memory used by get_oftree() + * + * @tree: Tree to free + */ +void free_oftree(oftree tree) +{ + if (of_live_active()) + free(tree.np); +} + static int dm_test_ofnode_compatible(struct unit_test_state *uts) { ofnode root_node = ofnode_path("/"); @@ -590,10 +630,10 @@ static int make_ofnode_fdt(struct unit_test_state *uts, void *fdt, int size) static int dm_test_ofnode_root(struct unit_test_state *uts) { - struct device_node *root = NULL; char fdt[256]; oftree tree; ofnode node; + int ret; /* Check that aliases work on the control FDT */ node = ofnode_get_aliases_node("ethernet3"); @@ -603,12 +643,13 @@ static int dm_test_ofnode_root(struct unit_test_state *uts) ut_assert(!oftree_valid(oftree_null())); ut_assertok(make_ofnode_fdt(uts, fdt, sizeof(fdt))); - if (of_live_active()) { - ut_assertok(unflatten_device_tree(fdt, &root)); - tree = oftree_from_np(root); - } else { - tree = oftree_from_fdt(fdt); - } + ret = get_oftree(uts, fdt, &tree); + + /* skip the rest of this test if multiple FDTs are not supported */ + if (ret == -EOVERFLOW) + return 0; + + ut_assertok(ret); ut_assert(oftree_valid(tree)); /* Make sure they don't work on this new tree */ @@ -623,7 +664,7 @@ static int dm_test_ofnode_root(struct unit_test_state *uts) node = oftree_path(oftree_default(), "/new-mmc"); ut_assert(!ofnode_valid(node)); - free(root); + free_oftree(tree); return 0; } From 47a677c2eb030d5a4e905fb8993a4cb43bcde55d Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 6 Sep 2022 20:27:30 -0600 Subject: [PATCH 371/374] dm: core: Expand ofnode tests The current tests do not cover all functions, nor do they cover the new multi-tree functionality. Add and update the tests accordingly and update the 'future work' notes in the documentation. There is a still more testing needed for the failure cases, since at present some ofnode functions return a libfdt error code instead of converting it to an errno. Signed-off-by: Simon Glass --- doc/develop/driver-model/livetree.rst | 7 +- test/dm/ofnode.c | 229 ++++++++++++++++++++++++-- 2 files changed, 214 insertions(+), 22 deletions(-) diff --git a/doc/develop/driver-model/livetree.rst b/doc/develop/driver-model/livetree.rst index 76be89b963..65b88f854e 100644 --- a/doc/develop/driver-model/livetree.rst +++ b/doc/develop/driver-model/livetree.rst @@ -321,10 +321,7 @@ Adding a new function for device-tree access involves the following steps: Future work ----------- -Live tree support was introduced in U-Boot 2017.07. There is still quite a bit -of work to do to flesh this out: +Live tree support was introduced in U-Boot 2017.07. Some possible enhancements +are: -- tests for all access functions -- more support for livetree modification -- addition of more access functions as needed - support for livetree in SPL and before relocation (if desired) diff --git a/test/dm/ofnode.c b/test/dm/ofnode.c index be5e3155e3..0912a53099 100644 --- a/test/dm/ofnode.c +++ b/test/dm/ofnode.c @@ -100,7 +100,21 @@ static int dm_test_ofnode_compatible(struct unit_test_state *uts) return 0; } -DM_TEST(dm_test_ofnode_compatible, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); +DM_TEST(dm_test_ofnode_compatible, + UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); + +/* check ofnode_device_is_compatible() with the 'other' FDT */ +static int dm_test_ofnode_compatible_ot(struct unit_test_state *uts) +{ + oftree otree = get_other_oftree(uts); + ofnode oroot = oftree_root(otree); + + ut_assert(ofnode_valid(oroot)); + ut_assert(ofnode_device_is_compatible(oroot, "sandbox-other")); + + return 0; +} +DM_TEST(dm_test_ofnode_compatible_ot, UT_TESTF_OTHER_FDT); static int dm_test_ofnode_get_by_phandle(struct unit_test_state *uts) { @@ -134,33 +148,56 @@ static int dm_test_ofnode_get_by_phandle_ot(struct unit_test_state *uts) } DM_TEST(dm_test_ofnode_get_by_phandle_ot, UT_TESTF_OTHER_FDT); -static int dm_test_ofnode_by_prop_value(struct unit_test_state *uts) +static int check_prop_values(struct unit_test_state *uts, ofnode start, + const char *propname, const char *propval, + int expect_count) { - const char propname[] = "compatible"; - const char propval[] = "denx,u-boot-fdt-test"; + int proplen = strlen(propval) + 1; const char *str; - ofnode node = ofnode_null(); + ofnode node; + int count; /* Find first matching node, there should be at least one */ - node = ofnode_by_prop_value(node, propname, propval, sizeof(propval)); + node = ofnode_by_prop_value(start, propname, propval, proplen); ut_assert(ofnode_valid(node)); str = ofnode_read_string(node, propname); ut_assert(str && !strcmp(str, propval)); /* Find the rest of the matching nodes */ + count = 1; while (true) { - node = ofnode_by_prop_value(node, propname, propval, - sizeof(propval)); + node = ofnode_by_prop_value(node, propname, propval, proplen); if (!ofnode_valid(node)) break; str = ofnode_read_string(node, propname); - ut_assert(str && !strcmp(str, propval)); + ut_asserteq_str(propval, str); + count++; } + ut_asserteq(expect_count, count); + + return 0; +} + +static int dm_test_ofnode_by_prop_value(struct unit_test_state *uts) +{ + ut_assertok(check_prop_values(uts, ofnode_null(), "compatible", + "denx,u-boot-fdt-test", 11)); return 0; } DM_TEST(dm_test_ofnode_by_prop_value, UT_TESTF_SCAN_FDT); +static int dm_test_ofnode_by_prop_value_ot(struct unit_test_state *uts) +{ + oftree otree = get_other_oftree(uts); + + ut_assertok(check_prop_values(uts, oftree_root(otree), "str-prop", + "other", 2)); + + return 0; +} +DM_TEST(dm_test_ofnode_by_prop_value_ot, UT_TESTF_OTHER_FDT); + static int dm_test_ofnode_fmap(struct unit_test_state *uts) { struct fmap_entry entry; @@ -202,6 +239,25 @@ static int dm_test_ofnode_read(struct unit_test_state *uts) } DM_TEST(dm_test_ofnode_read, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); +static int dm_test_ofnode_read_ot(struct unit_test_state *uts) +{ + oftree otree = get_other_oftree(uts); + const char *val; + ofnode node; + int size; + + node = oftree_path(otree, "/node/subnode"); + ut_assert(ofnode_valid(node)); + + val = ofnode_read_prop(node, "str-prop", &size); + ut_assertnonnull(val); + ut_asserteq_str("other", val); + ut_asserteq(6, size); + + return 0; +} +DM_TEST(dm_test_ofnode_read_ot, UT_TESTF_OTHER_FDT); + static int dm_test_ofnode_phandle(struct unit_test_state *uts) { struct ofnode_phandle_args args; @@ -377,6 +433,27 @@ static int dm_test_ofnode_get_child_count(struct unit_test_state *uts) DM_TEST(dm_test_ofnode_get_child_count, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); +static int dm_test_ofnode_get_child_count_ot(struct unit_test_state *uts) +{ + oftree otree = get_other_oftree(uts); + ofnode node, child_node; + u32 val; + + node = oftree_path(otree, "/node"); + ut_assert(ofnode_valid(node)); + + val = ofnode_get_child_count(node); + ut_asserteq(2, val); + + child_node = ofnode_first_subnode(node); + ut_assert(ofnode_valid(child_node)); + val = ofnode_get_child_count(child_node); + ut_asserteq(0, val); + + return 0; +} +DM_TEST(dm_test_ofnode_get_child_count_ot, UT_TESTF_OTHER_FDT); + static int dm_test_ofnode_is_enabled(struct unit_test_state *uts) { ofnode root_node = ofnode_path("/"); @@ -389,6 +466,19 @@ static int dm_test_ofnode_is_enabled(struct unit_test_state *uts) } DM_TEST(dm_test_ofnode_is_enabled, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); +static int dm_test_ofnode_is_enabled_ot(struct unit_test_state *uts) +{ + oftree otree = get_other_oftree(uts); + ofnode root_node = oftree_root(otree); + ofnode node = oftree_path(otree, "/target"); + + ut_assert(ofnode_is_enabled(root_node)); + ut_assert(!ofnode_is_enabled(node)); + + return 0; +} +DM_TEST(dm_test_ofnode_is_enabled_ot, UT_TESTF_OTHER_FDT); + static int dm_test_ofnode_get_reg(struct unit_test_state *uts) { ofnode node; @@ -425,30 +515,59 @@ static int dm_test_ofnode_get_reg(struct unit_test_state *uts) } DM_TEST(dm_test_ofnode_get_reg, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); +static int dm_test_ofnode_get_reg_ot(struct unit_test_state *uts) +{ + oftree otree = get_other_oftree(uts); + ofnode node = oftree_path(otree, "/target"); + fdt_addr_t addr; + + addr = ofnode_get_addr(node); + ut_asserteq(0x8000, addr); + + return 0; +} +DM_TEST(dm_test_ofnode_get_reg_ot, UT_TESTF_OTHER_FDT); + static int dm_test_ofnode_get_path(struct unit_test_state *uts) { const char *path = "/translation-test@8000/noxlatebus@3,300/dev@42"; char buf[64]; ofnode node; - int res; node = ofnode_path(path); ut_assert(ofnode_valid(node)); - res = ofnode_get_path(node, buf, 64); - ut_asserteq(0, res); + ut_assertok(ofnode_get_path(node, buf, sizeof(buf))); ut_asserteq_str(path, buf); - res = ofnode_get_path(node, buf, 32); - ut_asserteq(-ENOSPC, res); + ut_asserteq(-ENOSPC, ofnode_get_path(node, buf, 32)); - res = ofnode_get_path(ofnode_root(), buf, 32); + ut_assertok(ofnode_get_path(ofnode_root(), buf, 32)); ut_asserteq_str("/", buf); return 0; } DM_TEST(dm_test_ofnode_get_path, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); +static int dm_test_ofnode_get_path_ot(struct unit_test_state *uts) +{ + oftree otree = get_other_oftree(uts); + const char *path = "/node/subnode"; + ofnode node = oftree_path(otree, path); + char buf[64]; + + ut_assert(ofnode_valid(node)); + + ut_assertok(ofnode_get_path(node, buf, sizeof(buf))); + ut_asserteq_str(path, buf); + + ut_assertok(ofnode_get_path(oftree_root(otree), buf, 32)); + ut_asserteq_str("/", buf); + + return 0; +} +DM_TEST(dm_test_ofnode_get_path_ot, UT_TESTF_OTHER_FDT); + static int dm_test_ofnode_conf(struct unit_test_state *uts) { ut_assert(!ofnode_conf_read_bool("missing")); @@ -608,13 +727,17 @@ DM_TEST(dm_test_ofnode_get_phy, 0); * @uts: Test state * @fdt: Place to write FDT * @size: Maximum size of space for fdt + * @id: id value to add to the tree ('id' property in root node) */ -static int make_ofnode_fdt(struct unit_test_state *uts, void *fdt, int size) +static int make_ofnode_fdt(struct unit_test_state *uts, void *fdt, int size, + int id) { ut_assertok(fdt_create(fdt, size)); ut_assertok(fdt_finish_reservemap(fdt)); ut_assert(fdt_begin_node(fdt, "") >= 0); + ut_assertok(fdt_property_u32(fdt, "id", id)); + ut_assert(fdt_begin_node(fdt, "aliases") >= 0); ut_assertok(fdt_property_string(fdt, "mmc0", "/new-mmc")); ut_assertok(fdt_end_node(fdt)); @@ -642,7 +765,7 @@ static int dm_test_ofnode_root(struct unit_test_state *uts) ut_assert(!oftree_valid(oftree_null())); - ut_assertok(make_ofnode_fdt(uts, fdt, sizeof(fdt))); + ut_assertok(make_ofnode_fdt(uts, fdt, sizeof(fdt), 0)); ret = get_oftree(uts, fdt, &tree); /* skip the rest of this test if multiple FDTs are not supported */ @@ -892,6 +1015,23 @@ static int dm_test_ofnode_by_compatible(struct unit_test_state *uts) } DM_TEST(dm_test_ofnode_by_compatible, UT_TESTF_SCAN_FDT); +static int dm_test_ofnode_by_compatible_ot(struct unit_test_state *uts) +{ + const char *compat = "sandbox-other2"; + oftree otree = get_other_oftree(uts); + ofnode node; + int count; + + count = 0; + for (node = oftree_root(otree); + node = ofnode_by_compatible(node, compat), ofnode_valid(node);) + count++; + ut_asserteq(2, count); + + return 0; +} +DM_TEST(dm_test_ofnode_by_compatible_ot, UT_TESTF_OTHER_FDT); + static int dm_test_ofnode_find_subnode(struct unit_test_state *uts) { ofnode node, subnode; @@ -909,6 +1049,24 @@ static int dm_test_ofnode_find_subnode(struct unit_test_state *uts) } DM_TEST(dm_test_ofnode_find_subnode, UT_TESTF_SCAN_FDT); +static int dm_test_ofnode_find_subnode_ot(struct unit_test_state *uts) +{ + oftree otree = get_other_oftree(uts); + ofnode node, subnode; + + node = oftree_path(otree, "/node"); + + subnode = ofnode_find_subnode(node, "subnode"); + ut_assert(ofnode_valid(subnode)); + ut_asserteq_str("subnode", ofnode_get_name(subnode)); + + subnode = ofnode_find_subnode(node, "btn"); + ut_assert(!ofnode_valid(subnode)); + + return 0; +} +DM_TEST(dm_test_ofnode_find_subnode_ot, UT_TESTF_OTHER_FDT); + static int dm_test_ofnode_get_name(struct unit_test_state *uts) { ofnode node; @@ -921,3 +1079,40 @@ static int dm_test_ofnode_get_name(struct unit_test_state *uts) return 0; } DM_TEST(dm_test_ofnode_get_name, UT_TESTF_SCAN_FDT); + +/* try to access more FDTs than is supported */ +static int dm_test_ofnode_too_many(struct unit_test_state *uts) +{ + const int max_trees = CONFIG_IS_ENABLED(OFNODE_MULTI_TREE, + (CONFIG_OFNODE_MULTI_TREE_MAX), (1)); + const int fdt_size = 256; + const int num_trees = max_trees + 1; + char fdt[num_trees][fdt_size]; + int i; + + for (i = 0; i < num_trees; i++) { + oftree tree; + int ret; + + ut_assertok(make_ofnode_fdt(uts, fdt[i], fdt_size, i)); + ret = get_oftree(uts, fdt[i], &tree); + + /* + * With flat tree we have the control FDT using one slot. Live + * tree has no limit since it uses pointers, not integer tree + * IDs + */ + if (of_live_active() || i < max_trees - 1) { + ut_assertok(ret); + } else { + /* + * tree should be invalid when we try to register too + * many trees + */ + ut_asserteq(-EOVERFLOW, ret); + } + } + + return 0; +} +DM_TEST(dm_test_ofnode_too_many, UT_TESTF_SCAN_FDT); From 0d63213c1ed5246423c22cbe3c6798a09763a2b9 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 6 Sep 2022 20:27:31 -0600 Subject: [PATCH 372/374] vbe: Allow test to run with live/flat tree This test can operate in all conditions now. Update the test and comments. Signed-off-by: Simon Glass --- test/boot/vbe_simple.c | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/test/boot/vbe_simple.c b/test/boot/vbe_simple.c index 3f03fc3acd..8acd777f4c 100644 --- a/test/boot/vbe_simple.c +++ b/test/boot/vbe_simple.c @@ -74,26 +74,22 @@ static int vbe_simple_test_base(struct unit_test_state *uts) node_ofs = fdt_add_subnode(fdt_buf, node_ofs, "firmware0"); ut_assert(node_ofs > 0); - /* - * This can only work on the live tree, since the ofnode interface for - * flat tree assumes that ofnode points to the control FDT - */ - ut_assertok(unflatten_device_tree(fdt_buf, &np)); + if (of_live_active()) { + ut_assertok(unflatten_device_tree(fdt_buf, &np)); + fixup.tree = oftree_from_np(np); + } else { + fixup.tree = oftree_from_fdt(fdt_buf); + } /* * It would be better to call image_setup_libfdt() here, but that * function does not allow passing an ofnode. We can pass fdt_buf but - * when it comes to send the evenr, it creates an ofnode that uses the + * when it comes to send the event, it creates an ofnode that uses the * control FDT, since it has no way of accessing the live tree created * here. * - * Two fix this we need: - * - image_setup_libfdt() is updated to use ofnode - * - ofnode updated to support access to an FDT other than the control - * FDT. This is partially implemented with live tree, but not with - * flat tree + * Two fix this we need image_setup_libfdt() is updated to use ofnode */ - fixup.tree.np = np; ut_assertok(event_notify(EVT_FT_FIXUP, &fixup, sizeof(fixup))); node = oftree_path(fixup.tree, "/chosen/fwupd/firmware0"); @@ -111,5 +107,4 @@ static int vbe_simple_test_base(struct unit_test_state *uts) return 0; } -BOOTSTD_TEST(vbe_simple_test_base, UT_TESTF_DM | UT_TESTF_SCAN_FDT | - UT_TESTF_LIVE_TREE); +BOOTSTD_TEST(vbe_simple_test_base, UT_TESTF_DM | UT_TESTF_SCAN_FDT); From 0b58eaa89c4d7a4aea1f7f63ff4aca2c2f1d90c4 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 6 Sep 2022 20:27:32 -0600 Subject: [PATCH 373/374] dm: core: Allow copying ofnode property data when writing At present ofnode_write_prop() is inconsistent between livetree and flattree, in that livetree requires the caller to ensure the property value is stable (e.g. in rodata or allocated) but flattree does not, since it makes a copy. This makes the API call a bit painful to use, since the caller must do different things depending on OF_LIVE. Add a new 'copy' argument which tells the function to make a copy if needed. Add some tests to cover this behaviour. Signed-off-by: Simon Glass --- doc/develop/driver-model/livetree.rst | 2 + drivers/core/ofnode.c | 29 +++++++++---- include/dm/ofnode.h | 12 ++++-- test/dm/ofnode.c | 62 ++++++++++++++++++++++++++- 4 files changed, 92 insertions(+), 13 deletions(-) diff --git a/doc/develop/driver-model/livetree.rst b/doc/develop/driver-model/livetree.rst index 65b88f854e..55aa3eac92 100644 --- a/doc/develop/driver-model/livetree.rst +++ b/doc/develop/driver-model/livetree.rst @@ -325,3 +325,5 @@ Live tree support was introduced in U-Boot 2017.07. Some possible enhancements are: - support for livetree in SPL and before relocation (if desired) +- freeing leaked memory caused by writing new nodes / property values to the + livetree (ofnode_write_prop()) diff --git a/drivers/core/ofnode.c b/drivers/core/ofnode.c index 2c4d521009..39636a5a18 100644 --- a/drivers/core/ofnode.c +++ b/drivers/core/ofnode.c @@ -1388,15 +1388,27 @@ ofnode ofnode_by_prop_value(ofnode from, const char *propname, } int ofnode_write_prop(ofnode node, const char *propname, const void *value, - int len) + int len, bool copy) { - if (of_live_active()) - return of_write_prop(ofnode_to_np(node), propname, len, value); - else + if (of_live_active()) { + void *newval; + int ret; + + if (copy) { + newval = malloc(len); + if (!newval) + return log_ret(-ENOMEM); + memcpy(newval, value, len); + value = newval; + } + ret = of_write_prop(ofnode_to_np(node), propname, len, value); + if (ret && copy) + free(newval); + return ret; + } else { return fdt_setprop(ofnode_to_fdt(node), ofnode_to_offset(node), propname, value, len); - - return 0; + } } int ofnode_write_string(ofnode node, const char *propname, const char *value) @@ -1405,7 +1417,8 @@ int ofnode_write_string(ofnode node, const char *propname, const char *value) debug("%s: %s = %s", __func__, propname, value); - return ofnode_write_prop(node, propname, value, strlen(value) + 1); + return ofnode_write_prop(node, propname, value, strlen(value) + 1, + false); } int ofnode_write_u32(ofnode node, const char *propname, u32 value) @@ -1420,7 +1433,7 @@ int ofnode_write_u32(ofnode node, const char *propname, u32 value) return -ENOMEM; *val = cpu_to_fdt32(value); - return ofnode_write_prop(node, propname, val, sizeof(value)); + return ofnode_write_prop(node, propname, val, sizeof(value), false); } int ofnode_set_enabled(ofnode node, bool value) diff --git a/include/dm/ofnode.h b/include/dm/ofnode.h index 0c5a883eaf..5203045a58 100644 --- a/include/dm/ofnode.h +++ b/include/dm/ofnode.h @@ -1350,19 +1350,23 @@ int ofnode_device_is_compatible(ofnode node, const char *compat); /** * ofnode_write_prop() - Set a property of a ofnode * - * Note that the value passed to the function is *not* allocated by the - * function itself, but must be allocated by the caller if necessary. However - * it does allocate memory for the property struct and name. + * Note that if @copy is false, the value passed to the function is *not* + * allocated by the function itself, but must be allocated by the caller if + * necessary. However it does allocate memory for the property struct and name. * * @node: The node for whose property should be set * @propname: The name of the property to set * @value: The new value of the property (must be valid prior to calling * the function) * @len: The length of the new value of the property + * @copy: true to allocate memory for the value. This only has any effect with + * live tree, since flat tree handles this automatically. It allows a + * node's value to be written to the tree, without requiring that the + * caller allocate it * Return: 0 if successful, -ve on error */ int ofnode_write_prop(ofnode node, const char *propname, const void *value, - int len); + int len, bool copy); /** * ofnode_write_string() - Set a string property of a ofnode diff --git a/test/dm/ofnode.c b/test/dm/ofnode.c index 0912a53099..69ffba0653 100644 --- a/test/dm/ofnode.c +++ b/test/dm/ofnode.c @@ -822,7 +822,8 @@ static int dm_test_ofnode_livetree_writing(struct unit_test_state *uts) ut_asserteq_64(FDT_ADDR_T_NONE, dev_read_addr(dev)); /* reg = 0x42, size = 0x100 */ ut_assertok(ofnode_write_prop(node, "reg", - "\x00\x00\x00\x42\x00\x00\x01\x00", 8)); + "\x00\x00\x00\x42\x00\x00\x01\x00", 8, + false)); ut_asserteq(0x42, dev_read_addr(dev)); /* Test disabling devices */ @@ -838,6 +839,65 @@ static int dm_test_ofnode_livetree_writing(struct unit_test_state *uts) DM_TEST(dm_test_ofnode_livetree_writing, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); +static int check_write_prop(struct unit_test_state *uts, ofnode node) +{ + char prop[] = "middle-name"; + char name[10]; + int len; + + strcpy(name, "cecil"); + len = strlen(name) + 1; + ut_assertok(ofnode_write_prop(node, prop, name, len, false)); + ut_asserteq_str(name, ofnode_read_string(node, prop)); + + /* change the underlying value, this should mess up the live tree */ + strcpy(name, "tony"); + if (of_live_active()) { + ut_asserteq_str(name, ofnode_read_string(node, prop)); + } else { + ut_asserteq_str("cecil", ofnode_read_string(node, prop)); + } + + /* try again, this time copying the property */ + strcpy(name, "mary"); + ut_assertok(ofnode_write_prop(node, prop, name, len, true)); + ut_asserteq_str(name, ofnode_read_string(node, prop)); + strcpy(name, "leah"); + + /* both flattree and livetree behave the same */ + ut_asserteq_str("mary", ofnode_read_string(node, prop)); + + return 0; +} + +/* writing the tree with and without copying the property */ +static int dm_test_ofnode_write_copy(struct unit_test_state *uts) +{ + ofnode node; + + node = ofnode_path("/a-test"); + ut_assertok(check_write_prop(uts, node)); + + return 0; +} +DM_TEST(dm_test_ofnode_write_copy, UT_TESTF_SCAN_FDT); + +static int dm_test_ofnode_write_copy_ot(struct unit_test_state *uts) +{ + oftree otree = get_other_oftree(uts); + ofnode node, check_node; + + node = oftree_path(otree, "/node"); + ut_assertok(check_write_prop(uts, node)); + + /* make sure the control FDT is not touched */ + check_node = ofnode_path("/node"); + ut_assertnull(ofnode_read_string(check_node, "middle-name")); + + return 0; +} +DM_TEST(dm_test_ofnode_write_copy_ot, UT_TESTF_OTHER_FDT); + static int dm_test_ofnode_u32(struct unit_test_state *uts) { ofnode node; From db1ef1e12b993275e09f116ebc3d23d675c7e28c Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 6 Sep 2022 20:27:33 -0600 Subject: [PATCH 374/374] dm: core: Support copying properties with ofnode Add a function to copy properties from one node to another. Signed-off-by: Simon Glass --- drivers/core/ofnode.c | 24 ++++++++++++++++++ include/dm/ofnode.h | 16 ++++++++++++ test/dm/ofnode.c | 59 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 99 insertions(+) diff --git a/drivers/core/ofnode.c b/drivers/core/ofnode.c index 39636a5a18..14bbfe7232 100644 --- a/drivers/core/ofnode.c +++ b/drivers/core/ofnode.c @@ -1557,3 +1557,27 @@ int ofnode_add_subnode(ofnode node, const char *name, ofnode *subnodep) return ret; /* 0 or -EEXIST */ } + +int ofnode_copy_props(ofnode src, ofnode dst) +{ + struct ofprop prop; + + ofnode_for_each_prop(prop, src) { + const char *name; + const char *val; + int len, ret; + + val = ofprop_get_property(&prop, &name, &len); + if (!val) { + log_debug("Cannot read prop (err=%d)\n", len); + return log_msg_ret("get", -EINVAL); + } + ret = ofnode_write_prop(dst, name, val, len, true); + if (ret) { + log_debug("Cannot write prop (err=%d)\n", ret); + return log_msg_ret("wr", -EINVAL); + } + } + + return 0; +} diff --git a/include/dm/ofnode.h b/include/dm/ofnode.h index 5203045a58..7aae2c29ef 100644 --- a/include/dm/ofnode.h +++ b/include/dm/ofnode.h @@ -1505,4 +1505,20 @@ static inline const char *ofnode_conf_read_str(const char *prop_name) */ int ofnode_add_subnode(ofnode parent, const char *name, ofnode *nodep); +/** + * ofnode_copy_props() - copy all properties from one node to another + * + * Makes a copy of all properties from the source note in the destination node. + * Existing properties in the destination node remain unchanged, except that + * any with the same name are overwritten, including changing the size of the + * property. + * + * For livetree, properties are copied / allocated, so the source tree does not + * need to be present afterwards. + * + * @src: Source node to read properties from + * @dst: Destination node to write properties too + */ +int ofnode_copy_props(ofnode src, ofnode dst); + #endif diff --git a/test/dm/ofnode.c b/test/dm/ofnode.c index 69ffba0653..41811ec3bb 100644 --- a/test/dm/ofnode.c +++ b/test/dm/ofnode.c @@ -1176,3 +1176,62 @@ static int dm_test_ofnode_too_many(struct unit_test_state *uts) return 0; } DM_TEST(dm_test_ofnode_too_many, UT_TESTF_SCAN_FDT); + +static int check_copy_props(struct unit_test_state *uts, ofnode src, + ofnode dst) +{ + u32 reg[2], val; + + ut_assertok(ofnode_copy_props(src, dst)); + + ut_assertok(ofnode_read_u32(dst, "ping-expect", &val)); + ut_asserteq(3, val); + + ut_asserteq_str("denx,u-boot-fdt-test", + ofnode_read_string(dst, "compatible")); + + /* check that a property with the same name is overwritten */ + ut_assertok(ofnode_read_u32_array(dst, "reg", reg, ARRAY_SIZE(reg))); + ut_asserteq(3, reg[0]); + ut_asserteq(1, reg[1]); + + /* reset the compatible so the live tree does not change */ + ut_assertok(ofnode_write_string(dst, "compatible", "nothing")); + + return 0; +} + +static int dm_test_ofnode_copy_props(struct unit_test_state *uts) +{ + ofnode src, dst; + + /* + * These nodes are chosen so that the src node is before the destination + * node in the tree. This doesn't matter with livetree, but with + * flattree any attempt to insert a property earlier in the tree will + * mess up the offsets after it. + */ + src = ofnode_path("/b-test"); + dst = ofnode_path("/some-bus"); + + ut_assertok(check_copy_props(uts, src, dst)); + + /* check a property that is in the destination already */ + ut_asserteq_str("mux0", ofnode_read_string(dst, "mux-control-names")); + + return 0; +} +DM_TEST(dm_test_ofnode_copy_props, UT_TESTF_SCAN_FDT); + +static int dm_test_ofnode_copy_props_ot(struct unit_test_state *uts) +{ + ofnode src, dst; + oftree otree = get_other_oftree(uts); + + src = ofnode_path("/b-test"); + dst = oftree_path(otree, "/node/subnode2"); + ut_assertok(check_copy_props(uts, src, dst)); + + return 0; +} +DM_TEST(dm_test_ofnode_copy_props_ot, UT_TESTF_SCAN_FDT | UT_TESTF_OTHER_FDT);