From d6957948ef99f0d6c28bce715013557f433f07e2 Mon Sep 17 00:00:00 2001 From: Luo Chongjun Date: Thu, 19 Jan 2023 10:37:12 +0800 Subject: [PATCH] support MT2500 target --- .../boot/dts/mediatek/mt7981-gl-mt2500.dts | 184 +++++++++++++++++ target/linux/mediatek/mt7981/config-5.4 | 7 +- .../9999-block2mtd-support-partline.patch | 139 +++++++++++++ .../9999-support-partition-split.patch | 186 ++++++++++++++++++ 4 files changed, 514 insertions(+), 2 deletions(-) create mode 100755 target/linux/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7981-gl-mt2500.dts create mode 100644 target/linux/mediatek/patches-5.4/9999-block2mtd-support-partline.patch create mode 100644 target/linux/mediatek/patches-5.4/9999-support-partition-split.patch diff --git a/target/linux/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7981-gl-mt2500.dts b/target/linux/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7981-gl-mt2500.dts new file mode 100755 index 0000000000..2b673e74cc --- /dev/null +++ b/target/linux/mediatek/files-5.4/arch/arm64/boot/dts/mediatek/mt7981-gl-mt2500.dts @@ -0,0 +1,184 @@ +/dts-v1/; +#include "mt7981.dtsi" +/ { + model = "GL.iNet GL-MT2500"; + compatible = "glinet,mt2500-emmc", "mediatek,mt7981"; + + chosen { + bootargs = "console=ttyS0,115200n1 loglevel=8 \ + earlycon=uart8250,mmio32,0x11002000 \ + root=PARTLABEL=rootfs rootwait rootfstype=squashfs,f2fs \ + block2mtd.block2mtd=/dev/mmcblk0p1,65536,log"; + }; + + 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; + }; + + gl-hw { + compatible = "gl-hw-info"; + model = "mt2500"; + wan = "eth0"; + lan = "eth1"; + usb-port = "1-1"; + flash_size = <8192>; + temperature = "/sys/devices/virtual/thermal/thermal_zone0/temp"; + factory_data { + device_mac = "/dev/mmcblk0boot1", "0x0a"; + device_ddns = "/dev/mmcblk0boot1", "0x10"; + device_sn_bak = "/dev/mmcblk0boot1", "0x20"; + device_sn = "/dev/mmcblk0boot1", "0x30"; + country_code = "/dev/mmcblk0boot1", "0x88"; + }; + }; + + gpio-keys { + compatible = "gpio-keys"; + + reset { + label = "reset"; + linux,code = ; + gpios = <&pio 1 GPIO_ACTIVE_LOW>; + }; + }; + + gpio-export { + compatible = "gpio-export"; + + usb_power { + gpio-export,name = "usb_power"; + gpio-export,output = <1>; + gpios = <&pio 12 GPIO_ACTIVE_HIGH>; + }; + }; + + leds { + compatible = "gpio-leds"; + + led@0 { + label = "vpn"; + gpios = <&pio 31 GPIO_ACTIVE_LOW>; + }; + + led@1 { + label = "white:system"; + gpios = <&pio 30 GPIO_ACTIVE_LOW>; + }; + + led@2 { + label = "blue:system"; + gpios = <&pio 29 GPIO_ACTIVE_LOW>; + default-state = "on"; + }; + }; +}; + +&uart0 { + status = "okay"; +}; + +&watchdog { + status = "okay"; +}; + +&mmc0 { + pinctrl-names = "default", "state_uhs"; + pinctrl-0 = <&mmc0_pins_default>; + pinctrl-1 = <&mmc0_pins_uhs>; + bus-width = <8>; + max-frequency = <52000000>; + cap-mmc-highspeed; + vmmc-supply = <®_3p3v>; + non-removable; + status = "okay"; +}; + +ð { + status = "okay"; + + gmac0: mac@0 { + compatible = "mediatek,eth-mac"; + reg = <0>; + phy-mode = "2500base-x"; + fixed-link { + speed = <2500>; + full-duplex; + pause; + }; + }; + + gmac1: mac@1 { + compatible = "mediatek,eth-mac"; + reg = <1>; + phy-mode = "gmii"; + phy-handle = <&phy0>; + }; + + mdio: mdio-bus { + #address-cells = <1>; + #size-cells = <0>; + + phy0: ethernet-phy@0 { + compatible = "ethernet-phy-id03a2.9461"; + reg = <0>; + phy-mode = "gmii"; + nvmem-cells = <&phy_calibration>; + nvmem-cell-names = "phy-cal-data"; + }; + + phy5: phy@5 { + compatible = "ethernet-phy-id67c9.de0a"; + reg = <5>; + reset-gpios = <&pio 14 1>; + reset-assert-us = <600>; + reset-deassert-us = <20000>; + }; + }; +}; + +&hnat { + mtketh-wan = "eth0"; + mtketh-lan = "eth1"; + mtketh-ppd = "eth1"; + mtketh-max-gmac = <2>; + status = "okay"; +}; + +&spi1 { + pinctrl-names = "default"; + pinctrl-0 = <&spic_pins>; + status = "disabled"; +}; + +&pio { + spic_pins: spi1-pins { + mux { + function = "spi"; + groups = "spi1_1"; + }; + }; + mmc0_pins_default: mmc0-pins-default { + mux { + function = "flash"; + groups = "emmc_45"; + }; + }; + mmc0_pins_uhs: mmc0-pins-uhs { + mux { + function = "flash"; + groups = "emmc_45"; + }; + }; +}; + +&xhci { + mediatek,u3p-dis-msk = <0x0>; + phys = <&u2port0 PHY_TYPE_USB2>, + <&u3port0 PHY_TYPE_USB3>; + status = "okay"; +}; diff --git a/target/linux/mediatek/mt7981/config-5.4 b/target/linux/mediatek/mt7981/config-5.4 index 219c62fca8..d79d4ff221 100644 --- a/target/linux/mediatek/mt7981/config-5.4 +++ b/target/linux/mediatek/mt7981/config-5.4 @@ -264,6 +264,8 @@ CONFIG_MMC_MTK=y CONFIG_MODULES_TREE_LOOKUP=y CONFIG_MODULES_USE_ELF_RELA=y CONFIG_MT753X_GSW=y +CONFIG_MTD_BLOCK2MTD=y +CONFIG_MTD_CMDLINE_PARTS=y CONFIG_MTD_NAND_CORE=y CONFIG_MTD_NAND_ECC_SW_HAMMING=y CONFIG_MTD_NAND_MTK=y @@ -325,6 +327,7 @@ CONFIG_OF_NET=y CONFIG_OLD_SIGSUSPEND3=y CONFIG_PADATA=y CONFIG_PARTITION_PERCPU=y +CONFIG_PARTITION_SPLIT=y CONFIG_PCI=y # CONFIG_PCIE_MEDIATEK is not set CONFIG_PCIE_MEDIATEK_GEN3=y @@ -467,7 +470,7 @@ CONFIG_XPS=y CONFIG_ZLIB_DEFLATE=y CONFIG_ZLIB_INFLATE=y CONFIG_ZONE_DMA32=y -CONFIG_NVMEM=y -CONFIG_MTK_EFUSE=y # CONFIG_MTD_SPI_NAND_W25N01KV is not set # CONFIG_MAXLINEAR_GPHY is not set +# CONFIG_SHORTCUT_FE is not set +# CONFIG_NF_CONNTRACK_CHAIN_EVENTS is not set diff --git a/target/linux/mediatek/patches-5.4/9999-block2mtd-support-partline.patch b/target/linux/mediatek/patches-5.4/9999-block2mtd-support-partline.patch new file mode 100644 index 0000000000..2e4c2555da --- /dev/null +++ b/target/linux/mediatek/patches-5.4/9999-block2mtd-support-partline.patch @@ -0,0 +1,139 @@ +Index: linux-5.4.188/drivers/mtd/devices/block2mtd.c +=================================================================== +--- linux-5.4.188.orig/drivers/mtd/devices/block2mtd.c ++++ linux-5.4.188/drivers/mtd/devices/block2mtd.c +@@ -26,11 +26,14 @@ + #include + #include + #include ++#include + #include + #include + #include + #include + ++static const char * const block2mtd_probe_types[] = { "ofpart","cmdlinepart", NULL }; ++ + /* Info for the block device */ + struct block2mtd_dev { + struct list_head list; +@@ -183,10 +186,9 @@ static int block2mtd_write(struct mtd_in + mutex_unlock(&dev->write_mutex); + if (err > 0) + err = 0; ++ sync_blockdev(dev->blkdev); + return err; + } +- +- + /* sync the device - wait until the write queue is empty */ + static void block2mtd_sync(struct mtd_info *mtd) + { +@@ -214,12 +216,13 @@ static void block2mtd_free_device(struct + + + static struct block2mtd_dev *add_device(char *devname, int erase_size, +- int timeout) ++ const char *mtdname, int timeout) + { + #ifndef MODULE + int i; + #endif + const fmode_t mode = FMODE_READ | FMODE_WRITE | FMODE_EXCL; ++ struct mtd_part_parser_data ppdata; + struct block_device *bdev; + struct block2mtd_dev *dev; + char *name; +@@ -278,10 +281,13 @@ static struct block2mtd_dev *add_device( + + /* Setup the MTD structure */ + /* make the name contain the block device in */ +- name = kasprintf(GFP_KERNEL, "block2mtd: %s", devname); ++ if (!mtdname) ++ mtdname = devname; ++ name = kmalloc(strlen(mtdname) + 1, GFP_KERNEL); + if (!name) + goto err_destroy_mutex; + ++ strcpy(name, mtdname); + dev->mtd.name = name; + + dev->mtd.size = dev->blkdev->bd_inode->i_size & PAGE_MASK; +@@ -292,12 +298,14 @@ static struct block2mtd_dev *add_device( + dev->mtd.flags = MTD_CAP_RAM; + dev->mtd._erase = block2mtd_erase; + dev->mtd._write = block2mtd_write; ++ dev->mtd._panic_write = block2mtd_write; + dev->mtd._sync = block2mtd_sync; + dev->mtd._read = block2mtd_read; + dev->mtd.priv = dev; + dev->mtd.owner = THIS_MODULE; + +- if (mtd_device_register(&dev->mtd, NULL, 0)) { ++ memset(&ppdata, '\0', sizeof(ppdata)); ++ if (mtd_device_parse_register(&dev->mtd, block2mtd_probe_types, &ppdata, NULL, 0)) { + /* Device didn't get added, so free the entry */ + goto err_destroy_mutex; + } +@@ -305,7 +313,7 @@ static struct block2mtd_dev *add_device( + list_add(&dev->list, &blkmtd_device_list); + pr_info("mtd%d: [%s] erase_size = %dKiB [%d]\n", + dev->mtd.index, +- dev->mtd.name + strlen("block2mtd: "), ++ dev->mtd.name, + dev->mtd.erasesize >> 10, dev->mtd.erasesize); + return dev; + +@@ -381,7 +389,7 @@ static int block2mtd_setup2(const char * + /* 80 for device, 12 for erase size, 80 for name, 8 for timeout */ + char buf[80 + 12 + 80 + 8]; + char *str = buf; +- char *token[2]; ++ char *token[4]; + char *name; + size_t erase_size = PAGE_SIZE; + unsigned long timeout = MTD_DEFAULT_TIMEOUT; +@@ -395,7 +403,7 @@ static int block2mtd_setup2(const char * + strcpy(str, val); + kill_final_newline(str); + +- for (i = 0; i < 2; i++) ++ for (i = 0; i < 4; i++) + token[i] = strsep(&str, ","); + + if (str) { +@@ -421,8 +429,13 @@ static int block2mtd_setup2(const char * + return 0; + } + } ++ if (token[2] && (strlen(token[2]) + 1 > 80)) ++ pr_err("mtd device name too long\n"); ++ ++ if (token[3] && kstrtoul(token[3], 0, &timeout)) ++ pr_err("invalid timeout\n"); + +- add_device(name, erase_size, timeout); ++ add_device(name, erase_size, token[2], timeout); + + return 0; + } +@@ -454,9 +467,8 @@ static int block2mtd_setup(const char *v + #endif + } + +- + module_param_call(block2mtd, block2mtd_setup, NULL, NULL, 0200); +-MODULE_PARM_DESC(block2mtd, "Device to use. \"block2mtd=[,]\""); ++MODULE_PARM_DESC(block2mtd, "Device to use. \"block2mtd=[,[,[,]]]\""); + + static int __init block2mtd_init(void) + { +@@ -484,7 +496,7 @@ static void block2mtd_exit(void) + mutex_destroy(&dev->write_mutex); + pr_info("mtd%d: [%s] removed\n", + dev->mtd.index, +- dev->mtd.name + strlen("block2mtd: ")); ++ dev->mtd.name); + list_del(&dev->list); + block2mtd_free_device(dev); + } diff --git a/target/linux/mediatek/patches-5.4/9999-support-partition-split.patch b/target/linux/mediatek/patches-5.4/9999-support-partition-split.patch new file mode 100644 index 0000000000..8e0026c216 --- /dev/null +++ b/target/linux/mediatek/patches-5.4/9999-support-partition-split.patch @@ -0,0 +1,186 @@ +Index: linux-5.4.188/block/Kconfig +=================================================================== +--- linux-5.4.188.orig/block/Kconfig ++++ linux-5.4.188/block/Kconfig +@@ -105,6 +105,9 @@ config BLK_DEV_THROTTLING_LOW + + Note, this is an experimental interface and could be changed someday. + ++config PARTITION_SPLIT ++ bool "Openwrt Block device partition rootfs split" ++ + config BLK_CMDLINE_PARSER + bool "Block device command line partition parser" + ---help--- +Index: linux-5.4.188/block/Makefile +=================================================================== +--- linux-5.4.188.orig/block/Makefile ++++ linux-5.4.188/block/Makefile +@@ -36,3 +36,4 @@ obj-$(CONFIG_BLK_DEBUG_FS) += blk-mq-deb + obj-$(CONFIG_BLK_DEBUG_FS_ZONED)+= blk-mq-debugfs-zoned.o + obj-$(CONFIG_BLK_SED_OPAL) += sed-opal.o + obj-$(CONFIG_BLK_PM) += blk-pm.o ++obj-$(CONFIG_PARTITION_SPLIT) += partition-split.o +Index: linux-5.4.188/block/partition-generic.c +=================================================================== +--- linux-5.4.188.orig/block/partition-generic.c ++++ linux-5.4.188/block/partition-generic.c +@@ -21,6 +21,10 @@ + + #include "partitions/check.h" + ++#ifdef CONFIG_PARTITION_SPLIT ++#include "partition-split.h" ++#endif ++ + #ifdef CONFIG_BLK_DEV_MD + extern void md_autodetect_dev(dev_t dev); + #endif +@@ -569,6 +573,9 @@ rescan: + highest = p; + + disk_expand_part_tbl(disk, highest); ++#ifdef CONFIG_PARTITION_SPLIT ++ partition_split(bdev, state); ++#endif + + /* add partitions */ + for (p = 1; p < state->limit; p++) { +Index: linux-5.4.188/block/partition-split.c +=================================================================== +--- /dev/null ++++ linux-5.4.188/block/partition-split.c +@@ -0,0 +1,111 @@ ++#include ++#include ++#include ++#include "partitions/check.h" ++#include "partition-split.h" ++ ++void print_sblock_value(char *buf) ++{ ++ int i, j; ++ for (i = 0; i < sizeof(struct squashfs_sblock);) { ++ for (j = 0; j < 16; j++) { ++ printk("%02x ", buf[i]); ++ i++; ++ } ++ printk("\n"); ++ } ++} ++ ++unsigned char *fs_read_super_block(struct block_device *bdev, sector_t from, Sector *sector) ++{ ++ if (from >= get_capacity(bdev->bd_disk)) { ++ return NULL; ++ } ++ return read_dev_sector(bdev, from, sector); ++} ++ ++ ++int get_squashfs_len(struct block_device *bdev, sector_t from, size_t *squashfs_len) ++{ ++ struct squashfs_sblock sb; ++ unsigned char *buf; ++ Sector sector; ++ size_t retlen; ++ ++ buf = fs_read_super_block(bdev, from, §or); ++ if (!buf) { ++ printk("failed to get super\n"); ++ return -EIO; ++ } ++ memcpy((void *)&sb, buf, sizeof(sb)); ++ put_dev_sector(sector); ++ ++ if (le32_to_cpu(sb.s_magic) != SQUASHFS_MAGIC) { ++ printk("no squashfs found in\n"); ++ //print_sblock_value((char *)&sb); ++ return -EINVAL; ++ } ++ ++ retlen = le64_to_cpu(sb.bytes_used); ++ if (retlen <= 0) { ++ printk("squashfs is empty in \n"); ++ return -ENODEV; ++ } ++ ++ *squashfs_len = retlen; ++ return 0; ++} ++ ++static int find_part_by_lable(struct parsed_partitions *state, const char *lable) ++{ ++ int p; ++ /* add partitions */ ++ for (p = 1; p < state->limit; p++) { ++ if (!strcmp(state->parts[p].info.volname, lable)) ++ return p; ++ } ++ return 0; ++} ++ ++int partition_split(struct block_device *bdev, struct parsed_partitions *state) ++{ ++ int p, insert; ++ size_t sqfs_size; ++ sector_t new_size, new_from; ++ struct partition_meta_info *info; ++ char tmp[sizeof(info->volname) + 4]; ++ ++ p = find_part_by_lable(state, ROOTFS_PART); ++ if (p == 0) ++ return 0; ++ if (get_squashfs_len(bdev, state->parts[p].from, &sqfs_size)) ++ return 0; ++ ++ sqfs_size = (sqfs_size + (ALING_SQFS - 1)) & ~(ALING_SQFS - 1); //squashfs 64k对齐 ++ ++ //计算新分区大小和起始位置 ++ ++ new_size = state->parts[p].size - (sqfs_size >> 9); ++ new_from = state->parts[p].from + (sqfs_size >> 9); ++ ++ for (insert = 1; insert < state->limit; insert++) { ++ if (!state->parts[insert].size) ++ break; ++ } ++ ++ if (insert >= state->limit) ++ return 0; ++ ++ //追加一个新分区并设置相关信息 ++ put_partition(state, insert, new_from, new_size); ++ ++ info = &state->parts[insert].info; ++ ++ strncpy(info->volname, ROOTFS_PART_DATA, strlen(ROOTFS_PART_DATA) + 1); ++ snprintf(tmp, sizeof(tmp), "(%s)", info->volname); ++ strlcat(state->pp_buf, tmp, PAGE_SIZE); ++ ++ state->parts[insert].has_info = true; ++ return 0; ++ ++} +Index: linux-5.4.188/block/partition-split.h +=================================================================== +--- /dev/null ++++ linux-5.4.188/block/partition-split.h +@@ -0,0 +1,17 @@ ++#ifndef __PARTITION_SPLIT_H ++#define __PARTITION_SPLIT_H ++ ++#define ROOTFS_PART "rootfs" ++#define ROOTFS_PART_DATA "rootfs_data" ++ ++#define ALING_SQFS 0X10000 ++ ++struct squashfs_sblock { ++ __le32 s_magic; ++ __le32 pad0[9]; ++ __le64 bytes_used; ++}; ++ ++extern int partition_split(struct block_device *bdev, struct parsed_partitions *state); ++ ++#endif -- 2.25.1