From aa7c8e63c6a81cf054af4392e7ae1fbf4e9bbf04 Mon Sep 17 00:00:00 2001
From: Viacheslav Bocharov <adeep@lexina.in>
Date: Tue, 3 Oct 2023 17:26:36 +0300
Subject: [PATCH 4/8] Copy and update amlogic-2019 aml partition/keyman code to
 mainline (fixes)

---
 .../meson-axg-jethome-jethub-j100-u-boot.dtsi | 92 +++++++++++++++++
 cmd/Kconfig                                   |  5 +
 cmd/Makefile                                  |  3 +
 common/Makefile                               |  3 +
 configs/jethub_j100_defconfig                 |  7 ++
 configs/jethub_j80_defconfig                  |  7 ++
 disk/Kconfig                                  | 13 +++
 disk/Makefile                                 |  1 +
 drivers/Kconfig                               |  4 +
 drivers/Makefile                              |  3 +
 drivers/mmc/Makefile                          |  3 +
 drivers/mmc/mmc.c                             | 99 ++++++++++++++++++-
 include/mmc.h                                 | 25 +++++
 include/part.h                                |  3 +
 14 files changed, 267 insertions(+), 1 deletion(-)

diff --git a/arch/arm/dts/meson-axg-jethome-jethub-j100-u-boot.dtsi b/arch/arm/dts/meson-axg-jethome-jethub-j100-u-boot.dtsi
index 3ecb233f8e2..e0e6b2259cc 100644
--- a/arch/arm/dts/meson-axg-jethome-jethub-j100-u-boot.dtsi
+++ b/arch/arm/dts/meson-axg-jethome-jethub-j100-u-boot.dtsi
@@ -4,6 +4,98 @@
  * Author: Vyacheslav Bocharov <adeep@lexina.in>
  */
 
+/ {
+	partitions: partitions {
+		parts = <1>;
+		part-0 = <&rootfs>;
+		rootfs: rootfs {
+			pname = "rootfs";
+			size = <0xffffffff 0xffffffff>;
+			mask = <4>;
+		};
+	};
+
+	efusekey: efusekey {
+		keynum = <5>;
+		key0 = <&key_0>;
+		key1 = <&key_1>;
+		key2 = <&key_2>;
+		key3 = <&key_3>;
+		key4 = <&key_4>;
+
+		key_0: key_0 {
+			keyname = "mac";
+			offset = <0>;
+			size = <6>;
+		};
+		key_1: key_1 {
+			keyname = "mac_bt";
+			offset = <6>;
+			size = <6>;
+		};
+		key_2: key_2 {
+			keyname = "mac_wifi";
+			offset = <12>;
+			size = <6>;
+		};
+		key_3: key_3 {
+			keyname = "usid";
+			offset = <18>;
+			size = <32>;
+		};
+		key_4: key_4 {
+			keyname = "serial";
+			offset = <50>;
+			size = <32>;
+		};
+	}; //End efusekey
+
+	unifykey {
+		compatible = "amlogic, unifykey";
+		status = "ok";
+		unifykey-num = <6>;
+		unifykey-index-0 = <&keysn_0>;
+		unifykey-index-1 = <&keysn_1>;
+		unifykey-index-2 = <&keysn_2>;
+		unifykey-index-3 = <&keysn_3>;
+		unifykey-index-4 = <&keysn_4>;
+		unifykey-index-5 = <&keysn_5>;
+
+		keysn_0: key_0 {
+			key-name = "usid";
+			key-device = "normal";
+			key-permit = "read";
+		};
+		keysn_1: key_1 {
+			key-name = "mac";
+			key-device = "normal";
+			key-permit = "read";
+		};
+		keysn_2: key_2 {
+			key-name = "mac_bt";
+			key-device = "normal";
+			key-permit = "read","write","del";
+			key-type  = "mac";
+		};
+		keysn_3: key_3 {
+			key-name = "mac_wifi";
+			key-device = "normal";
+			key-permit = "read","write","del";
+			key-type = "mac";
+		};
+		keysn_4: key_4 {
+			key-name = "serial";
+			key-device = "normal";
+			key-permit = "read";
+		};
+		keysn_5:key_5 {
+			key-name = "deviceid";
+			key-device = "normal";
+			key-permit = "read","write","del";
+		};
+	}; //End unifykey
+};
+
 &saradc {
 	status = "okay";
 	vref-supply = <&vddio_ao18>;
diff --git a/cmd/Kconfig b/cmd/Kconfig
index 43ca10f69cc..71446cf0923 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -2698,6 +2698,11 @@ config CMD_REISER
 	    reiserls - list files
 	    reiserload - load a file
 
+config AML_STORAGE
+	bool "aml storage support"
+	help
+	  storage cmd support
+
 config CMD_YAFFS2
 	bool "yaffs2 - Access of YAFFS2 filesystem"
 	depends on YAFFS2
diff --git a/cmd/Makefile b/cmd/Makefile
index 9bebf321c39..1f68971aaee 100644
--- a/cmd/Makefile
+++ b/cmd/Makefile
@@ -214,6 +214,9 @@ obj-$(CONFIG_CMD_ETHSW) += ethsw.o
 obj-$(CONFIG_CMD_AXI) += axi.o
 obj-$(CONFIG_CMD_PVBLOCK) += pvblock.o
 
+obj-$(CONFIG_AML_STORAGE) += storage.o
+obj-$(CONFIG_CMD_MMC) += aml_mmc.o
+
 # Power
 obj-$(CONFIG_CMD_PMIC) += pmic.o
 obj-$(CONFIG_CMD_REGULATOR) += regulator.o
diff --git a/common/Makefile b/common/Makefile
index f5c3d90f067..26d9aefeaaf 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -11,6 +11,9 @@ obj-y += exports.o
 obj-$(CONFIG_HUSH_PARSER) += cli_hush.o
 obj-$(CONFIG_AUTOBOOT) += autoboot.o
 
+obj-$(CONFIG_AML_STORAGE) += partitions.o
+obj-$(CONFIG_AML_STORAGE) += aml_dt.o
+
 # # boards
 obj-y += board_f.o
 obj-y += board_r.o
diff --git a/configs/jethub_j100_defconfig b/configs/jethub_j100_defconfig
index 549d5514f7a..26a22d96a6d 100644
--- a/configs/jethub_j100_defconfig
+++ b/configs/jethub_j100_defconfig
@@ -68,3 +68,10 @@ CONFIG_USB_GADGET_VENDOR_NUM=0x1b8e
 CONFIG_USB_GADGET_PRODUCT_NUM=0xfada
 CONFIG_USB_GADGET_DWC2_OTG=y
 CONFIG_USB_GADGET_DOWNLOAD=y
+
+CONFIG_AML_DRIVER=y
+CONFIG_UNIFY_KEY_MANAGE=y
+CONFIG_SECURE_STORAGE=y
+CONFIG_AML_STORAGE=y
+CONFIG_EFUSE=y
+CONFIG_AML_PARTITION=y
diff --git a/configs/jethub_j80_defconfig b/configs/jethub_j80_defconfig
index df9b8f3aedf..46bc96516e7 100644
--- a/configs/jethub_j80_defconfig
+++ b/configs/jethub_j80_defconfig
@@ -72,3 +72,10 @@ CONFIG_USB_GADGET_VENDOR_NUM=0x1b8e
 CONFIG_USB_GADGET_PRODUCT_NUM=0xfada
 CONFIG_USB_GADGET_DWC2_OTG=y
 CONFIG_USB_GADGET_DOWNLOAD=y
+
+CONFIG_AML_DRIVER=y
+CONFIG_UNIFY_KEY_MANAGE=y
+CONFIG_SECURE_STORAGE=y
+CONFIG_AML_STORAGE=y
+CONFIG_EFUSE=y
+CONFIG_AML_PARTITION=y
diff --git a/disk/Kconfig b/disk/Kconfig
index 85496958074..5c65ad5065c 100644
--- a/disk/Kconfig
+++ b/disk/Kconfig
@@ -165,4 +165,17 @@ config SPL_PARTITION_TYPE_GUID
 	  Activate the configuration of GUID type
 	  for EFI partition
 
+config AML_PARTITION
+	bool "Enable AML partition table"
+	depends on PARTITIONS
+	help
+	   "AML_PARTITION_HELP"
+
+config AML_GPT
+	bool "Enable AML GPT partition table"
+	depends on PARTITIONS
+	select RANDOM_UUID
+	help
+	   "AML_GPT_HELP"
+
 endmenu
diff --git a/disk/Makefile b/disk/Makefile
index 45588cf66e4..23fc28bcbe4 100644
--- a/disk/Makefile
+++ b/disk/Makefile
@@ -17,4 +17,5 @@ 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
+#obj-$(CONFIG_AML_PARTITION) 		 += part_aml.o
 endif
diff --git a/drivers/Kconfig b/drivers/Kconfig
index a25f6ae02fd..c074b7dce93 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -156,6 +156,10 @@ source "drivers/watchdog/Kconfig"
 
 source "drivers/xen/Kconfig"
 
+source "drivers/amlogic/Kconfig"
+
+source "drivers/efuse/Kconfig"
+
 config PHYS_TO_BUS
 	bool "Custom physical to bus address mapping"
 	help
diff --git a/drivers/Makefile b/drivers/Makefile
index efc2a4afb24..91883a77af7 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -43,6 +43,9 @@ obj-$(CONFIG_$(SPL_)VIDEO) += video/
 
 obj-y += bus/
 
+obj-$(CONFIG_AML_DRIVER) += amlogic/
+obj-$(CONFIG_EFUSE) += efuse/
+
 ifndef CONFIG_TPL_BUILD
 ifndef CONFIG_VPL_BUILD
 ifdef CONFIG_SPL_BUILD
diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile
index 2c65c4765ab..2ee7af838ed 100644
--- a/drivers/mmc/Makefile
+++ b/drivers/mmc/Makefile
@@ -4,7 +4,10 @@
 # Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 
 obj-y += mmc.o
+obj-y += mmc_aml.o
 obj-$(CONFIG_$(SPL_)DM_MMC) += mmc-uclass.o
+obj-$(CONFIG_CMD_MMC) += storage_emmc.o
+obj-$(CONFIG_MMC_MESON_GX) += aml_emmc_partition.o
 
 ifdef CONFIG_$(SPL_TPL_)DM_MMC
 obj-$(CONFIG_$(SPL_TPL_)BOOTSTD) += mmc_bootdev.o
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index 31cfda28858..9b275b82e14 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -26,6 +26,24 @@
 #include <div64.h>
 #include "mmc_private.h"
 
+
+// TODO amlogic 
+#include <linux/crc32.h>
+#include <rand.h>
+#include <amlstorage/partition_table.h>
+#include <amlstorage/emmc_partitions.h>
+
+struct aml_pattern aml_pattern_table[] = {
+	AML_PATTERN_ELEMENT(MMC_PATTERN_NAME, CALI_PATTERN),
+	AML_PATTERN_ELEMENT(MMC_MAGIC_NAME, MAGIC_PATTERN),
+	AML_PATTERN_ELEMENT(MMC_RANDOM_NAME, RANDOM_PATTERN),
+};
+
+int mmc_pattern_check(struct mmc *mmc, struct aml_pattern *table);
+void mmc_write_cali_mattern(void *addr, struct aml_pattern *table);
+
+// end TODO
+
 #define DEFAULT_CMD6_TIMEOUT_MS  500
 
 static int mmc_set_signal_voltage(struct mmc *mmc, uint signal_voltage);
@@ -2391,6 +2409,12 @@ static int mmc_startup_v4(struct mmc *mmc)
 	}
 #endif
 
+	/* dev life time estimate type A/B */
+	mmc->dev_lifetime_est_typ_a
+		= ext_csd[EXT_CSD_DEV_LIFETIME_EST_TYP_A];
+	mmc->dev_lifetime_est_typ_b
+		= ext_csd[EXT_CSD_DEV_LIFETIME_EST_TYP_B];
+
 	/*
 	 * Host needs to enable ERASE_GRP_DEF bit if device is
 	 * partitioned. This bit will be lost every time after a reset
@@ -2984,7 +3008,7 @@ static int mmc_complete_init(struct mmc *mmc)
 
 int mmc_init(struct mmc *mmc)
 {
-	int err = 0;
+	int err = 0, i;
 	__maybe_unused ulong start;
 #if CONFIG_IS_ENABLED(DM_MMC)
 	struct mmc_uclass_priv *upriv = dev_get_uclass_priv(mmc->dev);
@@ -3003,6 +3027,18 @@ int mmc_init(struct mmc *mmc)
 		err = mmc_complete_init(mmc);
 	if (err)
 		pr_info("%s: %d, time %lu\n", __func__, err, get_timer(start));
+	info_disprotect |= DISPROTECT_KEY;
+	if (IS_MMC(mmc)) {
+		if (!is_partition_checked) {
+			if (mmc_device_init(mmc) == 0) {
+				is_partition_checked = true;
+				pr_info("eMMC/TSD partition table have been checked OK!\n");
+				for (i = 0; i < ARRAY_SIZE(aml_pattern_table); i++)
+					mmc_pattern_check(mmc, &aml_pattern_table[i]);
+			}
+		}
+	}
+	info_disprotect &= ~DISPROTECT_KEY;
 
 	return err;
 }
@@ -3193,3 +3229,64 @@ __weak int mmc_get_env_dev(void)
 	return 0;
 #endif
 }
+
+/// TODO: amlogic 
+int mmc_pattern_check(struct mmc *mmc, struct aml_pattern *table)
+{
+	void *addr = NULL;
+	u64 cnt = 0, n = 0, blk = 0;
+	u32 *buf = NULL;
+	u32 crc32_s = 0;
+	struct partitions *part = NULL;
+	struct virtual_partition *vpart = NULL;
+
+	vpart = aml_get_virtual_partition_by_name(table->name);
+
+	addr = (void *)malloc(vpart->size);
+	if (!addr) {
+		printf("%s malloc failed\n", table->name);
+		return 1;
+	}
+	part = aml_get_partition_by_name(MMC_RESERVED_NAME);
+	blk = (part->offset + vpart->offset) / mmc->read_bl_len;
+	cnt = vpart->size / mmc->read_bl_len;
+	n = blk_dread(mmc_get_blk_desc(mmc), blk, cnt, addr);
+	if (n != cnt) {
+		printf("read pattern failed\n");
+		free(addr);
+		return 1;
+	} else {
+		buf = (u32 *)addr;
+		crc32_s = crc32(0, (u8 *)addr, (vpart->size - 4));
+		if (crc32_s != buf[vpart->size/4 - 1]) {
+			printf("check %s failed,need to write\n",
+						table->name);
+			mmc_write_cali_mattern(addr, table);
+			n = blk_dwrite(mmc_get_blk_desc(mmc), blk, cnt, addr);
+			printf("several 0x%x pattern blocks write %s\n",
+				table->pattern, (n == cnt) ? "OK" : "ERROR");
+		}
+		printf("crc32_s:0x%x == storage crc_pattern:0x%x!!!\n",
+				crc32_s, buf[vpart->size/4 - 1]);
+	}
+	free(addr);
+	return (n == cnt) ? 0 : 1;
+}
+
+
+void mmc_write_cali_mattern(void *addr, struct aml_pattern *table)
+{
+	int i = 0;
+	unsigned int s = 10;
+	u32 *mattern = (u32 *)addr;
+	struct virtual_partition *vpart =
+		aml_get_virtual_partition_by_name(table->name);
+	for (i = 0;i < (vpart->size)/4 - 1;i++) {
+		if (!strcmp(table->name, "random"))
+			mattern[i] = rand_r(&s);
+		else
+			mattern[i] = table->pattern;
+	}
+	mattern[i] = crc32(0, (u8 *)addr, (vpart->size - 4));
+	return;
+}
diff --git a/include/mmc.h b/include/mmc.h
index 1022db3ffa7..721758c3c7b 100644
--- a/include/mmc.h
+++ b/include/mmc.h
@@ -109,6 +109,10 @@ struct bd_info;
 #define MMC_CMD_SET_BLOCK_COUNT         23
 #define MMC_CMD_WRITE_SINGLE_BLOCK	24
 #define MMC_CMD_WRITE_MULTIPLE_BLOCK	25
+#define MMC_CMD_SET_WRITE_PROTECT	28
+#define MMC_CMD_CLR_WRITE_PROT		29
+#define MMC_CMD_SEND_WRITE_PROT		30
+#define MMC_CMD_SEND_WRITE_PROT_TYPE	31
 #define MMC_CMD_ERASE_GROUP_START	35
 #define MMC_CMD_ERASE_GROUP_END		36
 #define MMC_CMD_ERASE			38
@@ -213,6 +217,7 @@ static inline bool mmc_is_tuning_cmd(uint cmdidx)
 /*
  * EXT_CSD fields
  */
+#define EXT_CSD_CLASS_6_CTRL		59	/*R/W/E_P*/
 #define EXT_CSD_ENH_START_ADDR		136	/* R/W */
 #define EXT_CSD_ENH_SIZE_MULT		140	/* R/W */
 #define EXT_CSD_GP_SIZE_MULT		143	/* R/W */
@@ -236,6 +241,7 @@ static inline bool mmc_is_tuning_cmd(uint cmdidx)
 #define EXT_CSD_HS_TIMING		185	/* R/W */
 #define EXT_CSD_REV			192	/* RO */
 #define EXT_CSD_CARD_TYPE		196	/* RO */
+#define EXT_CSD_DRIVER_STRENGTH		197	/* RO */
 #define EXT_CSD_PART_SWITCH_TIME	199	/* RO */
 #define EXT_CSD_SEC_CNT			212	/* RO, 4 bytes */
 #define EXT_CSD_HC_WP_GRP_SIZE		221	/* RO */
@@ -243,6 +249,9 @@ static inline bool mmc_is_tuning_cmd(uint cmdidx)
 #define EXT_CSD_BOOT_MULT		226	/* RO */
 #define EXT_CSD_SEC_FEATURE		231	/* RO */
 #define EXT_CSD_GENERIC_CMD6_TIME       248     /* RO */
+#define EXT_CSD_DEV_LIFETIME_EST_TYP_A	268	/* RO */
+#define EXT_CSD_DEV_LIFETIME_EST_TYP_B	269	/* RO */
+
 #define EXT_CSD_BKOPS_SUPPORT		502	/* RO */
 
 /*
@@ -344,6 +353,20 @@ static inline bool mmc_is_tuning_cmd(uint cmdidx)
 #define ENHNCD_SUPPORT		(0x2)
 #define PART_ENH_ATTRIB		(0x1f)
 
+#define US_PWR_WP_DIS_BIT      1<<3
+#define US_PERM_WP_DIS_BIT     1<<4
+#define WP_CLEAR_TYPE          0
+#define WP_POWER_ON_TYPE       (1<<1)
+#define WP_TEMPORARY_TYPE      1
+#define WP_PERMANENT_TYPE      ((1<<0)|(1<<1))
+#define WP_TYPE_MASK           3
+#define WP_ENABLE_MASK         7
+#define WP_TEMPORARY_EN_BIT    0
+#define WP_POWER_ON_EN_BIT     (1<<0)
+#define WP_PERM_EN_BIT         (1<<2)
+#define WP_GRP_SIZE_MASK       31
+
+
 #define MMC_QUIRK_RETRY_SEND_CID	BIT(0)
 #define MMC_QUIRK_RETRY_SET_BLOCKLEN	BIT(1)
 #define MMC_QUIRK_RETRY_APP_CMD	BIT(2)
@@ -703,6 +726,8 @@ struct mmc {
 #if CONFIG_IS_ENABLED(MMC_WRITE)
 	struct sd_ssr	ssr;	/* SD status register */
 #endif
+	uint dev_lifetime_est_typ_a;
+	uint dev_lifetime_est_typ_b;
 	u64 capacity;
 	u64 capacity_user;
 	u64 capacity_boot;
diff --git a/include/part.h b/include/part.h
index 8e451bbdff9..b61e22c863b 100644
--- a/include/part.h
+++ b/include/part.h
@@ -30,12 +30,15 @@ struct block_drvr {
 #define PART_TYPE_ISO		0x03
 #define PART_TYPE_AMIGA		0x04
 #define PART_TYPE_EFI		0x05
+#define PART_TYPE_AML		0x06
 
 /* maximum number of partition entries supported by search */
 #define DOS_ENTRY_NUMBERS	8
 #define ISO_ENTRY_NUMBERS	64
 #define MAC_ENTRY_NUMBERS	64
 #define AMIGA_ENTRY_NUMBERS	8
+#define AML_ENTRY_NUMBERS	128
+
 /*
  * Type string for U-Boot bootable partitions
  */
-- 
2.43.2

