199ad32a4SBo Jiao // SPDX-License-Identifier: ISC
299ad32a4SBo Jiao /* Copyright (C) 2022 MediaTek Inc. */
399ad32a4SBo Jiao 
499ad32a4SBo Jiao #include <linux/kernel.h>
599ad32a4SBo Jiao #include <linux/module.h>
699ad32a4SBo Jiao #include <linux/platform_device.h>
799ad32a4SBo Jiao #include <linux/pinctrl/consumer.h>
899ad32a4SBo Jiao #include <linux/of.h>
999ad32a4SBo Jiao #include <linux/of_reserved_mem.h>
1099ad32a4SBo Jiao #include <linux/of_gpio.h>
1199ad32a4SBo Jiao #include <linux/iopoll.h>
1299ad32a4SBo Jiao #include <linux/reset.h>
1399ad32a4SBo Jiao #include <linux/of_net.h>
14cd85efdfSLorenzo Bianconi #include <linux/clk.h>
1599ad32a4SBo Jiao 
1699ad32a4SBo Jiao #include "mt7915.h"
1799ad32a4SBo Jiao 
1899ad32a4SBo Jiao #define MT7981_CON_INFRA_VERSION 0x02090000
1999ad32a4SBo Jiao #define MT7986_CON_INFRA_VERSION 0x02070000
2099ad32a4SBo Jiao 
2199ad32a4SBo Jiao /* INFRACFG */
2299ad32a4SBo Jiao #define MT_INFRACFG_CONN2AP_SLPPROT	0x0d0
2399ad32a4SBo Jiao #define MT_INFRACFG_AP2CONN_SLPPROT	0x0d4
2499ad32a4SBo Jiao 
2599ad32a4SBo Jiao #define MT_INFRACFG_RX_EN_MASK		BIT(16)
2699ad32a4SBo Jiao #define MT_INFRACFG_TX_RDY_MASK		BIT(4)
2799ad32a4SBo Jiao #define MT_INFRACFG_TX_EN_MASK		BIT(0)
2899ad32a4SBo Jiao 
2999ad32a4SBo Jiao /* TOP POS */
3099ad32a4SBo Jiao #define MT_TOP_POS_FAST_CTRL		0x114
3199ad32a4SBo Jiao #define MT_TOP_POS_FAST_EN_MASK		BIT(3)
3299ad32a4SBo Jiao 
3399ad32a4SBo Jiao #define MT_TOP_POS_SKU			0x21c
3499ad32a4SBo Jiao #define MT_TOP_POS_SKU_MASK		GENMASK(31, 28)
3599ad32a4SBo Jiao #define MT_TOP_POS_SKU_ADIE_DBDC_MASK	BIT(2)
3699ad32a4SBo Jiao 
3799ad32a4SBo Jiao enum {
3899ad32a4SBo Jiao 	ADIE_SB,
3999ad32a4SBo Jiao 	ADIE_DBDC
4099ad32a4SBo Jiao };
4199ad32a4SBo Jiao 
4299ad32a4SBo Jiao static int
mt76_wmac_spi_read(struct mt7915_dev * dev,u8 adie,u32 addr,u32 * val)4399ad32a4SBo Jiao mt76_wmac_spi_read(struct mt7915_dev *dev, u8 adie, u32 addr, u32 *val)
4499ad32a4SBo Jiao {
4599ad32a4SBo Jiao 	int ret;
4699ad32a4SBo Jiao 	u32 cur;
4799ad32a4SBo Jiao 
4899ad32a4SBo Jiao 	ret = read_poll_timeout(mt76_rr, cur, !(cur & MT_TOP_SPI_POLLING_BIT),
4999ad32a4SBo Jiao 				USEC_PER_MSEC, 50 * USEC_PER_MSEC, false,
5099ad32a4SBo Jiao 				dev, MT_TOP_SPI_BUSY_CR(adie));
5199ad32a4SBo Jiao 	if (ret)
5299ad32a4SBo Jiao 		return ret;
5399ad32a4SBo Jiao 
5499ad32a4SBo Jiao 	mt76_wr(dev, MT_TOP_SPI_ADDR_CR(adie),
5599ad32a4SBo Jiao 		MT_TOP_SPI_READ_ADDR_FORMAT | addr);
5699ad32a4SBo Jiao 	mt76_wr(dev, MT_TOP_SPI_WRITE_DATA_CR(adie), 0);
5799ad32a4SBo Jiao 
5899ad32a4SBo Jiao 	ret = read_poll_timeout(mt76_rr, cur, !(cur & MT_TOP_SPI_POLLING_BIT),
5999ad32a4SBo Jiao 				USEC_PER_MSEC, 50 * USEC_PER_MSEC, false,
6099ad32a4SBo Jiao 				dev, MT_TOP_SPI_BUSY_CR(adie));
6199ad32a4SBo Jiao 	if (ret)
6299ad32a4SBo Jiao 		return ret;
6399ad32a4SBo Jiao 
6499ad32a4SBo Jiao 	*val = mt76_rr(dev, MT_TOP_SPI_READ_DATA_CR(adie));
6599ad32a4SBo Jiao 
6699ad32a4SBo Jiao 	return 0;
6799ad32a4SBo Jiao }
6899ad32a4SBo Jiao 
6999ad32a4SBo Jiao static int
mt76_wmac_spi_write(struct mt7915_dev * dev,u8 adie,u32 addr,u32 val)7099ad32a4SBo Jiao mt76_wmac_spi_write(struct mt7915_dev *dev, u8 adie, u32 addr, u32 val)
7199ad32a4SBo Jiao {
7299ad32a4SBo Jiao 	int ret;
7399ad32a4SBo Jiao 	u32 cur;
7499ad32a4SBo Jiao 
7599ad32a4SBo Jiao 	ret = read_poll_timeout(mt76_rr, cur, !(cur & MT_TOP_SPI_POLLING_BIT),
7699ad32a4SBo Jiao 				USEC_PER_MSEC, 50 * USEC_PER_MSEC, false,
7799ad32a4SBo Jiao 				dev, MT_TOP_SPI_BUSY_CR(adie));
7899ad32a4SBo Jiao 	if (ret)
7999ad32a4SBo Jiao 		return ret;
8099ad32a4SBo Jiao 
8199ad32a4SBo Jiao 	mt76_wr(dev, MT_TOP_SPI_ADDR_CR(adie),
8299ad32a4SBo Jiao 		MT_TOP_SPI_WRITE_ADDR_FORMAT | addr);
8399ad32a4SBo Jiao 	mt76_wr(dev, MT_TOP_SPI_WRITE_DATA_CR(adie), val);
8499ad32a4SBo Jiao 
8599ad32a4SBo Jiao 	return read_poll_timeout(mt76_rr, cur, !(cur & MT_TOP_SPI_POLLING_BIT),
8699ad32a4SBo Jiao 				 USEC_PER_MSEC, 50 * USEC_PER_MSEC, false,
8799ad32a4SBo Jiao 				 dev, MT_TOP_SPI_BUSY_CR(adie));
8899ad32a4SBo Jiao }
8999ad32a4SBo Jiao 
9099ad32a4SBo Jiao static int
mt76_wmac_spi_rmw(struct mt7915_dev * dev,u8 adie,u32 addr,u32 mask,u32 val)9199ad32a4SBo Jiao mt76_wmac_spi_rmw(struct mt7915_dev *dev, u8 adie,
9299ad32a4SBo Jiao 		  u32 addr, u32 mask, u32 val)
9399ad32a4SBo Jiao {
9499ad32a4SBo Jiao 	u32 cur, ret;
9599ad32a4SBo Jiao 
9699ad32a4SBo Jiao 	ret = mt76_wmac_spi_read(dev, adie, addr, &cur);
9799ad32a4SBo Jiao 	if (ret)
9899ad32a4SBo Jiao 		return ret;
9999ad32a4SBo Jiao 
10099ad32a4SBo Jiao 	cur &= ~mask;
10199ad32a4SBo Jiao 	cur |= val;
10299ad32a4SBo Jiao 
10399ad32a4SBo Jiao 	return mt76_wmac_spi_write(dev, adie, addr, cur);
10499ad32a4SBo Jiao }
10599ad32a4SBo Jiao 
10699ad32a4SBo Jiao static int
mt7986_wmac_adie_efuse_read(struct mt7915_dev * dev,u8 adie,u32 addr,u32 * data)10799ad32a4SBo Jiao mt7986_wmac_adie_efuse_read(struct mt7915_dev *dev, u8 adie,
10899ad32a4SBo Jiao 			    u32 addr, u32 *data)
10999ad32a4SBo Jiao {
11099ad32a4SBo Jiao 	int ret, temp;
11199ad32a4SBo Jiao 	u32 val, mask;
11299ad32a4SBo Jiao 
11399ad32a4SBo Jiao 	ret = mt76_wmac_spi_write(dev, adie, MT_ADIE_EFUSE_CFG,
11499ad32a4SBo Jiao 				  MT_ADIE_EFUSE_CTRL_MASK);
11599ad32a4SBo Jiao 	if (ret)
11699ad32a4SBo Jiao 		return ret;
11799ad32a4SBo Jiao 
11899ad32a4SBo Jiao 	ret = mt76_wmac_spi_rmw(dev, adie, MT_ADIE_EFUSE2_CTRL, BIT(30), 0x0);
11999ad32a4SBo Jiao 	if (ret)
12099ad32a4SBo Jiao 		return ret;
12199ad32a4SBo Jiao 
12299ad32a4SBo Jiao 	mask = (MT_ADIE_EFUSE_MODE_MASK | MT_ADIE_EFUSE_ADDR_MASK |
12399ad32a4SBo Jiao 		MT_ADIE_EFUSE_KICK_MASK);
12499ad32a4SBo Jiao 	val = FIELD_PREP(MT_ADIE_EFUSE_MODE_MASK, 0) |
12599ad32a4SBo Jiao 	      FIELD_PREP(MT_ADIE_EFUSE_ADDR_MASK, addr) |
12699ad32a4SBo Jiao 	      FIELD_PREP(MT_ADIE_EFUSE_KICK_MASK, 1);
12799ad32a4SBo Jiao 	ret = mt76_wmac_spi_rmw(dev, adie, MT_ADIE_EFUSE2_CTRL, mask, val);
12899ad32a4SBo Jiao 	if (ret)
12999ad32a4SBo Jiao 		return ret;
13099ad32a4SBo Jiao 
13199ad32a4SBo Jiao 	ret = read_poll_timeout(mt76_wmac_spi_read, temp,
13299ad32a4SBo Jiao 				!temp && !FIELD_GET(MT_ADIE_EFUSE_KICK_MASK, val),
13399ad32a4SBo Jiao 				USEC_PER_MSEC, 50 * USEC_PER_MSEC, false,
13499ad32a4SBo Jiao 				dev, adie, MT_ADIE_EFUSE2_CTRL, &val);
13599ad32a4SBo Jiao 	if (ret)
13699ad32a4SBo Jiao 		return ret;
13799ad32a4SBo Jiao 
13899ad32a4SBo Jiao 	ret = mt76_wmac_spi_read(dev, adie, MT_ADIE_EFUSE2_CTRL, &val);
13999ad32a4SBo Jiao 	if (ret)
14099ad32a4SBo Jiao 		return ret;
14199ad32a4SBo Jiao 
14299ad32a4SBo Jiao 	if (FIELD_GET(MT_ADIE_EFUSE_VALID_MASK, val) == 1)
14399ad32a4SBo Jiao 		ret = mt76_wmac_spi_read(dev, adie, MT_ADIE_EFUSE_RDATA0,
14499ad32a4SBo Jiao 					 data);
14599ad32a4SBo Jiao 
14699ad32a4SBo Jiao 	return ret;
14799ad32a4SBo Jiao }
14899ad32a4SBo Jiao 
mt76_wmac_spi_lock(struct mt7915_dev * dev)14999ad32a4SBo Jiao static inline void mt76_wmac_spi_lock(struct mt7915_dev *dev)
15099ad32a4SBo Jiao {
15199ad32a4SBo Jiao 	u32 cur;
15299ad32a4SBo Jiao 
15399ad32a4SBo Jiao 	read_poll_timeout(mt76_rr, cur,
15499ad32a4SBo Jiao 			  FIELD_GET(MT_SEMA_RFSPI_STATUS_MASK, cur),
15599ad32a4SBo Jiao 			  1000, 1000 * MSEC_PER_SEC, false, dev,
15699ad32a4SBo Jiao 			  MT_SEMA_RFSPI_STATUS);
15799ad32a4SBo Jiao }
15899ad32a4SBo Jiao 
mt76_wmac_spi_unlock(struct mt7915_dev * dev)15999ad32a4SBo Jiao static inline void mt76_wmac_spi_unlock(struct mt7915_dev *dev)
16099ad32a4SBo Jiao {
16199ad32a4SBo Jiao 	mt76_wr(dev, MT_SEMA_RFSPI_RELEASE, 1);
16299ad32a4SBo Jiao }
16399ad32a4SBo Jiao 
mt76_wmac_rmw(void __iomem * base,u32 offset,u32 mask,u32 val)16499ad32a4SBo Jiao static u32 mt76_wmac_rmw(void __iomem *base, u32 offset, u32 mask, u32 val)
16599ad32a4SBo Jiao {
16699ad32a4SBo Jiao 	val |= readl(base + offset) & ~mask;
16799ad32a4SBo Jiao 	writel(val, base + offset);
16899ad32a4SBo Jiao 
16999ad32a4SBo Jiao 	return val;
17099ad32a4SBo Jiao }
17199ad32a4SBo Jiao 
mt798x_wmac_check_adie_type(struct mt7915_dev * dev)17299ad32a4SBo Jiao static u8 mt798x_wmac_check_adie_type(struct mt7915_dev *dev)
17399ad32a4SBo Jiao {
17499ad32a4SBo Jiao 	u32 val;
17599ad32a4SBo Jiao 
17699ad32a4SBo Jiao 	/* Only DBDC A-die is used with MT7981 */
17799ad32a4SBo Jiao 	if (is_mt7981(&dev->mt76))
17899ad32a4SBo Jiao 		return ADIE_DBDC;
17999ad32a4SBo Jiao 
18099ad32a4SBo Jiao 	val = readl(dev->sku + MT_TOP_POS_SKU);
18199ad32a4SBo Jiao 
18299ad32a4SBo Jiao 	return FIELD_GET(MT_TOP_POS_SKU_ADIE_DBDC_MASK, val);
18399ad32a4SBo Jiao }
18499ad32a4SBo Jiao 
mt7986_wmac_consys_reset(struct mt7915_dev * dev,bool enable)18599ad32a4SBo Jiao static int mt7986_wmac_consys_reset(struct mt7915_dev *dev, bool enable)
18699ad32a4SBo Jiao {
18799ad32a4SBo Jiao 	if (!enable)
18899ad32a4SBo Jiao 		return reset_control_assert(dev->rstc);
18999ad32a4SBo Jiao 
19099ad32a4SBo Jiao 	mt76_wmac_rmw(dev->sku, MT_TOP_POS_FAST_CTRL,
19199ad32a4SBo Jiao 		      MT_TOP_POS_FAST_EN_MASK,
19299ad32a4SBo Jiao 		      FIELD_PREP(MT_TOP_POS_FAST_EN_MASK, 0x1));
19399ad32a4SBo Jiao 
19499ad32a4SBo Jiao 	return reset_control_deassert(dev->rstc);
19599ad32a4SBo Jiao }
19699ad32a4SBo Jiao 
mt7986_wmac_gpio_setup(struct mt7915_dev * dev)19799ad32a4SBo Jiao static int mt7986_wmac_gpio_setup(struct mt7915_dev *dev)
19899ad32a4SBo Jiao {
19901318bc0SDan Carpenter 	struct pinctrl_state *state;
20001318bc0SDan Carpenter 	struct pinctrl *pinctrl;
20199ad32a4SBo Jiao 	int ret;
20299ad32a4SBo Jiao 	u8 type;
20399ad32a4SBo Jiao 
20499ad32a4SBo Jiao 	type = mt798x_wmac_check_adie_type(dev);
20599ad32a4SBo Jiao 	pinctrl = devm_pinctrl_get(dev->mt76.dev);
20699ad32a4SBo Jiao 	if (IS_ERR(pinctrl))
20799ad32a4SBo Jiao 		return PTR_ERR(pinctrl);
20899ad32a4SBo Jiao 
20999ad32a4SBo Jiao 	switch (type) {
21099ad32a4SBo Jiao 	case ADIE_SB:
21199ad32a4SBo Jiao 		state = pinctrl_lookup_state(pinctrl, "default");
21299ad32a4SBo Jiao 		if (IS_ERR_OR_NULL(state))
2139bd6823fSLorenzo Bianconi 			return -EINVAL;
2149bd6823fSLorenzo Bianconi 		break;
21599ad32a4SBo Jiao 	case ADIE_DBDC:
21699ad32a4SBo Jiao 		state = pinctrl_lookup_state(pinctrl, "dbdc");
21799ad32a4SBo Jiao 		if (IS_ERR_OR_NULL(state))
21899ad32a4SBo Jiao 			return -EINVAL;
21999ad32a4SBo Jiao 		break;
22099ad32a4SBo Jiao 	default:
22199ad32a4SBo Jiao 		return -EINVAL;
22299ad32a4SBo Jiao 	}
22399ad32a4SBo Jiao 
22499ad32a4SBo Jiao 	ret = pinctrl_select_state(pinctrl, state);
22599ad32a4SBo Jiao 	if (ret)
22699ad32a4SBo Jiao 		return ret;
22799ad32a4SBo Jiao 
22899ad32a4SBo Jiao 	usleep_range(500, 1000);
22999ad32a4SBo Jiao 
23099ad32a4SBo Jiao 	return 0;
23199ad32a4SBo Jiao }
23299ad32a4SBo Jiao 
mt7986_wmac_consys_lockup(struct mt7915_dev * dev,bool enable)23399ad32a4SBo Jiao static int mt7986_wmac_consys_lockup(struct mt7915_dev *dev, bool enable)
23499ad32a4SBo Jiao {
23599ad32a4SBo Jiao 	int ret;
23699ad32a4SBo Jiao 	u32 cur;
23799ad32a4SBo Jiao 
23899ad32a4SBo Jiao 	mt76_wmac_rmw(dev->dcm, MT_INFRACFG_AP2CONN_SLPPROT,
23999ad32a4SBo Jiao 		      MT_INFRACFG_RX_EN_MASK,
24099ad32a4SBo Jiao 		      FIELD_PREP(MT_INFRACFG_RX_EN_MASK, enable));
24199ad32a4SBo Jiao 	ret = read_poll_timeout(readl, cur, !(cur & MT_INFRACFG_RX_EN_MASK),
24299ad32a4SBo Jiao 				USEC_PER_MSEC, 50 * USEC_PER_MSEC, false,
24399ad32a4SBo Jiao 				dev->dcm + MT_INFRACFG_AP2CONN_SLPPROT);
24499ad32a4SBo Jiao 	if (ret)
24599ad32a4SBo Jiao 		return ret;
24699ad32a4SBo Jiao 
24799ad32a4SBo Jiao 	mt76_wmac_rmw(dev->dcm, MT_INFRACFG_AP2CONN_SLPPROT,
24899ad32a4SBo Jiao 		      MT_INFRACFG_TX_EN_MASK,
24999ad32a4SBo Jiao 		      FIELD_PREP(MT_INFRACFG_TX_EN_MASK, enable));
25099ad32a4SBo Jiao 	ret = read_poll_timeout(readl, cur, !(cur & MT_INFRACFG_TX_RDY_MASK),
25199ad32a4SBo Jiao 				USEC_PER_MSEC, 50 * USEC_PER_MSEC, false,
25299ad32a4SBo Jiao 				dev->dcm + MT_INFRACFG_AP2CONN_SLPPROT);
25399ad32a4SBo Jiao 	if (ret)
25499ad32a4SBo Jiao 		return ret;
25599ad32a4SBo Jiao 
25699ad32a4SBo Jiao 	mt76_wmac_rmw(dev->dcm, MT_INFRACFG_CONN2AP_SLPPROT,
25799ad32a4SBo Jiao 		      MT_INFRACFG_RX_EN_MASK,
25899ad32a4SBo Jiao 		      FIELD_PREP(MT_INFRACFG_RX_EN_MASK, enable));
25999ad32a4SBo Jiao 	mt76_wmac_rmw(dev->dcm, MT_INFRACFG_CONN2AP_SLPPROT,
26099ad32a4SBo Jiao 		      MT_INFRACFG_TX_EN_MASK,
26199ad32a4SBo Jiao 		      FIELD_PREP(MT_INFRACFG_TX_EN_MASK, enable));
26299ad32a4SBo Jiao 
26399ad32a4SBo Jiao 	return 0;
26499ad32a4SBo Jiao }
26599ad32a4SBo Jiao 
mt798x_wmac_coninfra_check(struct mt7915_dev * dev)26699ad32a4SBo Jiao static int mt798x_wmac_coninfra_check(struct mt7915_dev *dev)
26799ad32a4SBo Jiao {
26899ad32a4SBo Jiao 	u32 cur;
26999ad32a4SBo Jiao 	u32 con_infra_version;
27099ad32a4SBo Jiao 
27199ad32a4SBo Jiao 	if (is_mt7981(&dev->mt76)) {
27299ad32a4SBo Jiao 		con_infra_version = MT7981_CON_INFRA_VERSION;
27399ad32a4SBo Jiao 	} else if (is_mt7986(&dev->mt76)) {
27499ad32a4SBo Jiao 		con_infra_version = MT7986_CON_INFRA_VERSION;
27599ad32a4SBo Jiao 	} else {
27699ad32a4SBo Jiao 		WARN_ON(1);
27799ad32a4SBo Jiao 		return -EINVAL;
27899ad32a4SBo Jiao 	}
27999ad32a4SBo Jiao 
28018425d7dSWang Yufen 	return read_poll_timeout(mt76_rr, cur, (cur == con_infra_version),
28199ad32a4SBo Jiao 				 USEC_PER_MSEC, 50 * USEC_PER_MSEC,
28299ad32a4SBo Jiao 				 false, dev, MT_CONN_INFRA_BASE);
28399ad32a4SBo Jiao }
28499ad32a4SBo Jiao 
mt798x_wmac_coninfra_setup(struct mt7915_dev * dev)28599ad32a4SBo Jiao static int mt798x_wmac_coninfra_setup(struct mt7915_dev *dev)
28699ad32a4SBo Jiao {
28799ad32a4SBo Jiao 	struct device *pdev = dev->mt76.dev;
28899ad32a4SBo Jiao 	struct reserved_mem *rmem;
28999ad32a4SBo Jiao 	struct device_node *np;
29099ad32a4SBo Jiao 	u32 val;
29199ad32a4SBo Jiao 
29299ad32a4SBo Jiao 	np = of_parse_phandle(pdev->of_node, "memory-region", 0);
29399ad32a4SBo Jiao 	if (!np)
29499ad32a4SBo Jiao 		return -EINVAL;
29599ad32a4SBo Jiao 
29699ad32a4SBo Jiao 	rmem = of_reserved_mem_lookup(np);
29799ad32a4SBo Jiao 	of_node_put(np);
29899ad32a4SBo Jiao 	if (!rmem)
29999ad32a4SBo Jiao 		return -EINVAL;
30099ad32a4SBo Jiao 
30199ad32a4SBo Jiao 	val = (rmem->base >> 16) & MT_TOP_MCU_EMI_BASE_MASK;
30299ad32a4SBo Jiao 
30399ad32a4SBo Jiao 	if (is_mt7986(&dev->mt76)) {
30499ad32a4SBo Jiao 		/* Set conninfra subsys PLL check */
30599ad32a4SBo Jiao 		mt76_rmw_field(dev, MT_INFRA_CKGEN_BUS,
30699ad32a4SBo Jiao 			       MT_INFRA_CKGEN_BUS_RDY_SEL_MASK, 0x1);
30799ad32a4SBo Jiao 		mt76_rmw_field(dev, MT_INFRA_CKGEN_BUS,
30899ad32a4SBo Jiao 			       MT_INFRA_CKGEN_BUS_RDY_SEL_MASK, 0x1);
30999ad32a4SBo Jiao 	}
31099ad32a4SBo Jiao 
31199ad32a4SBo Jiao 	mt76_rmw_field(dev, MT_TOP_MCU_EMI_BASE,
31299ad32a4SBo Jiao 		       MT_TOP_MCU_EMI_BASE_MASK, val);
31399ad32a4SBo Jiao 
31499ad32a4SBo Jiao 	if (is_mt7981(&dev->mt76)) {
31599ad32a4SBo Jiao 		mt76_rmw_field(dev, MT_TOP_WF_AP_PERI_BASE,
31699ad32a4SBo Jiao 			       MT_TOP_WF_AP_PERI_BASE_MASK, 0x300d0000 >> 16);
31799ad32a4SBo Jiao 
31899ad32a4SBo Jiao 		mt76_rmw_field(dev, MT_TOP_EFUSE_BASE,
31999ad32a4SBo Jiao 			       MT_TOP_EFUSE_BASE_MASK, 0x11f20000 >> 16);
32099ad32a4SBo Jiao 	}
32199ad32a4SBo Jiao 
32299ad32a4SBo Jiao 	mt76_wr(dev, MT_INFRA_BUS_EMI_START, rmem->base);
32399ad32a4SBo Jiao 	mt76_wr(dev, MT_INFRA_BUS_EMI_END, rmem->size);
32499ad32a4SBo Jiao 
32599ad32a4SBo Jiao 	mt76_rr(dev, MT_CONN_INFRA_EFUSE);
32699ad32a4SBo Jiao 
32799ad32a4SBo Jiao 	/* Set conninfra sysram */
32899ad32a4SBo Jiao 	mt76_wr(dev, MT_TOP_RGU_SYSRAM_PDN, 0);
32999ad32a4SBo Jiao 	mt76_wr(dev, MT_TOP_RGU_SYSRAM_SLP, 1);
33099ad32a4SBo Jiao 
33199ad32a4SBo Jiao 	return 0;
33299ad32a4SBo Jiao }
33399ad32a4SBo Jiao 
mt798x_wmac_sku_setup(struct mt7915_dev * dev,u32 * adie_type)33499ad32a4SBo Jiao static int mt798x_wmac_sku_setup(struct mt7915_dev *dev, u32 *adie_type)
33599ad32a4SBo Jiao {
33699ad32a4SBo Jiao 	int ret;
33799ad32a4SBo Jiao 	u32 adie_main = 0, adie_ext = 0;
33899ad32a4SBo Jiao 
33999ad32a4SBo Jiao 	mt76_rmw_field(dev, MT_CONN_INFRA_ADIE_RESET,
34099ad32a4SBo Jiao 		       MT_CONN_INFRA_ADIE1_RESET_MASK, 0x1);
34199ad32a4SBo Jiao 
34299ad32a4SBo Jiao 	if (is_mt7986(&dev->mt76)) {
34399ad32a4SBo Jiao 		mt76_rmw_field(dev, MT_CONN_INFRA_ADIE_RESET,
34499ad32a4SBo Jiao 			       MT_CONN_INFRA_ADIE2_RESET_MASK, 0x1);
34599ad32a4SBo Jiao 	}
34699ad32a4SBo Jiao 
34799ad32a4SBo Jiao 	mt76_wmac_spi_lock(dev);
34899ad32a4SBo Jiao 
34999ad32a4SBo Jiao 	ret = mt76_wmac_spi_read(dev, 0, MT_ADIE_CHIP_ID, &adie_main);
35099ad32a4SBo Jiao 	if (ret)
35199ad32a4SBo Jiao 		goto out;
35299ad32a4SBo Jiao 
35399ad32a4SBo Jiao 	if (is_mt7986(&dev->mt76)) {
35499ad32a4SBo Jiao 		ret = mt76_wmac_spi_read(dev, 1, MT_ADIE_CHIP_ID, &adie_ext);
35599ad32a4SBo Jiao 		if (ret)
35699ad32a4SBo Jiao 			goto out;
35799ad32a4SBo Jiao 	}
35899ad32a4SBo Jiao 
35999ad32a4SBo Jiao 	*adie_type = FIELD_GET(MT_ADIE_CHIP_ID_MASK, adie_main) |
36099ad32a4SBo Jiao 		     (MT_ADIE_CHIP_ID_MASK & adie_ext);
36199ad32a4SBo Jiao 
36299ad32a4SBo Jiao out:
36399ad32a4SBo Jiao 	mt76_wmac_spi_unlock(dev);
36499ad32a4SBo Jiao 
36599ad32a4SBo Jiao 	return 0;
36699ad32a4SBo Jiao }
36799ad32a4SBo Jiao 
mt7986_adie_idx(u8 adie,u32 adie_type)36899ad32a4SBo Jiao static inline u16 mt7986_adie_idx(u8 adie, u32 adie_type)
36999ad32a4SBo Jiao {
37099ad32a4SBo Jiao 	if (adie == 0)
37199ad32a4SBo Jiao 		return u32_get_bits(adie_type, MT_ADIE_IDX0);
37299ad32a4SBo Jiao 	else
37399ad32a4SBo Jiao 		return u32_get_bits(adie_type, MT_ADIE_IDX1);
37499ad32a4SBo Jiao }
37599ad32a4SBo Jiao 
is_7975(struct mt7915_dev * dev,u8 adie,u32 adie_type)37699ad32a4SBo Jiao static inline bool is_7975(struct mt7915_dev *dev, u8 adie, u32 adie_type)
37799ad32a4SBo Jiao {
37899ad32a4SBo Jiao 	return mt7986_adie_idx(adie, adie_type) == 0x7975;
37999ad32a4SBo Jiao }
38099ad32a4SBo Jiao 
is_7976(struct mt7915_dev * dev,u8 adie,u32 adie_type)38199ad32a4SBo Jiao static inline bool is_7976(struct mt7915_dev *dev, u8 adie, u32 adie_type)
38299ad32a4SBo Jiao {
38399ad32a4SBo Jiao 	return mt7986_adie_idx(adie, adie_type) == 0x7976;
38499ad32a4SBo Jiao }
38599ad32a4SBo Jiao 
mt7986_wmac_adie_thermal_cal(struct mt7915_dev * dev,u8 adie)38699ad32a4SBo Jiao static int mt7986_wmac_adie_thermal_cal(struct mt7915_dev *dev, u8 adie)
38799ad32a4SBo Jiao {
38899ad32a4SBo Jiao 	int ret;
38999ad32a4SBo Jiao 	u32 data, val;
39099ad32a4SBo Jiao 
39199ad32a4SBo Jiao 	ret = mt7986_wmac_adie_efuse_read(dev, adie, MT_ADIE_THADC_ANALOG,
39299ad32a4SBo Jiao 					  &data);
39399ad32a4SBo Jiao 	if (ret || FIELD_GET(MT_ADIE_ANA_EN_MASK, data)) {
39499ad32a4SBo Jiao 		val = FIELD_GET(MT_ADIE_VRPI_SEL_EFUSE_MASK, data);
39599ad32a4SBo Jiao 		ret = mt76_wmac_spi_rmw(dev, adie, MT_ADIE_RG_TOP_THADC_BG,
39699ad32a4SBo Jiao 					MT_ADIE_VRPI_SEL_CR_MASK,
39799ad32a4SBo Jiao 					FIELD_PREP(MT_ADIE_VRPI_SEL_CR_MASK, val));
39899ad32a4SBo Jiao 		if (ret)
39999ad32a4SBo Jiao 			return ret;
40099ad32a4SBo Jiao 
40199ad32a4SBo Jiao 		val = FIELD_GET(MT_ADIE_PGA_GAIN_EFUSE_MASK, data);
40299ad32a4SBo Jiao 		ret = mt76_wmac_spi_rmw(dev, adie, MT_ADIE_RG_TOP_THADC,
40399ad32a4SBo Jiao 					MT_ADIE_PGA_GAIN_MASK,
40499ad32a4SBo Jiao 					FIELD_PREP(MT_ADIE_PGA_GAIN_MASK, val));
40599ad32a4SBo Jiao 		if (ret)
40699ad32a4SBo Jiao 			return ret;
40799ad32a4SBo Jiao 	}
40899ad32a4SBo Jiao 
40999ad32a4SBo Jiao 	ret = mt7986_wmac_adie_efuse_read(dev, adie, MT_ADIE_THADC_SLOP,
41099ad32a4SBo Jiao 					  &data);
41199ad32a4SBo Jiao 	if (ret || FIELD_GET(MT_ADIE_ANA_EN_MASK, data)) {
41299ad32a4SBo Jiao 		val = FIELD_GET(MT_ADIE_LDO_CTRL_EFUSE_MASK, data);
41399ad32a4SBo Jiao 
41499ad32a4SBo Jiao 		return mt76_wmac_spi_rmw(dev, adie, MT_ADIE_RG_TOP_THADC,
41599ad32a4SBo Jiao 					 MT_ADIE_LDO_CTRL_MASK,
41699ad32a4SBo Jiao 					 FIELD_PREP(MT_ADIE_LDO_CTRL_MASK, val));
41799ad32a4SBo Jiao 	}
41899ad32a4SBo Jiao 
41999ad32a4SBo Jiao 	return 0;
42099ad32a4SBo Jiao }
42199ad32a4SBo Jiao 
42299ad32a4SBo Jiao static int
mt7986_read_efuse_xo_trim_7976(struct mt7915_dev * dev,u8 adie,bool is_40m,int * result)42399ad32a4SBo Jiao mt7986_read_efuse_xo_trim_7976(struct mt7915_dev *dev, u8 adie,
42499ad32a4SBo Jiao 			       bool is_40m, int *result)
42599ad32a4SBo Jiao {
42699ad32a4SBo Jiao 	int ret;
42799ad32a4SBo Jiao 	u32 data, addr;
42899ad32a4SBo Jiao 
42999ad32a4SBo Jiao 	addr = is_40m ? MT_ADIE_XTAL_AXM_40M_OSC : MT_ADIE_XTAL_AXM_80M_OSC;
43099ad32a4SBo Jiao 	ret = mt7986_wmac_adie_efuse_read(dev, adie, addr, &data);
43199ad32a4SBo Jiao 	if (ret)
43299ad32a4SBo Jiao 		return ret;
43399ad32a4SBo Jiao 
43499ad32a4SBo Jiao 	if (!FIELD_GET(MT_ADIE_XO_TRIM_EN_MASK, data)) {
43599ad32a4SBo Jiao 		*result = 64;
43699ad32a4SBo Jiao 	} else {
43799ad32a4SBo Jiao 		*result = FIELD_GET(MT_ADIE_TRIM_MASK, data);
43899ad32a4SBo Jiao 		addr = is_40m ? MT_ADIE_XTAL_TRIM1_40M_OSC :
43999ad32a4SBo Jiao 				MT_ADIE_XTAL_TRIM1_80M_OSC;
44099ad32a4SBo Jiao 		ret = mt7986_wmac_adie_efuse_read(dev, adie, addr, &data);
44199ad32a4SBo Jiao 		if (ret)
44299ad32a4SBo Jiao 			return ret;
44399ad32a4SBo Jiao 
44499ad32a4SBo Jiao 		if (FIELD_GET(MT_ADIE_XO_TRIM_EN_MASK, data) &&
44599ad32a4SBo Jiao 		    FIELD_GET(MT_ADIE_XTAL_DECREASE_MASK, data))
44699ad32a4SBo Jiao 			*result -= FIELD_GET(MT_ADIE_EFUSE_TRIM_MASK, data);
44799ad32a4SBo Jiao 		else if (FIELD_GET(MT_ADIE_XO_TRIM_EN_MASK, data))
44899ad32a4SBo Jiao 			*result += FIELD_GET(MT_ADIE_EFUSE_TRIM_MASK, data);
44999ad32a4SBo Jiao 
45099ad32a4SBo Jiao 		*result = max(0, min(127, *result));
45199ad32a4SBo Jiao 	}
45299ad32a4SBo Jiao 
45399ad32a4SBo Jiao 	return 0;
45499ad32a4SBo Jiao }
45599ad32a4SBo Jiao 
mt7986_wmac_adie_xtal_trim_7976(struct mt7915_dev * dev,u8 adie)45699ad32a4SBo Jiao static int mt7986_wmac_adie_xtal_trim_7976(struct mt7915_dev *dev, u8 adie)
45799ad32a4SBo Jiao {
45899ad32a4SBo Jiao 	int ret, trim_80m, trim_40m;
45999ad32a4SBo Jiao 	u32 data, val, mode;
46099ad32a4SBo Jiao 
46199ad32a4SBo Jiao 	ret = mt7986_wmac_adie_efuse_read(dev, adie, MT_ADIE_XO_TRIM_FLOW,
46299ad32a4SBo Jiao 					  &data);
46399ad32a4SBo Jiao 	if (ret || !FIELD_GET(BIT(1), data))
46499ad32a4SBo Jiao 		return 0;
46599ad32a4SBo Jiao 
46699ad32a4SBo Jiao 	ret = mt7986_read_efuse_xo_trim_7976(dev, adie, false, &trim_80m);
46799ad32a4SBo Jiao 	if (ret)
46899ad32a4SBo Jiao 		return ret;
46999ad32a4SBo Jiao 
47099ad32a4SBo Jiao 	ret = mt7986_read_efuse_xo_trim_7976(dev, adie, true, &trim_40m);
47199ad32a4SBo Jiao 	if (ret)
47299ad32a4SBo Jiao 		return ret;
47399ad32a4SBo Jiao 
474b5509983SPeter Chiu 	ret = mt76_wmac_spi_read(dev, adie, MT_ADIE_RG_STRAP_PIN_IN, &val);
47599ad32a4SBo Jiao 	if (ret)
47699ad32a4SBo Jiao 		return ret;
477b5509983SPeter Chiu 
478b5509983SPeter Chiu 	mode = FIELD_PREP(GENMASK(6, 4), val);
479b5509983SPeter Chiu 	if (!mode || mode == 0x2) {
480b5509983SPeter Chiu 		ret = mt76_wmac_spi_rmw(dev, adie, MT_ADIE_XTAL_C1,
481b5509983SPeter Chiu 					GENMASK(31, 24),
482b5509983SPeter Chiu 					FIELD_PREP(GENMASK(31, 24), trim_80m));
48399ad32a4SBo Jiao 		if (ret)
48499ad32a4SBo Jiao 			return ret;
48599ad32a4SBo Jiao 
48699ad32a4SBo Jiao 		ret = mt76_wmac_spi_rmw(dev, adie, MT_ADIE_XTAL_C2,
487b5509983SPeter Chiu 					GENMASK(31, 24),
488b5509983SPeter Chiu 					FIELD_PREP(GENMASK(31, 24), trim_80m));
489b5509983SPeter Chiu 	} else if (mode == 0x3 || mode == 0x4 || mode == 0x6) {
490b5509983SPeter Chiu 		ret = mt76_wmac_spi_rmw(dev, adie, MT_ADIE_XTAL_C1,
491b5509983SPeter Chiu 					GENMASK(23, 16),
492b5509983SPeter Chiu 					FIELD_PREP(GENMASK(23, 16), trim_40m));
493b5509983SPeter Chiu 		if (ret)
494b5509983SPeter Chiu 			return ret;
495b5509983SPeter Chiu 
49699ad32a4SBo Jiao 		ret = mt76_wmac_spi_rmw(dev, adie, MT_ADIE_XTAL_C2,
49799ad32a4SBo Jiao 					GENMASK(23, 16),
49899ad32a4SBo Jiao 					FIELD_PREP(GENMASK(23, 16), trim_40m));
499b5509983SPeter Chiu 	}
50099ad32a4SBo Jiao 
50199ad32a4SBo Jiao 	return ret;
50299ad32a4SBo Jiao }
50399ad32a4SBo Jiao 
mt798x_wmac_adie_patch_7976(struct mt7915_dev * dev,u8 adie)50499ad32a4SBo Jiao static int mt798x_wmac_adie_patch_7976(struct mt7915_dev *dev, u8 adie)
50599ad32a4SBo Jiao {
50699ad32a4SBo Jiao 	u32 id, version, rg_xo_01, rg_xo_03;
50799ad32a4SBo Jiao 	int ret;
50899ad32a4SBo Jiao 
50999ad32a4SBo Jiao 	ret = mt76_wmac_spi_read(dev, adie, MT_ADIE_CHIP_ID, &id);
51099ad32a4SBo Jiao 	if (ret)
51199ad32a4SBo Jiao 		return ret;
51299ad32a4SBo Jiao 
51399ad32a4SBo Jiao 	version = FIELD_GET(MT_ADIE_VERSION_MASK, id);
51499ad32a4SBo Jiao 
51599ad32a4SBo Jiao 	ret = mt76_wmac_spi_write(dev, adie, MT_ADIE_RG_TOP_THADC, 0x4a563b00);
51699ad32a4SBo Jiao 	if (ret)
51799ad32a4SBo Jiao 		return ret;
51899ad32a4SBo Jiao 
51999ad32a4SBo Jiao 	if (version == 0x8a00 || version == 0x8a10 || version == 0x8b00) {
52099ad32a4SBo Jiao 		rg_xo_01 = 0x1d59080f;
52199ad32a4SBo Jiao 		rg_xo_03 = 0x34c00fe0;
52299ad32a4SBo Jiao 	} else {
52399ad32a4SBo Jiao 		if (is_mt7981(&dev->mt76)) {
52499ad32a4SBo Jiao 			rg_xo_01 = 0x1959c80f;
52599ad32a4SBo Jiao 		} else if (is_mt7986(&dev->mt76)) {
52699ad32a4SBo Jiao 			rg_xo_01 = 0x1959f80f;
52799ad32a4SBo Jiao 		} else {
52899ad32a4SBo Jiao 			WARN_ON(1);
52999ad32a4SBo Jiao 			return -EINVAL;
53099ad32a4SBo Jiao 		}
53199ad32a4SBo Jiao 		rg_xo_03 = 0x34d00fe0;
53299ad32a4SBo Jiao 	}
53399ad32a4SBo Jiao 
53499ad32a4SBo Jiao 	ret = mt76_wmac_spi_write(dev, adie, MT_ADIE_RG_XO_01, rg_xo_01);
53599ad32a4SBo Jiao 	if (ret)
53699ad32a4SBo Jiao 		return ret;
53799ad32a4SBo Jiao 
53899ad32a4SBo Jiao 	return mt76_wmac_spi_write(dev, adie, MT_ADIE_RG_XO_03, rg_xo_03);
53999ad32a4SBo Jiao }
54099ad32a4SBo Jiao 
54199ad32a4SBo Jiao static int
mt7986_read_efuse_xo_trim_7975(struct mt7915_dev * dev,u8 adie,u32 addr,u32 * result)54299ad32a4SBo Jiao mt7986_read_efuse_xo_trim_7975(struct mt7915_dev *dev, u8 adie,
54399ad32a4SBo Jiao 			       u32 addr, u32 *result)
54499ad32a4SBo Jiao {
54599ad32a4SBo Jiao 	int ret;
54699ad32a4SBo Jiao 	u32 data;
54799ad32a4SBo Jiao 
54899ad32a4SBo Jiao 	ret = mt7986_wmac_adie_efuse_read(dev, adie, addr, &data);
54999ad32a4SBo Jiao 	if (ret)
55099ad32a4SBo Jiao 		return ret;
55199ad32a4SBo Jiao 
55299ad32a4SBo Jiao 	if ((data & MT_ADIE_XO_TRIM_EN_MASK)) {
55399ad32a4SBo Jiao 		if ((data & MT_ADIE_XTAL_DECREASE_MASK))
55499ad32a4SBo Jiao 			*result -= (data & MT_ADIE_EFUSE_TRIM_MASK);
55599ad32a4SBo Jiao 		else
55699ad32a4SBo Jiao 			*result += (data & MT_ADIE_EFUSE_TRIM_MASK);
55799ad32a4SBo Jiao 
55899ad32a4SBo Jiao 		*result = (*result & MT_ADIE_TRIM_MASK);
55999ad32a4SBo Jiao 	}
56099ad32a4SBo Jiao 
56199ad32a4SBo Jiao 	return 0;
56299ad32a4SBo Jiao }
56399ad32a4SBo Jiao 
mt7986_wmac_adie_xtal_trim_7975(struct mt7915_dev * dev,u8 adie)56499ad32a4SBo Jiao static int mt7986_wmac_adie_xtal_trim_7975(struct mt7915_dev *dev, u8 adie)
56599ad32a4SBo Jiao {
56699ad32a4SBo Jiao 	int ret;
56799ad32a4SBo Jiao 	u32 data, result = 0, value;
56899ad32a4SBo Jiao 
56999ad32a4SBo Jiao 	ret = mt7986_wmac_adie_efuse_read(dev, adie, MT_ADIE_7975_XTAL_EN,
57099ad32a4SBo Jiao 					  &data);
57199ad32a4SBo Jiao 	if (ret || !(data & BIT(1)))
57299ad32a4SBo Jiao 		return 0;
57399ad32a4SBo Jiao 
57499ad32a4SBo Jiao 	ret = mt7986_wmac_adie_efuse_read(dev, adie, MT_ADIE_7975_XTAL_CAL,
57599ad32a4SBo Jiao 					  &data);
57699ad32a4SBo Jiao 	if (ret)
57799ad32a4SBo Jiao 		return ret;
57899ad32a4SBo Jiao 
57999ad32a4SBo Jiao 	if (data & MT_ADIE_XO_TRIM_EN_MASK)
58099ad32a4SBo Jiao 		result = (data & MT_ADIE_TRIM_MASK);
58199ad32a4SBo Jiao 
58299ad32a4SBo Jiao 	ret = mt7986_read_efuse_xo_trim_7975(dev, adie, MT_ADIE_7975_XO_TRIM2,
58399ad32a4SBo Jiao 					     &result);
58499ad32a4SBo Jiao 	if (ret)
58599ad32a4SBo Jiao 		return ret;
58699ad32a4SBo Jiao 
58799ad32a4SBo Jiao 	ret = mt7986_read_efuse_xo_trim_7975(dev, adie, MT_ADIE_7975_XO_TRIM3,
58899ad32a4SBo Jiao 					     &result);
58999ad32a4SBo Jiao 	if (ret)
59099ad32a4SBo Jiao 		return ret;
59199ad32a4SBo Jiao 
59299ad32a4SBo Jiao 	ret = mt7986_read_efuse_xo_trim_7975(dev, adie, MT_ADIE_7975_XO_TRIM4,
59399ad32a4SBo Jiao 					     &result);
59499ad32a4SBo Jiao 	if (ret)
59599ad32a4SBo Jiao 		return ret;
59699ad32a4SBo Jiao 
59799ad32a4SBo Jiao 	/* Update trim value to C1 and C2*/
59899ad32a4SBo Jiao 	value = FIELD_GET(MT_ADIE_7975_XO_CTRL2_C1_MASK, result) |
59999ad32a4SBo Jiao 		FIELD_GET(MT_ADIE_7975_XO_CTRL2_C2_MASK, result);
60099ad32a4SBo Jiao 	ret = mt76_wmac_spi_rmw(dev, adie, MT_ADIE_7975_XO_CTRL2,
60199ad32a4SBo Jiao 				MT_ADIE_7975_XO_CTRL2_MASK, value);
60299ad32a4SBo Jiao 	if (ret)
60399ad32a4SBo Jiao 		return ret;
60499ad32a4SBo Jiao 
60599ad32a4SBo Jiao 	ret = mt76_wmac_spi_read(dev, adie, MT_ADIE_7975_XTAL, &value);
60699ad32a4SBo Jiao 	if (ret)
60799ad32a4SBo Jiao 		return ret;
60899ad32a4SBo Jiao 
60999ad32a4SBo Jiao 	if (value & MT_ADIE_7975_XTAL_EN_MASK) {
61099ad32a4SBo Jiao 		ret = mt76_wmac_spi_rmw(dev, adie, MT_ADIE_7975_XO_2,
61199ad32a4SBo Jiao 					MT_ADIE_7975_XO_2_FIX_EN, 0x0);
61299ad32a4SBo Jiao 		if (ret)
61399ad32a4SBo Jiao 			return ret;
61499ad32a4SBo Jiao 	}
61599ad32a4SBo Jiao 
61699ad32a4SBo Jiao 	return mt76_wmac_spi_rmw(dev, adie, MT_ADIE_7975_XO_CTRL6,
61799ad32a4SBo Jiao 				 MT_ADIE_7975_XO_CTRL6_MASK, 0x1);
61899ad32a4SBo Jiao }
61999ad32a4SBo Jiao 
mt7986_wmac_adie_patch_7975(struct mt7915_dev * dev,u8 adie)62099ad32a4SBo Jiao static int mt7986_wmac_adie_patch_7975(struct mt7915_dev *dev, u8 adie)
62199ad32a4SBo Jiao {
62299ad32a4SBo Jiao 	int ret;
62399ad32a4SBo Jiao 
62499ad32a4SBo Jiao 	/* disable CAL LDO and fine tune RFDIG LDO */
62599ad32a4SBo Jiao 	ret = mt76_wmac_spi_write(dev, adie, 0x348, 0x00000002);
62699ad32a4SBo Jiao 	if (ret)
62799ad32a4SBo Jiao 		return ret;
62899ad32a4SBo Jiao 
62999ad32a4SBo Jiao 	ret = mt76_wmac_spi_write(dev, adie, 0x378, 0x00000002);
63099ad32a4SBo Jiao 	if (ret)
63199ad32a4SBo Jiao 		return ret;
63299ad32a4SBo Jiao 
63399ad32a4SBo Jiao 	ret = mt76_wmac_spi_write(dev, adie, 0x3a8, 0x00000002);
63499ad32a4SBo Jiao 	if (ret)
63599ad32a4SBo Jiao 		return ret;
63699ad32a4SBo Jiao 
63799ad32a4SBo Jiao 	ret = mt76_wmac_spi_write(dev, adie, 0x3d8, 0x00000002);
63899ad32a4SBo Jiao 	if (ret)
63999ad32a4SBo Jiao 		return ret;
64099ad32a4SBo Jiao 
64199ad32a4SBo Jiao 	/* set CKA driving and filter */
64299ad32a4SBo Jiao 	ret = mt76_wmac_spi_write(dev, adie, 0xa1c, 0x30000aaa);
64399ad32a4SBo Jiao 	if (ret)
64499ad32a4SBo Jiao 		return ret;
64599ad32a4SBo Jiao 
64699ad32a4SBo Jiao 	/* set CKB LDO to 1.4V */
64799ad32a4SBo Jiao 	ret = mt76_wmac_spi_write(dev, adie, 0xa84, 0x8470008a);
64899ad32a4SBo Jiao 	if (ret)
64999ad32a4SBo Jiao 		return ret;
65099ad32a4SBo Jiao 
65199ad32a4SBo Jiao 	/* turn on SX0 LTBUF */
65299ad32a4SBo Jiao 	if (is_mt7981(&dev->mt76)) {
65399ad32a4SBo Jiao 		ret = mt76_wmac_spi_write(dev, adie, 0x074, 0x00000007);
65499ad32a4SBo Jiao 	} else if (is_mt7986(&dev->mt76)) {
65599ad32a4SBo Jiao 		ret = mt76_wmac_spi_write(dev, adie, 0x074, 0x00000002);
65699ad32a4SBo Jiao 	} else {
65799ad32a4SBo Jiao 		WARN_ON(1);
65899ad32a4SBo Jiao 		return -EINVAL;
65999ad32a4SBo Jiao 	}
66099ad32a4SBo Jiao 
66199ad32a4SBo Jiao 	if (ret)
66299ad32a4SBo Jiao 		return ret;
66399ad32a4SBo Jiao 
66499ad32a4SBo Jiao 	/* CK_BUF_SW_EN = 1 (all buf in manual mode.) */
66599ad32a4SBo Jiao 	ret = mt76_wmac_spi_write(dev, adie, 0xaa4, 0x01001fc0);
66699ad32a4SBo Jiao 	if (ret)
66799ad32a4SBo Jiao 		return ret;
66899ad32a4SBo Jiao 
66999ad32a4SBo Jiao 	/* BT mode/WF normal mode 00000005 */
67099ad32a4SBo Jiao 	ret = mt76_wmac_spi_write(dev, adie, 0x070, 0x00000005);
67199ad32a4SBo Jiao 	if (ret)
67299ad32a4SBo Jiao 		return ret;
67399ad32a4SBo Jiao 
67499ad32a4SBo Jiao 	/* BG thermal sensor offset update */
67599ad32a4SBo Jiao 	ret = mt76_wmac_spi_write(dev, adie, 0x344, 0x00000088);
67699ad32a4SBo Jiao 	if (ret)
67799ad32a4SBo Jiao 		return ret;
67899ad32a4SBo Jiao 
67999ad32a4SBo Jiao 	ret = mt76_wmac_spi_write(dev, adie, 0x374, 0x00000088);
68099ad32a4SBo Jiao 	if (ret)
68199ad32a4SBo Jiao 		return ret;
68299ad32a4SBo Jiao 
68399ad32a4SBo Jiao 	ret = mt76_wmac_spi_write(dev, adie, 0x3a4, 0x00000088);
68499ad32a4SBo Jiao 	if (ret)
68599ad32a4SBo Jiao 		return ret;
68699ad32a4SBo Jiao 
68799ad32a4SBo Jiao 	ret = mt76_wmac_spi_write(dev, adie, 0x3d4, 0x00000088);
68899ad32a4SBo Jiao 	if (ret)
68999ad32a4SBo Jiao 		return ret;
69099ad32a4SBo Jiao 
69199ad32a4SBo Jiao 	/* set WCON VDD IPTAT to "0000" */
69299ad32a4SBo Jiao 	ret = mt76_wmac_spi_write(dev, adie, 0xa80, 0x44d07000);
69399ad32a4SBo Jiao 	if (ret)
69499ad32a4SBo Jiao 		return ret;
69599ad32a4SBo Jiao 
69699ad32a4SBo Jiao 	/* change back LTBUF SX3 drving to default value */
69799ad32a4SBo Jiao 	ret = mt76_wmac_spi_write(dev, adie, 0xa88, 0x3900aaaa);
69899ad32a4SBo Jiao 	if (ret)
69999ad32a4SBo Jiao 		return ret;
70099ad32a4SBo Jiao 
70199ad32a4SBo Jiao 	/* SM input cap off */
70299ad32a4SBo Jiao 	ret = mt76_wmac_spi_write(dev, adie, 0x2c4, 0x00000000);
70399ad32a4SBo Jiao 	if (ret)
70499ad32a4SBo Jiao 		return ret;
70599ad32a4SBo Jiao 
70699ad32a4SBo Jiao 	/* set CKB driving and filter */
70799ad32a4SBo Jiao 	if (is_mt7986(&dev->mt76))
70899ad32a4SBo Jiao 		return mt76_wmac_spi_write(dev, adie, 0x2c8, 0x00000072);
70999ad32a4SBo Jiao 
71099ad32a4SBo Jiao 	return ret;
71199ad32a4SBo Jiao }
71299ad32a4SBo Jiao 
mt7986_wmac_adie_cfg(struct mt7915_dev * dev,u8 adie,u32 adie_type)71399ad32a4SBo Jiao static int mt7986_wmac_adie_cfg(struct mt7915_dev *dev, u8 adie, u32 adie_type)
71499ad32a4SBo Jiao {
71599ad32a4SBo Jiao 	int ret;
71699ad32a4SBo Jiao 
71799ad32a4SBo Jiao 	mt76_wmac_spi_lock(dev);
71899ad32a4SBo Jiao 	ret = mt76_wmac_spi_write(dev, adie, MT_ADIE_CLK_EN, ~0);
71999ad32a4SBo Jiao 	if (ret)
72099ad32a4SBo Jiao 		goto out;
72199ad32a4SBo Jiao 
72299ad32a4SBo Jiao 	if (is_7975(dev, adie, adie_type)) {
72399ad32a4SBo Jiao 		ret = mt76_wmac_spi_rmw(dev, adie, MT_ADIE_7975_COCLK,
72499ad32a4SBo Jiao 					BIT(1), 0x1);
72599ad32a4SBo Jiao 		if (ret)
72699ad32a4SBo Jiao 			goto out;
72799ad32a4SBo Jiao 
72899ad32a4SBo Jiao 		ret = mt7986_wmac_adie_thermal_cal(dev, adie);
72999ad32a4SBo Jiao 		if (ret)
73099ad32a4SBo Jiao 			goto out;
73199ad32a4SBo Jiao 
73299ad32a4SBo Jiao 		ret = mt7986_wmac_adie_xtal_trim_7975(dev, adie);
73399ad32a4SBo Jiao 		if (ret)
73499ad32a4SBo Jiao 			goto out;
73599ad32a4SBo Jiao 
73699ad32a4SBo Jiao 		ret = mt7986_wmac_adie_patch_7975(dev, adie);
73799ad32a4SBo Jiao 	} else if (is_7976(dev, adie, adie_type)) {
73899ad32a4SBo Jiao 		if (mt798x_wmac_check_adie_type(dev) == ADIE_DBDC) {
73999ad32a4SBo Jiao 			ret = mt76_wmac_spi_write(dev, adie,
74099ad32a4SBo Jiao 						  MT_ADIE_WRI_CK_SEL, 0x1c);
74199ad32a4SBo Jiao 			if (ret)
74299ad32a4SBo Jiao 				goto out;
74399ad32a4SBo Jiao 		}
74499ad32a4SBo Jiao 
74599ad32a4SBo Jiao 		ret = mt7986_wmac_adie_thermal_cal(dev, adie);
74699ad32a4SBo Jiao 		if (ret)
74799ad32a4SBo Jiao 			goto out;
74899ad32a4SBo Jiao 
74999ad32a4SBo Jiao 		ret = mt7986_wmac_adie_xtal_trim_7976(dev, adie);
75099ad32a4SBo Jiao 		if (ret)
75199ad32a4SBo Jiao 			goto out;
75299ad32a4SBo Jiao 
75399ad32a4SBo Jiao 		ret = mt798x_wmac_adie_patch_7976(dev, adie);
75499ad32a4SBo Jiao 	}
75599ad32a4SBo Jiao out:
75699ad32a4SBo Jiao 	mt76_wmac_spi_unlock(dev);
75799ad32a4SBo Jiao 
75899ad32a4SBo Jiao 	return ret;
75999ad32a4SBo Jiao }
76099ad32a4SBo Jiao 
76199ad32a4SBo Jiao static int
mt7986_wmac_afe_cal(struct mt7915_dev * dev,u8 adie,bool dbdc,u32 adie_type)76299ad32a4SBo Jiao mt7986_wmac_afe_cal(struct mt7915_dev *dev, u8 adie, bool dbdc, u32 adie_type)
76399ad32a4SBo Jiao {
76499ad32a4SBo Jiao 	int ret;
76599ad32a4SBo Jiao 	u8 idx;
76699ad32a4SBo Jiao 	u32 txcal;
76799ad32a4SBo Jiao 
76899ad32a4SBo Jiao 	mt76_wmac_spi_lock(dev);
76999ad32a4SBo Jiao 	if (is_7975(dev, adie, adie_type))
77099ad32a4SBo Jiao 		ret = mt76_wmac_spi_write(dev, adie,
77199ad32a4SBo Jiao 					  MT_AFE_RG_ENCAL_WBTAC_IF_SW,
77299ad32a4SBo Jiao 					  0x80000000);
77399ad32a4SBo Jiao 	else
77499ad32a4SBo Jiao 		ret = mt76_wmac_spi_write(dev, adie,
77599ad32a4SBo Jiao 					  MT_AFE_RG_ENCAL_WBTAC_IF_SW,
77699ad32a4SBo Jiao 					  0x88888005);
77799ad32a4SBo Jiao 	if (ret)
77899ad32a4SBo Jiao 		goto out;
77999ad32a4SBo Jiao 
78099ad32a4SBo Jiao 	idx = dbdc ? ADIE_DBDC : adie;
78199ad32a4SBo Jiao 
78299ad32a4SBo Jiao 	mt76_rmw_field(dev, MT_AFE_DIG_EN_01(idx),
78399ad32a4SBo Jiao 		       MT_AFE_RG_WBG_EN_RCK_MASK, 0x1);
78499ad32a4SBo Jiao 	usleep_range(60, 100);
78599ad32a4SBo Jiao 
78699ad32a4SBo Jiao 	mt76_rmw(dev, MT_AFE_DIG_EN_01(idx),
78799ad32a4SBo Jiao 		 MT_AFE_RG_WBG_EN_RCK_MASK, 0x0);
78899ad32a4SBo Jiao 
78999ad32a4SBo Jiao 	mt76_rmw_field(dev, MT_AFE_DIG_EN_03(idx),
79099ad32a4SBo Jiao 		       MT_AFE_RG_WBG_EN_BPLL_UP_MASK, 0x1);
79199ad32a4SBo Jiao 	usleep_range(30, 100);
79299ad32a4SBo Jiao 
79399ad32a4SBo Jiao 	mt76_rmw_field(dev, MT_AFE_DIG_EN_03(idx),
79499ad32a4SBo Jiao 		       MT_AFE_RG_WBG_EN_WPLL_UP_MASK, 0x1);
79599ad32a4SBo Jiao 	usleep_range(60, 100);
79699ad32a4SBo Jiao 
79799ad32a4SBo Jiao 	txcal = (MT_AFE_RG_WBG_EN_TXCAL_BT |
79899ad32a4SBo Jiao 		      MT_AFE_RG_WBG_EN_TXCAL_WF0 |
79999ad32a4SBo Jiao 		      MT_AFE_RG_WBG_EN_TXCAL_WF1 |
80099ad32a4SBo Jiao 		      MT_AFE_RG_WBG_EN_TXCAL_WF2 |
80199ad32a4SBo Jiao 		      MT_AFE_RG_WBG_EN_TXCAL_WF3);
80299ad32a4SBo Jiao 	if (is_mt7981(&dev->mt76))
80399ad32a4SBo Jiao 		txcal |= MT_AFE_RG_WBG_EN_TXCAL_WF4;
80499ad32a4SBo Jiao 
80599ad32a4SBo Jiao 	mt76_set(dev, MT_AFE_DIG_EN_01(idx), txcal);
80699ad32a4SBo Jiao 	usleep_range(800, 1000);
80799ad32a4SBo Jiao 
80899ad32a4SBo Jiao 	mt76_clear(dev, MT_AFE_DIG_EN_01(idx), txcal);
80999ad32a4SBo Jiao 	mt76_rmw(dev, MT_AFE_DIG_EN_03(idx),
81099ad32a4SBo Jiao 		 MT_AFE_RG_WBG_EN_PLL_UP_MASK, 0x0);
81199ad32a4SBo Jiao 
81299ad32a4SBo Jiao 	ret = mt76_wmac_spi_write(dev, adie, MT_AFE_RG_ENCAL_WBTAC_IF_SW,
81399ad32a4SBo Jiao 				  0x5);
81499ad32a4SBo Jiao 
81599ad32a4SBo Jiao out:
81699ad32a4SBo Jiao 	mt76_wmac_spi_unlock(dev);
81799ad32a4SBo Jiao 
81899ad32a4SBo Jiao 	return ret;
81999ad32a4SBo Jiao }
82099ad32a4SBo Jiao 
mt7986_wmac_subsys_pll_initial(struct mt7915_dev * dev,u8 band)82199ad32a4SBo Jiao static void mt7986_wmac_subsys_pll_initial(struct mt7915_dev *dev, u8 band)
82299ad32a4SBo Jiao {
82399ad32a4SBo Jiao 	mt76_rmw(dev, MT_AFE_PLL_STB_TIME(band),
82499ad32a4SBo Jiao 		 MT_AFE_PLL_STB_TIME_MASK, MT_AFE_PLL_STB_TIME_VAL);
82599ad32a4SBo Jiao 
82699ad32a4SBo Jiao 	mt76_rmw(dev, MT_AFE_DIG_EN_02(band),
82799ad32a4SBo Jiao 		 MT_AFE_PLL_CFG_MASK, MT_AFE_PLL_CFG_VAL);
82899ad32a4SBo Jiao 
82999ad32a4SBo Jiao 	mt76_rmw(dev, MT_AFE_DIG_TOP_01(band),
83099ad32a4SBo Jiao 		 MT_AFE_DIG_TOP_01_MASK, MT_AFE_DIG_TOP_01_VAL);
83199ad32a4SBo Jiao }
83299ad32a4SBo Jiao 
mt7986_wmac_subsys_setting(struct mt7915_dev * dev)83399ad32a4SBo Jiao static void mt7986_wmac_subsys_setting(struct mt7915_dev *dev)
83499ad32a4SBo Jiao {
83599ad32a4SBo Jiao 	/* Subsys pll init */
83699ad32a4SBo Jiao 	mt7986_wmac_subsys_pll_initial(dev, 0);
83799ad32a4SBo Jiao 	mt7986_wmac_subsys_pll_initial(dev, 1);
83899ad32a4SBo Jiao 
83999ad32a4SBo Jiao 	/* Set legacy OSC control stable time*/
84099ad32a4SBo Jiao 	mt76_rmw(dev, MT_CONN_INFRA_OSC_RC_EN,
84199ad32a4SBo Jiao 		 MT_CONN_INFRA_OSC_RC_EN_MASK, 0x0);
84299ad32a4SBo Jiao 	mt76_rmw(dev, MT_CONN_INFRA_OSC_CTRL,
84399ad32a4SBo Jiao 		 MT_CONN_INFRA_OSC_STB_TIME_MASK, 0x80706);
84499ad32a4SBo Jiao 
84599ad32a4SBo Jiao 	/* prevent subsys from power on/of in a short time interval */
84699ad32a4SBo Jiao 	mt76_rmw(dev, MT_TOP_WFSYS_PWR,
84799ad32a4SBo Jiao 		 MT_TOP_PWR_ACK_MASK | MT_TOP_PWR_KEY_MASK,
84899ad32a4SBo Jiao 		 MT_TOP_PWR_KEY);
84999ad32a4SBo Jiao }
85099ad32a4SBo Jiao 
mt7986_wmac_bus_timeout(struct mt7915_dev * dev)85199ad32a4SBo Jiao static int mt7986_wmac_bus_timeout(struct mt7915_dev *dev)
85299ad32a4SBo Jiao {
85399ad32a4SBo Jiao 	mt76_rmw_field(dev, MT_INFRA_BUS_OFF_TIMEOUT,
85499ad32a4SBo Jiao 		       MT_INFRA_BUS_TIMEOUT_LIMIT_MASK, 0x2);
85599ad32a4SBo Jiao 
85699ad32a4SBo Jiao 	mt76_rmw_field(dev, MT_INFRA_BUS_OFF_TIMEOUT,
85799ad32a4SBo Jiao 		       MT_INFRA_BUS_TIMEOUT_EN_MASK, 0xf);
85899ad32a4SBo Jiao 
85999ad32a4SBo Jiao 	mt76_rmw_field(dev, MT_INFRA_BUS_ON_TIMEOUT,
86099ad32a4SBo Jiao 		       MT_INFRA_BUS_TIMEOUT_LIMIT_MASK, 0xc);
86199ad32a4SBo Jiao 
86299ad32a4SBo Jiao 	mt76_rmw_field(dev, MT_INFRA_BUS_ON_TIMEOUT,
86399ad32a4SBo Jiao 		       MT_INFRA_BUS_TIMEOUT_EN_MASK, 0xf);
86499ad32a4SBo Jiao 
86599ad32a4SBo Jiao 	return mt798x_wmac_coninfra_check(dev);
86699ad32a4SBo Jiao }
86799ad32a4SBo Jiao 
mt7986_wmac_clock_enable(struct mt7915_dev * dev,u32 adie_type)86899ad32a4SBo Jiao static void mt7986_wmac_clock_enable(struct mt7915_dev *dev, u32 adie_type)
86999ad32a4SBo Jiao {
87099ad32a4SBo Jiao 	u32 cur;
87199ad32a4SBo Jiao 
87299ad32a4SBo Jiao 	mt76_rmw_field(dev, MT_INFRA_CKGEN_BUS_WPLL_DIV_1,
87399ad32a4SBo Jiao 		       MT_INFRA_CKGEN_DIV_SEL_MASK, 0x1);
87499ad32a4SBo Jiao 
87599ad32a4SBo Jiao 	mt76_rmw_field(dev, MT_INFRA_CKGEN_BUS_WPLL_DIV_2,
87699ad32a4SBo Jiao 		       MT_INFRA_CKGEN_DIV_SEL_MASK, 0x1);
87799ad32a4SBo Jiao 
87899ad32a4SBo Jiao 	mt76_rmw_field(dev, MT_INFRA_CKGEN_BUS_WPLL_DIV_1,
87999ad32a4SBo Jiao 		       MT_INFRA_CKGEN_DIV_EN_MASK, 0x1);
88099ad32a4SBo Jiao 
88199ad32a4SBo Jiao 	mt76_rmw_field(dev, MT_INFRA_CKGEN_BUS_WPLL_DIV_2,
88299ad32a4SBo Jiao 		       MT_INFRA_CKGEN_DIV_EN_MASK, 0x1);
88399ad32a4SBo Jiao 
88499ad32a4SBo Jiao 	mt76_rmw_field(dev, MT_INFRA_CKGEN_RFSPI_WPLL_DIV,
8850ad6b97eSPeter Chiu 		       MT_INFRA_CKGEN_DIV_SEL_MASK, 0x8);
8860ad6b97eSPeter Chiu 
88799ad32a4SBo Jiao 	mt76_rmw_field(dev, MT_INFRA_CKGEN_RFSPI_WPLL_DIV,
88899ad32a4SBo Jiao 		       MT_INFRA_CKGEN_DIV_EN_MASK, 0x1);
88999ad32a4SBo Jiao 
89099ad32a4SBo Jiao 	mt76_rmw_field(dev, MT_INFRA_CKGEN_BUS,
89199ad32a4SBo Jiao 		       MT_INFRA_CKGEN_BUS_CLK_SEL_MASK, 0x0);
89299ad32a4SBo Jiao 
89399ad32a4SBo Jiao 	mt76_rmw_field(dev, MT_CONN_INFRA_HW_CTRL,
89499ad32a4SBo Jiao 		       MT_CONN_INFRA_HW_CTRL_MASK, 0x1);
89599ad32a4SBo Jiao 
89699ad32a4SBo Jiao 	mt76_rmw(dev, MT_TOP_CONN_INFRA_WAKEUP,
89799ad32a4SBo Jiao 		 MT_TOP_CONN_INFRA_WAKEUP_MASK, 0x1);
89899ad32a4SBo Jiao 
89999ad32a4SBo Jiao 	usleep_range(900, 1000);
90099ad32a4SBo Jiao 
90199ad32a4SBo Jiao 	mt76_wmac_spi_lock(dev);
90299ad32a4SBo Jiao 	if (is_7975(dev, 0, adie_type) || is_7976(dev, 0, adie_type)) {
90399ad32a4SBo Jiao 		mt76_rmw_field(dev, MT_ADIE_SLP_CTRL_CK0(0),
90499ad32a4SBo Jiao 			       MT_SLP_CTRL_EN_MASK, 0x1);
90599ad32a4SBo Jiao 
90699ad32a4SBo Jiao 		read_poll_timeout(mt76_rr, cur, !(cur & MT_SLP_CTRL_BSY_MASK),
90799ad32a4SBo Jiao 				  USEC_PER_MSEC, 50 * USEC_PER_MSEC, false,
90899ad32a4SBo Jiao 				  dev, MT_ADIE_SLP_CTRL_CK0(0));
90999ad32a4SBo Jiao 	}
91099ad32a4SBo Jiao 	if (is_7975(dev, 1, adie_type) || is_7976(dev, 1, adie_type)) {
91199ad32a4SBo Jiao 		mt76_rmw_field(dev, MT_ADIE_SLP_CTRL_CK0(1),
91299ad32a4SBo Jiao 			       MT_SLP_CTRL_EN_MASK, 0x1);
91399ad32a4SBo Jiao 
91499ad32a4SBo Jiao 		read_poll_timeout(mt76_rr, cur, !(cur & MT_SLP_CTRL_BSY_MASK),
91599ad32a4SBo Jiao 				  USEC_PER_MSEC, 50 * USEC_PER_MSEC, false,
91699ad32a4SBo Jiao 				  dev, MT_ADIE_SLP_CTRL_CK0(0));
91799ad32a4SBo Jiao 	}
91899ad32a4SBo Jiao 	mt76_wmac_spi_unlock(dev);
91999ad32a4SBo Jiao 
92099ad32a4SBo Jiao 	mt76_rmw(dev, MT_TOP_CONN_INFRA_WAKEUP,
92199ad32a4SBo Jiao 		 MT_TOP_CONN_INFRA_WAKEUP_MASK, 0x0);
92299ad32a4SBo Jiao 	usleep_range(900, 1000);
92399ad32a4SBo Jiao }
92499ad32a4SBo Jiao 
mt7986_wmac_top_wfsys_wakeup(struct mt7915_dev * dev,bool enable)92599ad32a4SBo Jiao static int mt7986_wmac_top_wfsys_wakeup(struct mt7915_dev *dev, bool enable)
92699ad32a4SBo Jiao {
92799ad32a4SBo Jiao 	mt76_rmw_field(dev, MT_TOP_WFSYS_WAKEUP,
92899ad32a4SBo Jiao 		       MT_TOP_WFSYS_WAKEUP_MASK, enable);
92999ad32a4SBo Jiao 
93099ad32a4SBo Jiao 	usleep_range(900, 1000);
93199ad32a4SBo Jiao 
93299ad32a4SBo Jiao 	if (!enable)
93399ad32a4SBo Jiao 		return 0;
93499ad32a4SBo Jiao 
93599ad32a4SBo Jiao 	return mt798x_wmac_coninfra_check(dev);
93699ad32a4SBo Jiao }
93799ad32a4SBo Jiao 
mt7986_wmac_wm_enable(struct mt7915_dev * dev,bool enable)93899ad32a4SBo Jiao static int mt7986_wmac_wm_enable(struct mt7915_dev *dev, bool enable)
93999ad32a4SBo Jiao {
94099ad32a4SBo Jiao 	u32 cur;
94199ad32a4SBo Jiao 
94299ad32a4SBo Jiao 	if (is_mt7986(&dev->mt76))
94399ad32a4SBo Jiao 		mt76_wr(dev, MT_CONNINFRA_SKU_DEC_ADDR, 0);
94499ad32a4SBo Jiao 
94599ad32a4SBo Jiao 	mt76_rmw_field(dev, MT7986_TOP_WM_RESET,
94699ad32a4SBo Jiao 		       MT7986_TOP_WM_RESET_MASK, enable);
94799ad32a4SBo Jiao 	if (!enable)
94899ad32a4SBo Jiao 		return 0;
94999ad32a4SBo Jiao 
95099ad32a4SBo Jiao 	return read_poll_timeout(mt76_rr, cur, (cur == 0x1d1e),
95199ad32a4SBo Jiao 				 USEC_PER_MSEC, 5000 * USEC_PER_MSEC, false,
95299ad32a4SBo Jiao 				 dev, MT_TOP_CFG_ON_ROM_IDX);
95399ad32a4SBo Jiao }
95499ad32a4SBo Jiao 
mt7986_wmac_wfsys_poweron(struct mt7915_dev * dev,bool enable)95599ad32a4SBo Jiao static int mt7986_wmac_wfsys_poweron(struct mt7915_dev *dev, bool enable)
95699ad32a4SBo Jiao {
95799ad32a4SBo Jiao 	u32 mask = MT_TOP_PWR_EN_MASK | MT_TOP_PWR_KEY_MASK;
95899ad32a4SBo Jiao 	u32 cur;
95999ad32a4SBo Jiao 
96099ad32a4SBo Jiao 	mt76_rmw(dev, MT_TOP_WFSYS_PWR, mask,
96199ad32a4SBo Jiao 		 MT_TOP_PWR_KEY | FIELD_PREP(MT_TOP_PWR_EN_MASK, enable));
96299ad32a4SBo Jiao 
96399ad32a4SBo Jiao 	return read_poll_timeout(mt76_rr, cur,
96499ad32a4SBo Jiao 		(FIELD_GET(MT_TOP_WFSYS_RESET_STATUS_MASK, cur) == enable),
96599ad32a4SBo Jiao 		USEC_PER_MSEC, 50 * USEC_PER_MSEC, false,
96699ad32a4SBo Jiao 		dev, MT_TOP_WFSYS_RESET_STATUS);
96799ad32a4SBo Jiao }
96899ad32a4SBo Jiao 
mt7986_wmac_wfsys_setting(struct mt7915_dev * dev)96999ad32a4SBo Jiao static int mt7986_wmac_wfsys_setting(struct mt7915_dev *dev)
97099ad32a4SBo Jiao {
97199ad32a4SBo Jiao 	int ret;
97299ad32a4SBo Jiao 	u32 cur;
97399ad32a4SBo Jiao 
97499ad32a4SBo Jiao 	/* Turn off wfsys2conn bus sleep protect */
97599ad32a4SBo Jiao 	mt76_rmw(dev, MT_CONN_INFRA_WF_SLP_PROT,
97699ad32a4SBo Jiao 		 MT_CONN_INFRA_WF_SLP_PROT_MASK, 0x0);
97799ad32a4SBo Jiao 
97899ad32a4SBo Jiao 	ret = mt7986_wmac_wfsys_poweron(dev, true);
97999ad32a4SBo Jiao 	if (ret)
98099ad32a4SBo Jiao 		return ret;
98199ad32a4SBo Jiao 
98299ad32a4SBo Jiao 	/* Check bus sleep protect */
98399ad32a4SBo Jiao 
98499ad32a4SBo Jiao 	ret = read_poll_timeout(mt76_rr, cur,
98599ad32a4SBo Jiao 				!(cur & MT_CONN_INFRA_CONN_WF_MASK),
98699ad32a4SBo Jiao 				USEC_PER_MSEC, 50 * USEC_PER_MSEC, false,
98799ad32a4SBo Jiao 				dev, MT_CONN_INFRA_WF_SLP_PROT_RDY);
98899ad32a4SBo Jiao 	if (ret)
98999ad32a4SBo Jiao 		return ret;
99099ad32a4SBo Jiao 
99199ad32a4SBo Jiao 	ret = read_poll_timeout(mt76_rr, cur, !(cur & MT_SLP_WFDMA2CONN_MASK),
99299ad32a4SBo Jiao 				USEC_PER_MSEC, 50 * USEC_PER_MSEC, false,
99399ad32a4SBo Jiao 				dev, MT_SLP_STATUS);
99499ad32a4SBo Jiao 	if (ret)
99599ad32a4SBo Jiao 		return ret;
99699ad32a4SBo Jiao 
99799ad32a4SBo Jiao 	return read_poll_timeout(mt76_rr, cur, (cur == 0x02060000),
99899ad32a4SBo Jiao 				 USEC_PER_MSEC, 50 * USEC_PER_MSEC, false,
99999ad32a4SBo Jiao 				 dev, MT_TOP_CFG_IP_VERSION_ADDR);
100099ad32a4SBo Jiao }
100199ad32a4SBo Jiao 
mt7986_wmac_wfsys_set_timeout(struct mt7915_dev * dev)100299ad32a4SBo Jiao static void mt7986_wmac_wfsys_set_timeout(struct mt7915_dev *dev)
100399ad32a4SBo Jiao {
100499ad32a4SBo Jiao 	u32 mask = MT_MCU_BUS_TIMEOUT_SET_MASK |
100599ad32a4SBo Jiao 		   MT_MCU_BUS_TIMEOUT_CG_EN_MASK |
100699ad32a4SBo Jiao 		   MT_MCU_BUS_TIMEOUT_EN_MASK;
100799ad32a4SBo Jiao 	u32 val = FIELD_PREP(MT_MCU_BUS_TIMEOUT_SET_MASK, 1) |
100899ad32a4SBo Jiao 		  FIELD_PREP(MT_MCU_BUS_TIMEOUT_CG_EN_MASK, 1) |
100999ad32a4SBo Jiao 		  FIELD_PREP(MT_MCU_BUS_TIMEOUT_EN_MASK, 1);
101099ad32a4SBo Jiao 
101199ad32a4SBo Jiao 	mt76_rmw(dev, MT_MCU_BUS_TIMEOUT, mask, val);
101299ad32a4SBo Jiao 
101399ad32a4SBo Jiao 	mt76_wr(dev, MT_MCU_BUS_REMAP, 0x810f0000);
101499ad32a4SBo Jiao 
101599ad32a4SBo Jiao 	mask = MT_MCU_BUS_DBG_TIMEOUT_SET_MASK |
101699ad32a4SBo Jiao 	       MT_MCU_BUS_DBG_TIMEOUT_CK_EN_MASK |
101799ad32a4SBo Jiao 	       MT_MCU_BUS_DBG_TIMEOUT_EN_MASK;
101899ad32a4SBo Jiao 	val = FIELD_PREP(MT_MCU_BUS_DBG_TIMEOUT_SET_MASK, 0x3aa) |
101999ad32a4SBo Jiao 	      FIELD_PREP(MT_MCU_BUS_DBG_TIMEOUT_CK_EN_MASK, 1) |
102099ad32a4SBo Jiao 	      FIELD_PREP(MT_MCU_BUS_DBG_TIMEOUT_EN_MASK, 1);
102199ad32a4SBo Jiao 
102299ad32a4SBo Jiao 	mt76_rmw(dev, MT_MCU_BUS_DBG_TIMEOUT, mask, val);
102399ad32a4SBo Jiao }
102499ad32a4SBo Jiao 
mt7986_wmac_sku_update(struct mt7915_dev * dev,u32 adie_type)102599ad32a4SBo Jiao static int mt7986_wmac_sku_update(struct mt7915_dev *dev, u32 adie_type)
102699ad32a4SBo Jiao {
102799ad32a4SBo Jiao 	u32 val;
102899ad32a4SBo Jiao 
102999ad32a4SBo Jiao 	if (is_7976(dev, 0, adie_type) && is_7976(dev, 1, adie_type))
103099ad32a4SBo Jiao 		val = 0xf;
103199ad32a4SBo Jiao 	else if (is_7975(dev, 0, adie_type) && is_7975(dev, 1, adie_type))
103299ad32a4SBo Jiao 		val = 0xd;
103399ad32a4SBo Jiao 	else if (is_7976(dev, 0, adie_type))
103499ad32a4SBo Jiao 		val = 0x7;
103599ad32a4SBo Jiao 	else if (is_7975(dev, 1, adie_type))
103699ad32a4SBo Jiao 		val = 0x8;
103799ad32a4SBo Jiao 	else if (is_7976(dev, 1, adie_type))
103899ad32a4SBo Jiao 		val = 0xa;
103999ad32a4SBo Jiao 	else
104099ad32a4SBo Jiao 		return -EINVAL;
104199ad32a4SBo Jiao 
104299ad32a4SBo Jiao 	mt76_wmac_rmw(dev->sku, MT_TOP_POS_SKU, MT_TOP_POS_SKU_MASK,
104399ad32a4SBo Jiao 		      FIELD_PREP(MT_TOP_POS_SKU_MASK, val));
104499ad32a4SBo Jiao 
104599ad32a4SBo Jiao 	mt76_wr(dev, MT_CONNINFRA_SKU_DEC_ADDR, val);
104699ad32a4SBo Jiao 
104799ad32a4SBo Jiao 	return 0;
104899ad32a4SBo Jiao }
104999ad32a4SBo Jiao 
105099ad32a4SBo Jiao static int
mt7986_wmac_adie_setup(struct mt7915_dev * dev,u8 adie,u32 adie_type)105199ad32a4SBo Jiao mt7986_wmac_adie_setup(struct mt7915_dev *dev, u8 adie, u32 adie_type)
105299ad32a4SBo Jiao {
105399ad32a4SBo Jiao 	int ret;
105499ad32a4SBo Jiao 
105599ad32a4SBo Jiao 	if (!(is_7975(dev, adie, adie_type) || is_7976(dev, adie, adie_type)))
105699ad32a4SBo Jiao 		return 0;
105799ad32a4SBo Jiao 
105899ad32a4SBo Jiao 	ret = mt7986_wmac_adie_cfg(dev, adie, adie_type);
105999ad32a4SBo Jiao 	if (ret)
106099ad32a4SBo Jiao 		return ret;
106199ad32a4SBo Jiao 
106299ad32a4SBo Jiao 	ret = mt7986_wmac_afe_cal(dev, adie, false, adie_type);
106399ad32a4SBo Jiao 	if (ret)
106499ad32a4SBo Jiao 		return ret;
106599ad32a4SBo Jiao 
106699ad32a4SBo Jiao 	if (!adie && (mt798x_wmac_check_adie_type(dev) == ADIE_DBDC))
106799ad32a4SBo Jiao 		ret = mt7986_wmac_afe_cal(dev, adie, true, adie_type);
106899ad32a4SBo Jiao 
106999ad32a4SBo Jiao 	return ret;
107099ad32a4SBo Jiao }
107199ad32a4SBo Jiao 
mt7986_wmac_subsys_powerup(struct mt7915_dev * dev,u32 adie_type)107299ad32a4SBo Jiao static int mt7986_wmac_subsys_powerup(struct mt7915_dev *dev, u32 adie_type)
107399ad32a4SBo Jiao {
107499ad32a4SBo Jiao 	int ret;
107599ad32a4SBo Jiao 
107699ad32a4SBo Jiao 	mt7986_wmac_subsys_setting(dev);
107799ad32a4SBo Jiao 
107899ad32a4SBo Jiao 	ret = mt7986_wmac_bus_timeout(dev);
107999ad32a4SBo Jiao 	if (ret)
108099ad32a4SBo Jiao 		return ret;
108199ad32a4SBo Jiao 
108299ad32a4SBo Jiao 	mt7986_wmac_clock_enable(dev, adie_type);
108399ad32a4SBo Jiao 
108499ad32a4SBo Jiao 	return 0;
108599ad32a4SBo Jiao }
108699ad32a4SBo Jiao 
mt7986_wmac_wfsys_powerup(struct mt7915_dev * dev)108799ad32a4SBo Jiao static int mt7986_wmac_wfsys_powerup(struct mt7915_dev *dev)
108899ad32a4SBo Jiao {
108999ad32a4SBo Jiao 	int ret;
109099ad32a4SBo Jiao 
109199ad32a4SBo Jiao 	ret = mt7986_wmac_wm_enable(dev, false);
109299ad32a4SBo Jiao 	if (ret)
109399ad32a4SBo Jiao 		return ret;
109499ad32a4SBo Jiao 
109599ad32a4SBo Jiao 	ret = mt7986_wmac_wfsys_setting(dev);
109699ad32a4SBo Jiao 	if (ret)
109799ad32a4SBo Jiao 		return ret;
109899ad32a4SBo Jiao 
109999ad32a4SBo Jiao 	mt7986_wmac_wfsys_set_timeout(dev);
110099ad32a4SBo Jiao 
110199ad32a4SBo Jiao 	return mt7986_wmac_wm_enable(dev, true);
110299ad32a4SBo Jiao }
110399ad32a4SBo Jiao 
mt7986_wmac_enable(struct mt7915_dev * dev)110499ad32a4SBo Jiao int mt7986_wmac_enable(struct mt7915_dev *dev)
110599ad32a4SBo Jiao {
110699ad32a4SBo Jiao 	int ret;
110799ad32a4SBo Jiao 	u32 adie_type;
110899ad32a4SBo Jiao 
110999ad32a4SBo Jiao 	ret = mt7986_wmac_consys_reset(dev, true);
111099ad32a4SBo Jiao 	if (ret)
111199ad32a4SBo Jiao 		return ret;
111299ad32a4SBo Jiao 
111399ad32a4SBo Jiao 	ret = mt7986_wmac_gpio_setup(dev);
111499ad32a4SBo Jiao 	if (ret)
111599ad32a4SBo Jiao 		return ret;
111699ad32a4SBo Jiao 
111799ad32a4SBo Jiao 	ret = mt7986_wmac_consys_lockup(dev, false);
111899ad32a4SBo Jiao 	if (ret)
111999ad32a4SBo Jiao 		return ret;
112099ad32a4SBo Jiao 
112199ad32a4SBo Jiao 	ret = mt798x_wmac_coninfra_check(dev);
112299ad32a4SBo Jiao 	if (ret)
112399ad32a4SBo Jiao 		return ret;
112499ad32a4SBo Jiao 
112599ad32a4SBo Jiao 	ret = mt798x_wmac_coninfra_setup(dev);
112699ad32a4SBo Jiao 	if (ret)
112799ad32a4SBo Jiao 		return ret;
112899ad32a4SBo Jiao 
112999ad32a4SBo Jiao 	ret = mt798x_wmac_sku_setup(dev, &adie_type);
113099ad32a4SBo Jiao 	if (ret)
113199ad32a4SBo Jiao 		return ret;
113299ad32a4SBo Jiao 
113399ad32a4SBo Jiao 	ret = mt7986_wmac_adie_setup(dev, 0, adie_type);
113499ad32a4SBo Jiao 	if (ret)
113599ad32a4SBo Jiao 		return ret;
113699ad32a4SBo Jiao 
113799ad32a4SBo Jiao 	/* mt7981 doesn't support a second a-die */
1138cd85efdfSLorenzo Bianconi 	if (is_mt7986(&dev->mt76)) {
1139cd85efdfSLorenzo Bianconi 		ret = mt7986_wmac_adie_setup(dev, 1, adie_type);
1140cd85efdfSLorenzo Bianconi 		if (ret)
1141cd85efdfSLorenzo Bianconi 			return ret;
1142cd85efdfSLorenzo Bianconi 	}
1143cd85efdfSLorenzo Bianconi 
1144cd85efdfSLorenzo Bianconi 	ret = mt7986_wmac_subsys_powerup(dev, adie_type);
1145cd85efdfSLorenzo Bianconi 	if (ret)
1146cd85efdfSLorenzo Bianconi 		return ret;
1147cd85efdfSLorenzo Bianconi 
1148cd85efdfSLorenzo Bianconi 	ret = mt7986_wmac_top_wfsys_wakeup(dev, true);
1149cd85efdfSLorenzo Bianconi 	if (ret)
1150cd85efdfSLorenzo Bianconi 		return ret;
115199ad32a4SBo Jiao 
115299ad32a4SBo Jiao 	ret = mt7986_wmac_wfsys_powerup(dev);
115399ad32a4SBo Jiao 	if (ret)
115499ad32a4SBo Jiao 		return ret;
115599ad32a4SBo Jiao 
115699ad32a4SBo Jiao 	return mt7986_wmac_sku_update(dev, adie_type);
115799ad32a4SBo Jiao }
115899ad32a4SBo Jiao 
mt7986_wmac_disable(struct mt7915_dev * dev)115999ad32a4SBo Jiao void mt7986_wmac_disable(struct mt7915_dev *dev)
116099ad32a4SBo Jiao {
116199ad32a4SBo Jiao 	u32 cur;
116299ad32a4SBo Jiao 
116399ad32a4SBo Jiao 	mt7986_wmac_top_wfsys_wakeup(dev, true);
11645beadb27SRyder Lee 
116599ad32a4SBo Jiao 	/* Turn on wfsys2conn bus sleep protect */
116699ad32a4SBo Jiao 	mt76_rmw_field(dev, MT_CONN_INFRA_WF_SLP_PROT,
116799ad32a4SBo Jiao 		       MT_CONN_INFRA_WF_SLP_PROT_MASK, 0x1);
116899ad32a4SBo Jiao 
116999ad32a4SBo Jiao 	/* Check wfsys2conn bus sleep protect */
117099ad32a4SBo Jiao 	read_poll_timeout(mt76_rr, cur, !(cur ^ MT_CONN_INFRA_CONN),
117199ad32a4SBo Jiao 			  USEC_PER_MSEC, 50 * USEC_PER_MSEC, false,
117299ad32a4SBo Jiao 			  dev, MT_CONN_INFRA_WF_SLP_PROT_RDY);
117399ad32a4SBo Jiao 
117499ad32a4SBo Jiao 	mt7986_wmac_wfsys_poweron(dev, false);
117599ad32a4SBo Jiao 
117699ad32a4SBo Jiao 	/* Turn back wpll setting */
117799ad32a4SBo Jiao 	mt76_rmw_field(dev, MT_AFE_DIG_EN_02(0), MT_AFE_MCU_BPLL_CFG_MASK, 0x2);
117899ad32a4SBo Jiao 	mt76_rmw_field(dev, MT_AFE_DIG_EN_02(0), MT_AFE_WPLL_CFG_MASK, 0x2);
117999ad32a4SBo Jiao 
118099ad32a4SBo Jiao 	/* Reset EMI */
118199ad32a4SBo Jiao 	mt76_rmw_field(dev, MT_CONN_INFRA_EMI_REQ,
118299ad32a4SBo Jiao 		       MT_CONN_INFRA_EMI_REQ_MASK, 0x1);
118399ad32a4SBo Jiao 	mt76_rmw_field(dev, MT_CONN_INFRA_EMI_REQ,
118499ad32a4SBo Jiao 		       MT_CONN_INFRA_EMI_REQ_MASK, 0x0);
118599ad32a4SBo Jiao 	mt76_rmw_field(dev, MT_CONN_INFRA_EMI_REQ,
118699ad32a4SBo Jiao 		       MT_CONN_INFRA_INFRA_REQ_MASK, 0x1);
118799ad32a4SBo Jiao 	mt76_rmw_field(dev, MT_CONN_INFRA_EMI_REQ,
1188eebb7097SLorenzo Bianconi 		       MT_CONN_INFRA_INFRA_REQ_MASK, 0x0);
1189eebb7097SLorenzo Bianconi 
1190eebb7097SLorenzo Bianconi 	mt7986_wmac_top_wfsys_wakeup(dev, false);
1191eebb7097SLorenzo Bianconi 	mt7986_wmac_consys_lockup(dev, true);
1192eebb7097SLorenzo Bianconi 	mt7986_wmac_consys_reset(dev, false);
1193eebb7097SLorenzo Bianconi }
1194eebb7097SLorenzo Bianconi 
mt798x_wmac_init(struct mt7915_dev * dev)1195eebb7097SLorenzo Bianconi static int mt798x_wmac_init(struct mt7915_dev *dev)
1196eebb7097SLorenzo Bianconi {
1197eebb7097SLorenzo Bianconi 	struct device *pdev = dev->mt76.dev;
1198eebb7097SLorenzo Bianconi 	struct platform_device *pfdev = to_platform_device(pdev);
1199eebb7097SLorenzo Bianconi 	struct clk *mcu_clk, *ap_conn_clk;
120099ad32a4SBo Jiao 
120199ad32a4SBo Jiao 	mcu_clk = devm_clk_get(pdev, "mcu");
120299ad32a4SBo Jiao 	if (IS_ERR(mcu_clk))
120399ad32a4SBo Jiao 		dev_err(pdev, "mcu clock not found\n");
120499ad32a4SBo Jiao 	else if (clk_prepare_enable(mcu_clk))
120599ad32a4SBo Jiao 		dev_err(pdev, "mcu clock configuration failed\n");
120699ad32a4SBo Jiao 
120799ad32a4SBo Jiao 	ap_conn_clk = devm_clk_get(pdev, "ap2conn");
120899ad32a4SBo Jiao 	if (IS_ERR(ap_conn_clk))
12095beadb27SRyder Lee 		dev_err(pdev, "ap2conn clock not found\n");
12105beadb27SRyder Lee 	else if (clk_prepare_enable(ap_conn_clk))
121199ad32a4SBo Jiao 		dev_err(pdev, "ap2conn clock configuration failed\n");
121299ad32a4SBo Jiao 
121399ad32a4SBo Jiao 	dev->dcm = devm_platform_ioremap_resource(pfdev, 1);
121499ad32a4SBo Jiao 	if (IS_ERR(dev->dcm))
121599ad32a4SBo Jiao 		return PTR_ERR(dev->dcm);
121699ad32a4SBo Jiao 
121799ad32a4SBo Jiao 	dev->sku = devm_platform_ioremap_resource(pfdev, 2);
121899ad32a4SBo Jiao 	if (IS_ERR(dev->sku))
121999ad32a4SBo Jiao 		return PTR_ERR(dev->sku);
1220eebb7097SLorenzo Bianconi 
1221eebb7097SLorenzo Bianconi 	dev->rstc = devm_reset_control_get(pdev, "consys");
1222eebb7097SLorenzo Bianconi 	if (IS_ERR(dev->rstc))
122399ad32a4SBo Jiao 		return PTR_ERR(dev->rstc);
122499ad32a4SBo Jiao 
122599ad32a4SBo Jiao 	return 0;
122699ad32a4SBo Jiao }
122799ad32a4SBo Jiao 
mt798x_wmac_probe(struct platform_device * pdev)122899ad32a4SBo Jiao static int mt798x_wmac_probe(struct platform_device *pdev)
122999ad32a4SBo Jiao {
123099ad32a4SBo Jiao 	void __iomem *mem_base;
123199ad32a4SBo Jiao 	struct mt7915_dev *dev;
123299ad32a4SBo Jiao 	struct mt76_dev *mdev;
123399ad32a4SBo Jiao 	int irq, ret;
123499ad32a4SBo Jiao 	u32 chip_id;
123599ad32a4SBo Jiao 
123699ad32a4SBo Jiao 	chip_id = (uintptr_t)of_device_get_match_data(&pdev->dev);
123799ad32a4SBo Jiao 
123899ad32a4SBo Jiao 	mem_base = devm_platform_ioremap_resource(pdev, 0);
123999ad32a4SBo Jiao 	if (IS_ERR(mem_base)) {
124099ad32a4SBo Jiao 		dev_err(&pdev->dev, "Failed to get memory resource\n");
1241*90fb6921SLorenz Brun 		return PTR_ERR(mem_base);
1242*90fb6921SLorenz Brun 	}
124399ad32a4SBo Jiao 
124499ad32a4SBo Jiao 	dev = mt7915_mmio_probe(&pdev->dev, mem_base, chip_id);
124599ad32a4SBo Jiao 	if (IS_ERR(dev))
124699ad32a4SBo Jiao 		return PTR_ERR(dev);
124799ad32a4SBo Jiao 
124899ad32a4SBo Jiao 	mdev = &dev->mt76;
124999ad32a4SBo Jiao 	ret = mt7915_mmio_wed_init(dev, pdev, false, &irq);
125099ad32a4SBo Jiao 	if (ret < 0)
125199ad32a4SBo Jiao 		goto free_device;
125299ad32a4SBo Jiao 
125399ad32a4SBo Jiao 	if (!ret) {
125499ad32a4SBo Jiao 		irq = platform_get_irq(pdev, 0);
125599ad32a4SBo Jiao 		if (irq < 0) {
125699ad32a4SBo Jiao 			ret = irq;
1257 			goto free_device;
1258 		}
1259 	}
1260 
1261 	ret = devm_request_irq(mdev->dev, irq, mt7915_irq_handler,
1262 			       IRQF_SHARED, KBUILD_MODNAME, dev);
1263 	if (ret)
1264 		goto free_device;
1265 
1266 	ret = mt798x_wmac_init(dev);
1267 	if (ret)
1268 		goto free_irq;
1269 
1270 	mt7915_wfsys_reset(dev);
1271 
1272 	ret = mt7915_register_device(dev);
1273 	if (ret)
1274 		goto free_irq;
1275 
1276 	return 0;
1277 
1278 free_irq:
1279 	devm_free_irq(mdev->dev, irq, dev);
1280 free_device:
1281 	if (mtk_wed_device_active(&mdev->mmio.wed))
1282 		mtk_wed_device_detach(&mdev->mmio.wed);
1283 	mt76_free_device(mdev);
1284 
1285 	return ret;
1286 }
1287 
mt798x_wmac_remove(struct platform_device * pdev)1288 static int mt798x_wmac_remove(struct platform_device *pdev)
1289 {
1290 	struct mt7915_dev *dev = platform_get_drvdata(pdev);
1291 
1292 	mt7915_unregister_device(dev);
1293 
1294 	return 0;
1295 }
1296 
1297 static const struct of_device_id mt798x_wmac_of_match[] = {
1298 	{ .compatible = "mediatek,mt7981-wmac", .data = (u32 *)0x7981 },
1299 	{ .compatible = "mediatek,mt7986-wmac", .data = (u32 *)0x7986 },
1300 	{},
1301 };
1302 
1303 MODULE_DEVICE_TABLE(of, mt798x_wmac_of_match);
1304 
1305 struct platform_driver mt798x_wmac_driver = {
1306 	.driver = {
1307 		.name = "mt798x-wmac",
1308 		.of_match_table = mt798x_wmac_of_match,
1309 	},
1310 	.probe = mt798x_wmac_probe,
1311 	.remove = mt798x_wmac_remove,
1312 };
1313 
1314 MODULE_FIRMWARE(MT7986_FIRMWARE_WA);
1315 MODULE_FIRMWARE(MT7986_FIRMWARE_WM);
1316 MODULE_FIRMWARE(MT7986_FIRMWARE_WM_MT7975);
1317 MODULE_FIRMWARE(MT7986_ROM_PATCH);
1318 MODULE_FIRMWARE(MT7986_ROM_PATCH_MT7975);
1319 
1320 MODULE_FIRMWARE(MT7981_FIRMWARE_WA);
1321 MODULE_FIRMWARE(MT7981_FIRMWARE_WM);
1322 MODULE_FIRMWARE(MT7981_ROM_PATCH);
1323