From: Bo Jiao <bo.jiao@mediatek.com>
To: Felix Fietkau <nbd@nbd.name>
Cc: linux-wireless <linux-wireless@vger.kernel.org>,
Ryder Lee <ryder.lee@mediatek.com>,
Xing Song <xing.song@mediatek.com>,
Sujuan Chen <sujuan.chen@mediatek.com>,
Shayne Chen <shayne.chen@mediatek.com>,
"Evelyn Tsai" <evelyn.tsai@mediatek.com>,
linux-mediatek <linux-mediatek@lists.infradead.org>,
Bo Jiao <Bo.Jiao@mediatek.com>
Subject: [PATCH v4 05/12] mt76: mt7915: add firmware support for mt7916
Date: Mon, 20 Dec 2021 10:17:57 +0800 [thread overview]
Message-ID: <6b2d86cbbe6426a5ed0d91b8248b95ac3390885f.1639965732.git.Bo.Jiao@mediatek.com> (raw)
In-Reply-To: <cover.1639965732.git.Bo.Jiao@mediatek.com>
From: Bo Jiao <Bo.Jiao@mediatek.com>
Update firmware initialization for mt7916.
This is an intermediate patch to add mt7916 support.
Co-developed-by: Sujuan Chen <sujuan.chen@mediatek.com>
Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
Co-developed-by: Ryder Lee <ryder.lee@mediatek.com>
Signed-off-by: Ryder Lee <ryder.lee@mediatek.com>
Signed-off-by: Bo Jiao <Bo.Jiao@mediatek.com>
---
v3:
- modify the function mt7915_wfsys_reset to support mt7916
---
.../net/wireless/mediatek/mt76/mt7915/init.c | 75 ++++++++---------
.../net/wireless/mediatek/mt76/mt7915/mcu.c | 81 +++++++++++++++----
.../wireless/mediatek/mt76/mt7915/mt7915.h | 4 +
.../net/wireless/mediatek/mt76/mt7915/pci.c | 3 +
.../net/wireless/mediatek/mt76/mt7915/regs.h | 6 +-
5 files changed, 115 insertions(+), 54 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/init.c b/drivers/net/wireless/mediatek/mt76/mt7915/init.c
index 2da342d..edf0d7e 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/init.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/init.c
@@ -511,41 +511,53 @@ static void mt7915_init_work(struct work_struct *work)
static void mt7915_wfsys_reset(struct mt7915_dev *dev)
{
- u32 val = MT_TOP_PWR_KEY | MT_TOP_PWR_SW_PWR_ON | MT_TOP_PWR_PWR_ON;
+ u32 val;
#define MT_MCU_DUMMY_RANDOM GENMASK(15, 0)
#define MT_MCU_DUMMY_DEFAULT GENMASK(31, 16)
+ if (is_mt7915(&dev->mt76)) {
+ mt76_wr(dev, MT_MCU_WFDMA0_DUMMY_CR, MT_MCU_DUMMY_RANDOM);
+
+ /* change to software control */
+ val |= MT_TOP_PWR_SW_RST;
+ mt76_wr(dev, MT_TOP_PWR_CTRL, val);
+
+ /* reset wfsys */
+ val &= ~MT_TOP_PWR_SW_RST;
+ mt76_wr(dev, MT_TOP_PWR_CTRL, val);
+
+ /* release wfsys then mcu re-excutes romcode */
+ val |= MT_TOP_PWR_SW_RST;
+ mt76_wr(dev, MT_TOP_PWR_CTRL, val);
+
+ /* switch to hw control */
+ val &= ~MT_TOP_PWR_SW_RST;
+ val |= MT_TOP_PWR_HW_CTRL;
+ mt76_wr(dev, MT_TOP_PWR_CTRL, val);
+
+ /* check whether mcu resets to default */
+ if (!mt76_poll_msec(dev, MT_MCU_WFDMA0_DUMMY_CR,
+ MT_MCU_DUMMY_DEFAULT, MT_MCU_DUMMY_DEFAULT,
+ 1000)) {
+ dev_err(dev->mt76.dev, "wifi subsystem reset failure\n");
+ return;
+ }
- mt76_wr(dev, MT_MCU_WFDMA0_DUMMY_CR, MT_MCU_DUMMY_RANDOM);
-
- /* change to software control */
- val |= MT_TOP_PWR_SW_RST;
- mt76_wr(dev, MT_TOP_PWR_CTRL, val);
-
- /* reset wfsys */
- val &= ~MT_TOP_PWR_SW_RST;
- mt76_wr(dev, MT_TOP_PWR_CTRL, val);
+ /* wfsys reset won't clear host registers */
+ mt76_clear(dev, MT_TOP_MISC, MT_TOP_MISC_FW_STATE);
- /* release wfsys then mcu re-excutes romcode */
- val |= MT_TOP_PWR_SW_RST;
- mt76_wr(dev, MT_TOP_PWR_CTRL, val);
+ msleep(100);
+ } else {
+ val = mt76_rr(dev, MT_WF_SUBSYS_RST);
- /* switch to hw control */
- val &= ~MT_TOP_PWR_SW_RST;
- val |= MT_TOP_PWR_HW_CTRL;
- mt76_wr(dev, MT_TOP_PWR_CTRL, val);
+ val |= 0x1;
+ mt76_wr(dev, MT_WF_SUBSYS_RST, val);
+ msleep(20);
- /* check whether mcu resets to default */
- if (!mt76_poll_msec(dev, MT_MCU_WFDMA0_DUMMY_CR, MT_MCU_DUMMY_DEFAULT,
- MT_MCU_DUMMY_DEFAULT, 1000)) {
- dev_err(dev->mt76.dev, "wifi subsystem reset failure\n");
- return;
+ val &= ~0x1;
+ mt76_wr(dev, MT_WF_SUBSYS_RST, val);
+ msleep(20);
}
-
- /* wfsys reset won't clear host registers */
- mt76_clear(dev, MT_TOP_MISC, MT_TOP_MISC_FW_STATE);
-
- msleep(100);
}
static int mt7915_init_hardware(struct mt7915_dev *dev)
@@ -568,15 +580,6 @@ static int mt7915_init_hardware(struct mt7915_dev *dev)
set_bit(MT76_STATE_INITIALIZED, &dev->mphy.state);
- /*
- * force firmware operation mode into normal state,
- * which should be set before firmware download stage.
- */
- if (is_mt7915(&dev->mt76))
- mt76_wr(dev, MT_SWDEF_MODE, MT_SWDEF_NORMAL_MODE);
- else
- mt76_wr(dev, MT_SWDEF_MODE_MT7916, MT_SWDEF_NORMAL_MODE);
-
ret = mt7915_mcu_init(dev);
if (ret) {
/* Reset and try again */
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
index d068266..6ea213b 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
@@ -2693,16 +2693,20 @@ static int mt7915_mcu_start_patch(struct mt7915_dev *dev)
sizeof(req), true);
}
-static int mt7915_driver_own(struct mt7915_dev *dev)
+static int mt7915_driver_own(struct mt7915_dev *dev, u8 band)
{
- mt76_wr(dev, MT_TOP_LPCR_HOST_BAND0, MT_TOP_LPCR_HOST_DRV_OWN);
- if (!mt76_poll_msec(dev, MT_TOP_LPCR_HOST_BAND0,
+ mt76_wr(dev, MT_TOP_LPCR_HOST_BAND(band), MT_TOP_LPCR_HOST_DRV_OWN);
+ if (!mt76_poll_msec(dev, MT_TOP_LPCR_HOST_BAND(band),
MT_TOP_LPCR_HOST_FW_OWN_STAT,
0, 500)) {
dev_err(dev->mt76.dev, "Timeout for driver own\n");
return -EIO;
}
+ /* clear irq when the driver own success */
+ mt76_wr(dev, MT_TOP_LPCR_HOST_BAND_IRQ_STAT(band),
+ MT_TOP_LPCR_HOST_BAND_STAT);
+
return 0;
}
@@ -2732,6 +2736,7 @@ static int mt7915_load_patch(struct mt7915_dev *dev)
{
const struct mt7915_patch_hdr *hdr;
const struct firmware *fw = NULL;
+ const char *patch;
int i, ret, sem;
sem = mt7915_mcu_patch_sem_ctrl(dev, 1);
@@ -2745,7 +2750,8 @@ static int mt7915_load_patch(struct mt7915_dev *dev)
return -EAGAIN;
}
- ret = request_firmware(&fw, MT7915_ROM_PATCH, dev->mt76.dev);
+ patch = is_mt7915(&dev->mt76) ? MT7915_ROM_PATCH : MT7916_ROM_PATCH;
+ ret = request_firmware(&fw, patch, dev->mt76.dev);
if (ret)
goto out;
@@ -2876,9 +2882,11 @@ static int mt7915_load_ram(struct mt7915_dev *dev)
{
const struct mt7915_fw_trailer *hdr;
const struct firmware *fw;
+ const char *mcu;
int ret;
- ret = request_firmware(&fw, MT7915_FIRMWARE_WM, dev->mt76.dev);
+ mcu = is_mt7915(&dev->mt76) ? MT7915_FIRMWARE_WM : MT7916_FIRMWARE_WM;
+ ret = request_firmware(&fw, mcu, dev->mt76.dev);
if (ret)
return ret;
@@ -2902,7 +2910,8 @@ static int mt7915_load_ram(struct mt7915_dev *dev)
release_firmware(fw);
- ret = request_firmware(&fw, MT7915_FIRMWARE_WA, dev->mt76.dev);
+ mcu = is_mt7915(&dev->mt76) ? MT7915_FIRMWARE_WA : MT7916_FIRMWARE_WA;
+ ret = request_firmware(&fw, mcu, dev->mt76.dev);
if (ret)
return ret;
@@ -2934,10 +2943,36 @@ out:
return ret;
}
+static int
+mt7915_firmware_state(struct mt7915_dev *dev, bool wa)
+{
+ u32 state = FIELD_PREP(MT_TOP_MISC_FW_STATE,
+ wa ? FW_STATE_RDY : FW_STATE_FW_DOWNLOAD);
+
+ if (!mt76_poll_msec(dev, MT_TOP_MISC, MT_TOP_MISC_FW_STATE,
+ state, 1000)) {
+ dev_err(dev->mt76.dev, "Timeout for initializing firmware\n");
+ return -EIO;
+ }
+ return 0;
+}
+
static int mt7915_load_firmware(struct mt7915_dev *dev)
{
int ret;
+ /* make sure fw is download state */
+ if (mt7915_firmware_state(dev, false)) {
+ /* restart firmware once */
+ __mt76_mcu_restart(&dev->mt76);
+ ret = mt7915_firmware_state(dev, false);
+ if (ret) {
+ dev_err(dev->mt76.dev,
+ "Firmware is not ready for download\n");
+ return ret;
+ }
+ }
+
ret = mt7915_load_patch(dev);
if (ret)
return ret;
@@ -2946,12 +2981,9 @@ static int mt7915_load_firmware(struct mt7915_dev *dev)
if (ret)
return ret;
- if (!mt76_poll_msec(dev, MT_TOP_MISC, MT_TOP_MISC_FW_STATE,
- FIELD_PREP(MT_TOP_MISC_FW_STATE,
- FW_STATE_RDY), 1000)) {
- dev_err(dev->mt76.dev, "Timeout for initializing firmware\n");
- return -EIO;
- }
+ ret = mt7915_firmware_state(dev, true);
+ if (ret)
+ return ret;
mt76_queue_tx_cleanup(dev, dev->mt76.q_mcu[MT_MCUQ_FWDL], false);
@@ -3117,9 +3149,23 @@ int mt7915_mcu_init(struct mt7915_dev *dev)
dev->mt76.mcu_ops = &mt7915_mcu_ops;
- ret = mt7915_driver_own(dev);
+ /* force firmware operation mode into normal state,
+ * which should be set before firmware download stage.
+ */
+ if (is_mt7915(&dev->mt76))
+ mt76_wr(dev, MT_SWDEF_MODE, MT_SWDEF_NORMAL_MODE);
+ else
+ mt76_wr(dev, MT_SWDEF_MODE_MT7916, MT_SWDEF_NORMAL_MODE);
+
+ ret = mt7915_driver_own(dev, 0);
if (ret)
return ret;
+ /* set driver own for band1 when two hif exist */
+ if (dev->hif2) {
+ ret = mt7915_driver_own(dev, 1);
+ if (ret)
+ return ret;
+ }
ret = mt7915_load_firmware(dev);
if (ret)
@@ -3154,14 +3200,15 @@ int mt7915_mcu_init(struct mt7915_dev *dev)
void mt7915_mcu_exit(struct mt7915_dev *dev)
{
__mt76_mcu_restart(&dev->mt76);
- if (!mt76_poll_msec(dev, MT_TOP_MISC, MT_TOP_MISC_FW_STATE,
- FIELD_PREP(MT_TOP_MISC_FW_STATE,
- FW_STATE_FW_DOWNLOAD), 1000)) {
+ if (mt7915_firmware_state(dev, false)) {
dev_err(dev->mt76.dev, "Failed to exit mcu\n");
return;
}
- mt76_wr(dev, MT_TOP_LPCR_HOST_BAND0, MT_TOP_LPCR_HOST_FW_OWN);
+ mt76_wr(dev, MT_TOP_LPCR_HOST_BAND(0), MT_TOP_LPCR_HOST_FW_OWN);
+ if (dev->hif2)
+ mt76_wr(dev, MT_TOP_LPCR_HOST_BAND(1),
+ MT_TOP_LPCR_HOST_FW_OWN);
skb_queue_purge(&dev->mt76.mcu.res_q);
}
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
index 673c2d7..d4449e3 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h
@@ -30,6 +30,10 @@
#define MT7915_FIRMWARE_WM "mediatek/mt7915_wm.bin"
#define MT7915_ROM_PATCH "mediatek/mt7915_rom_patch.bin"
+#define MT7916_FIRMWARE_WA "mediatek/mt7916_wa.bin"
+#define MT7916_FIRMWARE_WM "mediatek/mt7916_wm.bin"
+#define MT7916_ROM_PATCH "mediatek/mt7916_rom_patch.bin"
+
#define MT7915_EEPROM_DEFAULT "mediatek/mt7915_eeprom.bin"
#define MT7915_EEPROM_DEFAULT_DBDC "mediatek/mt7915_eeprom_dbdc.bin"
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/pci.c b/drivers/net/wireless/mediatek/mt76/mt7915/pci.c
index e4854a4..5d6adcd 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/pci.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/pci.c
@@ -167,3 +167,6 @@ MODULE_DEVICE_TABLE(pci, mt7915_hif_device_table);
MODULE_FIRMWARE(MT7915_FIRMWARE_WA);
MODULE_FIRMWARE(MT7915_FIRMWARE_WM);
MODULE_FIRMWARE(MT7915_ROM_PATCH);
+MODULE_FIRMWARE(MT7916_FIRMWARE_WA);
+MODULE_FIRMWARE(MT7916_FIRMWARE_WM);
+MODULE_FIRMWARE(MT7916_ROM_PATCH);
diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/regs.h b/drivers/net/wireless/mediatek/mt76/mt7915/regs.h
index a8e864a..1168a62 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7915/regs.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7915/regs.h
@@ -729,17 +729,21 @@ enum offs_rev {
#define MT_TOP_BASE 0x18060000
#define MT_TOP(ofs) (MT_TOP_BASE + (ofs))
-#define MT_TOP_LPCR_HOST_BAND0 MT_TOP(0x10)
+#define MT_TOP_LPCR_HOST_BAND(_band) MT_TOP(0x10 + ((_band) * 0x10))
#define MT_TOP_LPCR_HOST_FW_OWN BIT(0)
#define MT_TOP_LPCR_HOST_DRV_OWN BIT(1)
#define MT_TOP_LPCR_HOST_FW_OWN_STAT BIT(2)
+#define MT_TOP_LPCR_HOST_BAND_IRQ_STAT(_band) MT_TOP(0x14 + ((_band) * 0x10))
+#define MT_TOP_LPCR_HOST_BAND_STAT BIT(0)
+
#define MT_TOP_MISC MT_TOP(0xf0)
#define MT_TOP_MISC_FW_STATE GENMASK(2, 0)
#define MT_HW_BOUND 0x70010020
#define MT_HW_CHIPID 0x70010200
#define MT_HW_REV 0x70010204
+#define MT_WF_SUBSYS_RST 0x70002600
/* PCIE MAC */
#define MT_PCIE_MAC_BASE 0x74030000
--
2.18.0
next prev parent reply other threads:[~2021-12-20 2:18 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-12-20 2:17 [PATCH v4 00/12] add mt7916 support Bo Jiao
2021-12-20 2:17 ` [PATCH v4 01/12] mt76: mt7915: add mt7915_mmio_probe() as a common probing function Bo Jiao
2021-12-20 2:17 ` [PATCH v4 02/12] mt76: mt7915: refine register definition Bo Jiao
2021-12-20 2:17 ` [PATCH v4 03/12] mt76: add MT_RXQ_MAIN_WA for mt7916 Bo Jiao
2021-12-20 2:17 ` [PATCH v4 04/12] mt76: mt7915: rework dma.c to adapt mt7916 changes Bo Jiao
2021-12-20 2:17 ` Bo Jiao [this message]
2022-01-20 21:29 ` [PATCH v4 05/12] mt76: mt7915: add firmware support for mt7916 Ben Greear
2022-01-20 21:38 ` Ryder Lee
2021-12-20 2:17 ` [PATCH v4 06/12] mt76: mt7915: rework eeprom.c to adapt mt7916 changes Bo Jiao
2021-12-20 2:17 ` [PATCH v4 07/12] mt76: mt7915: enlarge wcid size to 544 Bo Jiao
2021-12-20 2:18 ` [PATCH v4 08/12] mt76: mt7915: add txfree event v3 Bo Jiao
2021-12-20 2:18 ` [PATCH v4 09/12] mt76: mt7915: update rx rate reporting for mt7916 Bo Jiao
2021-12-20 2:18 ` [PATCH v4 10/12] mt76: mt7915: update mt7915_chan_mib_offs " Bo Jiao
2021-12-20 2:18 ` [PATCH v4 11/12] mt76: mt7915: add mt7916 calibrated data support Bo Jiao
2021-12-20 2:18 ` [PATCH v4 12/12] mt76: mt7915: add device id for mt7916 Bo Jiao
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=6b2d86cbbe6426a5ed0d91b8248b95ac3390885f.1639965732.git.Bo.Jiao@mediatek.com \
--to=bo.jiao@mediatek.com \
--cc=evelyn.tsai@mediatek.com \
--cc=linux-mediatek@lists.infradead.org \
--cc=linux-wireless@vger.kernel.org \
--cc=nbd@nbd.name \
--cc=ryder.lee@mediatek.com \
--cc=shayne.chen@mediatek.com \
--cc=sujuan.chen@mediatek.com \
--cc=xing.song@mediatek.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).