162306a36Sopenharmony_ci// SPDX-License-Identifier: ISC 262306a36Sopenharmony_ci/* Copyright (C) 2022 MediaTek Inc. */ 362306a36Sopenharmony_ci 462306a36Sopenharmony_ci#include <linux/kernel.h> 562306a36Sopenharmony_ci#include <linux/module.h> 662306a36Sopenharmony_ci#include <linux/platform_device.h> 762306a36Sopenharmony_ci#include <linux/pinctrl/consumer.h> 862306a36Sopenharmony_ci#include <linux/of.h> 962306a36Sopenharmony_ci#include <linux/of_reserved_mem.h> 1062306a36Sopenharmony_ci#include <linux/of_gpio.h> 1162306a36Sopenharmony_ci#include <linux/iopoll.h> 1262306a36Sopenharmony_ci#include <linux/reset.h> 1362306a36Sopenharmony_ci#include <linux/of_net.h> 1462306a36Sopenharmony_ci#include <linux/clk.h> 1562306a36Sopenharmony_ci 1662306a36Sopenharmony_ci#include "mt7915.h" 1762306a36Sopenharmony_ci 1862306a36Sopenharmony_ci#define MT7981_CON_INFRA_VERSION 0x02090000 1962306a36Sopenharmony_ci#define MT7986_CON_INFRA_VERSION 0x02070000 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_ci/* INFRACFG */ 2262306a36Sopenharmony_ci#define MT_INFRACFG_CONN2AP_SLPPROT 0x0d0 2362306a36Sopenharmony_ci#define MT_INFRACFG_AP2CONN_SLPPROT 0x0d4 2462306a36Sopenharmony_ci 2562306a36Sopenharmony_ci#define MT_INFRACFG_RX_EN_MASK BIT(16) 2662306a36Sopenharmony_ci#define MT_INFRACFG_TX_RDY_MASK BIT(4) 2762306a36Sopenharmony_ci#define MT_INFRACFG_TX_EN_MASK BIT(0) 2862306a36Sopenharmony_ci 2962306a36Sopenharmony_ci/* TOP POS */ 3062306a36Sopenharmony_ci#define MT_TOP_POS_FAST_CTRL 0x114 3162306a36Sopenharmony_ci#define MT_TOP_POS_FAST_EN_MASK BIT(3) 3262306a36Sopenharmony_ci 3362306a36Sopenharmony_ci#define MT_TOP_POS_SKU 0x21c 3462306a36Sopenharmony_ci#define MT_TOP_POS_SKU_MASK GENMASK(31, 28) 3562306a36Sopenharmony_ci#define MT_TOP_POS_SKU_ADIE_DBDC_MASK BIT(2) 3662306a36Sopenharmony_ci 3762306a36Sopenharmony_cienum { 3862306a36Sopenharmony_ci ADIE_SB, 3962306a36Sopenharmony_ci ADIE_DBDC 4062306a36Sopenharmony_ci}; 4162306a36Sopenharmony_ci 4262306a36Sopenharmony_cistatic int 4362306a36Sopenharmony_cimt76_wmac_spi_read(struct mt7915_dev *dev, u8 adie, u32 addr, u32 *val) 4462306a36Sopenharmony_ci{ 4562306a36Sopenharmony_ci int ret; 4662306a36Sopenharmony_ci u32 cur; 4762306a36Sopenharmony_ci 4862306a36Sopenharmony_ci ret = read_poll_timeout(mt76_rr, cur, !(cur & MT_TOP_SPI_POLLING_BIT), 4962306a36Sopenharmony_ci USEC_PER_MSEC, 50 * USEC_PER_MSEC, false, 5062306a36Sopenharmony_ci dev, MT_TOP_SPI_BUSY_CR(adie)); 5162306a36Sopenharmony_ci if (ret) 5262306a36Sopenharmony_ci return ret; 5362306a36Sopenharmony_ci 5462306a36Sopenharmony_ci mt76_wr(dev, MT_TOP_SPI_ADDR_CR(adie), 5562306a36Sopenharmony_ci MT_TOP_SPI_READ_ADDR_FORMAT | addr); 5662306a36Sopenharmony_ci mt76_wr(dev, MT_TOP_SPI_WRITE_DATA_CR(adie), 0); 5762306a36Sopenharmony_ci 5862306a36Sopenharmony_ci ret = read_poll_timeout(mt76_rr, cur, !(cur & MT_TOP_SPI_POLLING_BIT), 5962306a36Sopenharmony_ci USEC_PER_MSEC, 50 * USEC_PER_MSEC, false, 6062306a36Sopenharmony_ci dev, MT_TOP_SPI_BUSY_CR(adie)); 6162306a36Sopenharmony_ci if (ret) 6262306a36Sopenharmony_ci return ret; 6362306a36Sopenharmony_ci 6462306a36Sopenharmony_ci *val = mt76_rr(dev, MT_TOP_SPI_READ_DATA_CR(adie)); 6562306a36Sopenharmony_ci 6662306a36Sopenharmony_ci return 0; 6762306a36Sopenharmony_ci} 6862306a36Sopenharmony_ci 6962306a36Sopenharmony_cistatic int 7062306a36Sopenharmony_cimt76_wmac_spi_write(struct mt7915_dev *dev, u8 adie, u32 addr, u32 val) 7162306a36Sopenharmony_ci{ 7262306a36Sopenharmony_ci int ret; 7362306a36Sopenharmony_ci u32 cur; 7462306a36Sopenharmony_ci 7562306a36Sopenharmony_ci ret = read_poll_timeout(mt76_rr, cur, !(cur & MT_TOP_SPI_POLLING_BIT), 7662306a36Sopenharmony_ci USEC_PER_MSEC, 50 * USEC_PER_MSEC, false, 7762306a36Sopenharmony_ci dev, MT_TOP_SPI_BUSY_CR(adie)); 7862306a36Sopenharmony_ci if (ret) 7962306a36Sopenharmony_ci return ret; 8062306a36Sopenharmony_ci 8162306a36Sopenharmony_ci mt76_wr(dev, MT_TOP_SPI_ADDR_CR(adie), 8262306a36Sopenharmony_ci MT_TOP_SPI_WRITE_ADDR_FORMAT | addr); 8362306a36Sopenharmony_ci mt76_wr(dev, MT_TOP_SPI_WRITE_DATA_CR(adie), val); 8462306a36Sopenharmony_ci 8562306a36Sopenharmony_ci return read_poll_timeout(mt76_rr, cur, !(cur & MT_TOP_SPI_POLLING_BIT), 8662306a36Sopenharmony_ci USEC_PER_MSEC, 50 * USEC_PER_MSEC, false, 8762306a36Sopenharmony_ci dev, MT_TOP_SPI_BUSY_CR(adie)); 8862306a36Sopenharmony_ci} 8962306a36Sopenharmony_ci 9062306a36Sopenharmony_cistatic int 9162306a36Sopenharmony_cimt76_wmac_spi_rmw(struct mt7915_dev *dev, u8 adie, 9262306a36Sopenharmony_ci u32 addr, u32 mask, u32 val) 9362306a36Sopenharmony_ci{ 9462306a36Sopenharmony_ci u32 cur, ret; 9562306a36Sopenharmony_ci 9662306a36Sopenharmony_ci ret = mt76_wmac_spi_read(dev, adie, addr, &cur); 9762306a36Sopenharmony_ci if (ret) 9862306a36Sopenharmony_ci return ret; 9962306a36Sopenharmony_ci 10062306a36Sopenharmony_ci cur &= ~mask; 10162306a36Sopenharmony_ci cur |= val; 10262306a36Sopenharmony_ci 10362306a36Sopenharmony_ci return mt76_wmac_spi_write(dev, adie, addr, cur); 10462306a36Sopenharmony_ci} 10562306a36Sopenharmony_ci 10662306a36Sopenharmony_cistatic int 10762306a36Sopenharmony_cimt7986_wmac_adie_efuse_read(struct mt7915_dev *dev, u8 adie, 10862306a36Sopenharmony_ci u32 addr, u32 *data) 10962306a36Sopenharmony_ci{ 11062306a36Sopenharmony_ci int ret, temp; 11162306a36Sopenharmony_ci u32 val, mask; 11262306a36Sopenharmony_ci 11362306a36Sopenharmony_ci ret = mt76_wmac_spi_write(dev, adie, MT_ADIE_EFUSE_CFG, 11462306a36Sopenharmony_ci MT_ADIE_EFUSE_CTRL_MASK); 11562306a36Sopenharmony_ci if (ret) 11662306a36Sopenharmony_ci return ret; 11762306a36Sopenharmony_ci 11862306a36Sopenharmony_ci ret = mt76_wmac_spi_rmw(dev, adie, MT_ADIE_EFUSE2_CTRL, BIT(30), 0x0); 11962306a36Sopenharmony_ci if (ret) 12062306a36Sopenharmony_ci return ret; 12162306a36Sopenharmony_ci 12262306a36Sopenharmony_ci mask = (MT_ADIE_EFUSE_MODE_MASK | MT_ADIE_EFUSE_ADDR_MASK | 12362306a36Sopenharmony_ci MT_ADIE_EFUSE_KICK_MASK); 12462306a36Sopenharmony_ci val = FIELD_PREP(MT_ADIE_EFUSE_MODE_MASK, 0) | 12562306a36Sopenharmony_ci FIELD_PREP(MT_ADIE_EFUSE_ADDR_MASK, addr) | 12662306a36Sopenharmony_ci FIELD_PREP(MT_ADIE_EFUSE_KICK_MASK, 1); 12762306a36Sopenharmony_ci ret = mt76_wmac_spi_rmw(dev, adie, MT_ADIE_EFUSE2_CTRL, mask, val); 12862306a36Sopenharmony_ci if (ret) 12962306a36Sopenharmony_ci return ret; 13062306a36Sopenharmony_ci 13162306a36Sopenharmony_ci ret = read_poll_timeout(mt76_wmac_spi_read, temp, 13262306a36Sopenharmony_ci !temp && !FIELD_GET(MT_ADIE_EFUSE_KICK_MASK, val), 13362306a36Sopenharmony_ci USEC_PER_MSEC, 50 * USEC_PER_MSEC, false, 13462306a36Sopenharmony_ci dev, adie, MT_ADIE_EFUSE2_CTRL, &val); 13562306a36Sopenharmony_ci if (ret) 13662306a36Sopenharmony_ci return ret; 13762306a36Sopenharmony_ci 13862306a36Sopenharmony_ci ret = mt76_wmac_spi_read(dev, adie, MT_ADIE_EFUSE2_CTRL, &val); 13962306a36Sopenharmony_ci if (ret) 14062306a36Sopenharmony_ci return ret; 14162306a36Sopenharmony_ci 14262306a36Sopenharmony_ci if (FIELD_GET(MT_ADIE_EFUSE_VALID_MASK, val) == 1) 14362306a36Sopenharmony_ci ret = mt76_wmac_spi_read(dev, adie, MT_ADIE_EFUSE_RDATA0, 14462306a36Sopenharmony_ci data); 14562306a36Sopenharmony_ci 14662306a36Sopenharmony_ci return ret; 14762306a36Sopenharmony_ci} 14862306a36Sopenharmony_ci 14962306a36Sopenharmony_cistatic inline void mt76_wmac_spi_lock(struct mt7915_dev *dev) 15062306a36Sopenharmony_ci{ 15162306a36Sopenharmony_ci u32 cur; 15262306a36Sopenharmony_ci 15362306a36Sopenharmony_ci read_poll_timeout(mt76_rr, cur, 15462306a36Sopenharmony_ci FIELD_GET(MT_SEMA_RFSPI_STATUS_MASK, cur), 15562306a36Sopenharmony_ci 1000, 1000 * MSEC_PER_SEC, false, dev, 15662306a36Sopenharmony_ci MT_SEMA_RFSPI_STATUS); 15762306a36Sopenharmony_ci} 15862306a36Sopenharmony_ci 15962306a36Sopenharmony_cistatic inline void mt76_wmac_spi_unlock(struct mt7915_dev *dev) 16062306a36Sopenharmony_ci{ 16162306a36Sopenharmony_ci mt76_wr(dev, MT_SEMA_RFSPI_RELEASE, 1); 16262306a36Sopenharmony_ci} 16362306a36Sopenharmony_ci 16462306a36Sopenharmony_cistatic u32 mt76_wmac_rmw(void __iomem *base, u32 offset, u32 mask, u32 val) 16562306a36Sopenharmony_ci{ 16662306a36Sopenharmony_ci val |= readl(base + offset) & ~mask; 16762306a36Sopenharmony_ci writel(val, base + offset); 16862306a36Sopenharmony_ci 16962306a36Sopenharmony_ci return val; 17062306a36Sopenharmony_ci} 17162306a36Sopenharmony_ci 17262306a36Sopenharmony_cistatic u8 mt798x_wmac_check_adie_type(struct mt7915_dev *dev) 17362306a36Sopenharmony_ci{ 17462306a36Sopenharmony_ci u32 val; 17562306a36Sopenharmony_ci 17662306a36Sopenharmony_ci /* Only DBDC A-die is used with MT7981 */ 17762306a36Sopenharmony_ci if (is_mt7981(&dev->mt76)) 17862306a36Sopenharmony_ci return ADIE_DBDC; 17962306a36Sopenharmony_ci 18062306a36Sopenharmony_ci val = readl(dev->sku + MT_TOP_POS_SKU); 18162306a36Sopenharmony_ci 18262306a36Sopenharmony_ci return FIELD_GET(MT_TOP_POS_SKU_ADIE_DBDC_MASK, val); 18362306a36Sopenharmony_ci} 18462306a36Sopenharmony_ci 18562306a36Sopenharmony_cistatic int mt7986_wmac_consys_reset(struct mt7915_dev *dev, bool enable) 18662306a36Sopenharmony_ci{ 18762306a36Sopenharmony_ci if (!enable) 18862306a36Sopenharmony_ci return reset_control_assert(dev->rstc); 18962306a36Sopenharmony_ci 19062306a36Sopenharmony_ci mt76_wmac_rmw(dev->sku, MT_TOP_POS_FAST_CTRL, 19162306a36Sopenharmony_ci MT_TOP_POS_FAST_EN_MASK, 19262306a36Sopenharmony_ci FIELD_PREP(MT_TOP_POS_FAST_EN_MASK, 0x1)); 19362306a36Sopenharmony_ci 19462306a36Sopenharmony_ci return reset_control_deassert(dev->rstc); 19562306a36Sopenharmony_ci} 19662306a36Sopenharmony_ci 19762306a36Sopenharmony_cistatic int mt7986_wmac_gpio_setup(struct mt7915_dev *dev) 19862306a36Sopenharmony_ci{ 19962306a36Sopenharmony_ci struct pinctrl_state *state; 20062306a36Sopenharmony_ci struct pinctrl *pinctrl; 20162306a36Sopenharmony_ci int ret; 20262306a36Sopenharmony_ci u8 type; 20362306a36Sopenharmony_ci 20462306a36Sopenharmony_ci type = mt798x_wmac_check_adie_type(dev); 20562306a36Sopenharmony_ci pinctrl = devm_pinctrl_get(dev->mt76.dev); 20662306a36Sopenharmony_ci if (IS_ERR(pinctrl)) 20762306a36Sopenharmony_ci return PTR_ERR(pinctrl); 20862306a36Sopenharmony_ci 20962306a36Sopenharmony_ci switch (type) { 21062306a36Sopenharmony_ci case ADIE_SB: 21162306a36Sopenharmony_ci state = pinctrl_lookup_state(pinctrl, "default"); 21262306a36Sopenharmony_ci if (IS_ERR_OR_NULL(state)) 21362306a36Sopenharmony_ci return -EINVAL; 21462306a36Sopenharmony_ci break; 21562306a36Sopenharmony_ci case ADIE_DBDC: 21662306a36Sopenharmony_ci state = pinctrl_lookup_state(pinctrl, "dbdc"); 21762306a36Sopenharmony_ci if (IS_ERR_OR_NULL(state)) 21862306a36Sopenharmony_ci return -EINVAL; 21962306a36Sopenharmony_ci break; 22062306a36Sopenharmony_ci default: 22162306a36Sopenharmony_ci return -EINVAL; 22262306a36Sopenharmony_ci } 22362306a36Sopenharmony_ci 22462306a36Sopenharmony_ci ret = pinctrl_select_state(pinctrl, state); 22562306a36Sopenharmony_ci if (ret) 22662306a36Sopenharmony_ci return ret; 22762306a36Sopenharmony_ci 22862306a36Sopenharmony_ci usleep_range(500, 1000); 22962306a36Sopenharmony_ci 23062306a36Sopenharmony_ci return 0; 23162306a36Sopenharmony_ci} 23262306a36Sopenharmony_ci 23362306a36Sopenharmony_cistatic int mt7986_wmac_consys_lockup(struct mt7915_dev *dev, bool enable) 23462306a36Sopenharmony_ci{ 23562306a36Sopenharmony_ci int ret; 23662306a36Sopenharmony_ci u32 cur; 23762306a36Sopenharmony_ci 23862306a36Sopenharmony_ci mt76_wmac_rmw(dev->dcm, MT_INFRACFG_AP2CONN_SLPPROT, 23962306a36Sopenharmony_ci MT_INFRACFG_RX_EN_MASK, 24062306a36Sopenharmony_ci FIELD_PREP(MT_INFRACFG_RX_EN_MASK, enable)); 24162306a36Sopenharmony_ci ret = read_poll_timeout(readl, cur, !(cur & MT_INFRACFG_RX_EN_MASK), 24262306a36Sopenharmony_ci USEC_PER_MSEC, 50 * USEC_PER_MSEC, false, 24362306a36Sopenharmony_ci dev->dcm + MT_INFRACFG_AP2CONN_SLPPROT); 24462306a36Sopenharmony_ci if (ret) 24562306a36Sopenharmony_ci return ret; 24662306a36Sopenharmony_ci 24762306a36Sopenharmony_ci mt76_wmac_rmw(dev->dcm, MT_INFRACFG_AP2CONN_SLPPROT, 24862306a36Sopenharmony_ci MT_INFRACFG_TX_EN_MASK, 24962306a36Sopenharmony_ci FIELD_PREP(MT_INFRACFG_TX_EN_MASK, enable)); 25062306a36Sopenharmony_ci ret = read_poll_timeout(readl, cur, !(cur & MT_INFRACFG_TX_RDY_MASK), 25162306a36Sopenharmony_ci USEC_PER_MSEC, 50 * USEC_PER_MSEC, false, 25262306a36Sopenharmony_ci dev->dcm + MT_INFRACFG_AP2CONN_SLPPROT); 25362306a36Sopenharmony_ci if (ret) 25462306a36Sopenharmony_ci return ret; 25562306a36Sopenharmony_ci 25662306a36Sopenharmony_ci mt76_wmac_rmw(dev->dcm, MT_INFRACFG_CONN2AP_SLPPROT, 25762306a36Sopenharmony_ci MT_INFRACFG_RX_EN_MASK, 25862306a36Sopenharmony_ci FIELD_PREP(MT_INFRACFG_RX_EN_MASK, enable)); 25962306a36Sopenharmony_ci mt76_wmac_rmw(dev->dcm, MT_INFRACFG_CONN2AP_SLPPROT, 26062306a36Sopenharmony_ci MT_INFRACFG_TX_EN_MASK, 26162306a36Sopenharmony_ci FIELD_PREP(MT_INFRACFG_TX_EN_MASK, enable)); 26262306a36Sopenharmony_ci 26362306a36Sopenharmony_ci return 0; 26462306a36Sopenharmony_ci} 26562306a36Sopenharmony_ci 26662306a36Sopenharmony_cistatic int mt798x_wmac_coninfra_check(struct mt7915_dev *dev) 26762306a36Sopenharmony_ci{ 26862306a36Sopenharmony_ci u32 cur; 26962306a36Sopenharmony_ci u32 con_infra_version; 27062306a36Sopenharmony_ci 27162306a36Sopenharmony_ci if (is_mt7981(&dev->mt76)) { 27262306a36Sopenharmony_ci con_infra_version = MT7981_CON_INFRA_VERSION; 27362306a36Sopenharmony_ci } else if (is_mt7986(&dev->mt76)) { 27462306a36Sopenharmony_ci con_infra_version = MT7986_CON_INFRA_VERSION; 27562306a36Sopenharmony_ci } else { 27662306a36Sopenharmony_ci WARN_ON(1); 27762306a36Sopenharmony_ci return -EINVAL; 27862306a36Sopenharmony_ci } 27962306a36Sopenharmony_ci 28062306a36Sopenharmony_ci return read_poll_timeout(mt76_rr, cur, (cur == con_infra_version), 28162306a36Sopenharmony_ci USEC_PER_MSEC, 50 * USEC_PER_MSEC, 28262306a36Sopenharmony_ci false, dev, MT_CONN_INFRA_BASE); 28362306a36Sopenharmony_ci} 28462306a36Sopenharmony_ci 28562306a36Sopenharmony_cistatic int mt798x_wmac_coninfra_setup(struct mt7915_dev *dev) 28662306a36Sopenharmony_ci{ 28762306a36Sopenharmony_ci struct device *pdev = dev->mt76.dev; 28862306a36Sopenharmony_ci struct reserved_mem *rmem; 28962306a36Sopenharmony_ci struct device_node *np; 29062306a36Sopenharmony_ci u32 val; 29162306a36Sopenharmony_ci 29262306a36Sopenharmony_ci np = of_parse_phandle(pdev->of_node, "memory-region", 0); 29362306a36Sopenharmony_ci if (!np) 29462306a36Sopenharmony_ci return -EINVAL; 29562306a36Sopenharmony_ci 29662306a36Sopenharmony_ci rmem = of_reserved_mem_lookup(np); 29762306a36Sopenharmony_ci of_node_put(np); 29862306a36Sopenharmony_ci if (!rmem) 29962306a36Sopenharmony_ci return -EINVAL; 30062306a36Sopenharmony_ci 30162306a36Sopenharmony_ci val = (rmem->base >> 16) & MT_TOP_MCU_EMI_BASE_MASK; 30262306a36Sopenharmony_ci 30362306a36Sopenharmony_ci if (is_mt7986(&dev->mt76)) { 30462306a36Sopenharmony_ci /* Set conninfra subsys PLL check */ 30562306a36Sopenharmony_ci mt76_rmw_field(dev, MT_INFRA_CKGEN_BUS, 30662306a36Sopenharmony_ci MT_INFRA_CKGEN_BUS_RDY_SEL_MASK, 0x1); 30762306a36Sopenharmony_ci mt76_rmw_field(dev, MT_INFRA_CKGEN_BUS, 30862306a36Sopenharmony_ci MT_INFRA_CKGEN_BUS_RDY_SEL_MASK, 0x1); 30962306a36Sopenharmony_ci } 31062306a36Sopenharmony_ci 31162306a36Sopenharmony_ci mt76_rmw_field(dev, MT_TOP_MCU_EMI_BASE, 31262306a36Sopenharmony_ci MT_TOP_MCU_EMI_BASE_MASK, val); 31362306a36Sopenharmony_ci 31462306a36Sopenharmony_ci if (is_mt7981(&dev->mt76)) { 31562306a36Sopenharmony_ci mt76_rmw_field(dev, MT_TOP_WF_AP_PERI_BASE, 31662306a36Sopenharmony_ci MT_TOP_WF_AP_PERI_BASE_MASK, 0x300d0000 >> 16); 31762306a36Sopenharmony_ci 31862306a36Sopenharmony_ci mt76_rmw_field(dev, MT_TOP_EFUSE_BASE, 31962306a36Sopenharmony_ci MT_TOP_EFUSE_BASE_MASK, 0x11f20000 >> 16); 32062306a36Sopenharmony_ci } 32162306a36Sopenharmony_ci 32262306a36Sopenharmony_ci mt76_wr(dev, MT_INFRA_BUS_EMI_START, rmem->base); 32362306a36Sopenharmony_ci mt76_wr(dev, MT_INFRA_BUS_EMI_END, rmem->size); 32462306a36Sopenharmony_ci 32562306a36Sopenharmony_ci mt76_rr(dev, MT_CONN_INFRA_EFUSE); 32662306a36Sopenharmony_ci 32762306a36Sopenharmony_ci /* Set conninfra sysram */ 32862306a36Sopenharmony_ci mt76_wr(dev, MT_TOP_RGU_SYSRAM_PDN, 0); 32962306a36Sopenharmony_ci mt76_wr(dev, MT_TOP_RGU_SYSRAM_SLP, 1); 33062306a36Sopenharmony_ci 33162306a36Sopenharmony_ci return 0; 33262306a36Sopenharmony_ci} 33362306a36Sopenharmony_ci 33462306a36Sopenharmony_cistatic int mt798x_wmac_sku_setup(struct mt7915_dev *dev, u32 *adie_type) 33562306a36Sopenharmony_ci{ 33662306a36Sopenharmony_ci int ret; 33762306a36Sopenharmony_ci u32 adie_main = 0, adie_ext = 0; 33862306a36Sopenharmony_ci 33962306a36Sopenharmony_ci mt76_rmw_field(dev, MT_CONN_INFRA_ADIE_RESET, 34062306a36Sopenharmony_ci MT_CONN_INFRA_ADIE1_RESET_MASK, 0x1); 34162306a36Sopenharmony_ci 34262306a36Sopenharmony_ci if (is_mt7986(&dev->mt76)) { 34362306a36Sopenharmony_ci mt76_rmw_field(dev, MT_CONN_INFRA_ADIE_RESET, 34462306a36Sopenharmony_ci MT_CONN_INFRA_ADIE2_RESET_MASK, 0x1); 34562306a36Sopenharmony_ci } 34662306a36Sopenharmony_ci 34762306a36Sopenharmony_ci mt76_wmac_spi_lock(dev); 34862306a36Sopenharmony_ci 34962306a36Sopenharmony_ci ret = mt76_wmac_spi_read(dev, 0, MT_ADIE_CHIP_ID, &adie_main); 35062306a36Sopenharmony_ci if (ret) 35162306a36Sopenharmony_ci goto out; 35262306a36Sopenharmony_ci 35362306a36Sopenharmony_ci if (is_mt7986(&dev->mt76)) { 35462306a36Sopenharmony_ci ret = mt76_wmac_spi_read(dev, 1, MT_ADIE_CHIP_ID, &adie_ext); 35562306a36Sopenharmony_ci if (ret) 35662306a36Sopenharmony_ci goto out; 35762306a36Sopenharmony_ci } 35862306a36Sopenharmony_ci 35962306a36Sopenharmony_ci *adie_type = FIELD_GET(MT_ADIE_CHIP_ID_MASK, adie_main) | 36062306a36Sopenharmony_ci (MT_ADIE_CHIP_ID_MASK & adie_ext); 36162306a36Sopenharmony_ci 36262306a36Sopenharmony_ciout: 36362306a36Sopenharmony_ci mt76_wmac_spi_unlock(dev); 36462306a36Sopenharmony_ci 36562306a36Sopenharmony_ci return 0; 36662306a36Sopenharmony_ci} 36762306a36Sopenharmony_ci 36862306a36Sopenharmony_cistatic inline u16 mt7986_adie_idx(u8 adie, u32 adie_type) 36962306a36Sopenharmony_ci{ 37062306a36Sopenharmony_ci if (adie == 0) 37162306a36Sopenharmony_ci return u32_get_bits(adie_type, MT_ADIE_IDX0); 37262306a36Sopenharmony_ci else 37362306a36Sopenharmony_ci return u32_get_bits(adie_type, MT_ADIE_IDX1); 37462306a36Sopenharmony_ci} 37562306a36Sopenharmony_ci 37662306a36Sopenharmony_cistatic inline bool is_7975(struct mt7915_dev *dev, u8 adie, u32 adie_type) 37762306a36Sopenharmony_ci{ 37862306a36Sopenharmony_ci return mt7986_adie_idx(adie, adie_type) == 0x7975; 37962306a36Sopenharmony_ci} 38062306a36Sopenharmony_ci 38162306a36Sopenharmony_cistatic inline bool is_7976(struct mt7915_dev *dev, u8 adie, u32 adie_type) 38262306a36Sopenharmony_ci{ 38362306a36Sopenharmony_ci return mt7986_adie_idx(adie, adie_type) == 0x7976; 38462306a36Sopenharmony_ci} 38562306a36Sopenharmony_ci 38662306a36Sopenharmony_cistatic int mt7986_wmac_adie_thermal_cal(struct mt7915_dev *dev, u8 adie) 38762306a36Sopenharmony_ci{ 38862306a36Sopenharmony_ci int ret; 38962306a36Sopenharmony_ci u32 data, val; 39062306a36Sopenharmony_ci 39162306a36Sopenharmony_ci ret = mt7986_wmac_adie_efuse_read(dev, adie, MT_ADIE_THADC_ANALOG, 39262306a36Sopenharmony_ci &data); 39362306a36Sopenharmony_ci if (ret || FIELD_GET(MT_ADIE_ANA_EN_MASK, data)) { 39462306a36Sopenharmony_ci val = FIELD_GET(MT_ADIE_VRPI_SEL_EFUSE_MASK, data); 39562306a36Sopenharmony_ci ret = mt76_wmac_spi_rmw(dev, adie, MT_ADIE_RG_TOP_THADC_BG, 39662306a36Sopenharmony_ci MT_ADIE_VRPI_SEL_CR_MASK, 39762306a36Sopenharmony_ci FIELD_PREP(MT_ADIE_VRPI_SEL_CR_MASK, val)); 39862306a36Sopenharmony_ci if (ret) 39962306a36Sopenharmony_ci return ret; 40062306a36Sopenharmony_ci 40162306a36Sopenharmony_ci val = FIELD_GET(MT_ADIE_PGA_GAIN_EFUSE_MASK, data); 40262306a36Sopenharmony_ci ret = mt76_wmac_spi_rmw(dev, adie, MT_ADIE_RG_TOP_THADC, 40362306a36Sopenharmony_ci MT_ADIE_PGA_GAIN_MASK, 40462306a36Sopenharmony_ci FIELD_PREP(MT_ADIE_PGA_GAIN_MASK, val)); 40562306a36Sopenharmony_ci if (ret) 40662306a36Sopenharmony_ci return ret; 40762306a36Sopenharmony_ci } 40862306a36Sopenharmony_ci 40962306a36Sopenharmony_ci ret = mt7986_wmac_adie_efuse_read(dev, adie, MT_ADIE_THADC_SLOP, 41062306a36Sopenharmony_ci &data); 41162306a36Sopenharmony_ci if (ret || FIELD_GET(MT_ADIE_ANA_EN_MASK, data)) { 41262306a36Sopenharmony_ci val = FIELD_GET(MT_ADIE_LDO_CTRL_EFUSE_MASK, data); 41362306a36Sopenharmony_ci 41462306a36Sopenharmony_ci return mt76_wmac_spi_rmw(dev, adie, MT_ADIE_RG_TOP_THADC, 41562306a36Sopenharmony_ci MT_ADIE_LDO_CTRL_MASK, 41662306a36Sopenharmony_ci FIELD_PREP(MT_ADIE_LDO_CTRL_MASK, val)); 41762306a36Sopenharmony_ci } 41862306a36Sopenharmony_ci 41962306a36Sopenharmony_ci return 0; 42062306a36Sopenharmony_ci} 42162306a36Sopenharmony_ci 42262306a36Sopenharmony_cistatic int 42362306a36Sopenharmony_cimt7986_read_efuse_xo_trim_7976(struct mt7915_dev *dev, u8 adie, 42462306a36Sopenharmony_ci bool is_40m, int *result) 42562306a36Sopenharmony_ci{ 42662306a36Sopenharmony_ci int ret; 42762306a36Sopenharmony_ci u32 data, addr; 42862306a36Sopenharmony_ci 42962306a36Sopenharmony_ci addr = is_40m ? MT_ADIE_XTAL_AXM_40M_OSC : MT_ADIE_XTAL_AXM_80M_OSC; 43062306a36Sopenharmony_ci ret = mt7986_wmac_adie_efuse_read(dev, adie, addr, &data); 43162306a36Sopenharmony_ci if (ret) 43262306a36Sopenharmony_ci return ret; 43362306a36Sopenharmony_ci 43462306a36Sopenharmony_ci if (!FIELD_GET(MT_ADIE_XO_TRIM_EN_MASK, data)) { 43562306a36Sopenharmony_ci *result = 64; 43662306a36Sopenharmony_ci } else { 43762306a36Sopenharmony_ci *result = FIELD_GET(MT_ADIE_TRIM_MASK, data); 43862306a36Sopenharmony_ci addr = is_40m ? MT_ADIE_XTAL_TRIM1_40M_OSC : 43962306a36Sopenharmony_ci MT_ADIE_XTAL_TRIM1_80M_OSC; 44062306a36Sopenharmony_ci ret = mt7986_wmac_adie_efuse_read(dev, adie, addr, &data); 44162306a36Sopenharmony_ci if (ret) 44262306a36Sopenharmony_ci return ret; 44362306a36Sopenharmony_ci 44462306a36Sopenharmony_ci if (FIELD_GET(MT_ADIE_XO_TRIM_EN_MASK, data) && 44562306a36Sopenharmony_ci FIELD_GET(MT_ADIE_XTAL_DECREASE_MASK, data)) 44662306a36Sopenharmony_ci *result -= FIELD_GET(MT_ADIE_EFUSE_TRIM_MASK, data); 44762306a36Sopenharmony_ci else if (FIELD_GET(MT_ADIE_XO_TRIM_EN_MASK, data)) 44862306a36Sopenharmony_ci *result += FIELD_GET(MT_ADIE_EFUSE_TRIM_MASK, data); 44962306a36Sopenharmony_ci 45062306a36Sopenharmony_ci *result = max(0, min(127, *result)); 45162306a36Sopenharmony_ci } 45262306a36Sopenharmony_ci 45362306a36Sopenharmony_ci return 0; 45462306a36Sopenharmony_ci} 45562306a36Sopenharmony_ci 45662306a36Sopenharmony_cistatic int mt7986_wmac_adie_xtal_trim_7976(struct mt7915_dev *dev, u8 adie) 45762306a36Sopenharmony_ci{ 45862306a36Sopenharmony_ci int ret, trim_80m, trim_40m; 45962306a36Sopenharmony_ci u32 data, val, mode; 46062306a36Sopenharmony_ci 46162306a36Sopenharmony_ci ret = mt7986_wmac_adie_efuse_read(dev, adie, MT_ADIE_XO_TRIM_FLOW, 46262306a36Sopenharmony_ci &data); 46362306a36Sopenharmony_ci if (ret || !FIELD_GET(BIT(1), data)) 46462306a36Sopenharmony_ci return 0; 46562306a36Sopenharmony_ci 46662306a36Sopenharmony_ci ret = mt7986_read_efuse_xo_trim_7976(dev, adie, false, &trim_80m); 46762306a36Sopenharmony_ci if (ret) 46862306a36Sopenharmony_ci return ret; 46962306a36Sopenharmony_ci 47062306a36Sopenharmony_ci ret = mt7986_read_efuse_xo_trim_7976(dev, adie, true, &trim_40m); 47162306a36Sopenharmony_ci if (ret) 47262306a36Sopenharmony_ci return ret; 47362306a36Sopenharmony_ci 47462306a36Sopenharmony_ci ret = mt76_wmac_spi_read(dev, adie, MT_ADIE_RG_STRAP_PIN_IN, &val); 47562306a36Sopenharmony_ci if (ret) 47662306a36Sopenharmony_ci return ret; 47762306a36Sopenharmony_ci 47862306a36Sopenharmony_ci mode = FIELD_PREP(GENMASK(6, 4), val); 47962306a36Sopenharmony_ci if (!mode || mode == 0x2) { 48062306a36Sopenharmony_ci ret = mt76_wmac_spi_rmw(dev, adie, MT_ADIE_XTAL_C1, 48162306a36Sopenharmony_ci GENMASK(31, 24), 48262306a36Sopenharmony_ci FIELD_PREP(GENMASK(31, 24), trim_80m)); 48362306a36Sopenharmony_ci if (ret) 48462306a36Sopenharmony_ci return ret; 48562306a36Sopenharmony_ci 48662306a36Sopenharmony_ci ret = mt76_wmac_spi_rmw(dev, adie, MT_ADIE_XTAL_C2, 48762306a36Sopenharmony_ci GENMASK(31, 24), 48862306a36Sopenharmony_ci FIELD_PREP(GENMASK(31, 24), trim_80m)); 48962306a36Sopenharmony_ci } else if (mode == 0x3 || mode == 0x4 || mode == 0x6) { 49062306a36Sopenharmony_ci ret = mt76_wmac_spi_rmw(dev, adie, MT_ADIE_XTAL_C1, 49162306a36Sopenharmony_ci GENMASK(23, 16), 49262306a36Sopenharmony_ci FIELD_PREP(GENMASK(23, 16), trim_40m)); 49362306a36Sopenharmony_ci if (ret) 49462306a36Sopenharmony_ci return ret; 49562306a36Sopenharmony_ci 49662306a36Sopenharmony_ci ret = mt76_wmac_spi_rmw(dev, adie, MT_ADIE_XTAL_C2, 49762306a36Sopenharmony_ci GENMASK(23, 16), 49862306a36Sopenharmony_ci FIELD_PREP(GENMASK(23, 16), trim_40m)); 49962306a36Sopenharmony_ci } 50062306a36Sopenharmony_ci 50162306a36Sopenharmony_ci return ret; 50262306a36Sopenharmony_ci} 50362306a36Sopenharmony_ci 50462306a36Sopenharmony_cistatic int mt798x_wmac_adie_patch_7976(struct mt7915_dev *dev, u8 adie) 50562306a36Sopenharmony_ci{ 50662306a36Sopenharmony_ci u32 id, version, rg_xo_01, rg_xo_03; 50762306a36Sopenharmony_ci int ret; 50862306a36Sopenharmony_ci 50962306a36Sopenharmony_ci ret = mt76_wmac_spi_read(dev, adie, MT_ADIE_CHIP_ID, &id); 51062306a36Sopenharmony_ci if (ret) 51162306a36Sopenharmony_ci return ret; 51262306a36Sopenharmony_ci 51362306a36Sopenharmony_ci version = FIELD_GET(MT_ADIE_VERSION_MASK, id); 51462306a36Sopenharmony_ci 51562306a36Sopenharmony_ci ret = mt76_wmac_spi_write(dev, adie, MT_ADIE_RG_TOP_THADC, 0x4a563b00); 51662306a36Sopenharmony_ci if (ret) 51762306a36Sopenharmony_ci return ret; 51862306a36Sopenharmony_ci 51962306a36Sopenharmony_ci if (version == 0x8a00 || version == 0x8a10 || version == 0x8b00) { 52062306a36Sopenharmony_ci rg_xo_01 = 0x1d59080f; 52162306a36Sopenharmony_ci rg_xo_03 = 0x34c00fe0; 52262306a36Sopenharmony_ci } else { 52362306a36Sopenharmony_ci if (is_mt7981(&dev->mt76)) { 52462306a36Sopenharmony_ci rg_xo_01 = 0x1959c80f; 52562306a36Sopenharmony_ci } else if (is_mt7986(&dev->mt76)) { 52662306a36Sopenharmony_ci rg_xo_01 = 0x1959f80f; 52762306a36Sopenharmony_ci } else { 52862306a36Sopenharmony_ci WARN_ON(1); 52962306a36Sopenharmony_ci return -EINVAL; 53062306a36Sopenharmony_ci } 53162306a36Sopenharmony_ci rg_xo_03 = 0x34d00fe0; 53262306a36Sopenharmony_ci } 53362306a36Sopenharmony_ci 53462306a36Sopenharmony_ci ret = mt76_wmac_spi_write(dev, adie, MT_ADIE_RG_XO_01, rg_xo_01); 53562306a36Sopenharmony_ci if (ret) 53662306a36Sopenharmony_ci return ret; 53762306a36Sopenharmony_ci 53862306a36Sopenharmony_ci return mt76_wmac_spi_write(dev, adie, MT_ADIE_RG_XO_03, rg_xo_03); 53962306a36Sopenharmony_ci} 54062306a36Sopenharmony_ci 54162306a36Sopenharmony_cistatic int 54262306a36Sopenharmony_cimt7986_read_efuse_xo_trim_7975(struct mt7915_dev *dev, u8 adie, 54362306a36Sopenharmony_ci u32 addr, u32 *result) 54462306a36Sopenharmony_ci{ 54562306a36Sopenharmony_ci int ret; 54662306a36Sopenharmony_ci u32 data; 54762306a36Sopenharmony_ci 54862306a36Sopenharmony_ci ret = mt7986_wmac_adie_efuse_read(dev, adie, addr, &data); 54962306a36Sopenharmony_ci if (ret) 55062306a36Sopenharmony_ci return ret; 55162306a36Sopenharmony_ci 55262306a36Sopenharmony_ci if ((data & MT_ADIE_XO_TRIM_EN_MASK)) { 55362306a36Sopenharmony_ci if ((data & MT_ADIE_XTAL_DECREASE_MASK)) 55462306a36Sopenharmony_ci *result -= (data & MT_ADIE_EFUSE_TRIM_MASK); 55562306a36Sopenharmony_ci else 55662306a36Sopenharmony_ci *result += (data & MT_ADIE_EFUSE_TRIM_MASK); 55762306a36Sopenharmony_ci 55862306a36Sopenharmony_ci *result = (*result & MT_ADIE_TRIM_MASK); 55962306a36Sopenharmony_ci } 56062306a36Sopenharmony_ci 56162306a36Sopenharmony_ci return 0; 56262306a36Sopenharmony_ci} 56362306a36Sopenharmony_ci 56462306a36Sopenharmony_cistatic int mt7986_wmac_adie_xtal_trim_7975(struct mt7915_dev *dev, u8 adie) 56562306a36Sopenharmony_ci{ 56662306a36Sopenharmony_ci int ret; 56762306a36Sopenharmony_ci u32 data, result = 0, value; 56862306a36Sopenharmony_ci 56962306a36Sopenharmony_ci ret = mt7986_wmac_adie_efuse_read(dev, adie, MT_ADIE_7975_XTAL_EN, 57062306a36Sopenharmony_ci &data); 57162306a36Sopenharmony_ci if (ret || !(data & BIT(1))) 57262306a36Sopenharmony_ci return 0; 57362306a36Sopenharmony_ci 57462306a36Sopenharmony_ci ret = mt7986_wmac_adie_efuse_read(dev, adie, MT_ADIE_7975_XTAL_CAL, 57562306a36Sopenharmony_ci &data); 57662306a36Sopenharmony_ci if (ret) 57762306a36Sopenharmony_ci return ret; 57862306a36Sopenharmony_ci 57962306a36Sopenharmony_ci if (data & MT_ADIE_XO_TRIM_EN_MASK) 58062306a36Sopenharmony_ci result = (data & MT_ADIE_TRIM_MASK); 58162306a36Sopenharmony_ci 58262306a36Sopenharmony_ci ret = mt7986_read_efuse_xo_trim_7975(dev, adie, MT_ADIE_7975_XO_TRIM2, 58362306a36Sopenharmony_ci &result); 58462306a36Sopenharmony_ci if (ret) 58562306a36Sopenharmony_ci return ret; 58662306a36Sopenharmony_ci 58762306a36Sopenharmony_ci ret = mt7986_read_efuse_xo_trim_7975(dev, adie, MT_ADIE_7975_XO_TRIM3, 58862306a36Sopenharmony_ci &result); 58962306a36Sopenharmony_ci if (ret) 59062306a36Sopenharmony_ci return ret; 59162306a36Sopenharmony_ci 59262306a36Sopenharmony_ci ret = mt7986_read_efuse_xo_trim_7975(dev, adie, MT_ADIE_7975_XO_TRIM4, 59362306a36Sopenharmony_ci &result); 59462306a36Sopenharmony_ci if (ret) 59562306a36Sopenharmony_ci return ret; 59662306a36Sopenharmony_ci 59762306a36Sopenharmony_ci /* Update trim value to C1 and C2*/ 59862306a36Sopenharmony_ci value = FIELD_GET(MT_ADIE_7975_XO_CTRL2_C1_MASK, result) | 59962306a36Sopenharmony_ci FIELD_GET(MT_ADIE_7975_XO_CTRL2_C2_MASK, result); 60062306a36Sopenharmony_ci ret = mt76_wmac_spi_rmw(dev, adie, MT_ADIE_7975_XO_CTRL2, 60162306a36Sopenharmony_ci MT_ADIE_7975_XO_CTRL2_MASK, value); 60262306a36Sopenharmony_ci if (ret) 60362306a36Sopenharmony_ci return ret; 60462306a36Sopenharmony_ci 60562306a36Sopenharmony_ci ret = mt76_wmac_spi_read(dev, adie, MT_ADIE_7975_XTAL, &value); 60662306a36Sopenharmony_ci if (ret) 60762306a36Sopenharmony_ci return ret; 60862306a36Sopenharmony_ci 60962306a36Sopenharmony_ci if (value & MT_ADIE_7975_XTAL_EN_MASK) { 61062306a36Sopenharmony_ci ret = mt76_wmac_spi_rmw(dev, adie, MT_ADIE_7975_XO_2, 61162306a36Sopenharmony_ci MT_ADIE_7975_XO_2_FIX_EN, 0x0); 61262306a36Sopenharmony_ci if (ret) 61362306a36Sopenharmony_ci return ret; 61462306a36Sopenharmony_ci } 61562306a36Sopenharmony_ci 61662306a36Sopenharmony_ci return mt76_wmac_spi_rmw(dev, adie, MT_ADIE_7975_XO_CTRL6, 61762306a36Sopenharmony_ci MT_ADIE_7975_XO_CTRL6_MASK, 0x1); 61862306a36Sopenharmony_ci} 61962306a36Sopenharmony_ci 62062306a36Sopenharmony_cistatic int mt7986_wmac_adie_patch_7975(struct mt7915_dev *dev, u8 adie) 62162306a36Sopenharmony_ci{ 62262306a36Sopenharmony_ci int ret; 62362306a36Sopenharmony_ci 62462306a36Sopenharmony_ci /* disable CAL LDO and fine tune RFDIG LDO */ 62562306a36Sopenharmony_ci ret = mt76_wmac_spi_write(dev, adie, 0x348, 0x00000002); 62662306a36Sopenharmony_ci if (ret) 62762306a36Sopenharmony_ci return ret; 62862306a36Sopenharmony_ci 62962306a36Sopenharmony_ci ret = mt76_wmac_spi_write(dev, adie, 0x378, 0x00000002); 63062306a36Sopenharmony_ci if (ret) 63162306a36Sopenharmony_ci return ret; 63262306a36Sopenharmony_ci 63362306a36Sopenharmony_ci ret = mt76_wmac_spi_write(dev, adie, 0x3a8, 0x00000002); 63462306a36Sopenharmony_ci if (ret) 63562306a36Sopenharmony_ci return ret; 63662306a36Sopenharmony_ci 63762306a36Sopenharmony_ci ret = mt76_wmac_spi_write(dev, adie, 0x3d8, 0x00000002); 63862306a36Sopenharmony_ci if (ret) 63962306a36Sopenharmony_ci return ret; 64062306a36Sopenharmony_ci 64162306a36Sopenharmony_ci /* set CKA driving and filter */ 64262306a36Sopenharmony_ci ret = mt76_wmac_spi_write(dev, adie, 0xa1c, 0x30000aaa); 64362306a36Sopenharmony_ci if (ret) 64462306a36Sopenharmony_ci return ret; 64562306a36Sopenharmony_ci 64662306a36Sopenharmony_ci /* set CKB LDO to 1.4V */ 64762306a36Sopenharmony_ci ret = mt76_wmac_spi_write(dev, adie, 0xa84, 0x8470008a); 64862306a36Sopenharmony_ci if (ret) 64962306a36Sopenharmony_ci return ret; 65062306a36Sopenharmony_ci 65162306a36Sopenharmony_ci /* turn on SX0 LTBUF */ 65262306a36Sopenharmony_ci if (is_mt7981(&dev->mt76)) { 65362306a36Sopenharmony_ci ret = mt76_wmac_spi_write(dev, adie, 0x074, 0x00000007); 65462306a36Sopenharmony_ci } else if (is_mt7986(&dev->mt76)) { 65562306a36Sopenharmony_ci ret = mt76_wmac_spi_write(dev, adie, 0x074, 0x00000002); 65662306a36Sopenharmony_ci } else { 65762306a36Sopenharmony_ci WARN_ON(1); 65862306a36Sopenharmony_ci return -EINVAL; 65962306a36Sopenharmony_ci } 66062306a36Sopenharmony_ci 66162306a36Sopenharmony_ci if (ret) 66262306a36Sopenharmony_ci return ret; 66362306a36Sopenharmony_ci 66462306a36Sopenharmony_ci /* CK_BUF_SW_EN = 1 (all buf in manual mode.) */ 66562306a36Sopenharmony_ci ret = mt76_wmac_spi_write(dev, adie, 0xaa4, 0x01001fc0); 66662306a36Sopenharmony_ci if (ret) 66762306a36Sopenharmony_ci return ret; 66862306a36Sopenharmony_ci 66962306a36Sopenharmony_ci /* BT mode/WF normal mode 00000005 */ 67062306a36Sopenharmony_ci ret = mt76_wmac_spi_write(dev, adie, 0x070, 0x00000005); 67162306a36Sopenharmony_ci if (ret) 67262306a36Sopenharmony_ci return ret; 67362306a36Sopenharmony_ci 67462306a36Sopenharmony_ci /* BG thermal sensor offset update */ 67562306a36Sopenharmony_ci ret = mt76_wmac_spi_write(dev, adie, 0x344, 0x00000088); 67662306a36Sopenharmony_ci if (ret) 67762306a36Sopenharmony_ci return ret; 67862306a36Sopenharmony_ci 67962306a36Sopenharmony_ci ret = mt76_wmac_spi_write(dev, adie, 0x374, 0x00000088); 68062306a36Sopenharmony_ci if (ret) 68162306a36Sopenharmony_ci return ret; 68262306a36Sopenharmony_ci 68362306a36Sopenharmony_ci ret = mt76_wmac_spi_write(dev, adie, 0x3a4, 0x00000088); 68462306a36Sopenharmony_ci if (ret) 68562306a36Sopenharmony_ci return ret; 68662306a36Sopenharmony_ci 68762306a36Sopenharmony_ci ret = mt76_wmac_spi_write(dev, adie, 0x3d4, 0x00000088); 68862306a36Sopenharmony_ci if (ret) 68962306a36Sopenharmony_ci return ret; 69062306a36Sopenharmony_ci 69162306a36Sopenharmony_ci /* set WCON VDD IPTAT to "0000" */ 69262306a36Sopenharmony_ci ret = mt76_wmac_spi_write(dev, adie, 0xa80, 0x44d07000); 69362306a36Sopenharmony_ci if (ret) 69462306a36Sopenharmony_ci return ret; 69562306a36Sopenharmony_ci 69662306a36Sopenharmony_ci /* change back LTBUF SX3 drving to default value */ 69762306a36Sopenharmony_ci ret = mt76_wmac_spi_write(dev, adie, 0xa88, 0x3900aaaa); 69862306a36Sopenharmony_ci if (ret) 69962306a36Sopenharmony_ci return ret; 70062306a36Sopenharmony_ci 70162306a36Sopenharmony_ci /* SM input cap off */ 70262306a36Sopenharmony_ci ret = mt76_wmac_spi_write(dev, adie, 0x2c4, 0x00000000); 70362306a36Sopenharmony_ci if (ret) 70462306a36Sopenharmony_ci return ret; 70562306a36Sopenharmony_ci 70662306a36Sopenharmony_ci /* set CKB driving and filter */ 70762306a36Sopenharmony_ci if (is_mt7986(&dev->mt76)) 70862306a36Sopenharmony_ci return mt76_wmac_spi_write(dev, adie, 0x2c8, 0x00000072); 70962306a36Sopenharmony_ci 71062306a36Sopenharmony_ci return ret; 71162306a36Sopenharmony_ci} 71262306a36Sopenharmony_ci 71362306a36Sopenharmony_cistatic int mt7986_wmac_adie_cfg(struct mt7915_dev *dev, u8 adie, u32 adie_type) 71462306a36Sopenharmony_ci{ 71562306a36Sopenharmony_ci int ret; 71662306a36Sopenharmony_ci 71762306a36Sopenharmony_ci mt76_wmac_spi_lock(dev); 71862306a36Sopenharmony_ci ret = mt76_wmac_spi_write(dev, adie, MT_ADIE_CLK_EN, ~0); 71962306a36Sopenharmony_ci if (ret) 72062306a36Sopenharmony_ci goto out; 72162306a36Sopenharmony_ci 72262306a36Sopenharmony_ci if (is_7975(dev, adie, adie_type)) { 72362306a36Sopenharmony_ci ret = mt76_wmac_spi_rmw(dev, adie, MT_ADIE_7975_COCLK, 72462306a36Sopenharmony_ci BIT(1), 0x1); 72562306a36Sopenharmony_ci if (ret) 72662306a36Sopenharmony_ci goto out; 72762306a36Sopenharmony_ci 72862306a36Sopenharmony_ci ret = mt7986_wmac_adie_thermal_cal(dev, adie); 72962306a36Sopenharmony_ci if (ret) 73062306a36Sopenharmony_ci goto out; 73162306a36Sopenharmony_ci 73262306a36Sopenharmony_ci ret = mt7986_wmac_adie_xtal_trim_7975(dev, adie); 73362306a36Sopenharmony_ci if (ret) 73462306a36Sopenharmony_ci goto out; 73562306a36Sopenharmony_ci 73662306a36Sopenharmony_ci ret = mt7986_wmac_adie_patch_7975(dev, adie); 73762306a36Sopenharmony_ci } else if (is_7976(dev, adie, adie_type)) { 73862306a36Sopenharmony_ci if (mt798x_wmac_check_adie_type(dev) == ADIE_DBDC) { 73962306a36Sopenharmony_ci ret = mt76_wmac_spi_write(dev, adie, 74062306a36Sopenharmony_ci MT_ADIE_WRI_CK_SEL, 0x1c); 74162306a36Sopenharmony_ci if (ret) 74262306a36Sopenharmony_ci goto out; 74362306a36Sopenharmony_ci } 74462306a36Sopenharmony_ci 74562306a36Sopenharmony_ci ret = mt7986_wmac_adie_thermal_cal(dev, adie); 74662306a36Sopenharmony_ci if (ret) 74762306a36Sopenharmony_ci goto out; 74862306a36Sopenharmony_ci 74962306a36Sopenharmony_ci ret = mt7986_wmac_adie_xtal_trim_7976(dev, adie); 75062306a36Sopenharmony_ci if (ret) 75162306a36Sopenharmony_ci goto out; 75262306a36Sopenharmony_ci 75362306a36Sopenharmony_ci ret = mt798x_wmac_adie_patch_7976(dev, adie); 75462306a36Sopenharmony_ci } 75562306a36Sopenharmony_ciout: 75662306a36Sopenharmony_ci mt76_wmac_spi_unlock(dev); 75762306a36Sopenharmony_ci 75862306a36Sopenharmony_ci return ret; 75962306a36Sopenharmony_ci} 76062306a36Sopenharmony_ci 76162306a36Sopenharmony_cistatic int 76262306a36Sopenharmony_cimt7986_wmac_afe_cal(struct mt7915_dev *dev, u8 adie, bool dbdc, u32 adie_type) 76362306a36Sopenharmony_ci{ 76462306a36Sopenharmony_ci int ret; 76562306a36Sopenharmony_ci u8 idx; 76662306a36Sopenharmony_ci u32 txcal; 76762306a36Sopenharmony_ci 76862306a36Sopenharmony_ci mt76_wmac_spi_lock(dev); 76962306a36Sopenharmony_ci if (is_7975(dev, adie, adie_type)) 77062306a36Sopenharmony_ci ret = mt76_wmac_spi_write(dev, adie, 77162306a36Sopenharmony_ci MT_AFE_RG_ENCAL_WBTAC_IF_SW, 77262306a36Sopenharmony_ci 0x80000000); 77362306a36Sopenharmony_ci else 77462306a36Sopenharmony_ci ret = mt76_wmac_spi_write(dev, adie, 77562306a36Sopenharmony_ci MT_AFE_RG_ENCAL_WBTAC_IF_SW, 77662306a36Sopenharmony_ci 0x88888005); 77762306a36Sopenharmony_ci if (ret) 77862306a36Sopenharmony_ci goto out; 77962306a36Sopenharmony_ci 78062306a36Sopenharmony_ci idx = dbdc ? ADIE_DBDC : adie; 78162306a36Sopenharmony_ci 78262306a36Sopenharmony_ci mt76_rmw_field(dev, MT_AFE_DIG_EN_01(idx), 78362306a36Sopenharmony_ci MT_AFE_RG_WBG_EN_RCK_MASK, 0x1); 78462306a36Sopenharmony_ci usleep_range(60, 100); 78562306a36Sopenharmony_ci 78662306a36Sopenharmony_ci mt76_rmw(dev, MT_AFE_DIG_EN_01(idx), 78762306a36Sopenharmony_ci MT_AFE_RG_WBG_EN_RCK_MASK, 0x0); 78862306a36Sopenharmony_ci 78962306a36Sopenharmony_ci mt76_rmw_field(dev, MT_AFE_DIG_EN_03(idx), 79062306a36Sopenharmony_ci MT_AFE_RG_WBG_EN_BPLL_UP_MASK, 0x1); 79162306a36Sopenharmony_ci usleep_range(30, 100); 79262306a36Sopenharmony_ci 79362306a36Sopenharmony_ci mt76_rmw_field(dev, MT_AFE_DIG_EN_03(idx), 79462306a36Sopenharmony_ci MT_AFE_RG_WBG_EN_WPLL_UP_MASK, 0x1); 79562306a36Sopenharmony_ci usleep_range(60, 100); 79662306a36Sopenharmony_ci 79762306a36Sopenharmony_ci txcal = (MT_AFE_RG_WBG_EN_TXCAL_BT | 79862306a36Sopenharmony_ci MT_AFE_RG_WBG_EN_TXCAL_WF0 | 79962306a36Sopenharmony_ci MT_AFE_RG_WBG_EN_TXCAL_WF1 | 80062306a36Sopenharmony_ci MT_AFE_RG_WBG_EN_TXCAL_WF2 | 80162306a36Sopenharmony_ci MT_AFE_RG_WBG_EN_TXCAL_WF3); 80262306a36Sopenharmony_ci if (is_mt7981(&dev->mt76)) 80362306a36Sopenharmony_ci txcal |= MT_AFE_RG_WBG_EN_TXCAL_WF4; 80462306a36Sopenharmony_ci 80562306a36Sopenharmony_ci mt76_set(dev, MT_AFE_DIG_EN_01(idx), txcal); 80662306a36Sopenharmony_ci usleep_range(800, 1000); 80762306a36Sopenharmony_ci 80862306a36Sopenharmony_ci mt76_clear(dev, MT_AFE_DIG_EN_01(idx), txcal); 80962306a36Sopenharmony_ci mt76_rmw(dev, MT_AFE_DIG_EN_03(idx), 81062306a36Sopenharmony_ci MT_AFE_RG_WBG_EN_PLL_UP_MASK, 0x0); 81162306a36Sopenharmony_ci 81262306a36Sopenharmony_ci ret = mt76_wmac_spi_write(dev, adie, MT_AFE_RG_ENCAL_WBTAC_IF_SW, 81362306a36Sopenharmony_ci 0x5); 81462306a36Sopenharmony_ci 81562306a36Sopenharmony_ciout: 81662306a36Sopenharmony_ci mt76_wmac_spi_unlock(dev); 81762306a36Sopenharmony_ci 81862306a36Sopenharmony_ci return ret; 81962306a36Sopenharmony_ci} 82062306a36Sopenharmony_ci 82162306a36Sopenharmony_cistatic void mt7986_wmac_subsys_pll_initial(struct mt7915_dev *dev, u8 band) 82262306a36Sopenharmony_ci{ 82362306a36Sopenharmony_ci mt76_rmw(dev, MT_AFE_PLL_STB_TIME(band), 82462306a36Sopenharmony_ci MT_AFE_PLL_STB_TIME_MASK, MT_AFE_PLL_STB_TIME_VAL); 82562306a36Sopenharmony_ci 82662306a36Sopenharmony_ci mt76_rmw(dev, MT_AFE_DIG_EN_02(band), 82762306a36Sopenharmony_ci MT_AFE_PLL_CFG_MASK, MT_AFE_PLL_CFG_VAL); 82862306a36Sopenharmony_ci 82962306a36Sopenharmony_ci mt76_rmw(dev, MT_AFE_DIG_TOP_01(band), 83062306a36Sopenharmony_ci MT_AFE_DIG_TOP_01_MASK, MT_AFE_DIG_TOP_01_VAL); 83162306a36Sopenharmony_ci} 83262306a36Sopenharmony_ci 83362306a36Sopenharmony_cistatic void mt7986_wmac_subsys_setting(struct mt7915_dev *dev) 83462306a36Sopenharmony_ci{ 83562306a36Sopenharmony_ci /* Subsys pll init */ 83662306a36Sopenharmony_ci mt7986_wmac_subsys_pll_initial(dev, 0); 83762306a36Sopenharmony_ci mt7986_wmac_subsys_pll_initial(dev, 1); 83862306a36Sopenharmony_ci 83962306a36Sopenharmony_ci /* Set legacy OSC control stable time*/ 84062306a36Sopenharmony_ci mt76_rmw(dev, MT_CONN_INFRA_OSC_RC_EN, 84162306a36Sopenharmony_ci MT_CONN_INFRA_OSC_RC_EN_MASK, 0x0); 84262306a36Sopenharmony_ci mt76_rmw(dev, MT_CONN_INFRA_OSC_CTRL, 84362306a36Sopenharmony_ci MT_CONN_INFRA_OSC_STB_TIME_MASK, 0x80706); 84462306a36Sopenharmony_ci 84562306a36Sopenharmony_ci /* prevent subsys from power on/of in a short time interval */ 84662306a36Sopenharmony_ci mt76_rmw(dev, MT_TOP_WFSYS_PWR, 84762306a36Sopenharmony_ci MT_TOP_PWR_ACK_MASK | MT_TOP_PWR_KEY_MASK, 84862306a36Sopenharmony_ci MT_TOP_PWR_KEY); 84962306a36Sopenharmony_ci} 85062306a36Sopenharmony_ci 85162306a36Sopenharmony_cistatic int mt7986_wmac_bus_timeout(struct mt7915_dev *dev) 85262306a36Sopenharmony_ci{ 85362306a36Sopenharmony_ci mt76_rmw_field(dev, MT_INFRA_BUS_OFF_TIMEOUT, 85462306a36Sopenharmony_ci MT_INFRA_BUS_TIMEOUT_LIMIT_MASK, 0x2); 85562306a36Sopenharmony_ci 85662306a36Sopenharmony_ci mt76_rmw_field(dev, MT_INFRA_BUS_OFF_TIMEOUT, 85762306a36Sopenharmony_ci MT_INFRA_BUS_TIMEOUT_EN_MASK, 0xf); 85862306a36Sopenharmony_ci 85962306a36Sopenharmony_ci mt76_rmw_field(dev, MT_INFRA_BUS_ON_TIMEOUT, 86062306a36Sopenharmony_ci MT_INFRA_BUS_TIMEOUT_LIMIT_MASK, 0xc); 86162306a36Sopenharmony_ci 86262306a36Sopenharmony_ci mt76_rmw_field(dev, MT_INFRA_BUS_ON_TIMEOUT, 86362306a36Sopenharmony_ci MT_INFRA_BUS_TIMEOUT_EN_MASK, 0xf); 86462306a36Sopenharmony_ci 86562306a36Sopenharmony_ci return mt798x_wmac_coninfra_check(dev); 86662306a36Sopenharmony_ci} 86762306a36Sopenharmony_ci 86862306a36Sopenharmony_cistatic void mt7986_wmac_clock_enable(struct mt7915_dev *dev, u32 adie_type) 86962306a36Sopenharmony_ci{ 87062306a36Sopenharmony_ci u32 cur; 87162306a36Sopenharmony_ci 87262306a36Sopenharmony_ci mt76_rmw_field(dev, MT_INFRA_CKGEN_BUS_WPLL_DIV_1, 87362306a36Sopenharmony_ci MT_INFRA_CKGEN_DIV_SEL_MASK, 0x1); 87462306a36Sopenharmony_ci 87562306a36Sopenharmony_ci mt76_rmw_field(dev, MT_INFRA_CKGEN_BUS_WPLL_DIV_2, 87662306a36Sopenharmony_ci MT_INFRA_CKGEN_DIV_SEL_MASK, 0x1); 87762306a36Sopenharmony_ci 87862306a36Sopenharmony_ci mt76_rmw_field(dev, MT_INFRA_CKGEN_BUS_WPLL_DIV_1, 87962306a36Sopenharmony_ci MT_INFRA_CKGEN_DIV_EN_MASK, 0x1); 88062306a36Sopenharmony_ci 88162306a36Sopenharmony_ci mt76_rmw_field(dev, MT_INFRA_CKGEN_BUS_WPLL_DIV_2, 88262306a36Sopenharmony_ci MT_INFRA_CKGEN_DIV_EN_MASK, 0x1); 88362306a36Sopenharmony_ci 88462306a36Sopenharmony_ci mt76_rmw_field(dev, MT_INFRA_CKGEN_RFSPI_WPLL_DIV, 88562306a36Sopenharmony_ci MT_INFRA_CKGEN_DIV_SEL_MASK, 0x8); 88662306a36Sopenharmony_ci 88762306a36Sopenharmony_ci mt76_rmw_field(dev, MT_INFRA_CKGEN_RFSPI_WPLL_DIV, 88862306a36Sopenharmony_ci MT_INFRA_CKGEN_DIV_EN_MASK, 0x1); 88962306a36Sopenharmony_ci 89062306a36Sopenharmony_ci mt76_rmw_field(dev, MT_INFRA_CKGEN_BUS, 89162306a36Sopenharmony_ci MT_INFRA_CKGEN_BUS_CLK_SEL_MASK, 0x0); 89262306a36Sopenharmony_ci 89362306a36Sopenharmony_ci mt76_rmw_field(dev, MT_CONN_INFRA_HW_CTRL, 89462306a36Sopenharmony_ci MT_CONN_INFRA_HW_CTRL_MASK, 0x1); 89562306a36Sopenharmony_ci 89662306a36Sopenharmony_ci mt76_rmw(dev, MT_TOP_CONN_INFRA_WAKEUP, 89762306a36Sopenharmony_ci MT_TOP_CONN_INFRA_WAKEUP_MASK, 0x1); 89862306a36Sopenharmony_ci 89962306a36Sopenharmony_ci usleep_range(900, 1000); 90062306a36Sopenharmony_ci 90162306a36Sopenharmony_ci mt76_wmac_spi_lock(dev); 90262306a36Sopenharmony_ci if (is_7975(dev, 0, adie_type) || is_7976(dev, 0, adie_type)) { 90362306a36Sopenharmony_ci mt76_rmw_field(dev, MT_ADIE_SLP_CTRL_CK0(0), 90462306a36Sopenharmony_ci MT_SLP_CTRL_EN_MASK, 0x1); 90562306a36Sopenharmony_ci 90662306a36Sopenharmony_ci read_poll_timeout(mt76_rr, cur, !(cur & MT_SLP_CTRL_BSY_MASK), 90762306a36Sopenharmony_ci USEC_PER_MSEC, 50 * USEC_PER_MSEC, false, 90862306a36Sopenharmony_ci dev, MT_ADIE_SLP_CTRL_CK0(0)); 90962306a36Sopenharmony_ci } 91062306a36Sopenharmony_ci if (is_7975(dev, 1, adie_type) || is_7976(dev, 1, adie_type)) { 91162306a36Sopenharmony_ci mt76_rmw_field(dev, MT_ADIE_SLP_CTRL_CK0(1), 91262306a36Sopenharmony_ci MT_SLP_CTRL_EN_MASK, 0x1); 91362306a36Sopenharmony_ci 91462306a36Sopenharmony_ci read_poll_timeout(mt76_rr, cur, !(cur & MT_SLP_CTRL_BSY_MASK), 91562306a36Sopenharmony_ci USEC_PER_MSEC, 50 * USEC_PER_MSEC, false, 91662306a36Sopenharmony_ci dev, MT_ADIE_SLP_CTRL_CK0(0)); 91762306a36Sopenharmony_ci } 91862306a36Sopenharmony_ci mt76_wmac_spi_unlock(dev); 91962306a36Sopenharmony_ci 92062306a36Sopenharmony_ci mt76_rmw(dev, MT_TOP_CONN_INFRA_WAKEUP, 92162306a36Sopenharmony_ci MT_TOP_CONN_INFRA_WAKEUP_MASK, 0x0); 92262306a36Sopenharmony_ci usleep_range(900, 1000); 92362306a36Sopenharmony_ci} 92462306a36Sopenharmony_ci 92562306a36Sopenharmony_cistatic int mt7986_wmac_top_wfsys_wakeup(struct mt7915_dev *dev, bool enable) 92662306a36Sopenharmony_ci{ 92762306a36Sopenharmony_ci mt76_rmw_field(dev, MT_TOP_WFSYS_WAKEUP, 92862306a36Sopenharmony_ci MT_TOP_WFSYS_WAKEUP_MASK, enable); 92962306a36Sopenharmony_ci 93062306a36Sopenharmony_ci usleep_range(900, 1000); 93162306a36Sopenharmony_ci 93262306a36Sopenharmony_ci if (!enable) 93362306a36Sopenharmony_ci return 0; 93462306a36Sopenharmony_ci 93562306a36Sopenharmony_ci return mt798x_wmac_coninfra_check(dev); 93662306a36Sopenharmony_ci} 93762306a36Sopenharmony_ci 93862306a36Sopenharmony_cistatic int mt7986_wmac_wm_enable(struct mt7915_dev *dev, bool enable) 93962306a36Sopenharmony_ci{ 94062306a36Sopenharmony_ci u32 cur; 94162306a36Sopenharmony_ci 94262306a36Sopenharmony_ci if (is_mt7986(&dev->mt76)) 94362306a36Sopenharmony_ci mt76_wr(dev, MT_CONNINFRA_SKU_DEC_ADDR, 0); 94462306a36Sopenharmony_ci 94562306a36Sopenharmony_ci mt76_rmw_field(dev, MT7986_TOP_WM_RESET, 94662306a36Sopenharmony_ci MT7986_TOP_WM_RESET_MASK, enable); 94762306a36Sopenharmony_ci if (!enable) 94862306a36Sopenharmony_ci return 0; 94962306a36Sopenharmony_ci 95062306a36Sopenharmony_ci return read_poll_timeout(mt76_rr, cur, (cur == 0x1d1e), 95162306a36Sopenharmony_ci USEC_PER_MSEC, 5000 * USEC_PER_MSEC, false, 95262306a36Sopenharmony_ci dev, MT_TOP_CFG_ON_ROM_IDX); 95362306a36Sopenharmony_ci} 95462306a36Sopenharmony_ci 95562306a36Sopenharmony_cistatic int mt7986_wmac_wfsys_poweron(struct mt7915_dev *dev, bool enable) 95662306a36Sopenharmony_ci{ 95762306a36Sopenharmony_ci u32 mask = MT_TOP_PWR_EN_MASK | MT_TOP_PWR_KEY_MASK; 95862306a36Sopenharmony_ci u32 cur; 95962306a36Sopenharmony_ci 96062306a36Sopenharmony_ci mt76_rmw(dev, MT_TOP_WFSYS_PWR, mask, 96162306a36Sopenharmony_ci MT_TOP_PWR_KEY | FIELD_PREP(MT_TOP_PWR_EN_MASK, enable)); 96262306a36Sopenharmony_ci 96362306a36Sopenharmony_ci return read_poll_timeout(mt76_rr, cur, 96462306a36Sopenharmony_ci (FIELD_GET(MT_TOP_WFSYS_RESET_STATUS_MASK, cur) == enable), 96562306a36Sopenharmony_ci USEC_PER_MSEC, 50 * USEC_PER_MSEC, false, 96662306a36Sopenharmony_ci dev, MT_TOP_WFSYS_RESET_STATUS); 96762306a36Sopenharmony_ci} 96862306a36Sopenharmony_ci 96962306a36Sopenharmony_cistatic int mt7986_wmac_wfsys_setting(struct mt7915_dev *dev) 97062306a36Sopenharmony_ci{ 97162306a36Sopenharmony_ci int ret; 97262306a36Sopenharmony_ci u32 cur; 97362306a36Sopenharmony_ci 97462306a36Sopenharmony_ci /* Turn off wfsys2conn bus sleep protect */ 97562306a36Sopenharmony_ci mt76_rmw(dev, MT_CONN_INFRA_WF_SLP_PROT, 97662306a36Sopenharmony_ci MT_CONN_INFRA_WF_SLP_PROT_MASK, 0x0); 97762306a36Sopenharmony_ci 97862306a36Sopenharmony_ci ret = mt7986_wmac_wfsys_poweron(dev, true); 97962306a36Sopenharmony_ci if (ret) 98062306a36Sopenharmony_ci return ret; 98162306a36Sopenharmony_ci 98262306a36Sopenharmony_ci /* Check bus sleep protect */ 98362306a36Sopenharmony_ci 98462306a36Sopenharmony_ci ret = read_poll_timeout(mt76_rr, cur, 98562306a36Sopenharmony_ci !(cur & MT_CONN_INFRA_CONN_WF_MASK), 98662306a36Sopenharmony_ci USEC_PER_MSEC, 50 * USEC_PER_MSEC, false, 98762306a36Sopenharmony_ci dev, MT_CONN_INFRA_WF_SLP_PROT_RDY); 98862306a36Sopenharmony_ci if (ret) 98962306a36Sopenharmony_ci return ret; 99062306a36Sopenharmony_ci 99162306a36Sopenharmony_ci ret = read_poll_timeout(mt76_rr, cur, !(cur & MT_SLP_WFDMA2CONN_MASK), 99262306a36Sopenharmony_ci USEC_PER_MSEC, 50 * USEC_PER_MSEC, false, 99362306a36Sopenharmony_ci dev, MT_SLP_STATUS); 99462306a36Sopenharmony_ci if (ret) 99562306a36Sopenharmony_ci return ret; 99662306a36Sopenharmony_ci 99762306a36Sopenharmony_ci return read_poll_timeout(mt76_rr, cur, (cur == 0x02060000), 99862306a36Sopenharmony_ci USEC_PER_MSEC, 50 * USEC_PER_MSEC, false, 99962306a36Sopenharmony_ci dev, MT_TOP_CFG_IP_VERSION_ADDR); 100062306a36Sopenharmony_ci} 100162306a36Sopenharmony_ci 100262306a36Sopenharmony_cistatic void mt7986_wmac_wfsys_set_timeout(struct mt7915_dev *dev) 100362306a36Sopenharmony_ci{ 100462306a36Sopenharmony_ci u32 mask = MT_MCU_BUS_TIMEOUT_SET_MASK | 100562306a36Sopenharmony_ci MT_MCU_BUS_TIMEOUT_CG_EN_MASK | 100662306a36Sopenharmony_ci MT_MCU_BUS_TIMEOUT_EN_MASK; 100762306a36Sopenharmony_ci u32 val = FIELD_PREP(MT_MCU_BUS_TIMEOUT_SET_MASK, 1) | 100862306a36Sopenharmony_ci FIELD_PREP(MT_MCU_BUS_TIMEOUT_CG_EN_MASK, 1) | 100962306a36Sopenharmony_ci FIELD_PREP(MT_MCU_BUS_TIMEOUT_EN_MASK, 1); 101062306a36Sopenharmony_ci 101162306a36Sopenharmony_ci mt76_rmw(dev, MT_MCU_BUS_TIMEOUT, mask, val); 101262306a36Sopenharmony_ci 101362306a36Sopenharmony_ci mt76_wr(dev, MT_MCU_BUS_REMAP, 0x810f0000); 101462306a36Sopenharmony_ci 101562306a36Sopenharmony_ci mask = MT_MCU_BUS_DBG_TIMEOUT_SET_MASK | 101662306a36Sopenharmony_ci MT_MCU_BUS_DBG_TIMEOUT_CK_EN_MASK | 101762306a36Sopenharmony_ci MT_MCU_BUS_DBG_TIMEOUT_EN_MASK; 101862306a36Sopenharmony_ci val = FIELD_PREP(MT_MCU_BUS_DBG_TIMEOUT_SET_MASK, 0x3aa) | 101962306a36Sopenharmony_ci FIELD_PREP(MT_MCU_BUS_DBG_TIMEOUT_CK_EN_MASK, 1) | 102062306a36Sopenharmony_ci FIELD_PREP(MT_MCU_BUS_DBG_TIMEOUT_EN_MASK, 1); 102162306a36Sopenharmony_ci 102262306a36Sopenharmony_ci mt76_rmw(dev, MT_MCU_BUS_DBG_TIMEOUT, mask, val); 102362306a36Sopenharmony_ci} 102462306a36Sopenharmony_ci 102562306a36Sopenharmony_cistatic int mt7986_wmac_sku_update(struct mt7915_dev *dev, u32 adie_type) 102662306a36Sopenharmony_ci{ 102762306a36Sopenharmony_ci u32 val; 102862306a36Sopenharmony_ci 102962306a36Sopenharmony_ci if (is_7976(dev, 0, adie_type) && is_7976(dev, 1, adie_type)) 103062306a36Sopenharmony_ci val = 0xf; 103162306a36Sopenharmony_ci else if (is_7975(dev, 0, adie_type) && is_7975(dev, 1, adie_type)) 103262306a36Sopenharmony_ci val = 0xd; 103362306a36Sopenharmony_ci else if (is_7976(dev, 0, adie_type)) 103462306a36Sopenharmony_ci val = 0x7; 103562306a36Sopenharmony_ci else if (is_7975(dev, 1, adie_type)) 103662306a36Sopenharmony_ci val = 0x8; 103762306a36Sopenharmony_ci else if (is_7976(dev, 1, adie_type)) 103862306a36Sopenharmony_ci val = 0xa; 103962306a36Sopenharmony_ci else 104062306a36Sopenharmony_ci return -EINVAL; 104162306a36Sopenharmony_ci 104262306a36Sopenharmony_ci mt76_wmac_rmw(dev->sku, MT_TOP_POS_SKU, MT_TOP_POS_SKU_MASK, 104362306a36Sopenharmony_ci FIELD_PREP(MT_TOP_POS_SKU_MASK, val)); 104462306a36Sopenharmony_ci 104562306a36Sopenharmony_ci mt76_wr(dev, MT_CONNINFRA_SKU_DEC_ADDR, val); 104662306a36Sopenharmony_ci 104762306a36Sopenharmony_ci return 0; 104862306a36Sopenharmony_ci} 104962306a36Sopenharmony_ci 105062306a36Sopenharmony_cistatic int 105162306a36Sopenharmony_cimt7986_wmac_adie_setup(struct mt7915_dev *dev, u8 adie, u32 adie_type) 105262306a36Sopenharmony_ci{ 105362306a36Sopenharmony_ci int ret; 105462306a36Sopenharmony_ci 105562306a36Sopenharmony_ci if (!(is_7975(dev, adie, adie_type) || is_7976(dev, adie, adie_type))) 105662306a36Sopenharmony_ci return 0; 105762306a36Sopenharmony_ci 105862306a36Sopenharmony_ci ret = mt7986_wmac_adie_cfg(dev, adie, adie_type); 105962306a36Sopenharmony_ci if (ret) 106062306a36Sopenharmony_ci return ret; 106162306a36Sopenharmony_ci 106262306a36Sopenharmony_ci ret = mt7986_wmac_afe_cal(dev, adie, false, adie_type); 106362306a36Sopenharmony_ci if (ret) 106462306a36Sopenharmony_ci return ret; 106562306a36Sopenharmony_ci 106662306a36Sopenharmony_ci if (!adie && (mt798x_wmac_check_adie_type(dev) == ADIE_DBDC)) 106762306a36Sopenharmony_ci ret = mt7986_wmac_afe_cal(dev, adie, true, adie_type); 106862306a36Sopenharmony_ci 106962306a36Sopenharmony_ci return ret; 107062306a36Sopenharmony_ci} 107162306a36Sopenharmony_ci 107262306a36Sopenharmony_cistatic int mt7986_wmac_subsys_powerup(struct mt7915_dev *dev, u32 adie_type) 107362306a36Sopenharmony_ci{ 107462306a36Sopenharmony_ci int ret; 107562306a36Sopenharmony_ci 107662306a36Sopenharmony_ci mt7986_wmac_subsys_setting(dev); 107762306a36Sopenharmony_ci 107862306a36Sopenharmony_ci ret = mt7986_wmac_bus_timeout(dev); 107962306a36Sopenharmony_ci if (ret) 108062306a36Sopenharmony_ci return ret; 108162306a36Sopenharmony_ci 108262306a36Sopenharmony_ci mt7986_wmac_clock_enable(dev, adie_type); 108362306a36Sopenharmony_ci 108462306a36Sopenharmony_ci return 0; 108562306a36Sopenharmony_ci} 108662306a36Sopenharmony_ci 108762306a36Sopenharmony_cistatic int mt7986_wmac_wfsys_powerup(struct mt7915_dev *dev) 108862306a36Sopenharmony_ci{ 108962306a36Sopenharmony_ci int ret; 109062306a36Sopenharmony_ci 109162306a36Sopenharmony_ci ret = mt7986_wmac_wm_enable(dev, false); 109262306a36Sopenharmony_ci if (ret) 109362306a36Sopenharmony_ci return ret; 109462306a36Sopenharmony_ci 109562306a36Sopenharmony_ci ret = mt7986_wmac_wfsys_setting(dev); 109662306a36Sopenharmony_ci if (ret) 109762306a36Sopenharmony_ci return ret; 109862306a36Sopenharmony_ci 109962306a36Sopenharmony_ci mt7986_wmac_wfsys_set_timeout(dev); 110062306a36Sopenharmony_ci 110162306a36Sopenharmony_ci return mt7986_wmac_wm_enable(dev, true); 110262306a36Sopenharmony_ci} 110362306a36Sopenharmony_ci 110462306a36Sopenharmony_ciint mt7986_wmac_enable(struct mt7915_dev *dev) 110562306a36Sopenharmony_ci{ 110662306a36Sopenharmony_ci int ret; 110762306a36Sopenharmony_ci u32 adie_type; 110862306a36Sopenharmony_ci 110962306a36Sopenharmony_ci ret = mt7986_wmac_consys_reset(dev, true); 111062306a36Sopenharmony_ci if (ret) 111162306a36Sopenharmony_ci return ret; 111262306a36Sopenharmony_ci 111362306a36Sopenharmony_ci ret = mt7986_wmac_gpio_setup(dev); 111462306a36Sopenharmony_ci if (ret) 111562306a36Sopenharmony_ci return ret; 111662306a36Sopenharmony_ci 111762306a36Sopenharmony_ci ret = mt7986_wmac_consys_lockup(dev, false); 111862306a36Sopenharmony_ci if (ret) 111962306a36Sopenharmony_ci return ret; 112062306a36Sopenharmony_ci 112162306a36Sopenharmony_ci ret = mt798x_wmac_coninfra_check(dev); 112262306a36Sopenharmony_ci if (ret) 112362306a36Sopenharmony_ci return ret; 112462306a36Sopenharmony_ci 112562306a36Sopenharmony_ci ret = mt798x_wmac_coninfra_setup(dev); 112662306a36Sopenharmony_ci if (ret) 112762306a36Sopenharmony_ci return ret; 112862306a36Sopenharmony_ci 112962306a36Sopenharmony_ci ret = mt798x_wmac_sku_setup(dev, &adie_type); 113062306a36Sopenharmony_ci if (ret) 113162306a36Sopenharmony_ci return ret; 113262306a36Sopenharmony_ci 113362306a36Sopenharmony_ci ret = mt7986_wmac_adie_setup(dev, 0, adie_type); 113462306a36Sopenharmony_ci if (ret) 113562306a36Sopenharmony_ci return ret; 113662306a36Sopenharmony_ci 113762306a36Sopenharmony_ci /* mt7981 doesn't support a second a-die */ 113862306a36Sopenharmony_ci if (is_mt7986(&dev->mt76)) { 113962306a36Sopenharmony_ci ret = mt7986_wmac_adie_setup(dev, 1, adie_type); 114062306a36Sopenharmony_ci if (ret) 114162306a36Sopenharmony_ci return ret; 114262306a36Sopenharmony_ci } 114362306a36Sopenharmony_ci 114462306a36Sopenharmony_ci ret = mt7986_wmac_subsys_powerup(dev, adie_type); 114562306a36Sopenharmony_ci if (ret) 114662306a36Sopenharmony_ci return ret; 114762306a36Sopenharmony_ci 114862306a36Sopenharmony_ci ret = mt7986_wmac_top_wfsys_wakeup(dev, true); 114962306a36Sopenharmony_ci if (ret) 115062306a36Sopenharmony_ci return ret; 115162306a36Sopenharmony_ci 115262306a36Sopenharmony_ci ret = mt7986_wmac_wfsys_powerup(dev); 115362306a36Sopenharmony_ci if (ret) 115462306a36Sopenharmony_ci return ret; 115562306a36Sopenharmony_ci 115662306a36Sopenharmony_ci return mt7986_wmac_sku_update(dev, adie_type); 115762306a36Sopenharmony_ci} 115862306a36Sopenharmony_ci 115962306a36Sopenharmony_civoid mt7986_wmac_disable(struct mt7915_dev *dev) 116062306a36Sopenharmony_ci{ 116162306a36Sopenharmony_ci u32 cur; 116262306a36Sopenharmony_ci 116362306a36Sopenharmony_ci mt7986_wmac_top_wfsys_wakeup(dev, true); 116462306a36Sopenharmony_ci 116562306a36Sopenharmony_ci /* Turn on wfsys2conn bus sleep protect */ 116662306a36Sopenharmony_ci mt76_rmw_field(dev, MT_CONN_INFRA_WF_SLP_PROT, 116762306a36Sopenharmony_ci MT_CONN_INFRA_WF_SLP_PROT_MASK, 0x1); 116862306a36Sopenharmony_ci 116962306a36Sopenharmony_ci /* Check wfsys2conn bus sleep protect */ 117062306a36Sopenharmony_ci read_poll_timeout(mt76_rr, cur, !(cur ^ MT_CONN_INFRA_CONN), 117162306a36Sopenharmony_ci USEC_PER_MSEC, 50 * USEC_PER_MSEC, false, 117262306a36Sopenharmony_ci dev, MT_CONN_INFRA_WF_SLP_PROT_RDY); 117362306a36Sopenharmony_ci 117462306a36Sopenharmony_ci mt7986_wmac_wfsys_poweron(dev, false); 117562306a36Sopenharmony_ci 117662306a36Sopenharmony_ci /* Turn back wpll setting */ 117762306a36Sopenharmony_ci mt76_rmw_field(dev, MT_AFE_DIG_EN_02(0), MT_AFE_MCU_BPLL_CFG_MASK, 0x2); 117862306a36Sopenharmony_ci mt76_rmw_field(dev, MT_AFE_DIG_EN_02(0), MT_AFE_WPLL_CFG_MASK, 0x2); 117962306a36Sopenharmony_ci 118062306a36Sopenharmony_ci /* Reset EMI */ 118162306a36Sopenharmony_ci mt76_rmw_field(dev, MT_CONN_INFRA_EMI_REQ, 118262306a36Sopenharmony_ci MT_CONN_INFRA_EMI_REQ_MASK, 0x1); 118362306a36Sopenharmony_ci mt76_rmw_field(dev, MT_CONN_INFRA_EMI_REQ, 118462306a36Sopenharmony_ci MT_CONN_INFRA_EMI_REQ_MASK, 0x0); 118562306a36Sopenharmony_ci mt76_rmw_field(dev, MT_CONN_INFRA_EMI_REQ, 118662306a36Sopenharmony_ci MT_CONN_INFRA_INFRA_REQ_MASK, 0x1); 118762306a36Sopenharmony_ci mt76_rmw_field(dev, MT_CONN_INFRA_EMI_REQ, 118862306a36Sopenharmony_ci MT_CONN_INFRA_INFRA_REQ_MASK, 0x0); 118962306a36Sopenharmony_ci 119062306a36Sopenharmony_ci mt7986_wmac_top_wfsys_wakeup(dev, false); 119162306a36Sopenharmony_ci mt7986_wmac_consys_lockup(dev, true); 119262306a36Sopenharmony_ci mt7986_wmac_consys_reset(dev, false); 119362306a36Sopenharmony_ci} 119462306a36Sopenharmony_ci 119562306a36Sopenharmony_cistatic int mt798x_wmac_init(struct mt7915_dev *dev) 119662306a36Sopenharmony_ci{ 119762306a36Sopenharmony_ci struct device *pdev = dev->mt76.dev; 119862306a36Sopenharmony_ci struct platform_device *pfdev = to_platform_device(pdev); 119962306a36Sopenharmony_ci struct clk *mcu_clk, *ap_conn_clk; 120062306a36Sopenharmony_ci 120162306a36Sopenharmony_ci mcu_clk = devm_clk_get(pdev, "mcu"); 120262306a36Sopenharmony_ci if (IS_ERR(mcu_clk)) 120362306a36Sopenharmony_ci dev_err(pdev, "mcu clock not found\n"); 120462306a36Sopenharmony_ci else if (clk_prepare_enable(mcu_clk)) 120562306a36Sopenharmony_ci dev_err(pdev, "mcu clock configuration failed\n"); 120662306a36Sopenharmony_ci 120762306a36Sopenharmony_ci ap_conn_clk = devm_clk_get(pdev, "ap2conn"); 120862306a36Sopenharmony_ci if (IS_ERR(ap_conn_clk)) 120962306a36Sopenharmony_ci dev_err(pdev, "ap2conn clock not found\n"); 121062306a36Sopenharmony_ci else if (clk_prepare_enable(ap_conn_clk)) 121162306a36Sopenharmony_ci dev_err(pdev, "ap2conn clock configuration failed\n"); 121262306a36Sopenharmony_ci 121362306a36Sopenharmony_ci dev->dcm = devm_platform_ioremap_resource(pfdev, 1); 121462306a36Sopenharmony_ci if (IS_ERR(dev->dcm)) 121562306a36Sopenharmony_ci return PTR_ERR(dev->dcm); 121662306a36Sopenharmony_ci 121762306a36Sopenharmony_ci dev->sku = devm_platform_ioremap_resource(pfdev, 2); 121862306a36Sopenharmony_ci if (IS_ERR(dev->sku)) 121962306a36Sopenharmony_ci return PTR_ERR(dev->sku); 122062306a36Sopenharmony_ci 122162306a36Sopenharmony_ci dev->rstc = devm_reset_control_get(pdev, "consys"); 122262306a36Sopenharmony_ci if (IS_ERR(dev->rstc)) 122362306a36Sopenharmony_ci return PTR_ERR(dev->rstc); 122462306a36Sopenharmony_ci 122562306a36Sopenharmony_ci return 0; 122662306a36Sopenharmony_ci} 122762306a36Sopenharmony_ci 122862306a36Sopenharmony_cistatic int mt798x_wmac_probe(struct platform_device *pdev) 122962306a36Sopenharmony_ci{ 123062306a36Sopenharmony_ci void __iomem *mem_base; 123162306a36Sopenharmony_ci struct mt7915_dev *dev; 123262306a36Sopenharmony_ci struct mt76_dev *mdev; 123362306a36Sopenharmony_ci int irq, ret; 123462306a36Sopenharmony_ci u32 chip_id; 123562306a36Sopenharmony_ci 123662306a36Sopenharmony_ci chip_id = (uintptr_t)of_device_get_match_data(&pdev->dev); 123762306a36Sopenharmony_ci 123862306a36Sopenharmony_ci mem_base = devm_platform_ioremap_resource(pdev, 0); 123962306a36Sopenharmony_ci if (IS_ERR(mem_base)) { 124062306a36Sopenharmony_ci dev_err(&pdev->dev, "Failed to get memory resource\n"); 124162306a36Sopenharmony_ci return PTR_ERR(mem_base); 124262306a36Sopenharmony_ci } 124362306a36Sopenharmony_ci 124462306a36Sopenharmony_ci dev = mt7915_mmio_probe(&pdev->dev, mem_base, chip_id); 124562306a36Sopenharmony_ci if (IS_ERR(dev)) 124662306a36Sopenharmony_ci return PTR_ERR(dev); 124762306a36Sopenharmony_ci 124862306a36Sopenharmony_ci mdev = &dev->mt76; 124962306a36Sopenharmony_ci ret = mt7915_mmio_wed_init(dev, pdev, false, &irq); 125062306a36Sopenharmony_ci if (ret < 0) 125162306a36Sopenharmony_ci goto free_device; 125262306a36Sopenharmony_ci 125362306a36Sopenharmony_ci if (!ret) { 125462306a36Sopenharmony_ci irq = platform_get_irq(pdev, 0); 125562306a36Sopenharmony_ci if (irq < 0) { 125662306a36Sopenharmony_ci ret = irq; 125762306a36Sopenharmony_ci goto free_device; 125862306a36Sopenharmony_ci } 125962306a36Sopenharmony_ci } 126062306a36Sopenharmony_ci 126162306a36Sopenharmony_ci ret = devm_request_irq(mdev->dev, irq, mt7915_irq_handler, 126262306a36Sopenharmony_ci IRQF_SHARED, KBUILD_MODNAME, dev); 126362306a36Sopenharmony_ci if (ret) 126462306a36Sopenharmony_ci goto free_device; 126562306a36Sopenharmony_ci 126662306a36Sopenharmony_ci ret = mt798x_wmac_init(dev); 126762306a36Sopenharmony_ci if (ret) 126862306a36Sopenharmony_ci goto free_irq; 126962306a36Sopenharmony_ci 127062306a36Sopenharmony_ci mt7915_wfsys_reset(dev); 127162306a36Sopenharmony_ci 127262306a36Sopenharmony_ci ret = mt7915_register_device(dev); 127362306a36Sopenharmony_ci if (ret) 127462306a36Sopenharmony_ci goto free_irq; 127562306a36Sopenharmony_ci 127662306a36Sopenharmony_ci return 0; 127762306a36Sopenharmony_ci 127862306a36Sopenharmony_cifree_irq: 127962306a36Sopenharmony_ci devm_free_irq(mdev->dev, irq, dev); 128062306a36Sopenharmony_cifree_device: 128162306a36Sopenharmony_ci if (mtk_wed_device_active(&mdev->mmio.wed)) 128262306a36Sopenharmony_ci mtk_wed_device_detach(&mdev->mmio.wed); 128362306a36Sopenharmony_ci mt76_free_device(mdev); 128462306a36Sopenharmony_ci 128562306a36Sopenharmony_ci return ret; 128662306a36Sopenharmony_ci} 128762306a36Sopenharmony_ci 128862306a36Sopenharmony_cistatic int mt798x_wmac_remove(struct platform_device *pdev) 128962306a36Sopenharmony_ci{ 129062306a36Sopenharmony_ci struct mt7915_dev *dev = platform_get_drvdata(pdev); 129162306a36Sopenharmony_ci 129262306a36Sopenharmony_ci mt7915_unregister_device(dev); 129362306a36Sopenharmony_ci 129462306a36Sopenharmony_ci return 0; 129562306a36Sopenharmony_ci} 129662306a36Sopenharmony_ci 129762306a36Sopenharmony_cistatic const struct of_device_id mt798x_wmac_of_match[] = { 129862306a36Sopenharmony_ci { .compatible = "mediatek,mt7981-wmac", .data = (u32 *)0x7981 }, 129962306a36Sopenharmony_ci { .compatible = "mediatek,mt7986-wmac", .data = (u32 *)0x7986 }, 130062306a36Sopenharmony_ci {}, 130162306a36Sopenharmony_ci}; 130262306a36Sopenharmony_ci 130362306a36Sopenharmony_ciMODULE_DEVICE_TABLE(of, mt798x_wmac_of_match); 130462306a36Sopenharmony_ci 130562306a36Sopenharmony_cistruct platform_driver mt798x_wmac_driver = { 130662306a36Sopenharmony_ci .driver = { 130762306a36Sopenharmony_ci .name = "mt798x-wmac", 130862306a36Sopenharmony_ci .of_match_table = mt798x_wmac_of_match, 130962306a36Sopenharmony_ci }, 131062306a36Sopenharmony_ci .probe = mt798x_wmac_probe, 131162306a36Sopenharmony_ci .remove = mt798x_wmac_remove, 131262306a36Sopenharmony_ci}; 131362306a36Sopenharmony_ci 131462306a36Sopenharmony_ciMODULE_FIRMWARE(MT7986_FIRMWARE_WA); 131562306a36Sopenharmony_ciMODULE_FIRMWARE(MT7986_FIRMWARE_WM); 131662306a36Sopenharmony_ciMODULE_FIRMWARE(MT7986_FIRMWARE_WM_MT7975); 131762306a36Sopenharmony_ciMODULE_FIRMWARE(MT7986_ROM_PATCH); 131862306a36Sopenharmony_ciMODULE_FIRMWARE(MT7986_ROM_PATCH_MT7975); 131962306a36Sopenharmony_ci 132062306a36Sopenharmony_ciMODULE_FIRMWARE(MT7981_FIRMWARE_WA); 132162306a36Sopenharmony_ciMODULE_FIRMWARE(MT7981_FIRMWARE_WM); 132262306a36Sopenharmony_ciMODULE_FIRMWARE(MT7981_ROM_PATCH); 1323