Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: ISC
0002 /* Copyright (C) 2022 MediaTek Inc. */
0003 
0004 #include <linux/kernel.h>
0005 #include <linux/module.h>
0006 #include <linux/platform_device.h>
0007 #include <linux/pinctrl/consumer.h>
0008 #include <linux/of.h>
0009 #include <linux/of_device.h>
0010 #include <linux/of_reserved_mem.h>
0011 #include <linux/of_gpio.h>
0012 #include <linux/iopoll.h>
0013 #include <linux/reset.h>
0014 #include <linux/of_net.h>
0015 #include <linux/clk.h>
0016 
0017 #include "mt7915.h"
0018 
0019 /* INFRACFG */
0020 #define MT_INFRACFG_CONN2AP_SLPPROT 0x0d0
0021 #define MT_INFRACFG_AP2CONN_SLPPROT 0x0d4
0022 
0023 #define MT_INFRACFG_RX_EN_MASK      BIT(16)
0024 #define MT_INFRACFG_TX_RDY_MASK     BIT(4)
0025 #define MT_INFRACFG_TX_EN_MASK      BIT(0)
0026 
0027 /* TOP POS */
0028 #define MT_TOP_POS_FAST_CTRL        0x114
0029 #define MT_TOP_POS_FAST_EN_MASK     BIT(3)
0030 
0031 #define MT_TOP_POS_SKU          0x21c
0032 #define MT_TOP_POS_SKU_MASK     GENMASK(31, 28)
0033 #define MT_TOP_POS_SKU_ADIE_DBDC_MASK   BIT(2)
0034 
0035 enum {
0036     ADIE_SB,
0037     ADIE_DBDC
0038 };
0039 
0040 static int
0041 mt76_wmac_spi_read(struct mt7915_dev *dev, u8 adie, u32 addr, u32 *val)
0042 {
0043     int ret;
0044     u32 cur;
0045 
0046     ret = read_poll_timeout(mt76_rr, cur, !(cur & MT_TOP_SPI_POLLING_BIT),
0047                 USEC_PER_MSEC, 50 * USEC_PER_MSEC, false,
0048                 dev, MT_TOP_SPI_BUSY_CR(adie));
0049     if (ret)
0050         return ret;
0051 
0052     mt76_wr(dev, MT_TOP_SPI_ADDR_CR(adie),
0053         MT_TOP_SPI_READ_ADDR_FORMAT | addr);
0054     mt76_wr(dev, MT_TOP_SPI_WRITE_DATA_CR(adie), 0);
0055 
0056     ret = read_poll_timeout(mt76_rr, cur, !(cur & MT_TOP_SPI_POLLING_BIT),
0057                 USEC_PER_MSEC, 50 * USEC_PER_MSEC, false,
0058                 dev, MT_TOP_SPI_BUSY_CR(adie));
0059     if (ret)
0060         return ret;
0061 
0062     *val = mt76_rr(dev, MT_TOP_SPI_READ_DATA_CR(adie));
0063 
0064     return 0;
0065 }
0066 
0067 static int
0068 mt76_wmac_spi_write(struct mt7915_dev *dev, u8 adie, u32 addr, u32 val)
0069 {
0070     int ret;
0071     u32 cur;
0072 
0073     ret = read_poll_timeout(mt76_rr, cur, !(cur & MT_TOP_SPI_POLLING_BIT),
0074                 USEC_PER_MSEC, 50 * USEC_PER_MSEC, false,
0075                 dev, MT_TOP_SPI_BUSY_CR(adie));
0076     if (ret)
0077         return ret;
0078 
0079     mt76_wr(dev, MT_TOP_SPI_ADDR_CR(adie),
0080         MT_TOP_SPI_WRITE_ADDR_FORMAT | addr);
0081     mt76_wr(dev, MT_TOP_SPI_WRITE_DATA_CR(adie), val);
0082 
0083     return read_poll_timeout(mt76_rr, cur, !(cur & MT_TOP_SPI_POLLING_BIT),
0084                  USEC_PER_MSEC, 50 * USEC_PER_MSEC, false,
0085                  dev, MT_TOP_SPI_BUSY_CR(adie));
0086 }
0087 
0088 static int
0089 mt76_wmac_spi_rmw(struct mt7915_dev *dev, u8 adie,
0090           u32 addr, u32 mask, u32 val)
0091 {
0092     u32 cur, ret;
0093 
0094     ret = mt76_wmac_spi_read(dev, adie, addr, &cur);
0095     if (ret)
0096         return ret;
0097 
0098     cur &= ~mask;
0099     cur |= val;
0100 
0101     return mt76_wmac_spi_write(dev, adie, addr, cur);
0102 }
0103 
0104 static int
0105 mt7986_wmac_adie_efuse_read(struct mt7915_dev *dev, u8 adie,
0106                 u32 addr, u32 *data)
0107 {
0108     int ret, temp;
0109     u32 val, mask;
0110 
0111     ret = mt76_wmac_spi_write(dev, adie, MT_ADIE_EFUSE_CFG,
0112                   MT_ADIE_EFUSE_CTRL_MASK);
0113     if (ret)
0114         return ret;
0115 
0116     ret = mt76_wmac_spi_rmw(dev, adie, MT_ADIE_EFUSE2_CTRL, BIT(30), 0x0);
0117     if (ret)
0118         return ret;
0119 
0120     mask = (MT_ADIE_EFUSE_MODE_MASK | MT_ADIE_EFUSE_ADDR_MASK |
0121         MT_ADIE_EFUSE_KICK_MASK);
0122     val = FIELD_PREP(MT_ADIE_EFUSE_MODE_MASK, 0) |
0123           FIELD_PREP(MT_ADIE_EFUSE_ADDR_MASK, addr) |
0124           FIELD_PREP(MT_ADIE_EFUSE_KICK_MASK, 1);
0125     ret = mt76_wmac_spi_rmw(dev, adie, MT_ADIE_EFUSE2_CTRL, mask, val);
0126     if (ret)
0127         return ret;
0128 
0129     ret = read_poll_timeout(mt76_wmac_spi_read, temp,
0130                 !temp && !FIELD_GET(MT_ADIE_EFUSE_KICK_MASK, val),
0131                 USEC_PER_MSEC, 50 * USEC_PER_MSEC, false,
0132                 dev, adie, MT_ADIE_EFUSE2_CTRL, &val);
0133     if (ret)
0134         return ret;
0135 
0136     ret = mt76_wmac_spi_read(dev, adie, MT_ADIE_EFUSE2_CTRL, &val);
0137     if (ret)
0138         return ret;
0139 
0140     if (FIELD_GET(MT_ADIE_EFUSE_VALID_MASK, val) == 1)
0141         ret = mt76_wmac_spi_read(dev, adie, MT_ADIE_EFUSE_RDATA0,
0142                      data);
0143 
0144     return ret;
0145 }
0146 
0147 static inline void mt76_wmac_spi_lock(struct mt7915_dev *dev)
0148 {
0149     u32 cur;
0150 
0151     read_poll_timeout(mt76_rr, cur,
0152               FIELD_GET(MT_SEMA_RFSPI_STATUS_MASK, cur),
0153               1000, 1000 * MSEC_PER_SEC, false, dev,
0154               MT_SEMA_RFSPI_STATUS);
0155 }
0156 
0157 static inline void mt76_wmac_spi_unlock(struct mt7915_dev *dev)
0158 {
0159     mt76_wr(dev, MT_SEMA_RFSPI_RELEASE, 1);
0160 }
0161 
0162 static u32 mt76_wmac_rmw(void __iomem *base, u32 offset, u32 mask, u32 val)
0163 {
0164     val |= readl(base + offset) & ~mask;
0165     writel(val, base + offset);
0166 
0167     return val;
0168 }
0169 
0170 static u8 mt7986_wmac_check_adie_type(struct mt7915_dev *dev)
0171 {
0172     u32 val;
0173 
0174     val = readl(dev->sku + MT_TOP_POS_SKU);
0175 
0176     return FIELD_GET(MT_TOP_POS_SKU_ADIE_DBDC_MASK, val);
0177 }
0178 
0179 static int mt7986_wmac_consys_reset(struct mt7915_dev *dev, bool enable)
0180 {
0181     if (!enable)
0182         return reset_control_assert(dev->rstc);
0183 
0184     mt76_wmac_rmw(dev->sku, MT_TOP_POS_FAST_CTRL,
0185               MT_TOP_POS_FAST_EN_MASK,
0186               FIELD_PREP(MT_TOP_POS_FAST_EN_MASK, 0x1));
0187 
0188     return reset_control_deassert(dev->rstc);
0189 }
0190 
0191 static int mt7986_wmac_gpio_setup(struct mt7915_dev *dev)
0192 {
0193     struct pinctrl_state *state;
0194     struct pinctrl *pinctrl;
0195     int ret;
0196     u8 type;
0197 
0198     type = mt7986_wmac_check_adie_type(dev);
0199     pinctrl = devm_pinctrl_get(dev->mt76.dev);
0200     if (IS_ERR(pinctrl))
0201         return PTR_ERR(pinctrl);
0202 
0203     switch (type) {
0204     case ADIE_SB:
0205         state = pinctrl_lookup_state(pinctrl, "default");
0206         if (IS_ERR_OR_NULL(state))
0207             return -EINVAL;
0208         break;
0209     case ADIE_DBDC:
0210         state = pinctrl_lookup_state(pinctrl, "dbdc");
0211         if (IS_ERR_OR_NULL(state))
0212             return -EINVAL;
0213         break;
0214     default:
0215         return -EINVAL;
0216     }
0217 
0218     ret = pinctrl_select_state(pinctrl, state);
0219     if (ret)
0220         return ret;
0221 
0222     usleep_range(500, 1000);
0223 
0224     return 0;
0225 }
0226 
0227 static int mt7986_wmac_consys_lockup(struct mt7915_dev *dev, bool enable)
0228 {
0229     int ret;
0230     u32 cur;
0231 
0232     mt76_wmac_rmw(dev->dcm, MT_INFRACFG_AP2CONN_SLPPROT,
0233               MT_INFRACFG_RX_EN_MASK,
0234               FIELD_PREP(MT_INFRACFG_RX_EN_MASK, enable));
0235     ret = read_poll_timeout(readl, cur, !(cur & MT_INFRACFG_RX_EN_MASK),
0236                 USEC_PER_MSEC, 50 * USEC_PER_MSEC, false,
0237                 dev->dcm + MT_INFRACFG_AP2CONN_SLPPROT);
0238     if (ret)
0239         return ret;
0240 
0241     mt76_wmac_rmw(dev->dcm, MT_INFRACFG_AP2CONN_SLPPROT,
0242               MT_INFRACFG_TX_EN_MASK,
0243               FIELD_PREP(MT_INFRACFG_TX_EN_MASK, enable));
0244     ret = read_poll_timeout(readl, cur, !(cur & MT_INFRACFG_TX_RDY_MASK),
0245                 USEC_PER_MSEC, 50 * USEC_PER_MSEC, false,
0246                 dev->dcm + MT_INFRACFG_AP2CONN_SLPPROT);
0247     if (ret)
0248         return ret;
0249 
0250     mt76_wmac_rmw(dev->dcm, MT_INFRACFG_CONN2AP_SLPPROT,
0251               MT_INFRACFG_RX_EN_MASK,
0252               FIELD_PREP(MT_INFRACFG_RX_EN_MASK, enable));
0253     mt76_wmac_rmw(dev->dcm, MT_INFRACFG_CONN2AP_SLPPROT,
0254               MT_INFRACFG_TX_EN_MASK,
0255               FIELD_PREP(MT_INFRACFG_TX_EN_MASK, enable));
0256 
0257     return 0;
0258 }
0259 
0260 static int mt7986_wmac_coninfra_check(struct mt7915_dev *dev)
0261 {
0262     u32 cur;
0263 
0264     return read_poll_timeout(mt76_rr, cur, (cur == 0x02070000),
0265                  USEC_PER_MSEC, 50 * USEC_PER_MSEC,
0266                  false, dev, MT_CONN_INFRA_BASE);
0267 }
0268 
0269 static int mt7986_wmac_coninfra_setup(struct mt7915_dev *dev)
0270 {
0271     struct device *pdev = dev->mt76.dev;
0272     struct reserved_mem *rmem;
0273     struct device_node *np;
0274     u32 val;
0275 
0276     np = of_parse_phandle(pdev->of_node, "memory-region", 0);
0277     if (!np)
0278         return -EINVAL;
0279 
0280     rmem = of_reserved_mem_lookup(np);
0281     if (!rmem)
0282         return -EINVAL;
0283 
0284     val = (rmem->base >> 16) & MT_TOP_MCU_EMI_BASE_MASK;
0285 
0286     /* Set conninfra subsys PLL check */
0287     mt76_rmw_field(dev, MT_INFRA_CKGEN_BUS,
0288                MT_INFRA_CKGEN_BUS_RDY_SEL_MASK, 0x1);
0289     mt76_rmw_field(dev, MT_INFRA_CKGEN_BUS,
0290                MT_INFRA_CKGEN_BUS_RDY_SEL_MASK, 0x1);
0291 
0292     mt76_rmw_field(dev, MT_TOP_MCU_EMI_BASE,
0293                MT_TOP_MCU_EMI_BASE_MASK, val);
0294 
0295     mt76_wr(dev, MT_INFRA_BUS_EMI_START, rmem->base);
0296     mt76_wr(dev, MT_INFRA_BUS_EMI_END, rmem->size);
0297 
0298     mt76_rr(dev, MT_CONN_INFRA_EFUSE);
0299 
0300     /* Set conninfra sysram */
0301     mt76_wr(dev, MT_TOP_RGU_SYSRAM_PDN, 0);
0302     mt76_wr(dev, MT_TOP_RGU_SYSRAM_SLP, 1);
0303 
0304     return 0;
0305 }
0306 
0307 static int mt7986_wmac_sku_setup(struct mt7915_dev *dev, u32 *adie_type)
0308 {
0309     int ret;
0310     u32 adie_main, adie_ext;
0311 
0312     mt76_rmw_field(dev, MT_CONN_INFRA_ADIE_RESET,
0313                MT_CONN_INFRA_ADIE1_RESET_MASK, 0x1);
0314     mt76_rmw_field(dev, MT_CONN_INFRA_ADIE_RESET,
0315                MT_CONN_INFRA_ADIE2_RESET_MASK, 0x1);
0316 
0317     mt76_wmac_spi_lock(dev);
0318 
0319     ret = mt76_wmac_spi_read(dev, 0, MT_ADIE_CHIP_ID, &adie_main);
0320     if (ret)
0321         goto out;
0322 
0323     ret = mt76_wmac_spi_read(dev, 1, MT_ADIE_CHIP_ID, &adie_ext);
0324     if (ret)
0325         goto out;
0326 
0327     *adie_type = FIELD_GET(MT_ADIE_CHIP_ID_MASK, adie_main) |
0328              (MT_ADIE_CHIP_ID_MASK & adie_ext);
0329 
0330 out:
0331     mt76_wmac_spi_unlock(dev);
0332 
0333     return 0;
0334 }
0335 
0336 static inline u16 mt7986_adie_idx(u8 adie, u32 adie_type)
0337 {
0338     if (adie == 0)
0339         return u32_get_bits(adie_type, MT_ADIE_IDX0);
0340     else
0341         return u32_get_bits(adie_type, MT_ADIE_IDX1);
0342 }
0343 
0344 static inline bool is_7975(struct mt7915_dev *dev, u8 adie, u32 adie_type)
0345 {
0346     return mt7986_adie_idx(adie, adie_type) == 0x7975;
0347 }
0348 
0349 static inline bool is_7976(struct mt7915_dev *dev, u8 adie, u32 adie_type)
0350 {
0351     return mt7986_adie_idx(adie, adie_type) == 0x7976;
0352 }
0353 
0354 static int mt7986_wmac_adie_thermal_cal(struct mt7915_dev *dev, u8 adie)
0355 {
0356     int ret;
0357     u32 data, val;
0358 
0359     ret = mt7986_wmac_adie_efuse_read(dev, adie, MT_ADIE_THADC_ANALOG,
0360                       &data);
0361     if (ret || FIELD_GET(MT_ADIE_ANA_EN_MASK, data)) {
0362         val = FIELD_GET(MT_ADIE_VRPI_SEL_EFUSE_MASK, data);
0363         ret = mt76_wmac_spi_rmw(dev, adie, MT_ADIE_RG_TOP_THADC_BG,
0364                     MT_ADIE_VRPI_SEL_CR_MASK,
0365                     FIELD_PREP(MT_ADIE_VRPI_SEL_CR_MASK, val));
0366         if (ret)
0367             return ret;
0368 
0369         val = FIELD_GET(MT_ADIE_PGA_GAIN_EFUSE_MASK, data);
0370         ret = mt76_wmac_spi_rmw(dev, adie, MT_ADIE_RG_TOP_THADC,
0371                     MT_ADIE_PGA_GAIN_MASK,
0372                     FIELD_PREP(MT_ADIE_PGA_GAIN_MASK, val));
0373         if (ret)
0374             return ret;
0375     }
0376 
0377     ret = mt7986_wmac_adie_efuse_read(dev, adie, MT_ADIE_THADC_SLOP,
0378                       &data);
0379     if (ret || FIELD_GET(MT_ADIE_ANA_EN_MASK, data)) {
0380         val = FIELD_GET(MT_ADIE_LDO_CTRL_EFUSE_MASK, data);
0381 
0382         return mt76_wmac_spi_rmw(dev, adie, MT_ADIE_RG_TOP_THADC,
0383                      MT_ADIE_LDO_CTRL_MASK,
0384                      FIELD_PREP(MT_ADIE_LDO_CTRL_MASK, val));
0385     }
0386 
0387     return 0;
0388 }
0389 
0390 static int
0391 mt7986_read_efuse_xo_trim_7976(struct mt7915_dev *dev, u8 adie,
0392                    bool is_40m, int *result)
0393 {
0394     int ret;
0395     u32 data, addr;
0396 
0397     addr = is_40m ? MT_ADIE_XTAL_AXM_40M_OSC : MT_ADIE_XTAL_AXM_80M_OSC;
0398     ret = mt7986_wmac_adie_efuse_read(dev, adie, addr, &data);
0399     if (ret)
0400         return ret;
0401 
0402     if (!FIELD_GET(MT_ADIE_XO_TRIM_EN_MASK, data)) {
0403         *result = 64;
0404     } else {
0405         *result = FIELD_GET(MT_ADIE_TRIM_MASK, data);
0406         addr = is_40m ? MT_ADIE_XTAL_TRIM1_40M_OSC :
0407                 MT_ADIE_XTAL_TRIM1_80M_OSC;
0408         ret = mt7986_wmac_adie_efuse_read(dev, adie, addr, &data);
0409         if (ret)
0410             return ret;
0411 
0412         if (FIELD_GET(MT_ADIE_XO_TRIM_EN_MASK, data) &&
0413             FIELD_GET(MT_ADIE_XTAL_DECREASE_MASK, data))
0414             *result -= FIELD_GET(MT_ADIE_EFUSE_TRIM_MASK, data);
0415         else if (FIELD_GET(MT_ADIE_XO_TRIM_EN_MASK, data))
0416             *result += FIELD_GET(MT_ADIE_EFUSE_TRIM_MASK, data);
0417 
0418         *result = max(0, min(127, *result));
0419     }
0420 
0421     return 0;
0422 }
0423 
0424 static int mt7986_wmac_adie_xtal_trim_7976(struct mt7915_dev *dev, u8 adie)
0425 {
0426     int ret, trim_80m, trim_40m;
0427     u32 data, val, mode;
0428 
0429     ret = mt7986_wmac_adie_efuse_read(dev, adie, MT_ADIE_XO_TRIM_FLOW,
0430                       &data);
0431     if (ret || !FIELD_GET(BIT(1), data))
0432         return 0;
0433 
0434     ret = mt7986_read_efuse_xo_trim_7976(dev, adie, false, &trim_80m);
0435     if (ret)
0436         return ret;
0437 
0438     ret = mt7986_read_efuse_xo_trim_7976(dev, adie, true, &trim_40m);
0439     if (ret)
0440         return ret;
0441 
0442     ret = mt76_wmac_spi_read(dev, adie, MT_ADIE_RG_STRAP_PIN_IN, &val);
0443     if (ret)
0444         return ret;
0445 
0446     mode = FIELD_PREP(GENMASK(6, 4), val);
0447     if (!mode || mode == 0x2) {
0448         ret = mt76_wmac_spi_rmw(dev, adie, MT_ADIE_XTAL_C1,
0449                     GENMASK(31, 24),
0450                     FIELD_PREP(GENMASK(31, 24), trim_80m));
0451         if (ret)
0452             return ret;
0453 
0454         ret = mt76_wmac_spi_rmw(dev, adie, MT_ADIE_XTAL_C2,
0455                     GENMASK(31, 24),
0456                     FIELD_PREP(GENMASK(31, 24), trim_80m));
0457     } else if (mode == 0x3 || mode == 0x4 || mode == 0x6) {
0458         ret = mt76_wmac_spi_rmw(dev, adie, MT_ADIE_XTAL_C1,
0459                     GENMASK(23, 16),
0460                     FIELD_PREP(GENMASK(23, 16), trim_40m));
0461         if (ret)
0462             return ret;
0463 
0464         ret = mt76_wmac_spi_rmw(dev, adie, MT_ADIE_XTAL_C2,
0465                     GENMASK(23, 16),
0466                     FIELD_PREP(GENMASK(23, 16), trim_40m));
0467     }
0468 
0469     return ret;
0470 }
0471 
0472 static int mt7986_wmac_adie_patch_7976(struct mt7915_dev *dev, u8 adie)
0473 {
0474     u32 id, version, rg_xo_01, rg_xo_03;
0475     int ret;
0476 
0477     ret = mt76_wmac_spi_read(dev, adie, MT_ADIE_CHIP_ID, &id);
0478     if (ret)
0479         return ret;
0480 
0481     version = FIELD_GET(MT_ADIE_VERSION_MASK, id);
0482 
0483     ret = mt76_wmac_spi_write(dev, adie, MT_ADIE_RG_TOP_THADC, 0x4a563b00);
0484     if (ret)
0485         return ret;
0486 
0487     if (version == 0x8a00 || version == 0x8a10 || version == 0x8b00) {
0488         rg_xo_01 = 0x1d59080f;
0489         rg_xo_03 = 0x34c00fe0;
0490     } else {
0491         rg_xo_01 = 0x1959f80f;
0492         rg_xo_03 = 0x34d00fe0;
0493     }
0494 
0495     ret = mt76_wmac_spi_write(dev, adie, MT_ADIE_RG_XO_01, rg_xo_01);
0496     if (ret)
0497         return ret;
0498 
0499     return mt76_wmac_spi_write(dev, adie, MT_ADIE_RG_XO_03, rg_xo_03);
0500 }
0501 
0502 static int
0503 mt7986_read_efuse_xo_trim_7975(struct mt7915_dev *dev, u8 adie,
0504                    u32 addr, u32 *result)
0505 {
0506     int ret;
0507     u32 data;
0508 
0509     ret = mt7986_wmac_adie_efuse_read(dev, adie, addr, &data);
0510     if (ret)
0511         return ret;
0512 
0513     if ((data & MT_ADIE_XO_TRIM_EN_MASK)) {
0514         if ((data & MT_ADIE_XTAL_DECREASE_MASK))
0515             *result -= (data & MT_ADIE_EFUSE_TRIM_MASK);
0516         else
0517             *result += (data & MT_ADIE_EFUSE_TRIM_MASK);
0518 
0519         *result = (*result & MT_ADIE_TRIM_MASK);
0520     }
0521 
0522     return 0;
0523 }
0524 
0525 static int mt7986_wmac_adie_xtal_trim_7975(struct mt7915_dev *dev, u8 adie)
0526 {
0527     int ret;
0528     u32 data, result = 0, value;
0529 
0530     ret = mt7986_wmac_adie_efuse_read(dev, adie, MT_ADIE_7975_XTAL_EN,
0531                       &data);
0532     if (ret || !(data & BIT(1)))
0533         return 0;
0534 
0535     ret = mt7986_wmac_adie_efuse_read(dev, adie, MT_ADIE_7975_XTAL_CAL,
0536                       &data);
0537     if (ret)
0538         return ret;
0539 
0540     if (data & MT_ADIE_XO_TRIM_EN_MASK)
0541         result = (data & MT_ADIE_TRIM_MASK);
0542 
0543     ret = mt7986_read_efuse_xo_trim_7975(dev, adie, MT_ADIE_7975_XO_TRIM2,
0544                          &result);
0545     if (ret)
0546         return ret;
0547 
0548     ret = mt7986_read_efuse_xo_trim_7975(dev, adie, MT_ADIE_7975_XO_TRIM3,
0549                          &result);
0550     if (ret)
0551         return ret;
0552 
0553     ret = mt7986_read_efuse_xo_trim_7975(dev, adie, MT_ADIE_7975_XO_TRIM4,
0554                          &result);
0555     if (ret)
0556         return ret;
0557 
0558     /* Update trim value to C1 and C2*/
0559     value = FIELD_GET(MT_ADIE_7975_XO_CTRL2_C1_MASK, result) |
0560         FIELD_GET(MT_ADIE_7975_XO_CTRL2_C2_MASK, result);
0561     ret = mt76_wmac_spi_rmw(dev, adie, MT_ADIE_7975_XO_CTRL2,
0562                 MT_ADIE_7975_XO_CTRL2_MASK, value);
0563     if (ret)
0564         return ret;
0565 
0566     ret = mt76_wmac_spi_read(dev, adie, MT_ADIE_7975_XTAL, &value);
0567     if (ret)
0568         return ret;
0569 
0570     if (value & MT_ADIE_7975_XTAL_EN_MASK) {
0571         ret = mt76_wmac_spi_rmw(dev, adie, MT_ADIE_7975_XO_2,
0572                     MT_ADIE_7975_XO_2_FIX_EN, 0x0);
0573         if (ret)
0574             return ret;
0575     }
0576 
0577     return mt76_wmac_spi_rmw(dev, adie, MT_ADIE_7975_XO_CTRL6,
0578                  MT_ADIE_7975_XO_CTRL6_MASK, 0x1);
0579 }
0580 
0581 static int mt7986_wmac_adie_patch_7975(struct mt7915_dev *dev, u8 adie)
0582 {
0583     int ret;
0584 
0585     /* disable CAL LDO and fine tune RFDIG LDO */
0586     ret = mt76_wmac_spi_write(dev, adie, 0x348, 0x00000002);
0587     if (ret)
0588         return ret;
0589 
0590     ret = mt76_wmac_spi_write(dev, adie, 0x378, 0x00000002);
0591     if (ret)
0592         return ret;
0593 
0594     ret = mt76_wmac_spi_write(dev, adie, 0x3a8, 0x00000002);
0595     if (ret)
0596         return ret;
0597 
0598     ret = mt76_wmac_spi_write(dev, adie, 0x3d8, 0x00000002);
0599     if (ret)
0600         return ret;
0601 
0602     /* set CKA driving and filter */
0603     ret = mt76_wmac_spi_write(dev, adie, 0xa1c, 0x30000aaa);
0604     if (ret)
0605         return ret;
0606 
0607     /* set CKB LDO to 1.4V */
0608     ret = mt76_wmac_spi_write(dev, adie, 0xa84, 0x8470008a);
0609     if (ret)
0610         return ret;
0611 
0612     /* turn on SX0 LTBUF */
0613     ret = mt76_wmac_spi_write(dev, adie, 0x074, 0x00000002);
0614     if (ret)
0615         return ret;
0616 
0617     /* CK_BUF_SW_EN = 1 (all buf in manual mode.) */
0618     ret = mt76_wmac_spi_write(dev, adie, 0xaa4, 0x01001fc0);
0619     if (ret)
0620         return ret;
0621 
0622     /* BT mode/WF normal mode 00000005 */
0623     ret = mt76_wmac_spi_write(dev, adie, 0x070, 0x00000005);
0624     if (ret)
0625         return ret;
0626 
0627     /* BG thermal sensor offset update */
0628     ret = mt76_wmac_spi_write(dev, adie, 0x344, 0x00000088);
0629     if (ret)
0630         return ret;
0631 
0632     ret = mt76_wmac_spi_write(dev, adie, 0x374, 0x00000088);
0633     if (ret)
0634         return ret;
0635 
0636     ret = mt76_wmac_spi_write(dev, adie, 0x3a4, 0x00000088);
0637     if (ret)
0638         return ret;
0639 
0640     ret = mt76_wmac_spi_write(dev, adie, 0x3d4, 0x00000088);
0641     if (ret)
0642         return ret;
0643 
0644     /* set WCON VDD IPTAT to "0000" */
0645     ret = mt76_wmac_spi_write(dev, adie, 0xa80, 0x44d07000);
0646     if (ret)
0647         return ret;
0648 
0649     /* change back LTBUF SX3 drving to default value */
0650     ret = mt76_wmac_spi_write(dev, adie, 0xa88, 0x3900aaaa);
0651     if (ret)
0652         return ret;
0653 
0654     /* SM input cap off */
0655     ret = mt76_wmac_spi_write(dev, adie, 0x2c4, 0x00000000);
0656     if (ret)
0657         return ret;
0658 
0659     /* set CKB driving and filter */
0660     return mt76_wmac_spi_write(dev, adie, 0x2c8, 0x00000072);
0661 }
0662 
0663 static int mt7986_wmac_adie_cfg(struct mt7915_dev *dev, u8 adie, u32 adie_type)
0664 {
0665     int ret;
0666 
0667     mt76_wmac_spi_lock(dev);
0668     ret = mt76_wmac_spi_write(dev, adie, MT_ADIE_CLK_EN, ~0);
0669     if (ret)
0670         goto out;
0671 
0672     if (is_7975(dev, adie, adie_type)) {
0673         ret = mt76_wmac_spi_rmw(dev, adie, MT_ADIE_7975_COCLK,
0674                     BIT(1), 0x1);
0675         if (ret)
0676             goto out;
0677 
0678         ret = mt7986_wmac_adie_thermal_cal(dev, adie);
0679         if (ret)
0680             goto out;
0681 
0682         ret = mt7986_wmac_adie_xtal_trim_7975(dev, adie);
0683         if (ret)
0684             goto out;
0685 
0686         ret = mt7986_wmac_adie_patch_7975(dev, adie);
0687     } else if (is_7976(dev, adie, adie_type)) {
0688         if (mt7986_wmac_check_adie_type(dev) == ADIE_DBDC) {
0689             ret = mt76_wmac_spi_write(dev, adie,
0690                           MT_ADIE_WRI_CK_SEL, 0x1c);
0691             if (ret)
0692                 goto out;
0693         }
0694 
0695         ret = mt7986_wmac_adie_thermal_cal(dev, adie);
0696         if (ret)
0697             goto out;
0698 
0699         ret = mt7986_wmac_adie_xtal_trim_7976(dev, adie);
0700         if (ret)
0701             goto out;
0702 
0703         ret = mt7986_wmac_adie_patch_7976(dev, adie);
0704     }
0705 out:
0706     mt76_wmac_spi_unlock(dev);
0707 
0708     return ret;
0709 }
0710 
0711 static int
0712 mt7986_wmac_afe_cal(struct mt7915_dev *dev, u8 adie, bool dbdc, u32 adie_type)
0713 {
0714     int ret;
0715     u8 idx;
0716 
0717     mt76_wmac_spi_lock(dev);
0718     if (is_7975(dev, adie, adie_type))
0719         ret = mt76_wmac_spi_write(dev, adie,
0720                       MT_AFE_RG_ENCAL_WBTAC_IF_SW,
0721                       0x80000000);
0722     else
0723         ret = mt76_wmac_spi_write(dev, adie,
0724                       MT_AFE_RG_ENCAL_WBTAC_IF_SW,
0725                       0x88888005);
0726     if (ret)
0727         goto out;
0728 
0729     idx = dbdc ? ADIE_DBDC : adie;
0730 
0731     mt76_rmw_field(dev, MT_AFE_DIG_EN_01(idx),
0732                MT_AFE_RG_WBG_EN_RCK_MASK, 0x1);
0733     usleep_range(60, 100);
0734 
0735     mt76_rmw(dev, MT_AFE_DIG_EN_01(idx),
0736          MT_AFE_RG_WBG_EN_RCK_MASK, 0x0);
0737 
0738     mt76_rmw_field(dev, MT_AFE_DIG_EN_03(idx),
0739                MT_AFE_RG_WBG_EN_BPLL_UP_MASK, 0x1);
0740     usleep_range(30, 100);
0741 
0742     mt76_rmw_field(dev, MT_AFE_DIG_EN_03(idx),
0743                MT_AFE_RG_WBG_EN_WPLL_UP_MASK, 0x1);
0744     usleep_range(60, 100);
0745 
0746     mt76_rmw_field(dev, MT_AFE_DIG_EN_01(idx),
0747                MT_AFE_RG_WBG_EN_TXCAL_MASK, 0x1f);
0748     usleep_range(800, 1000);
0749 
0750     mt76_rmw(dev, MT_AFE_DIG_EN_01(idx),
0751          MT_AFE_RG_WBG_EN_TXCAL_MASK, 0x0);
0752     mt76_rmw(dev, MT_AFE_DIG_EN_03(idx),
0753          MT_AFE_RG_WBG_EN_PLL_UP_MASK, 0x0);
0754 
0755     ret = mt76_wmac_spi_write(dev, adie, MT_AFE_RG_ENCAL_WBTAC_IF_SW,
0756                   0x5);
0757 
0758 out:
0759     mt76_wmac_spi_unlock(dev);
0760 
0761     return ret;
0762 }
0763 
0764 static void mt7986_wmac_subsys_pll_initial(struct mt7915_dev *dev, u8 band)
0765 {
0766     mt76_rmw(dev, MT_AFE_PLL_STB_TIME(band),
0767          MT_AFE_PLL_STB_TIME_MASK, MT_AFE_PLL_STB_TIME_VAL);
0768 
0769     mt76_rmw(dev, MT_AFE_DIG_EN_02(band),
0770          MT_AFE_PLL_CFG_MASK, MT_AFE_PLL_CFG_VAL);
0771 
0772     mt76_rmw(dev, MT_AFE_DIG_TOP_01(band),
0773          MT_AFE_DIG_TOP_01_MASK, MT_AFE_DIG_TOP_01_VAL);
0774 }
0775 
0776 static void mt7986_wmac_subsys_setting(struct mt7915_dev *dev)
0777 {
0778     /* Subsys pll init */
0779     mt7986_wmac_subsys_pll_initial(dev, 0);
0780     mt7986_wmac_subsys_pll_initial(dev, 1);
0781 
0782     /* Set legacy OSC control stable time*/
0783     mt76_rmw(dev, MT_CONN_INFRA_OSC_RC_EN,
0784          MT_CONN_INFRA_OSC_RC_EN_MASK, 0x0);
0785     mt76_rmw(dev, MT_CONN_INFRA_OSC_CTRL,
0786          MT_CONN_INFRA_OSC_STB_TIME_MASK, 0x80706);
0787 
0788     /* prevent subsys from power on/of in a short time interval */
0789     mt76_rmw(dev, MT_TOP_WFSYS_PWR,
0790          MT_TOP_PWR_ACK_MASK | MT_TOP_PWR_KEY_MASK,
0791          MT_TOP_PWR_KEY);
0792 }
0793 
0794 static int mt7986_wmac_bus_timeout(struct mt7915_dev *dev)
0795 {
0796     mt76_rmw_field(dev, MT_INFRA_BUS_OFF_TIMEOUT,
0797                MT_INFRA_BUS_TIMEOUT_LIMIT_MASK, 0x2);
0798 
0799     mt76_rmw_field(dev, MT_INFRA_BUS_OFF_TIMEOUT,
0800                MT_INFRA_BUS_TIMEOUT_EN_MASK, 0xf);
0801 
0802     mt76_rmw_field(dev, MT_INFRA_BUS_ON_TIMEOUT,
0803                MT_INFRA_BUS_TIMEOUT_LIMIT_MASK, 0xc);
0804 
0805     mt76_rmw_field(dev, MT_INFRA_BUS_ON_TIMEOUT,
0806                MT_INFRA_BUS_TIMEOUT_EN_MASK, 0xf);
0807 
0808     return mt7986_wmac_coninfra_check(dev);
0809 }
0810 
0811 static void mt7986_wmac_clock_enable(struct mt7915_dev *dev, u32 adie_type)
0812 {
0813     u32 cur;
0814 
0815     mt76_rmw_field(dev, MT_INFRA_CKGEN_BUS_WPLL_DIV_1,
0816                MT_INFRA_CKGEN_DIV_SEL_MASK, 0x1);
0817 
0818     mt76_rmw_field(dev, MT_INFRA_CKGEN_BUS_WPLL_DIV_2,
0819                MT_INFRA_CKGEN_DIV_SEL_MASK, 0x1);
0820 
0821     mt76_rmw_field(dev, MT_INFRA_CKGEN_BUS_WPLL_DIV_1,
0822                MT_INFRA_CKGEN_DIV_EN_MASK, 0x1);
0823 
0824     mt76_rmw_field(dev, MT_INFRA_CKGEN_BUS_WPLL_DIV_2,
0825                MT_INFRA_CKGEN_DIV_EN_MASK, 0x1);
0826 
0827     mt76_rmw_field(dev, MT_INFRA_CKGEN_RFSPI_WPLL_DIV,
0828                MT_INFRA_CKGEN_DIV_SEL_MASK, 0x8);
0829 
0830     mt76_rmw_field(dev, MT_INFRA_CKGEN_RFSPI_WPLL_DIV,
0831                MT_INFRA_CKGEN_DIV_EN_MASK, 0x1);
0832 
0833     mt76_rmw_field(dev, MT_INFRA_CKGEN_BUS,
0834                MT_INFRA_CKGEN_BUS_CLK_SEL_MASK, 0x0);
0835 
0836     mt76_rmw_field(dev, MT_CONN_INFRA_HW_CTRL,
0837                MT_CONN_INFRA_HW_CTRL_MASK, 0x1);
0838 
0839     mt76_rmw(dev, MT_TOP_CONN_INFRA_WAKEUP,
0840          MT_TOP_CONN_INFRA_WAKEUP_MASK, 0x1);
0841 
0842     usleep_range(900, 1000);
0843 
0844     mt76_wmac_spi_lock(dev);
0845     if (is_7975(dev, 0, adie_type) || is_7976(dev, 0, adie_type)) {
0846         mt76_rmw_field(dev, MT_ADIE_SLP_CTRL_CK0(0),
0847                    MT_SLP_CTRL_EN_MASK, 0x1);
0848 
0849         read_poll_timeout(mt76_rr, cur, !(cur & MT_SLP_CTRL_BSY_MASK),
0850                   USEC_PER_MSEC, 50 * USEC_PER_MSEC, false,
0851                   dev, MT_ADIE_SLP_CTRL_CK0(0));
0852     }
0853     if (is_7975(dev, 1, adie_type) || is_7976(dev, 1, adie_type)) {
0854         mt76_rmw_field(dev, MT_ADIE_SLP_CTRL_CK0(1),
0855                    MT_SLP_CTRL_EN_MASK, 0x1);
0856 
0857         read_poll_timeout(mt76_rr, cur, !(cur & MT_SLP_CTRL_BSY_MASK),
0858                   USEC_PER_MSEC, 50 * USEC_PER_MSEC, false,
0859                   dev, MT_ADIE_SLP_CTRL_CK0(0));
0860     }
0861     mt76_wmac_spi_unlock(dev);
0862 
0863     mt76_rmw(dev, MT_TOP_CONN_INFRA_WAKEUP,
0864          MT_TOP_CONN_INFRA_WAKEUP_MASK, 0x0);
0865     usleep_range(900, 1000);
0866 }
0867 
0868 static int mt7986_wmac_top_wfsys_wakeup(struct mt7915_dev *dev, bool enable)
0869 {
0870     mt76_rmw_field(dev, MT_TOP_WFSYS_WAKEUP,
0871                MT_TOP_WFSYS_WAKEUP_MASK, enable);
0872 
0873     usleep_range(900, 1000);
0874 
0875     if (!enable)
0876         return 0;
0877 
0878     return mt7986_wmac_coninfra_check(dev);
0879 }
0880 
0881 static int mt7986_wmac_wm_enable(struct mt7915_dev *dev, bool enable)
0882 {
0883     u32 cur;
0884 
0885     mt76_rmw_field(dev, MT7986_TOP_WM_RESET,
0886                MT7986_TOP_WM_RESET_MASK, enable);
0887     if (!enable)
0888         return 0;
0889 
0890     return read_poll_timeout(mt76_rr, cur, (cur == 0x1d1e),
0891                  USEC_PER_MSEC, 5000 * USEC_PER_MSEC, false,
0892                  dev, MT_TOP_CFG_ON_ROM_IDX);
0893 }
0894 
0895 static int mt7986_wmac_wfsys_poweron(struct mt7915_dev *dev, bool enable)
0896 {
0897     u32 mask = MT_TOP_PWR_EN_MASK | MT_TOP_PWR_KEY_MASK;
0898     u32 cur;
0899 
0900     mt76_rmw(dev, MT_TOP_WFSYS_PWR, mask,
0901          MT_TOP_PWR_KEY | FIELD_PREP(MT_TOP_PWR_EN_MASK, enable));
0902 
0903     return read_poll_timeout(mt76_rr, cur,
0904         (FIELD_GET(MT_TOP_WFSYS_RESET_STATUS_MASK, cur) == enable),
0905         USEC_PER_MSEC, 50 * USEC_PER_MSEC, false,
0906         dev, MT_TOP_WFSYS_RESET_STATUS);
0907 }
0908 
0909 static int mt7986_wmac_wfsys_setting(struct mt7915_dev *dev)
0910 {
0911     int ret;
0912     u32 cur;
0913 
0914     /* Turn off wfsys2conn bus sleep protect */
0915     mt76_rmw(dev, MT_CONN_INFRA_WF_SLP_PROT,
0916          MT_CONN_INFRA_WF_SLP_PROT_MASK, 0x0);
0917 
0918     ret = mt7986_wmac_wfsys_poweron(dev, true);
0919     if (ret)
0920         return ret;
0921 
0922     /* Check bus sleep protect */
0923 
0924     ret = read_poll_timeout(mt76_rr, cur,
0925                 !(cur & MT_CONN_INFRA_CONN_WF_MASK),
0926                 USEC_PER_MSEC, 50 * USEC_PER_MSEC, false,
0927                 dev, MT_CONN_INFRA_WF_SLP_PROT_RDY);
0928     if (ret)
0929         return ret;
0930 
0931     ret = read_poll_timeout(mt76_rr, cur, !(cur & MT_SLP_WFDMA2CONN_MASK),
0932                 USEC_PER_MSEC, 50 * USEC_PER_MSEC, false,
0933                 dev, MT_SLP_STATUS);
0934     if (ret)
0935         return ret;
0936 
0937     return read_poll_timeout(mt76_rr, cur, (cur == 0x02060000),
0938                  USEC_PER_MSEC, 50 * USEC_PER_MSEC, false,
0939                  dev, MT_TOP_CFG_IP_VERSION_ADDR);
0940 }
0941 
0942 static void mt7986_wmac_wfsys_set_timeout(struct mt7915_dev *dev)
0943 {
0944     u32 mask = MT_MCU_BUS_TIMEOUT_SET_MASK |
0945            MT_MCU_BUS_TIMEOUT_CG_EN_MASK |
0946            MT_MCU_BUS_TIMEOUT_EN_MASK;
0947     u32 val = FIELD_PREP(MT_MCU_BUS_TIMEOUT_SET_MASK, 1) |
0948           FIELD_PREP(MT_MCU_BUS_TIMEOUT_CG_EN_MASK, 1) |
0949           FIELD_PREP(MT_MCU_BUS_TIMEOUT_EN_MASK, 1);
0950 
0951     mt76_rmw(dev, MT_MCU_BUS_TIMEOUT, mask, val);
0952 
0953     mt76_wr(dev, MT_MCU_BUS_REMAP, 0x810f0000);
0954 
0955     mask = MT_MCU_BUS_DBG_TIMEOUT_SET_MASK |
0956            MT_MCU_BUS_DBG_TIMEOUT_CK_EN_MASK |
0957            MT_MCU_BUS_DBG_TIMEOUT_EN_MASK;
0958     val = FIELD_PREP(MT_MCU_BUS_DBG_TIMEOUT_SET_MASK, 0x3aa) |
0959           FIELD_PREP(MT_MCU_BUS_DBG_TIMEOUT_CK_EN_MASK, 1) |
0960           FIELD_PREP(MT_MCU_BUS_DBG_TIMEOUT_EN_MASK, 1);
0961 
0962     mt76_rmw(dev, MT_MCU_BUS_DBG_TIMEOUT, mask, val);
0963 }
0964 
0965 static int mt7986_wmac_sku_update(struct mt7915_dev *dev, u32 adie_type)
0966 {
0967     u32 val;
0968 
0969     if (is_7976(dev, 0, adie_type) && is_7976(dev, 1, adie_type))
0970         val = 0xf;
0971     else if (is_7975(dev, 0, adie_type) && is_7975(dev, 1, adie_type))
0972         val = 0xd;
0973     else if (is_7976(dev, 0, adie_type))
0974         val = 0x7;
0975     else if (is_7975(dev, 1, adie_type))
0976         val = 0x8;
0977     else if (is_7976(dev, 1, adie_type))
0978         val = 0xa;
0979     else
0980         return -EINVAL;
0981 
0982     mt76_wmac_rmw(dev->sku, MT_TOP_POS_SKU, MT_TOP_POS_SKU_MASK,
0983               FIELD_PREP(MT_TOP_POS_SKU_MASK, val));
0984 
0985     mt76_wr(dev, MT_CONNINFRA_SKU_DEC_ADDR, val);
0986 
0987     return 0;
0988 }
0989 
0990 static int
0991 mt7986_wmac_adie_setup(struct mt7915_dev *dev, u8 adie, u32 adie_type)
0992 {
0993     int ret;
0994 
0995     if (!(is_7975(dev, adie, adie_type) || is_7976(dev, adie, adie_type)))
0996         return 0;
0997 
0998     ret = mt7986_wmac_adie_cfg(dev, adie, adie_type);
0999     if (ret)
1000         return ret;
1001 
1002     ret = mt7986_wmac_afe_cal(dev, adie, false, adie_type);
1003     if (ret)
1004         return ret;
1005 
1006     if (!adie && (mt7986_wmac_check_adie_type(dev) == ADIE_DBDC))
1007         ret = mt7986_wmac_afe_cal(dev, adie, true, adie_type);
1008 
1009     return ret;
1010 }
1011 
1012 static int mt7986_wmac_subsys_powerup(struct mt7915_dev *dev, u32 adie_type)
1013 {
1014     int ret;
1015 
1016     mt7986_wmac_subsys_setting(dev);
1017 
1018     ret = mt7986_wmac_bus_timeout(dev);
1019     if (ret)
1020         return ret;
1021 
1022     mt7986_wmac_clock_enable(dev, adie_type);
1023 
1024     return 0;
1025 }
1026 
1027 static int mt7986_wmac_wfsys_powerup(struct mt7915_dev *dev)
1028 {
1029     int ret;
1030 
1031     ret = mt7986_wmac_wm_enable(dev, false);
1032     if (ret)
1033         return ret;
1034 
1035     ret = mt7986_wmac_wfsys_setting(dev);
1036     if (ret)
1037         return ret;
1038 
1039     mt7986_wmac_wfsys_set_timeout(dev);
1040 
1041     return mt7986_wmac_wm_enable(dev, true);
1042 }
1043 
1044 int mt7986_wmac_enable(struct mt7915_dev *dev)
1045 {
1046     int ret;
1047     u32 adie_type;
1048 
1049     ret = mt7986_wmac_consys_reset(dev, true);
1050     if (ret)
1051         return ret;
1052 
1053     ret = mt7986_wmac_gpio_setup(dev);
1054     if (ret)
1055         return ret;
1056 
1057     ret = mt7986_wmac_consys_lockup(dev, false);
1058     if (ret)
1059         return ret;
1060 
1061     ret = mt7986_wmac_coninfra_check(dev);
1062     if (ret)
1063         return ret;
1064 
1065     ret = mt7986_wmac_coninfra_setup(dev);
1066     if (ret)
1067         return ret;
1068 
1069     ret = mt7986_wmac_sku_setup(dev, &adie_type);
1070     if (ret)
1071         return ret;
1072 
1073     ret = mt7986_wmac_adie_setup(dev, 0, adie_type);
1074     if (ret)
1075         return ret;
1076 
1077     ret = mt7986_wmac_adie_setup(dev, 1, adie_type);
1078     if (ret)
1079         return ret;
1080 
1081     ret = mt7986_wmac_subsys_powerup(dev, adie_type);
1082     if (ret)
1083         return ret;
1084 
1085     ret = mt7986_wmac_top_wfsys_wakeup(dev, true);
1086     if (ret)
1087         return ret;
1088 
1089     ret = mt7986_wmac_wfsys_powerup(dev);
1090     if (ret)
1091         return ret;
1092 
1093     return mt7986_wmac_sku_update(dev, adie_type);
1094 }
1095 
1096 void mt7986_wmac_disable(struct mt7915_dev *dev)
1097 {
1098     u32 cur;
1099 
1100     mt7986_wmac_top_wfsys_wakeup(dev, true);
1101 
1102     /* Turn on wfsys2conn bus sleep protect */
1103     mt76_rmw_field(dev, MT_CONN_INFRA_WF_SLP_PROT,
1104                MT_CONN_INFRA_WF_SLP_PROT_MASK, 0x1);
1105 
1106     /* Check wfsys2conn bus sleep protect */
1107     read_poll_timeout(mt76_rr, cur, !(cur ^ MT_CONN_INFRA_CONN),
1108               USEC_PER_MSEC, 50 * USEC_PER_MSEC, false,
1109               dev, MT_CONN_INFRA_WF_SLP_PROT_RDY);
1110 
1111     mt7986_wmac_wfsys_poweron(dev, false);
1112 
1113     /* Turn back wpll setting */
1114     mt76_rmw_field(dev, MT_AFE_DIG_EN_02(0), MT_AFE_MCU_BPLL_CFG_MASK, 0x2);
1115     mt76_rmw_field(dev, MT_AFE_DIG_EN_02(0), MT_AFE_WPLL_CFG_MASK, 0x2);
1116 
1117     /* Reset EMI */
1118     mt76_rmw_field(dev, MT_CONN_INFRA_EMI_REQ,
1119                MT_CONN_INFRA_EMI_REQ_MASK, 0x1);
1120     mt76_rmw_field(dev, MT_CONN_INFRA_EMI_REQ,
1121                MT_CONN_INFRA_EMI_REQ_MASK, 0x0);
1122     mt76_rmw_field(dev, MT_CONN_INFRA_EMI_REQ,
1123                MT_CONN_INFRA_INFRA_REQ_MASK, 0x1);
1124     mt76_rmw_field(dev, MT_CONN_INFRA_EMI_REQ,
1125                MT_CONN_INFRA_INFRA_REQ_MASK, 0x0);
1126 
1127     mt7986_wmac_top_wfsys_wakeup(dev, false);
1128     mt7986_wmac_consys_lockup(dev, true);
1129     mt7986_wmac_consys_reset(dev, false);
1130 }
1131 
1132 static int mt7986_wmac_init(struct mt7915_dev *dev)
1133 {
1134     struct device *pdev = dev->mt76.dev;
1135     struct platform_device *pfdev = to_platform_device(pdev);
1136     struct clk *mcu_clk, *ap_conn_clk;
1137 
1138     mcu_clk = devm_clk_get(pdev, "mcu");
1139     if (IS_ERR(mcu_clk))
1140         dev_err(pdev, "mcu clock not found\n");
1141     else if (clk_prepare_enable(mcu_clk))
1142         dev_err(pdev, "mcu clock configuration failed\n");
1143 
1144     ap_conn_clk = devm_clk_get(pdev, "ap2conn");
1145     if (IS_ERR(ap_conn_clk))
1146         dev_err(pdev, "ap2conn clock not found\n");
1147     else if (clk_prepare_enable(ap_conn_clk))
1148         dev_err(pdev, "ap2conn clock configuration failed\n");
1149 
1150     dev->dcm = devm_platform_ioremap_resource(pfdev, 1);
1151     if (IS_ERR(dev->dcm))
1152         return PTR_ERR(dev->dcm);
1153 
1154     dev->sku = devm_platform_ioremap_resource(pfdev, 2);
1155     if (IS_ERR(dev->sku))
1156         return PTR_ERR(dev->sku);
1157 
1158     dev->rstc = devm_reset_control_get(pdev, "consys");
1159     if (IS_ERR(dev->rstc))
1160         return PTR_ERR(dev->rstc);
1161 
1162     return 0;
1163 }
1164 
1165 static int mt7986_wmac_probe(struct platform_device *pdev)
1166 {
1167     void __iomem *mem_base;
1168     struct mt7915_dev *dev;
1169     struct mt76_dev *mdev;
1170     int irq, ret;
1171     u32 chip_id;
1172 
1173     chip_id = (uintptr_t)of_device_get_match_data(&pdev->dev);
1174 
1175     irq = platform_get_irq(pdev, 0);
1176     if (irq < 0)
1177         return irq;
1178 
1179     mem_base = devm_platform_ioremap_resource(pdev, 0);
1180     if (IS_ERR(mem_base)) {
1181         dev_err(&pdev->dev, "Failed to get memory resource\n");
1182         return PTR_ERR(mem_base);
1183     }
1184 
1185     dev = mt7915_mmio_probe(&pdev->dev, mem_base, chip_id);
1186     if (IS_ERR(dev))
1187         return PTR_ERR(dev);
1188 
1189     mdev = &dev->mt76;
1190     ret = devm_request_irq(mdev->dev, irq, mt7915_irq_handler,
1191                    IRQF_SHARED, KBUILD_MODNAME, dev);
1192     if (ret)
1193         goto free_device;
1194 
1195     ret = mt7986_wmac_init(dev);
1196     if (ret)
1197         goto free_irq;
1198 
1199     mt7915_wfsys_reset(dev);
1200 
1201     ret = mt7915_register_device(dev);
1202     if (ret)
1203         goto free_irq;
1204 
1205     return 0;
1206 
1207 free_irq:
1208     devm_free_irq(mdev->dev, irq, dev);
1209 
1210 free_device:
1211     mt76_free_device(&dev->mt76);
1212 
1213     return ret;
1214 }
1215 
1216 static int mt7986_wmac_remove(struct platform_device *pdev)
1217 {
1218     struct mt7915_dev *dev = platform_get_drvdata(pdev);
1219 
1220     mt7915_unregister_device(dev);
1221 
1222     return 0;
1223 }
1224 
1225 static const struct of_device_id mt7986_wmac_of_match[] = {
1226     { .compatible = "mediatek,mt7986-wmac", .data = (u32 *)0x7986 },
1227     {},
1228 };
1229 
1230 struct platform_driver mt7986_wmac_driver = {
1231     .driver = {
1232         .name = "mt7986-wmac",
1233         .of_match_table = mt7986_wmac_of_match,
1234     },
1235     .probe = mt7986_wmac_probe,
1236     .remove = mt7986_wmac_remove,
1237 };
1238 
1239 MODULE_FIRMWARE(MT7986_FIRMWARE_WA);
1240 MODULE_FIRMWARE(MT7986_FIRMWARE_WM);
1241 MODULE_FIRMWARE(MT7986_FIRMWARE_WM_MT7975);
1242 MODULE_FIRMWARE(MT7986_ROM_PATCH);
1243 MODULE_FIRMWARE(MT7986_ROM_PATCH_MT7975);