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