cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

soc.c (30342B)


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