File Index
Files and directories
Sign in
FILE

soc.c

File preview with syntax highlighting.

linux-6.19.14/drivers/net/wireless/mediatek/mt76/mt7915/soc.c C
   1// SPDX-License-Identifier: BSD-3-Clause-Clear
   2/* Copyright (C) 2022 MediaTek Inc. */
   3
   4#include <linux/kernel.h>
   5#include <linux/module.h>
   6#include <linux/platform_device.h>
   7#include <linux/pinctrl/consumer.h>
   8#include <linux/of.h>
   9#include <linux/of_reserved_mem.h>
  10#include <linux/iopoll.h>
  11#include <linux/reset.h>
  12#include <linux/of_net.h>
  13#include <linux/clk.h>
  14
  15#include "mt7915.h"
  16
  17#define MT7981_CON_INFRA_VERSION 0x02090000
  18#define MT7986_CON_INFRA_VERSION 0x02070000
  19
  20/* INFRACFG */
  21#define MT_INFRACFG_CONN2AP_SLPPROT	0x0d0
  22#define MT_INFRACFG_AP2CONN_SLPPROT	0x0d4
  23
  24#define MT_INFRACFG_RX_EN_MASK		BIT(16)
  25#define MT_INFRACFG_TX_RDY_MASK		BIT(4)
  26#define MT_INFRACFG_TX_EN_MASK		BIT(0)
  27
  28/* TOP POS */
  29#define MT_TOP_POS_FAST_CTRL		0x114
  30#define MT_TOP_POS_FAST_EN_MASK		BIT(3)
  31
  32#define MT_TOP_POS_SKU			0x21c
  33#define MT_TOP_POS_SKU_MASK		GENMASK(31, 28)
  34#define MT_TOP_POS_SKU_ADIE_DBDC_MASK	BIT(2)
  35
  36enum {
  37	ADIE_SB,
  38	ADIE_DBDC
  39};
  40
  41static int
  42mt76_wmac_spi_read(struct mt7915_dev *dev, u8 adie, u32 addr, u32 *val)
  43{
  44	int ret;
  45	u32 cur;
  46
  47	ret = read_poll_timeout(mt76_rr, cur, !(cur & MT_TOP_SPI_POLLING_BIT),
  48				USEC_PER_MSEC, 50 * USEC_PER_MSEC, false,
  49				dev, MT_TOP_SPI_BUSY_CR(adie));
  50	if (ret)
  51		return ret;
  52
  53	mt76_wr(dev, MT_TOP_SPI_ADDR_CR(adie),
  54		MT_TOP_SPI_READ_ADDR_FORMAT | addr);
  55	mt76_wr(dev, MT_TOP_SPI_WRITE_DATA_CR(adie), 0);
  56
  57	ret = read_poll_timeout(mt76_rr, cur, !(cur & MT_TOP_SPI_POLLING_BIT),
  58				USEC_PER_MSEC, 50 * USEC_PER_MSEC, false,
  59				dev, MT_TOP_SPI_BUSY_CR(adie));
  60	if (ret)
  61		return ret;
  62
  63	*val = mt76_rr(dev, MT_TOP_SPI_READ_DATA_CR(adie));
  64
  65	return 0;
  66}
  67
  68static int
  69mt76_wmac_spi_write(struct mt7915_dev *dev, u8 adie, u32 addr, u32 val)
  70{
  71	int ret;
  72	u32 cur;
  73
  74	ret = read_poll_timeout(mt76_rr, cur, !(cur & MT_TOP_SPI_POLLING_BIT),
  75				USEC_PER_MSEC, 50 * USEC_PER_MSEC, false,
  76				dev, MT_TOP_SPI_BUSY_CR(adie));
  77	if (ret)
  78		return ret;
  79
  80	mt76_wr(dev, MT_TOP_SPI_ADDR_CR(adie),
  81		MT_TOP_SPI_WRITE_ADDR_FORMAT | addr);
  82	mt76_wr(dev, MT_TOP_SPI_WRITE_DATA_CR(adie), val);
  83
  84	return read_poll_timeout(mt76_rr, cur, !(cur & MT_TOP_SPI_POLLING_BIT),
  85				 USEC_PER_MSEC, 50 * USEC_PER_MSEC, false,
  86				 dev, MT_TOP_SPI_BUSY_CR(adie));
  87}
  88
  89static int
  90mt76_wmac_spi_rmw(struct mt7915_dev *dev, u8 adie,
  91		  u32 addr, u32 mask, u32 val)
  92{
  93	u32 cur, ret;
  94
  95	ret = mt76_wmac_spi_read(dev, adie, addr, &cur);
  96	if (ret)
  97		return ret;
  98
  99	cur &= ~mask;
 100	cur |= val;
 101
 102	return mt76_wmac_spi_write(dev, adie, addr, cur);
 103}
 104
 105static int
 106mt7986_wmac_adie_efuse_read(struct mt7915_dev *dev, u8 adie,
 107			    u32 addr, u32 *data)
 108{
 109	int ret, temp;
 110	u32 val, mask;
 111
 112	ret = mt76_wmac_spi_write(dev, adie, MT_ADIE_EFUSE_CFG,
 113				  MT_ADIE_EFUSE_CTRL_MASK);
 114	if (ret)
 115		return ret;
 116
 117	ret = mt76_wmac_spi_rmw(dev, adie, MT_ADIE_EFUSE2_CTRL, BIT(30), 0x0);
 118	if (ret)
 119		return ret;
 120
 121	mask = (MT_ADIE_EFUSE_MODE_MASK | MT_ADIE_EFUSE_ADDR_MASK |
 122		MT_ADIE_EFUSE_KICK_MASK);
 123	val = FIELD_PREP(MT_ADIE_EFUSE_MODE_MASK, 0) |
 124	      FIELD_PREP(MT_ADIE_EFUSE_ADDR_MASK, addr) |
 125	      FIELD_PREP(MT_ADIE_EFUSE_KICK_MASK, 1);
 126	ret = mt76_wmac_spi_rmw(dev, adie, MT_ADIE_EFUSE2_CTRL, mask, val);
 127	if (ret)
 128		return ret;
 129
 130	ret = read_poll_timeout(mt76_wmac_spi_read, temp,
 131				!temp && !FIELD_GET(MT_ADIE_EFUSE_KICK_MASK, val),
 132				USEC_PER_MSEC, 50 * USEC_PER_MSEC, false,
 133				dev, adie, MT_ADIE_EFUSE2_CTRL, &val);
 134	if (ret)
 135		return ret;
 136
 137	ret = mt76_wmac_spi_read(dev, adie, MT_ADIE_EFUSE2_CTRL, &val);
 138	if (ret)
 139		return ret;
 140
 141	if (FIELD_GET(MT_ADIE_EFUSE_VALID_MASK, val) == 1)
 142		ret = mt76_wmac_spi_read(dev, adie, MT_ADIE_EFUSE_RDATA0,
 143					 data);
 144
 145	return ret;
 146}
 147
 148static inline void mt76_wmac_spi_lock(struct mt7915_dev *dev)
 149{
 150	u32 cur;
 151
 152	read_poll_timeout(mt76_rr, cur,
 153			  FIELD_GET(MT_SEMA_RFSPI_STATUS_MASK, cur),
 154			  1000, 1000 * MSEC_PER_SEC, false, dev,
 155			  MT_SEMA_RFSPI_STATUS);
 156}
 157
 158static inline void mt76_wmac_spi_unlock(struct mt7915_dev *dev)
 159{
 160	mt76_wr(dev, MT_SEMA_RFSPI_RELEASE, 1);
 161}
 162
 163static u32 mt76_wmac_rmw(void __iomem *base, u32 offset, u32 mask, u32 val)
 164{
 165	val |= readl(base + offset) & ~mask;
 166	writel(val, base + offset);
 167
 168	return val;
 169}
 170
 171static u8 mt798x_wmac_check_adie_type(struct mt7915_dev *dev)
 172{
 173	u32 val;
 174
 175	/* Only DBDC A-die is used with MT7981 */
 176	if (is_mt7981(&dev->mt76))
 177		return ADIE_DBDC;
 178
 179	val = readl(dev->sku + MT_TOP_POS_SKU);
 180
 181	return FIELD_GET(MT_TOP_POS_SKU_ADIE_DBDC_MASK, val);
 182}
 183
 184static int mt7986_wmac_consys_reset(struct mt7915_dev *dev, bool enable)
 185{
 186	if (!enable)
 187		return reset_control_assert(dev->rstc);
 188
 189	mt76_wmac_rmw(dev->sku, MT_TOP_POS_FAST_CTRL,
 190		      MT_TOP_POS_FAST_EN_MASK,
 191		      FIELD_PREP(MT_TOP_POS_FAST_EN_MASK, 0x1));
 192
 193	return reset_control_deassert(dev->rstc);
 194}
 195
 196static int mt7986_wmac_gpio_setup(struct mt7915_dev *dev)
 197{
 198	struct pinctrl_state *state;
 199	struct pinctrl *pinctrl;
 200	int ret;
 201	u8 type;
 202
 203	type = mt798x_wmac_check_adie_type(dev);
 204	pinctrl = devm_pinctrl_get(dev->mt76.dev);
 205	if (IS_ERR(pinctrl))
 206		return PTR_ERR(pinctrl);
 207
 208	switch (type) {
 209	case ADIE_SB:
 210		state = pinctrl_lookup_state(pinctrl, "default");
 211		if (IS_ERR_OR_NULL(state))
 212			return -EINVAL;
 213		break;
 214	case ADIE_DBDC:
 215		state = pinctrl_lookup_state(pinctrl, "dbdc");
 216		if (IS_ERR_OR_NULL(state))
 217			return -EINVAL;
 218		break;
 219	default:
 220		return -EINVAL;
 221	}
 222
 223	ret = pinctrl_select_state(pinctrl, state);
 224	if (ret)
 225		return ret;
 226
 227	usleep_range(500, 1000);
 228
 229	return 0;
 230}
 231
 232static int mt7986_wmac_consys_lockup(struct mt7915_dev *dev, bool enable)
 233{
 234	int ret;
 235	u32 cur;
 236
 237	mt76_wmac_rmw(dev->dcm, MT_INFRACFG_AP2CONN_SLPPROT,
 238		      MT_INFRACFG_RX_EN_MASK,
 239		      FIELD_PREP(MT_INFRACFG_RX_EN_MASK, enable));
 240	ret = read_poll_timeout(readl, cur, !(cur & MT_INFRACFG_RX_EN_MASK),
 241				USEC_PER_MSEC, 50 * USEC_PER_MSEC, false,
 242				dev->dcm + MT_INFRACFG_AP2CONN_SLPPROT);
 243	if (ret)
 244		return ret;
 245
 246	mt76_wmac_rmw(dev->dcm, MT_INFRACFG_AP2CONN_SLPPROT,
 247		      MT_INFRACFG_TX_EN_MASK,
 248		      FIELD_PREP(MT_INFRACFG_TX_EN_MASK, enable));
 249	ret = read_poll_timeout(readl, cur, !(cur & MT_INFRACFG_TX_RDY_MASK),
 250				USEC_PER_MSEC, 50 * USEC_PER_MSEC, false,
 251				dev->dcm + MT_INFRACFG_AP2CONN_SLPPROT);
 252	if (ret)
 253		return ret;
 254
 255	mt76_wmac_rmw(dev->dcm, MT_INFRACFG_CONN2AP_SLPPROT,
 256		      MT_INFRACFG_RX_EN_MASK,
 257		      FIELD_PREP(MT_INFRACFG_RX_EN_MASK, enable));
 258	mt76_wmac_rmw(dev->dcm, MT_INFRACFG_CONN2AP_SLPPROT,
 259		      MT_INFRACFG_TX_EN_MASK,
 260		      FIELD_PREP(MT_INFRACFG_TX_EN_MASK, enable));
 261
 262	return 0;
 263}
 264
 265static int mt798x_wmac_coninfra_check(struct mt7915_dev *dev)
 266{
 267	u32 cur;
 268	u32 con_infra_version;
 269
 270	if (is_mt7981(&dev->mt76)) {
 271		con_infra_version = MT7981_CON_INFRA_VERSION;
 272	} else if (is_mt7986(&dev->mt76)) {
 273		con_infra_version = MT7986_CON_INFRA_VERSION;
 274	} else {
 275		WARN_ON(1);
 276		return -EINVAL;
 277	}
 278
 279	return read_poll_timeout(mt76_rr, cur, (cur == con_infra_version),
 280				 USEC_PER_MSEC, 50 * USEC_PER_MSEC,
 281				 false, dev, MT_CONN_INFRA_BASE);
 282}
 283
 284static int mt798x_wmac_coninfra_setup(struct mt7915_dev *dev)
 285{
 286	struct device *pdev = dev->mt76.dev;
 287	struct resource res;
 288	u32 val;
 289	int ret;
 290
 291	ret = of_reserved_mem_region_to_resource(pdev->of_node, 0, &res);
 292	if (ret)
 293		return ret;
 294
 295	val = (res.start >> 16) & MT_TOP_MCU_EMI_BASE_MASK;
 296
 297	if (is_mt7986(&dev->mt76)) {
 298		/* Set conninfra subsys PLL check */
 299		mt76_rmw_field(dev, MT_INFRA_CKGEN_BUS,
 300			       MT_INFRA_CKGEN_BUS_RDY_SEL_MASK, 0x1);
 301		mt76_rmw_field(dev, MT_INFRA_CKGEN_BUS,
 302			       MT_INFRA_CKGEN_BUS_RDY_SEL_MASK, 0x1);
 303	}
 304
 305	mt76_rmw_field(dev, MT_TOP_MCU_EMI_BASE,
 306		       MT_TOP_MCU_EMI_BASE_MASK, val);
 307
 308	if (is_mt7981(&dev->mt76)) {
 309		mt76_rmw_field(dev, MT_TOP_WF_AP_PERI_BASE,
 310			       MT_TOP_WF_AP_PERI_BASE_MASK, 0x300d0000 >> 16);
 311
 312		mt76_rmw_field(dev, MT_TOP_EFUSE_BASE,
 313			       MT_TOP_EFUSE_BASE_MASK, 0x11f20000 >> 16);
 314	}
 315
 316	mt76_wr(dev, MT_INFRA_BUS_EMI_START, res.start);
 317	mt76_wr(dev, MT_INFRA_BUS_EMI_END, resource_size(&res));
 318
 319	mt76_rr(dev, MT_CONN_INFRA_EFUSE);
 320
 321	/* Set conninfra sysram */
 322	mt76_wr(dev, MT_TOP_RGU_SYSRAM_PDN, 0);
 323	mt76_wr(dev, MT_TOP_RGU_SYSRAM_SLP, 1);
 324
 325	return 0;
 326}
 327
 328static int mt798x_wmac_sku_setup(struct mt7915_dev *dev, u32 *adie_type)
 329{
 330	int ret;
 331	u32 adie_main = 0, adie_ext = 0;
 332
 333	mt76_rmw_field(dev, MT_CONN_INFRA_ADIE_RESET,
 334		       MT_CONN_INFRA_ADIE1_RESET_MASK, 0x1);
 335
 336	if (is_mt7986(&dev->mt76)) {
 337		mt76_rmw_field(dev, MT_CONN_INFRA_ADIE_RESET,
 338			       MT_CONN_INFRA_ADIE2_RESET_MASK, 0x1);
 339	}
 340
 341	mt76_wmac_spi_lock(dev);
 342
 343	ret = mt76_wmac_spi_read(dev, 0, MT_ADIE_CHIP_ID, &adie_main);
 344	if (ret)
 345		goto out;
 346
 347	if (is_mt7986(&dev->mt76)) {
 348		ret = mt76_wmac_spi_read(dev, 1, MT_ADIE_CHIP_ID, &adie_ext);
 349		if (ret)
 350			goto out;
 351	}
 352
 353	*adie_type = FIELD_GET(MT_ADIE_CHIP_ID_MASK, adie_main) |
 354		     (MT_ADIE_CHIP_ID_MASK & adie_ext);
 355
 356out:
 357	mt76_wmac_spi_unlock(dev);
 358
 359	return 0;
 360}
 361
 362static inline u16 mt7986_adie_idx(u8 adie, u32 adie_type)
 363{
 364	if (adie == 0)
 365		return u32_get_bits(adie_type, MT_ADIE_IDX0);
 366	else
 367		return u32_get_bits(adie_type, MT_ADIE_IDX1);
 368}
 369
 370static inline bool is_7975(struct mt7915_dev *dev, u8 adie, u32 adie_type)
 371{
 372	return mt7986_adie_idx(adie, adie_type) == 0x7975;
 373}
 374
 375static inline bool is_7976(struct mt7915_dev *dev, u8 adie, u32 adie_type)
 376{
 377	return mt7986_adie_idx(adie, adie_type) == 0x7976;
 378}
 379
 380static int mt7986_wmac_adie_thermal_cal(struct mt7915_dev *dev, u8 adie)
 381{
 382	int ret;
 383	u32 data, val;
 384
 385	ret = mt7986_wmac_adie_efuse_read(dev, adie, MT_ADIE_THADC_ANALOG,
 386					  &data);
 387	if (ret || FIELD_GET(MT_ADIE_ANA_EN_MASK, data)) {
 388		val = FIELD_GET(MT_ADIE_VRPI_SEL_EFUSE_MASK, data);
 389		ret = mt76_wmac_spi_rmw(dev, adie, MT_ADIE_RG_TOP_THADC_BG,
 390					MT_ADIE_VRPI_SEL_CR_MASK,
 391					FIELD_PREP(MT_ADIE_VRPI_SEL_CR_MASK, val));
 392		if (ret)
 393			return ret;
 394
 395		val = FIELD_GET(MT_ADIE_PGA_GAIN_EFUSE_MASK, data);
 396		ret = mt76_wmac_spi_rmw(dev, adie, MT_ADIE_RG_TOP_THADC,
 397					MT_ADIE_PGA_GAIN_MASK,
 398					FIELD_PREP(MT_ADIE_PGA_GAIN_MASK, val));
 399		if (ret)
 400			return ret;
 401	}
 402
 403	ret = mt7986_wmac_adie_efuse_read(dev, adie, MT_ADIE_THADC_SLOP,
 404					  &data);
 405	if (ret || FIELD_GET(MT_ADIE_ANA_EN_MASK, data)) {
 406		val = FIELD_GET(MT_ADIE_LDO_CTRL_EFUSE_MASK, data);
 407
 408		return mt76_wmac_spi_rmw(dev, adie, MT_ADIE_RG_TOP_THADC,
 409					 MT_ADIE_LDO_CTRL_MASK,
 410					 FIELD_PREP(MT_ADIE_LDO_CTRL_MASK, val));
 411	}
 412
 413	return 0;
 414}
 415
 416static int
 417mt7986_read_efuse_xo_trim_7976(struct mt7915_dev *dev, u8 adie,
 418			       bool is_40m, int *result)
 419{
 420	int ret;
 421	u32 data, addr;
 422
 423	addr = is_40m ? MT_ADIE_XTAL_AXM_40M_OSC : MT_ADIE_XTAL_AXM_80M_OSC;
 424	ret = mt7986_wmac_adie_efuse_read(dev, adie, addr, &data);
 425	if (ret)
 426		return ret;
 427
 428	if (!FIELD_GET(MT_ADIE_XO_TRIM_EN_MASK, data)) {
 429		*result = 64;
 430	} else {
 431		*result = FIELD_GET(MT_ADIE_TRIM_MASK, data);
 432		addr = is_40m ? MT_ADIE_XTAL_TRIM1_40M_OSC :
 433				MT_ADIE_XTAL_TRIM1_80M_OSC;
 434		ret = mt7986_wmac_adie_efuse_read(dev, adie, addr, &data);
 435		if (ret)
 436			return ret;
 437
 438		if (FIELD_GET(MT_ADIE_XO_TRIM_EN_MASK, data) &&
 439		    FIELD_GET(MT_ADIE_XTAL_DECREASE_MASK, data))
 440			*result -= FIELD_GET(MT_ADIE_EFUSE_TRIM_MASK, data);
 441		else if (FIELD_GET(MT_ADIE_XO_TRIM_EN_MASK, data))
 442			*result += FIELD_GET(MT_ADIE_EFUSE_TRIM_MASK, data);
 443
 444		*result = max(0, min(127, *result));
 445	}
 446
 447	return 0;
 448}
 449
 450static int mt7986_wmac_adie_xtal_trim_7976(struct mt7915_dev *dev, u8 adie)
 451{
 452	int ret, trim_80m, trim_40m;
 453	u32 data, val, mode;
 454
 455	ret = mt7986_wmac_adie_efuse_read(dev, adie, MT_ADIE_XO_TRIM_FLOW,
 456					  &data);
 457	if (ret || !FIELD_GET(BIT(1), data))
 458		return 0;
 459
 460	ret = mt7986_read_efuse_xo_trim_7976(dev, adie, false, &trim_80m);
 461	if (ret)
 462		return ret;
 463
 464	ret = mt7986_read_efuse_xo_trim_7976(dev, adie, true, &trim_40m);
 465	if (ret)
 466		return ret;
 467
 468	ret = mt76_wmac_spi_read(dev, adie, MT_ADIE_RG_STRAP_PIN_IN, &val);
 469	if (ret)
 470		return ret;
 471
 472	mode = FIELD_PREP(GENMASK(6, 4), val);
 473	if (!mode || mode == 0x2) {
 474		ret = mt76_wmac_spi_rmw(dev, adie, MT_ADIE_XTAL_C1,
 475					GENMASK(31, 24),
 476					FIELD_PREP(GENMASK(31, 24), trim_80m));
 477		if (ret)
 478			return ret;
 479
 480		ret = mt76_wmac_spi_rmw(dev, adie, MT_ADIE_XTAL_C2,
 481					GENMASK(31, 24),
 482					FIELD_PREP(GENMASK(31, 24), trim_80m));
 483	} else if (mode == 0x3 || mode == 0x4 || mode == 0x6) {
 484		ret = mt76_wmac_spi_rmw(dev, adie, MT_ADIE_XTAL_C1,
 485					GENMASK(23, 16),
 486					FIELD_PREP(GENMASK(23, 16), trim_40m));
 487		if (ret)
 488			return ret;
 489
 490		ret = mt76_wmac_spi_rmw(dev, adie, MT_ADIE_XTAL_C2,
 491					GENMASK(23, 16),
 492					FIELD_PREP(GENMASK(23, 16), trim_40m));
 493	}
 494
 495	return ret;
 496}
 497
 498static int mt798x_wmac_adie_patch_7976(struct mt7915_dev *dev, u8 adie)
 499{
 500	u32 id, version, rg_xo_01, rg_xo_03;
 501	int ret;
 502
 503	ret = mt76_wmac_spi_read(dev, adie, MT_ADIE_CHIP_ID, &id);
 504	if (ret)
 505		return ret;
 506
 507	version = FIELD_GET(MT_ADIE_VERSION_MASK, id);
 508
 509	ret = mt76_wmac_spi_write(dev, adie, MT_ADIE_RG_TOP_THADC, 0x4a563b00);
 510	if (ret)
 511		return ret;
 512
 513	if (version == 0x8a00 || version == 0x8a10 ||
 514	    version == 0x8b00 || version == 0x8c10) {
 515		rg_xo_01 = 0x1d59080f;
 516		rg_xo_03 = 0x34c00fe0;
 517	} else {
 518		if (is_mt7981(&dev->mt76)) {
 519			rg_xo_01 = 0x1959c80f;
 520		} else if (is_mt7986(&dev->mt76)) {
 521			rg_xo_01 = 0x1959f80f;
 522		} else {
 523			WARN_ON(1);
 524			return -EINVAL;
 525		}
 526		rg_xo_03 = 0x34d00fe0;
 527	}
 528
 529	ret = mt76_wmac_spi_write(dev, adie, MT_ADIE_RG_XO_01, rg_xo_01);
 530	if (ret)
 531		return ret;
 532
 533	return mt76_wmac_spi_write(dev, adie, MT_ADIE_RG_XO_03, rg_xo_03);
 534}
 535
 536static int
 537mt7986_read_efuse_xo_trim_7975(struct mt7915_dev *dev, u8 adie,
 538			       u32 addr, u32 *result)
 539{
 540	int ret;
 541	u32 data;
 542
 543	ret = mt7986_wmac_adie_efuse_read(dev, adie, addr, &data);
 544	if (ret)
 545		return ret;
 546
 547	if ((data & MT_ADIE_XO_TRIM_EN_MASK)) {
 548		if ((data & MT_ADIE_XTAL_DECREASE_MASK))
 549			*result -= (data & MT_ADIE_EFUSE_TRIM_MASK);
 550		else
 551			*result += (data & MT_ADIE_EFUSE_TRIM_MASK);
 552
 553		*result = (*result & MT_ADIE_TRIM_MASK);
 554	}
 555
 556	return 0;
 557}
 558
 559static int mt7986_wmac_adie_xtal_trim_7975(struct mt7915_dev *dev, u8 adie)
 560{
 561	int ret;
 562	u32 data, result = 0, value;
 563
 564	ret = mt7986_wmac_adie_efuse_read(dev, adie, MT_ADIE_7975_XTAL_EN,
 565					  &data);
 566	if (ret || !(data & BIT(1)))
 567		return 0;
 568
 569	ret = mt7986_wmac_adie_efuse_read(dev, adie, MT_ADIE_7975_XTAL_CAL,
 570					  &data);
 571	if (ret)
 572		return ret;
 573
 574	if (data & MT_ADIE_XO_TRIM_EN_MASK)
 575		result = (data & MT_ADIE_TRIM_MASK);
 576
 577	ret = mt7986_read_efuse_xo_trim_7975(dev, adie, MT_ADIE_7975_XO_TRIM2,
 578					     &result);
 579	if (ret)
 580		return ret;
 581
 582	ret = mt7986_read_efuse_xo_trim_7975(dev, adie, MT_ADIE_7975_XO_TRIM3,
 583					     &result);
 584	if (ret)
 585		return ret;
 586
 587	ret = mt7986_read_efuse_xo_trim_7975(dev, adie, MT_ADIE_7975_XO_TRIM4,
 588					     &result);
 589	if (ret)
 590		return ret;
 591
 592	/* Update trim value to C1 and C2*/
 593	value = FIELD_GET(MT_ADIE_7975_XO_CTRL2_C1_MASK, result) |
 594		FIELD_GET(MT_ADIE_7975_XO_CTRL2_C2_MASK, result);
 595	ret = mt76_wmac_spi_rmw(dev, adie, MT_ADIE_7975_XO_CTRL2,
 596				MT_ADIE_7975_XO_CTRL2_MASK, value);
 597	if (ret)
 598		return ret;
 599
 600	ret = mt76_wmac_spi_read(dev, adie, MT_ADIE_7975_XTAL, &value);
 601	if (ret)
 602		return ret;
 603
 604	if (value & MT_ADIE_7975_XTAL_EN_MASK) {
 605		ret = mt76_wmac_spi_rmw(dev, adie, MT_ADIE_7975_XO_2,
 606					MT_ADIE_7975_XO_2_FIX_EN, 0x0);
 607		if (ret)
 608			return ret;
 609	}
 610
 611	return mt76_wmac_spi_rmw(dev, adie, MT_ADIE_7975_XO_CTRL6,
 612				 MT_ADIE_7975_XO_CTRL6_MASK, 0x1);
 613}
 614
 615static int mt7986_wmac_adie_patch_7975(struct mt7915_dev *dev, u8 adie)
 616{
 617	int ret;
 618
 619	/* disable CAL LDO and fine tune RFDIG LDO */
 620	ret = mt76_wmac_spi_write(dev, adie, 0x348, 0x00000002);
 621	if (ret)
 622		return ret;
 623
 624	ret = mt76_wmac_spi_write(dev, adie, 0x378, 0x00000002);
 625	if (ret)
 626		return ret;
 627
 628	ret = mt76_wmac_spi_write(dev, adie, 0x3a8, 0x00000002);
 629	if (ret)
 630		return ret;
 631
 632	ret = mt76_wmac_spi_write(dev, adie, 0x3d8, 0x00000002);
 633	if (ret)
 634		return ret;
 635
 636	/* set CKA driving and filter */
 637	ret = mt76_wmac_spi_write(dev, adie, 0xa1c, 0x30000aaa);
 638	if (ret)
 639		return ret;
 640
 641	/* set CKB LDO to 1.4V */
 642	ret = mt76_wmac_spi_write(dev, adie, 0xa84, 0x8470008a);
 643	if (ret)
 644		return ret;
 645
 646	/* turn on SX0 LTBUF */
 647	if (is_mt7981(&dev->mt76)) {
 648		ret = mt76_wmac_spi_write(dev, adie, 0x074, 0x00000007);
 649	} else if (is_mt7986(&dev->mt76)) {
 650		ret = mt76_wmac_spi_write(dev, adie, 0x074, 0x00000002);
 651	} else {
 652		WARN_ON(1);
 653		return -EINVAL;
 654	}
 655
 656	if (ret)
 657		return ret;
 658
 659	/* CK_BUF_SW_EN = 1 (all buf in manual mode.) */
 660	ret = mt76_wmac_spi_write(dev, adie, 0xaa4, 0x01001fc0);
 661	if (ret)
 662		return ret;
 663
 664	/* BT mode/WF normal mode 00000005 */
 665	ret = mt76_wmac_spi_write(dev, adie, 0x070, 0x00000005);
 666	if (ret)
 667		return ret;
 668
 669	/* BG thermal sensor offset update */
 670	ret = mt76_wmac_spi_write(dev, adie, 0x344, 0x00000088);
 671	if (ret)
 672		return ret;
 673
 674	ret = mt76_wmac_spi_write(dev, adie, 0x374, 0x00000088);
 675	if (ret)
 676		return ret;
 677
 678	ret = mt76_wmac_spi_write(dev, adie, 0x3a4, 0x00000088);
 679	if (ret)
 680		return ret;
 681
 682	ret = mt76_wmac_spi_write(dev, adie, 0x3d4, 0x00000088);
 683	if (ret)
 684		return ret;
 685
 686	/* set WCON VDD IPTAT to "0000" */
 687	ret = mt76_wmac_spi_write(dev, adie, 0xa80, 0x44d07000);
 688	if (ret)
 689		return ret;
 690
 691	/* change back LTBUF SX3 drving to default value */
 692	ret = mt76_wmac_spi_write(dev, adie, 0xa88, 0x3900aaaa);
 693	if (ret)
 694		return ret;
 695
 696	/* SM input cap off */
 697	ret = mt76_wmac_spi_write(dev, adie, 0x2c4, 0x00000000);
 698	if (ret)
 699		return ret;
 700
 701	/* set CKB driving and filter */
 702	if (is_mt7986(&dev->mt76))
 703		return mt76_wmac_spi_write(dev, adie, 0x2c8, 0x00000072);
 704
 705	return ret;
 706}
 707
 708static int mt7986_wmac_adie_cfg(struct mt7915_dev *dev, u8 adie, u32 adie_type)
 709{
 710	int ret;
 711
 712	mt76_wmac_spi_lock(dev);
 713	ret = mt76_wmac_spi_write(dev, adie, MT_ADIE_CLK_EN, ~0);
 714	if (ret)
 715		goto out;
 716
 717	if (is_7975(dev, adie, adie_type)) {
 718		ret = mt76_wmac_spi_rmw(dev, adie, MT_ADIE_7975_COCLK,
 719					BIT(1), 0x1);
 720		if (ret)
 721			goto out;
 722
 723		ret = mt7986_wmac_adie_thermal_cal(dev, adie);
 724		if (ret)
 725			goto out;
 726
 727		ret = mt7986_wmac_adie_xtal_trim_7975(dev, adie);
 728		if (ret)
 729			goto out;
 730
 731		ret = mt7986_wmac_adie_patch_7975(dev, adie);
 732	} else if (is_7976(dev, adie, adie_type)) {
 733		if (mt798x_wmac_check_adie_type(dev) == ADIE_DBDC) {
 734			ret = mt76_wmac_spi_write(dev, adie,
 735						  MT_ADIE_WRI_CK_SEL, 0x1c);
 736			if (ret)
 737				goto out;
 738		}
 739
 740		ret = mt7986_wmac_adie_thermal_cal(dev, adie);
 741		if (ret)
 742			goto out;
 743
 744		ret = mt7986_wmac_adie_xtal_trim_7976(dev, adie);
 745		if (ret)
 746			goto out;
 747
 748		ret = mt798x_wmac_adie_patch_7976(dev, adie);
 749	}
 750out:
 751	mt76_wmac_spi_unlock(dev);
 752
 753	return ret;
 754}
 755
 756static int
 757mt7986_wmac_afe_cal(struct mt7915_dev *dev, u8 adie, bool dbdc, u32 adie_type)
 758{
 759	int ret;
 760	u8 idx;
 761	u32 txcal;
 762
 763	mt76_wmac_spi_lock(dev);
 764	if (is_7975(dev, adie, adie_type))
 765		ret = mt76_wmac_spi_write(dev, adie,
 766					  MT_AFE_RG_ENCAL_WBTAC_IF_SW,
 767					  0x80000000);
 768	else
 769		ret = mt76_wmac_spi_write(dev, adie,
 770					  MT_AFE_RG_ENCAL_WBTAC_IF_SW,
 771					  0x88888005);
 772	if (ret)
 773		goto out;
 774
 775	idx = dbdc ? ADIE_DBDC : adie;
 776
 777	mt76_rmw_field(dev, MT_AFE_DIG_EN_01(idx),
 778		       MT_AFE_RG_WBG_EN_RCK_MASK, 0x1);
 779	usleep_range(60, 100);
 780
 781	mt76_rmw(dev, MT_AFE_DIG_EN_01(idx),
 782		 MT_AFE_RG_WBG_EN_RCK_MASK, 0x0);
 783
 784	mt76_rmw_field(dev, MT_AFE_DIG_EN_03(idx),
 785		       MT_AFE_RG_WBG_EN_BPLL_UP_MASK, 0x1);
 786	usleep_range(30, 100);
 787
 788	mt76_rmw_field(dev, MT_AFE_DIG_EN_03(idx),
 789		       MT_AFE_RG_WBG_EN_WPLL_UP_MASK, 0x1);
 790	usleep_range(60, 100);
 791
 792	txcal = (MT_AFE_RG_WBG_EN_TXCAL_BT |
 793		      MT_AFE_RG_WBG_EN_TXCAL_WF0 |
 794		      MT_AFE_RG_WBG_EN_TXCAL_WF1 |
 795		      MT_AFE_RG_WBG_EN_TXCAL_WF2 |
 796		      MT_AFE_RG_WBG_EN_TXCAL_WF3);
 797	if (is_mt7981(&dev->mt76))
 798		txcal |= MT_AFE_RG_WBG_EN_TXCAL_WF4;
 799
 800	mt76_set(dev, MT_AFE_DIG_EN_01(idx), txcal);
 801	usleep_range(800, 1000);
 802
 803	mt76_clear(dev, MT_AFE_DIG_EN_01(idx), txcal);
 804	mt76_rmw(dev, MT_AFE_DIG_EN_03(idx),
 805		 MT_AFE_RG_WBG_EN_PLL_UP_MASK, 0x0);
 806
 807	ret = mt76_wmac_spi_write(dev, adie, MT_AFE_RG_ENCAL_WBTAC_IF_SW,
 808				  0x5);
 809
 810out:
 811	mt76_wmac_spi_unlock(dev);
 812
 813	return ret;
 814}
 815
 816static void mt7986_wmac_subsys_pll_initial(struct mt7915_dev *dev, u8 band)
 817{
 818	mt76_rmw(dev, MT_AFE_PLL_STB_TIME(band),
 819		 MT_AFE_PLL_STB_TIME_MASK, MT_AFE_PLL_STB_TIME_VAL);
 820
 821	mt76_rmw(dev, MT_AFE_DIG_EN_02(band),
 822		 MT_AFE_PLL_CFG_MASK, MT_AFE_PLL_CFG_VAL);
 823
 824	mt76_rmw(dev, MT_AFE_DIG_TOP_01(band),
 825		 MT_AFE_DIG_TOP_01_MASK, MT_AFE_DIG_TOP_01_VAL);
 826}
 827
 828static void mt7986_wmac_subsys_setting(struct mt7915_dev *dev)
 829{
 830	/* Subsys pll init */
 831	mt7986_wmac_subsys_pll_initial(dev, 0);
 832	mt7986_wmac_subsys_pll_initial(dev, 1);
 833
 834	/* Set legacy OSC control stable time*/
 835	mt76_rmw(dev, MT_CONN_INFRA_OSC_RC_EN,
 836		 MT_CONN_INFRA_OSC_RC_EN_MASK, 0x0);
 837	mt76_rmw(dev, MT_CONN_INFRA_OSC_CTRL,
 838		 MT_CONN_INFRA_OSC_STB_TIME_MASK, 0x80706);
 839
 840	/* prevent subsys from power on/of in a short time interval */
 841	mt76_rmw(dev, MT_TOP_WFSYS_PWR,
 842		 MT_TOP_PWR_ACK_MASK | MT_TOP_PWR_KEY_MASK,
 843		 MT_TOP_PWR_KEY);
 844}
 845
 846static int mt7986_wmac_bus_timeout(struct mt7915_dev *dev)
 847{
 848	mt76_rmw_field(dev, MT_INFRA_BUS_OFF_TIMEOUT,
 849		       MT_INFRA_BUS_TIMEOUT_LIMIT_MASK, 0x2);
 850
 851	mt76_rmw_field(dev, MT_INFRA_BUS_OFF_TIMEOUT,
 852		       MT_INFRA_BUS_TIMEOUT_EN_MASK, 0xf);
 853
 854	mt76_rmw_field(dev, MT_INFRA_BUS_ON_TIMEOUT,
 855		       MT_INFRA_BUS_TIMEOUT_LIMIT_MASK, 0xc);
 856
 857	mt76_rmw_field(dev, MT_INFRA_BUS_ON_TIMEOUT,
 858		       MT_INFRA_BUS_TIMEOUT_EN_MASK, 0xf);
 859
 860	return mt798x_wmac_coninfra_check(dev);
 861}
 862
 863static void mt7986_wmac_clock_enable(struct mt7915_dev *dev, u32 adie_type)
 864{
 865	u32 cur;
 866
 867	mt76_rmw_field(dev, MT_INFRA_CKGEN_BUS_WPLL_DIV_1,
 868		       MT_INFRA_CKGEN_DIV_SEL_MASK, 0x1);
 869
 870	mt76_rmw_field(dev, MT_INFRA_CKGEN_BUS_WPLL_DIV_2,
 871		       MT_INFRA_CKGEN_DIV_SEL_MASK, 0x1);
 872
 873	mt76_rmw_field(dev, MT_INFRA_CKGEN_BUS_WPLL_DIV_1,
 874		       MT_INFRA_CKGEN_DIV_EN_MASK, 0x1);
 875
 876	mt76_rmw_field(dev, MT_INFRA_CKGEN_BUS_WPLL_DIV_2,
 877		       MT_INFRA_CKGEN_DIV_EN_MASK, 0x1);
 878
 879	mt76_rmw_field(dev, MT_INFRA_CKGEN_RFSPI_WPLL_DIV,
 880		       MT_INFRA_CKGEN_DIV_SEL_MASK, 0x8);
 881
 882	mt76_rmw_field(dev, MT_INFRA_CKGEN_RFSPI_WPLL_DIV,
 883		       MT_INFRA_CKGEN_DIV_EN_MASK, 0x1);
 884
 885	mt76_rmw_field(dev, MT_INFRA_CKGEN_BUS,
 886		       MT_INFRA_CKGEN_BUS_CLK_SEL_MASK, 0x0);
 887
 888	mt76_rmw_field(dev, MT_CONN_INFRA_HW_CTRL,
 889		       MT_CONN_INFRA_HW_CTRL_MASK, 0x1);
 890
 891	mt76_rmw(dev, MT_TOP_CONN_INFRA_WAKEUP,
 892		 MT_TOP_CONN_INFRA_WAKEUP_MASK, 0x1);
 893
 894	usleep_range(900, 1000);
 895
 896	mt76_wmac_spi_lock(dev);
 897	if (is_7975(dev, 0, adie_type) || is_7976(dev, 0, adie_type)) {
 898		mt76_rmw_field(dev, MT_ADIE_SLP_CTRL_CK0(0),
 899			       MT_SLP_CTRL_EN_MASK, 0x1);
 900
 901		read_poll_timeout(mt76_rr, cur, !(cur & MT_SLP_CTRL_BSY_MASK),
 902				  USEC_PER_MSEC, 50 * USEC_PER_MSEC, false,
 903				  dev, MT_ADIE_SLP_CTRL_CK0(0));
 904	}
 905	if (is_7975(dev, 1, adie_type) || is_7976(dev, 1, adie_type)) {
 906		mt76_rmw_field(dev, MT_ADIE_SLP_CTRL_CK0(1),
 907			       MT_SLP_CTRL_EN_MASK, 0x1);
 908
 909		read_poll_timeout(mt76_rr, cur, !(cur & MT_SLP_CTRL_BSY_MASK),
 910				  USEC_PER_MSEC, 50 * USEC_PER_MSEC, false,
 911				  dev, MT_ADIE_SLP_CTRL_CK0(0));
 912	}
 913	mt76_wmac_spi_unlock(dev);
 914
 915	mt76_rmw(dev, MT_TOP_CONN_INFRA_WAKEUP,
 916		 MT_TOP_CONN_INFRA_WAKEUP_MASK, 0x0);
 917	usleep_range(900, 1000);
 918}
 919
 920static int mt7986_wmac_top_wfsys_wakeup(struct mt7915_dev *dev, bool enable)
 921{
 922	mt76_rmw_field(dev, MT_TOP_WFSYS_WAKEUP,
 923		       MT_TOP_WFSYS_WAKEUP_MASK, enable);
 924
 925	usleep_range(900, 1000);
 926
 927	if (!enable)
 928		return 0;
 929
 930	return mt798x_wmac_coninfra_check(dev);
 931}
 932
 933static int mt7986_wmac_wm_enable(struct mt7915_dev *dev, bool enable)
 934{
 935	u32 cur;
 936
 937	if (is_mt7986(&dev->mt76))
 938		mt76_wr(dev, MT_CONNINFRA_SKU_DEC_ADDR, 0);
 939
 940	mt76_rmw_field(dev, MT7986_TOP_WM_RESET,
 941		       MT7986_TOP_WM_RESET_MASK, enable);
 942	if (!enable)
 943		return 0;
 944
 945	return read_poll_timeout(mt76_rr, cur, (cur == 0x1d1e),
 946				 USEC_PER_MSEC, 5000 * USEC_PER_MSEC, false,
 947				 dev, MT_TOP_CFG_ON_ROM_IDX);
 948}
 949
 950static int mt7986_wmac_wfsys_poweron(struct mt7915_dev *dev, bool enable)
 951{
 952	u32 mask = MT_TOP_PWR_EN_MASK | MT_TOP_PWR_KEY_MASK;
 953	u32 cur;
 954
 955	mt76_rmw(dev, MT_TOP_WFSYS_PWR, mask,
 956		 MT_TOP_PWR_KEY | FIELD_PREP(MT_TOP_PWR_EN_MASK, enable));
 957
 958	return read_poll_timeout(mt76_rr, cur,
 959		(FIELD_GET(MT_TOP_WFSYS_RESET_STATUS_MASK, cur) == enable),
 960		USEC_PER_MSEC, 50 * USEC_PER_MSEC, false,
 961		dev, MT_TOP_WFSYS_RESET_STATUS);
 962}
 963
 964static int mt7986_wmac_wfsys_setting(struct mt7915_dev *dev)
 965{
 966	int ret;
 967	u32 cur;
 968
 969	/* Turn off wfsys2conn bus sleep protect */
 970	mt76_rmw(dev, MT_CONN_INFRA_WF_SLP_PROT,
 971		 MT_CONN_INFRA_WF_SLP_PROT_MASK, 0x0);
 972
 973	ret = mt7986_wmac_wfsys_poweron(dev, true);
 974	if (ret)
 975		return ret;
 976
 977	/* Check bus sleep protect */
 978
 979	ret = read_poll_timeout(mt76_rr, cur,
 980				!(cur & MT_CONN_INFRA_CONN_WF_MASK),
 981				USEC_PER_MSEC, 50 * USEC_PER_MSEC, false,
 982				dev, MT_CONN_INFRA_WF_SLP_PROT_RDY);
 983	if (ret)
 984		return ret;
 985
 986	ret = read_poll_timeout(mt76_rr, cur, !(cur & MT_SLP_WFDMA2CONN_MASK),
 987				USEC_PER_MSEC, 50 * USEC_PER_MSEC, false,
 988				dev, MT_SLP_STATUS);
 989	if (ret)
 990		return ret;
 991
 992	return read_poll_timeout(mt76_rr, cur, (cur == 0x02060000),
 993				 USEC_PER_MSEC, 50 * USEC_PER_MSEC, false,
 994				 dev, MT_TOP_CFG_IP_VERSION_ADDR);
 995}
 996
 997static void mt7986_wmac_wfsys_set_timeout(struct mt7915_dev *dev)
 998{
 999	u32 mask = MT_MCU_BUS_TIMEOUT_SET_MASK |
1000		   MT_MCU_BUS_TIMEOUT_CG_EN_MASK |
1001		   MT_MCU_BUS_TIMEOUT_EN_MASK;
1002	u32 val = FIELD_PREP(MT_MCU_BUS_TIMEOUT_SET_MASK, 1) |
1003		  FIELD_PREP(MT_MCU_BUS_TIMEOUT_CG_EN_MASK, 1) |
1004		  FIELD_PREP(MT_MCU_BUS_TIMEOUT_EN_MASK, 1);
1005
1006	mt76_rmw(dev, MT_MCU_BUS_TIMEOUT, mask, val);
1007
1008	mt76_wr(dev, MT_MCU_BUS_REMAP, 0x810f0000);
1009
1010	mask = MT_MCU_BUS_DBG_TIMEOUT_SET_MASK |
1011	       MT_MCU_BUS_DBG_TIMEOUT_CK_EN_MASK |
1012	       MT_MCU_BUS_DBG_TIMEOUT_EN_MASK;
1013	val = FIELD_PREP(MT_MCU_BUS_DBG_TIMEOUT_SET_MASK, 0x3aa) |
1014	      FIELD_PREP(MT_MCU_BUS_DBG_TIMEOUT_CK_EN_MASK, 1) |
1015	      FIELD_PREP(MT_MCU_BUS_DBG_TIMEOUT_EN_MASK, 1);
1016
1017	mt76_rmw(dev, MT_MCU_BUS_DBG_TIMEOUT, mask, val);
1018}
1019
1020static int mt7986_wmac_sku_update(struct mt7915_dev *dev, u32 adie_type)
1021{
1022	u32 val;
1023
1024	if (is_7976(dev, 0, adie_type) && is_7976(dev, 1, adie_type))
1025		val = 0xf;
1026	else if (is_7975(dev, 0, adie_type) && is_7975(dev, 1, adie_type))
1027		val = 0xd;
1028	else if (is_7976(dev, 0, adie_type))
1029		val = 0x7;
1030	else if (is_7975(dev, 1, adie_type))
1031		val = 0x8;
1032	else if (is_7976(dev, 1, adie_type))
1033		val = 0xa;
1034	else
1035		return -EINVAL;
1036
1037	mt76_wmac_rmw(dev->sku, MT_TOP_POS_SKU, MT_TOP_POS_SKU_MASK,
1038		      FIELD_PREP(MT_TOP_POS_SKU_MASK, val));
1039
1040	mt76_wr(dev, MT_CONNINFRA_SKU_DEC_ADDR, val);
1041
1042	return 0;
1043}
1044
1045static int
1046mt7986_wmac_adie_setup(struct mt7915_dev *dev, u8 adie, u32 adie_type)
1047{
1048	int ret;
1049
1050	if (!(is_7975(dev, adie, adie_type) || is_7976(dev, adie, adie_type)))
1051		return 0;
1052
1053	ret = mt7986_wmac_adie_cfg(dev, adie, adie_type);
1054	if (ret)
1055		return ret;
1056
1057	ret = mt7986_wmac_afe_cal(dev, adie, false, adie_type);
1058	if (ret)
1059		return ret;
1060
1061	if (!adie && (mt798x_wmac_check_adie_type(dev) == ADIE_DBDC))
1062		ret = mt7986_wmac_afe_cal(dev, adie, true, adie_type);
1063
1064	return ret;
1065}
1066
1067static int mt7986_wmac_subsys_powerup(struct mt7915_dev *dev, u32 adie_type)
1068{
1069	int ret;
1070
1071	mt7986_wmac_subsys_setting(dev);
1072
1073	ret = mt7986_wmac_bus_timeout(dev);
1074	if (ret)
1075		return ret;
1076
1077	mt7986_wmac_clock_enable(dev, adie_type);
1078
1079	return 0;
1080}
1081
1082static int mt7986_wmac_wfsys_powerup(struct mt7915_dev *dev)
1083{
1084	int ret;
1085
1086	ret = mt7986_wmac_wm_enable(dev, false);
1087	if (ret)
1088		return ret;
1089
1090	ret = mt7986_wmac_wfsys_setting(dev);
1091	if (ret)
1092		return ret;
1093
1094	mt7986_wmac_wfsys_set_timeout(dev);
1095
1096	return mt7986_wmac_wm_enable(dev, true);
1097}
1098
1099int mt7986_wmac_enable(struct mt7915_dev *dev)
1100{
1101	int ret;
1102	u32 adie_type;
1103
1104	ret = mt7986_wmac_consys_reset(dev, true);
1105	if (ret)
1106		return ret;
1107
1108	ret = mt7986_wmac_gpio_setup(dev);
1109	if (ret)
1110		return ret;
1111
1112	ret = mt7986_wmac_consys_lockup(dev, false);
1113	if (ret)
1114		return ret;
1115
1116	ret = mt798x_wmac_coninfra_check(dev);
1117	if (ret)
1118		return ret;
1119
1120	ret = mt798x_wmac_coninfra_setup(dev);
1121	if (ret)
1122		return ret;
1123
1124	ret = mt798x_wmac_sku_setup(dev, &adie_type);
1125	if (ret)
1126		return ret;
1127
1128	ret = mt7986_wmac_adie_setup(dev, 0, adie_type);
1129	if (ret)
1130		return ret;
1131
1132	/* mt7981 doesn't support a second a-die */
1133	if (is_mt7986(&dev->mt76)) {
1134		ret = mt7986_wmac_adie_setup(dev, 1, adie_type);
1135		if (ret)
1136			return ret;
1137	}
1138
1139	ret = mt7986_wmac_subsys_powerup(dev, adie_type);
1140	if (ret)
1141		return ret;
1142
1143	ret = mt7986_wmac_top_wfsys_wakeup(dev, true);
1144	if (ret)
1145		return ret;
1146
1147	ret = mt7986_wmac_wfsys_powerup(dev);
1148	if (ret)
1149		return ret;
1150
1151	return mt7986_wmac_sku_update(dev, adie_type);
1152}
1153
1154void mt7986_wmac_disable(struct mt7915_dev *dev)
1155{
1156	u32 cur;
1157
1158	mt7986_wmac_top_wfsys_wakeup(dev, true);
1159
1160	/* Turn on wfsys2conn bus sleep protect */
1161	mt76_rmw_field(dev, MT_CONN_INFRA_WF_SLP_PROT,
1162		       MT_CONN_INFRA_WF_SLP_PROT_MASK, 0x1);
1163
1164	/* Check wfsys2conn bus sleep protect */
1165	read_poll_timeout(mt76_rr, cur, !(cur ^ MT_CONN_INFRA_CONN),
1166			  USEC_PER_MSEC, 50 * USEC_PER_MSEC, false,
1167			  dev, MT_CONN_INFRA_WF_SLP_PROT_RDY);
1168
1169	mt7986_wmac_wfsys_poweron(dev, false);
1170
1171	/* Turn back wpll setting */
1172	mt76_rmw_field(dev, MT_AFE_DIG_EN_02(0), MT_AFE_MCU_BPLL_CFG_MASK, 0x2);
1173	mt76_rmw_field(dev, MT_AFE_DIG_EN_02(0), MT_AFE_WPLL_CFG_MASK, 0x2);
1174
1175	/* Reset EMI */
1176	mt76_rmw_field(dev, MT_CONN_INFRA_EMI_REQ,
1177		       MT_CONN_INFRA_EMI_REQ_MASK, 0x1);
1178	mt76_rmw_field(dev, MT_CONN_INFRA_EMI_REQ,
1179		       MT_CONN_INFRA_EMI_REQ_MASK, 0x0);
1180	mt76_rmw_field(dev, MT_CONN_INFRA_EMI_REQ,
1181		       MT_CONN_INFRA_INFRA_REQ_MASK, 0x1);
1182	mt76_rmw_field(dev, MT_CONN_INFRA_EMI_REQ,
1183		       MT_CONN_INFRA_INFRA_REQ_MASK, 0x0);
1184
1185	mt7986_wmac_top_wfsys_wakeup(dev, false);
1186	mt7986_wmac_consys_lockup(dev, true);
1187	mt7986_wmac_consys_reset(dev, false);
1188}
1189
1190static int mt798x_wmac_init(struct mt7915_dev *dev)
1191{
1192	struct device *pdev = dev->mt76.dev;
1193	struct platform_device *pfdev = to_platform_device(pdev);
1194	struct clk *mcu_clk, *ap_conn_clk;
1195
1196	mcu_clk = devm_clk_get(pdev, "mcu");
1197	if (IS_ERR(mcu_clk))
1198		dev_err(pdev, "mcu clock not found\n");
1199	else if (clk_prepare_enable(mcu_clk))
1200		dev_err(pdev, "mcu clock configuration failed\n");
1201
1202	ap_conn_clk = devm_clk_get(pdev, "ap2conn");
1203	if (IS_ERR(ap_conn_clk))
1204		dev_err(pdev, "ap2conn clock not found\n");
1205	else if (clk_prepare_enable(ap_conn_clk))
1206		dev_err(pdev, "ap2conn clock configuration failed\n");
1207
1208	dev->dcm = devm_platform_ioremap_resource(pfdev, 1);
1209	if (IS_ERR(dev->dcm))
1210		return PTR_ERR(dev->dcm);
1211
1212	dev->sku = devm_platform_ioremap_resource(pfdev, 2);
1213	if (IS_ERR(dev->sku))
1214		return PTR_ERR(dev->sku);
1215
1216	dev->rstc = devm_reset_control_get(pdev, "consys");
1217	return PTR_ERR_OR_ZERO(dev->rstc);
1218}
1219
1220static int mt798x_wmac_probe(struct platform_device *pdev)
1221{
1222	void __iomem *mem_base;
1223	struct mt7915_dev *dev;
1224	struct mt76_dev *mdev;
1225	int irq, ret;
1226	u32 chip_id;
1227
1228	chip_id = (uintptr_t)of_device_get_match_data(&pdev->dev);
1229
1230	mem_base = devm_platform_ioremap_resource(pdev, 0);
1231	if (IS_ERR(mem_base)) {
1232		dev_err(&pdev->dev, "Failed to get memory resource\n");
1233		return PTR_ERR(mem_base);
1234	}
1235
1236	dev = mt7915_mmio_probe(&pdev->dev, mem_base, chip_id);
1237	if (IS_ERR(dev))
1238		return PTR_ERR(dev);
1239
1240	mdev = &dev->mt76;
1241	ret = mt7915_mmio_wed_init(dev, pdev, false, &irq);
1242	if (ret < 0)
1243		goto free_device;
1244
1245	if (!ret) {
1246		irq = platform_get_irq(pdev, 0);
1247		if (irq < 0) {
1248			ret = irq;
1249			goto free_device;
1250		}
1251	}
1252
1253	ret = devm_request_irq(mdev->dev, irq, mt7915_irq_handler,
1254			       IRQF_SHARED, KBUILD_MODNAME, dev);
1255	if (ret)
1256		goto free_device;
1257
1258	ret = mt798x_wmac_init(dev);
1259	if (ret)
1260		goto free_irq;
1261
1262	mt7915_wfsys_reset(dev);
1263
1264	ret = mt7915_register_device(dev);
1265	if (ret)
1266		goto free_irq;
1267
1268	return 0;
1269
1270free_irq:
1271	devm_free_irq(mdev->dev, irq, dev);
1272free_device:
1273	if (mtk_wed_device_active(&mdev->mmio.wed))
1274		mtk_wed_device_detach(&mdev->mmio.wed);
1275	mt76_free_device(mdev);
1276
1277	return ret;
1278}
1279
1280static void mt798x_wmac_remove(struct platform_device *pdev)
1281{
1282	struct mt7915_dev *dev = platform_get_drvdata(pdev);
1283
1284	mt7915_unregister_device(dev);
1285}
1286
1287static const struct of_device_id mt798x_wmac_of_match[] = {
1288	{ .compatible = "mediatek,mt7981-wmac", .data = (u32 *)0x7981 },
1289	{ .compatible = "mediatek,mt7986-wmac", .data = (u32 *)0x7986 },
1290	{},
1291};
1292
1293MODULE_DEVICE_TABLE(of, mt798x_wmac_of_match);
1294
1295struct platform_driver mt798x_wmac_driver = {
1296	.driver = {
1297		.name = "mt798x-wmac",
1298		.of_match_table = mt798x_wmac_of_match,
1299	},
1300	.probe = mt798x_wmac_probe,
1301	.remove = mt798x_wmac_remove,
1302};
1303
1304MODULE_FIRMWARE(MT7986_FIRMWARE_WA);
1305MODULE_FIRMWARE(MT7986_FIRMWARE_WM);
1306MODULE_FIRMWARE(MT7986_FIRMWARE_WM_MT7975);
1307MODULE_FIRMWARE(MT7986_ROM_PATCH);
1308MODULE_FIRMWARE(MT7986_ROM_PATCH_MT7975);
1309
1310MODULE_FIRMWARE(MT7981_FIRMWARE_WA);
1311MODULE_FIRMWARE(MT7981_FIRMWARE_WM);
1312MODULE_FIRMWARE(MT7981_ROM_PATCH);
~/ Read-only file preview.