diff --git a/target/linux/mediatek/patches-6.6/341-mtd-spinand-winbond-Support-for-W25MxxGV-W25NxxKV-se.patch b/target/linux/mediatek/patches-6.6/341-mtd-spinand-winbond-Support-for-W25MxxGV-W25NxxKV-se.patch new file mode 100644 index 0000000000..197c9af2b6 --- /dev/null +++ b/target/linux/mediatek/patches-6.6/341-mtd-spinand-winbond-Support-for-W25MxxGV-W25NxxKV-se.patch @@ -0,0 +1,161 @@ +From 9471c6ebf176284108115f60e22a176e70b97c0b Mon Sep 17 00:00:00 2001 +From: Chen Minqiang +Date: Thu, 12 Oct 2023 06:51:40 +0800 +Subject: [PATCH] mtd: spinand: winbond: Support for W25MxxGV W25NxxKV series + +--- + drivers/mtd/nand/spi/winbond.c | 115 +++++++++++++++++++++++++++++++++ + 1 file changed, 115 insertions(+) + +--- a/drivers/mtd/nand/spi/winbond.c ++++ b/drivers/mtd/nand/spi/winbond.c +@@ -15,6 +15,23 @@ + + #define WINBOND_CFG_BUF_READ BIT(3) + ++#define W25N02_N04KV_STATUS_ECC_MASK (3 << 4) ++#define W25N02_N04KV_STATUS_ECC_NO_BITFLIPS (0 << 4) ++#define W25N02_N04KV_STATUS_ECC_1_4_BITFLIPS (1 << 4) ++#define W25N02_N04KV_STATUS_ECC_5_8_BITFLIPS (3 << 4) ++#define W25N02_N04KV_STATUS_ECC_UNCOR_ERROR (2 << 4) ++ ++#define W25N01_M02GV_STATUS_ECC_MASK (3 << 4) ++#define W25N01_M02GV_STATUS_ECC_NO_BITFLIPS (0 << 4) ++#define W25N01_M02GV_STATUS_ECC_1_BITFLIPS (1 << 4) ++#define W25N01_M02GV_STATUS_ECC_UNCOR_ERROR (2 << 4) ++ ++#define W25N01KV_STATUS_ECC_MASK (3 << 4) ++#define W25N01KV_STATUS_ECC_NO_BITFLIPS (0 << 4) ++#define W25N01KV_STATUS_ECC_1_3_BITFLIPS (1 << 4) ++#define W25N01KV_STATUS_ECC_4_BITFLIPS (3 << 4) ++#define W25N01KV_STATUS_ECC_UNCOR_ERROR (2 << 4) ++ + static SPINAND_OP_VARIANTS(read_cache_variants, + SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 2, NULL, 0), + SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0), +@@ -31,6 +48,29 @@ static SPINAND_OP_VARIANTS(update_cache_ + SPINAND_PROG_LOAD_X4(false, 0, NULL, 0), + SPINAND_PROG_LOAD(false, 0, NULL, 0)); + ++static int w25n02kv_n04kv_ooblayout_ecc(struct mtd_info *mtd, int section, ++ struct mtd_oob_region *region) ++{ ++ return -ERANGE; ++} ++ ++static int w25n02kv_n04kv_ooblayout_free(struct mtd_info *mtd, int section, ++ struct mtd_oob_region *region) ++{ ++ if (section > 3) ++ return -ERANGE; ++ ++ region->offset = (16 * section) + 2; ++ region->length = 14; ++ ++ return 0; ++} ++ ++static const struct mtd_ooblayout_ops w25n02kv_n04kv_ooblayout = { ++ .ecc = w25n02kv_n04kv_ooblayout_ecc, ++ .free = w25n02kv_n04kv_ooblayout_free, ++}; ++ + static int w25m02gv_ooblayout_ecc(struct mtd_info *mtd, int section, + struct mtd_oob_region *region) + { +@@ -140,6 +180,58 @@ static int w25n02kv_ecc_get_status(struc + return -EINVAL; + } + ++static int w25n01kv_ecc_get_status(struct spinand_device *spinand, ++ u8 status) ++{ ++ switch (status & W25N01KV_STATUS_ECC_MASK) { ++ case W25N01KV_STATUS_ECC_NO_BITFLIPS: ++ return 0; ++ ++ case W25N01KV_STATUS_ECC_1_3_BITFLIPS: ++ return 3; ++ ++ case W25N01KV_STATUS_ECC_4_BITFLIPS: ++ return 4; ++ ++ case W25N01KV_STATUS_ECC_UNCOR_ERROR: ++ return -EBADMSG; ++ ++ default: ++ break; ++ } ++ ++ return -EINVAL; ++} ++ ++static int w25n02kv_n04kv_ecc_get_status(struct spinand_device *spinand, ++ u8 status) ++{ ++ switch (status & W25N02_N04KV_STATUS_ECC_MASK) { ++ case W25N02_N04KV_STATUS_ECC_NO_BITFLIPS: ++ return 0; ++ ++ case W25N02_N04KV_STATUS_ECC_1_4_BITFLIPS: ++ return 3; ++ ++ case W25N02_N04KV_STATUS_ECC_5_8_BITFLIPS: ++ return 4; ++ ++ /* W25N02_N04KV_use internal 8bit ECC algorithm. ++ * But the ECC strength is 4 bit requried. ++ * Return 3 if the bit bit flip count less than 5. ++ * Return 4 if the bit bit flip count more than 5 to 8. ++ */ ++ ++ case W25N02_N04KV_STATUS_ECC_UNCOR_ERROR: ++ return -EBADMSG; ++ ++ default: ++ break; ++ } ++ ++ return -EINVAL; ++} ++ + static const struct spinand_info winbond_spinand_table[] = { + SPINAND_INFO("W25M02GV", + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xab, 0x21), +@@ -151,6 +243,16 @@ static const struct spinand_info winbond + 0, + SPINAND_ECCINFO(&w25m02gv_ooblayout, NULL), + SPINAND_SELECT_TARGET(w25m02gv_select_target)), ++ SPINAND_INFO("W25N01KV", ++ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xae, 0x21), ++ NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1), ++ NAND_ECCREQ(4, 512), ++ SPINAND_INFO_OP_VARIANTS(&read_cache_variants, ++ &write_cache_variants, ++ &update_cache_variants), ++ 0, ++ SPINAND_ECCINFO(&w25n02kv_n04kv_ooblayout, ++ w25n01kv_ecc_get_status)), + SPINAND_INFO("W25N01GV", + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xaa, 0x21), + NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1), +@@ -169,6 +271,19 @@ static const struct spinand_info winbond + &update_cache_variants), + 0, + SPINAND_ECCINFO(&w25n02kv_ooblayout, w25n02kv_ecc_get_status)), ++ /* W25N04KV has 2-die(lun), however, it can select die automatically. ++ * Treat it as single die here and double block size. ++ */ ++ SPINAND_INFO("W25N04KV", ++ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xaa, 0x23), ++ NAND_MEMORG(1, 2048, 128, 64, 4096, 40, 2, 1, 1), ++ NAND_ECCREQ(8, 512), ++ SPINAND_INFO_OP_VARIANTS(&read_cache_variants, ++ &write_cache_variants, ++ &update_cache_variants), ++ 0, ++ SPINAND_ECCINFO(&w25n02kv_n04kv_ooblayout, ++ w25n02kv_n04kv_ecc_get_status)), + }; + + static int winbond_spinand_init(struct spinand_device *spinand) diff --git a/target/linux/mediatek/patches-6.6/790-net-phy-realtek-add-led-link-select-for-RTL8221.patch b/target/linux/mediatek/patches-6.6/790-net-phy-realtek-add-led-link-select-for-RTL8221.patch new file mode 100644 index 0000000000..e1e84a2e2c --- /dev/null +++ b/target/linux/mediatek/patches-6.6/790-net-phy-realtek-add-led-link-select-for-RTL8221.patch @@ -0,0 +1,69 @@ +From f9e17c264d316611c26b98ad1a3ca01c289c67b4 Mon Sep 17 00:00:00 2001 +From: Yangyu Chen +Date: Sun, 23 Apr 2023 20:06:41 +0800 +Subject: [PATCH] net: phy: realtek: add led-link-select for RTL8221 + +RTL8221B PHYs will select the different speeds for 3 LEDs to 10M/100M/1G +respectively by default. Some devices like TP-LINK XDR-6088/XDR-6086 +have only one LED connects to the PHY chip LED0. If we didn't change the +default settings, the LED will only blink at 10M speed. + +This patch allows configuring LED link select bitmask from DT. And it +has been tested with TP-Link XDR6088 with different DT configurations. + +Signed-off-by: Yangyu Chen +--- + drivers/net/phy/realtek.c | 28 +++++++++++++++++++++++++++- + 1 file changed, 27 insertions(+), 1 deletion(-) + +--- a/drivers/net/phy/realtek.c ++++ b/drivers/net/phy/realtek.c +@@ -67,6 +67,10 @@ + #define RTL8221B_PHYCR1_ALDPS_EN BIT(2) + #define RTL8221B_PHYCR1_ALDPS_XTAL_OFF_EN BIT(12) + ++#define RTL8221B_NR_LEDS 3 ++#define RTL8221B_LED_LINK_SELECT 0xd032 ++#define RTL8221B_LED_LINK_SELECT_OFFSET 0x2 ++ + #define RTL8366RB_POWER_SAVE 0x15 + #define RTL8366RB_POWER_SAVE_ON BIT(12) + +@@ -976,6 +980,28 @@ static irqreturn_t rtl9000a_handle_inter + return IRQ_HANDLED; + } + ++static int rtl8221b_config_led(struct phy_device *phydev) { ++ struct device *node = &phydev->mdio.dev; ++ u32 link_select[RTL8221B_NR_LEDS]; ++ int i, val; ++ ++ val = device_property_read_u32_array(node, "realtek,led-link-select", ++ link_select, RTL8221B_NR_LEDS); ++ ++ if (val) ++ return 0; ++ ++ for (i = 0; i < RTL8221B_NR_LEDS; i++) { ++ val = phy_write_mmd(phydev, RTL8221B_MMD_PHY_CTRL, ++ RTL8221B_LED_LINK_SELECT + i * RTL8221B_LED_LINK_SELECT_OFFSET, ++ link_select[i]); ++ if (val < 0) ++ return val; ++ } ++ ++ return 0; ++} ++ + static int rtl8221b_config_init(struct phy_device *phydev) + { + u16 option_mode; +@@ -1023,7 +1049,7 @@ static int rtl8221b_config_init(struct p + phy_read_mmd_poll_timeout(phydev, RTL8221B_MMD_SERDES_CTRL, 0x7587, + val, !(val & BIT(0)), 500, 100000, false); + +- return 0; ++ return rtl8221b_config_led(phydev); + } + + static int rtl8221b_ack_interrupt(struct phy_device *phydev)