Linux Audio

Check our new training course

Loading...
v6.8
  1// SPDX-License-Identifier: ISC
  2/* Copyright (C) 2021 MediaTek Inc. */
  3
  4#include <linux/iopoll.h>
  5#include <linux/mmc/sdio_func.h>
  6#include "mt7921.h"
  7#include "../mt76_connac2_mac.h"
  8#include "../sdio.h"
  9
 10static void mt7921s_enable_irq(struct mt76_dev *dev)
 11{
 12	struct mt76_sdio *sdio = &dev->sdio;
 13
 14	sdio_claim_host(sdio->func);
 15	sdio_writel(sdio->func, WHLPCR_INT_EN_SET, MCR_WHLPCR, NULL);
 16	sdio_release_host(sdio->func);
 17}
 18
 19static void mt7921s_disable_irq(struct mt76_dev *dev)
 20{
 21	struct mt76_sdio *sdio = &dev->sdio;
 22
 23	sdio_claim_host(sdio->func);
 24	sdio_writel(sdio->func, WHLPCR_INT_EN_CLR, MCR_WHLPCR, NULL);
 25	sdio_release_host(sdio->func);
 26}
 27
 28static u32 mt7921s_read_whcr(struct mt76_dev *dev)
 29{
 30	return sdio_readl(dev->sdio.func, MCR_WHCR, NULL);
 31}
 32
 33int mt7921s_wfsys_reset(struct mt792x_dev *dev)
 34{
 35	struct mt76_sdio *sdio = &dev->mt76.sdio;
 36	u32 val, status;
 37
 38	mt7921s_mcu_drv_pmctrl(dev);
 39
 40	sdio_claim_host(sdio->func);
 41
 42	val = sdio_readl(sdio->func, MCR_WHCR, NULL);
 43	val &= ~WF_WHOLE_PATH_RSTB;
 44	sdio_writel(sdio->func, val, MCR_WHCR, NULL);
 45
 46	msleep(50);
 47
 48	val = sdio_readl(sdio->func, MCR_WHCR, NULL);
 49	val &= ~WF_SDIO_WF_PATH_RSTB;
 50	sdio_writel(sdio->func, val, MCR_WHCR, NULL);
 51
 52	usleep_range(1000, 2000);
 53
 54	val = sdio_readl(sdio->func, MCR_WHCR, NULL);
 55	val |= WF_WHOLE_PATH_RSTB;
 56	sdio_writel(sdio->func, val, MCR_WHCR, NULL);
 57
 58	readx_poll_timeout(mt7921s_read_whcr, &dev->mt76, status,
 59			   status & WF_RST_DONE, 50000, 2000000);
 60
 61	sdio_release_host(sdio->func);
 62
 63	clear_bit(MT76_STATE_MCU_RUNNING, &dev->mphy.state);
 64
 65	/* activate mt7921s again */
 66	mt7921s_mcu_drv_pmctrl(dev);
 67	mt76_clear(dev, MT_CONN_STATUS, MT_WIFI_PATCH_DL_STATE);
 68	mt7921s_mcu_fw_pmctrl(dev);
 69	mt7921s_mcu_drv_pmctrl(dev);
 70
 71	return 0;
 72}
 73
 74int mt7921s_init_reset(struct mt792x_dev *dev)
 75{
 76	set_bit(MT76_MCU_RESET, &dev->mphy.state);
 77
 78	wake_up(&dev->mt76.mcu.wait);
 79	skb_queue_purge(&dev->mt76.mcu.res_q);
 80	wait_event_timeout(dev->mt76.sdio.wait,
 81			   mt76s_txqs_empty(&dev->mt76), 5 * HZ);
 82	mt76_worker_disable(&dev->mt76.sdio.txrx_worker);
 83
 84	mt7921s_disable_irq(&dev->mt76);
 85	mt7921s_wfsys_reset(dev);
 86
 87	mt76_worker_enable(&dev->mt76.sdio.txrx_worker);
 88	clear_bit(MT76_MCU_RESET, &dev->mphy.state);
 89	mt7921s_enable_irq(&dev->mt76);
 90
 91	return 0;
 92}
 93
 94int mt7921s_mac_reset(struct mt792x_dev *dev)
 95{
 96	int err;
 97
 98	mt76_connac_free_pending_tx_skbs(&dev->pm, NULL);
 99	mt76_txq_schedule_all(&dev->mphy);
100	mt76_worker_disable(&dev->mt76.tx_worker);
101	set_bit(MT76_RESET, &dev->mphy.state);
102	set_bit(MT76_MCU_RESET, &dev->mphy.state);
103	wake_up(&dev->mt76.mcu.wait);
104	skb_queue_purge(&dev->mt76.mcu.res_q);
105	wait_event_timeout(dev->mt76.sdio.wait,
106			   mt76s_txqs_empty(&dev->mt76), 5 * HZ);
107	mt76_worker_disable(&dev->mt76.sdio.txrx_worker);
108	mt76_worker_disable(&dev->mt76.sdio.status_worker);
109	mt76_worker_disable(&dev->mt76.sdio.net_worker);
110	mt76_worker_disable(&dev->mt76.sdio.stat_worker);
111
112	mt7921s_disable_irq(&dev->mt76);
113	mt7921s_wfsys_reset(dev);
114
115	mt76_worker_enable(&dev->mt76.sdio.txrx_worker);
116	mt76_worker_enable(&dev->mt76.sdio.status_worker);
117	mt76_worker_enable(&dev->mt76.sdio.net_worker);
118	mt76_worker_enable(&dev->mt76.sdio.stat_worker);
119
120	dev->fw_assert = false;
121	clear_bit(MT76_MCU_RESET, &dev->mphy.state);
122	mt7921s_enable_irq(&dev->mt76);
123
124	err = mt7921_run_firmware(dev);
125	if (err)
126		goto out;
127
128	err = mt7921_mcu_set_eeprom(dev);
129	if (err)
130		goto out;
131
132	err = mt7921_mac_init(dev);
133	if (err)
134		goto out;
135
136	err = __mt7921_start(&dev->phy);
137out:
138	clear_bit(MT76_RESET, &dev->mphy.state);
139
140	mt76_worker_enable(&dev->mt76.tx_worker);
141
142	return err;
143}
v6.13.7
  1// SPDX-License-Identifier: ISC
  2/* Copyright (C) 2021 MediaTek Inc. */
  3
  4#include <linux/iopoll.h>
  5#include <linux/mmc/sdio_func.h>
  6#include "mt7921.h"
  7#include "../mt76_connac2_mac.h"
  8#include "../sdio.h"
  9
 10static void mt7921s_enable_irq(struct mt76_dev *dev)
 11{
 12	struct mt76_sdio *sdio = &dev->sdio;
 13
 14	sdio_claim_host(sdio->func);
 15	sdio_writel(sdio->func, WHLPCR_INT_EN_SET, MCR_WHLPCR, NULL);
 16	sdio_release_host(sdio->func);
 17}
 18
 19static void mt7921s_disable_irq(struct mt76_dev *dev)
 20{
 21	struct mt76_sdio *sdio = &dev->sdio;
 22
 23	sdio_claim_host(sdio->func);
 24	sdio_writel(sdio->func, WHLPCR_INT_EN_CLR, MCR_WHLPCR, NULL);
 25	sdio_release_host(sdio->func);
 26}
 27
 28static u32 mt7921s_read_whcr(struct mt76_dev *dev)
 29{
 30	return sdio_readl(dev->sdio.func, MCR_WHCR, NULL);
 31}
 32
 33int mt7921s_wfsys_reset(struct mt792x_dev *dev)
 34{
 35	struct mt76_sdio *sdio = &dev->mt76.sdio;
 36	u32 val, status;
 37
 38	mt7921s_mcu_drv_pmctrl(dev);
 39
 40	sdio_claim_host(sdio->func);
 41
 42	val = sdio_readl(sdio->func, MCR_WHCR, NULL);
 43	val &= ~WF_WHOLE_PATH_RSTB;
 44	sdio_writel(sdio->func, val, MCR_WHCR, NULL);
 45
 46	msleep(50);
 47
 48	val = sdio_readl(sdio->func, MCR_WHCR, NULL);
 49	val &= ~WF_SDIO_WF_PATH_RSTB;
 50	sdio_writel(sdio->func, val, MCR_WHCR, NULL);
 51
 52	usleep_range(1000, 2000);
 53
 54	val = sdio_readl(sdio->func, MCR_WHCR, NULL);
 55	val |= WF_WHOLE_PATH_RSTB;
 56	sdio_writel(sdio->func, val, MCR_WHCR, NULL);
 57
 58	readx_poll_timeout(mt7921s_read_whcr, &dev->mt76, status,
 59			   status & WF_RST_DONE, 50000, 2000000);
 60
 61	sdio_release_host(sdio->func);
 62
 63	clear_bit(MT76_STATE_MCU_RUNNING, &dev->mphy.state);
 64
 65	/* activate mt7921s again */
 66	mt7921s_mcu_drv_pmctrl(dev);
 67	mt76_clear(dev, MT_CONN_STATUS, MT_WIFI_PATCH_DL_STATE);
 68	mt7921s_mcu_fw_pmctrl(dev);
 69	mt7921s_mcu_drv_pmctrl(dev);
 70
 71	return 0;
 72}
 73
 74int mt7921s_init_reset(struct mt792x_dev *dev)
 75{
 76	set_bit(MT76_MCU_RESET, &dev->mphy.state);
 77
 78	wake_up(&dev->mt76.mcu.wait);
 79	skb_queue_purge(&dev->mt76.mcu.res_q);
 80	wait_event_timeout(dev->mt76.sdio.wait,
 81			   mt76s_txqs_empty(&dev->mt76), 5 * HZ);
 82	mt76_worker_disable(&dev->mt76.sdio.txrx_worker);
 83
 84	mt7921s_disable_irq(&dev->mt76);
 85	mt7921s_wfsys_reset(dev);
 86
 87	mt76_worker_enable(&dev->mt76.sdio.txrx_worker);
 88	clear_bit(MT76_MCU_RESET, &dev->mphy.state);
 89	mt7921s_enable_irq(&dev->mt76);
 90
 91	return 0;
 92}
 93
 94int mt7921s_mac_reset(struct mt792x_dev *dev)
 95{
 96	int err;
 97
 98	mt76_connac_free_pending_tx_skbs(&dev->pm, NULL);
 99	mt76_txq_schedule_all(&dev->mphy);
100	mt76_worker_disable(&dev->mt76.tx_worker);
 
101	set_bit(MT76_MCU_RESET, &dev->mphy.state);
102	wake_up(&dev->mt76.mcu.wait);
103	skb_queue_purge(&dev->mt76.mcu.res_q);
104	wait_event_timeout(dev->mt76.sdio.wait,
105			   mt76s_txqs_empty(&dev->mt76), 5 * HZ);
106	mt76_worker_disable(&dev->mt76.sdio.txrx_worker);
107	mt76_worker_disable(&dev->mt76.sdio.status_worker);
108	mt76_worker_disable(&dev->mt76.sdio.net_worker);
109	mt76_worker_disable(&dev->mt76.sdio.stat_worker);
110
111	mt7921s_disable_irq(&dev->mt76);
112	mt7921s_wfsys_reset(dev);
113
114	mt76_worker_enable(&dev->mt76.sdio.txrx_worker);
115	mt76_worker_enable(&dev->mt76.sdio.status_worker);
116	mt76_worker_enable(&dev->mt76.sdio.net_worker);
117	mt76_worker_enable(&dev->mt76.sdio.stat_worker);
118
119	dev->fw_assert = false;
120	clear_bit(MT76_MCU_RESET, &dev->mphy.state);
121	mt7921s_enable_irq(&dev->mt76);
122
123	err = mt7921_run_firmware(dev);
124	if (err)
125		goto out;
126
127	err = mt7921_mcu_set_eeprom(dev);
128	if (err)
129		goto out;
130
131	err = mt7921_mac_init(dev);
132	if (err)
133		goto out;
134
135	err = __mt7921_start(&dev->phy);
136out:
 
137
138	mt76_worker_enable(&dev->mt76.tx_worker);
139
140	return err;
141}