1 // SPDX-License-Identifier: GPL-2.0 2 /* Copyright (C) 2020 MediaTek Inc. 3 * 4 * Author: Felix Fietkau <nbd@nbd.name> 5 * Lorenzo Bianconi <lorenzo@kernel.org> 6 * Sean Wang <sean.wang@mediatek.com> 7 */ 8 #include <linux/kernel.h> 9 #include <linux/mmc/sdio_func.h> 10 #include <linux/module.h> 11 #include <linux/iopoll.h> 12 13 #include "mt7615.h" 14 #include "mac.h" 15 #include "mcu.h" 16 #include "regs.h" 17 #include "sdio.h" 18 19 static int mt7663s_mcu_init_sched(struct mt7615_dev *dev) 20 { 21 struct mt76_sdio *sdio = &dev->mt76.sdio; 22 u32 txdwcnt; 23 24 sdio->sched.pse_data_quota = mt76_get_field(dev, MT_PSE_PG_HIF0_GROUP, 25 MT_HIF0_MIN_QUOTA); 26 sdio->sched.pse_mcu_quota = mt76_get_field(dev, MT_PSE_PG_HIF1_GROUP, 27 MT_HIF1_MIN_QUOTA); 28 sdio->sched.ple_data_quota = mt76_get_field(dev, MT_PLE_PG_HIF0_GROUP, 29 MT_HIF0_MIN_QUOTA); 30 txdwcnt = mt76_get_field(dev, MT_PP_TXDWCNT, 31 MT_PP_TXDWCNT_TX1_ADD_DW_CNT); 32 sdio->sched.deficit = txdwcnt << 2; 33 34 return 0; 35 } 36 37 static int 38 mt7663s_mcu_send_message(struct mt76_dev *mdev, struct sk_buff *skb, 39 int cmd, int *seq) 40 { 41 struct mt7615_dev *dev = container_of(mdev, struct mt7615_dev, mt76); 42 int ret; 43 44 mt7615_mcu_fill_msg(dev, skb, cmd, seq); 45 ret = mt76_tx_queue_skb_raw(dev, mdev->q_mcu[MT_MCUQ_WM], skb, 0); 46 if (ret) 47 return ret; 48 49 mt76_queue_kick(dev, mdev->q_mcu[MT_MCUQ_WM]); 50 51 return ret; 52 } 53 54 static int __mt7663s_mcu_drv_pmctrl(struct mt7615_dev *dev) 55 { 56 struct sdio_func *func = dev->mt76.sdio.func; 57 struct mt76_phy *mphy = &dev->mt76.phy; 58 struct mt76_connac_pm *pm = &dev->pm; 59 u32 status; 60 int ret; 61 62 sdio_claim_host(func); 63 64 sdio_writel(func, WHLPCR_FW_OWN_REQ_CLR, MCR_WHLPCR, NULL); 65 66 ret = readx_poll_timeout(mt7663s_read_pcr, dev, status, 67 status & WHLPCR_IS_DRIVER_OWN, 2000, 1000000); 68 if (ret < 0) { 69 dev_err(dev->mt76.dev, "Cannot get ownership from device"); 70 } else { 71 clear_bit(MT76_STATE_PM, &mphy->state); 72 73 pm->stats.last_wake_event = jiffies; 74 pm->stats.doze_time += pm->stats.last_wake_event - 75 pm->stats.last_doze_event; 76 } 77 sdio_release_host(func); 78 79 return ret; 80 } 81 82 static int mt7663s_mcu_drv_pmctrl(struct mt7615_dev *dev) 83 { 84 struct mt76_phy *mphy = &dev->mt76.phy; 85 int ret = 0; 86 87 mutex_lock(&dev->pm.mutex); 88 89 if (test_bit(MT76_STATE_PM, &mphy->state)) 90 ret = __mt7663s_mcu_drv_pmctrl(dev); 91 92 mutex_unlock(&dev->pm.mutex); 93 94 return ret; 95 } 96 97 static int mt7663s_mcu_fw_pmctrl(struct mt7615_dev *dev) 98 { 99 struct sdio_func *func = dev->mt76.sdio.func; 100 struct mt76_phy *mphy = &dev->mt76.phy; 101 struct mt76_connac_pm *pm = &dev->pm; 102 int ret = 0; 103 u32 status; 104 105 mutex_lock(&pm->mutex); 106 107 if (mt76_connac_skip_fw_pmctrl(mphy, pm)) 108 goto out; 109 110 sdio_claim_host(func); 111 112 sdio_writel(func, WHLPCR_FW_OWN_REQ_SET, MCR_WHLPCR, NULL); 113 114 ret = readx_poll_timeout(mt7663s_read_pcr, dev, status, 115 !(status & WHLPCR_IS_DRIVER_OWN), 2000, 1000000); 116 if (ret < 0) { 117 dev_err(dev->mt76.dev, "Cannot set ownership to device"); 118 clear_bit(MT76_STATE_PM, &mphy->state); 119 } else { 120 pm->stats.last_doze_event = jiffies; 121 pm->stats.awake_time += pm->stats.last_doze_event - 122 pm->stats.last_wake_event; 123 } 124 125 sdio_release_host(func); 126 out: 127 mutex_unlock(&pm->mutex); 128 129 return ret; 130 } 131 132 int mt7663s_mcu_init(struct mt7615_dev *dev) 133 { 134 static const struct mt76_mcu_ops mt7663s_mcu_ops = { 135 .headroom = sizeof(struct mt7615_mcu_txd), 136 .tailroom = MT_USB_TAIL_SIZE, 137 .mcu_skb_send_msg = mt7663s_mcu_send_message, 138 .mcu_parse_response = mt7615_mcu_parse_response, 139 .mcu_restart = mt7615_mcu_restart, 140 .mcu_rr = mt7615_mcu_reg_rr, 141 .mcu_wr = mt7615_mcu_reg_wr, 142 }; 143 struct mt7615_mcu_ops *mcu_ops; 144 int ret; 145 146 ret = __mt7663s_mcu_drv_pmctrl(dev); 147 if (ret) 148 return ret; 149 150 dev->mt76.mcu_ops = &mt7663s_mcu_ops, 151 152 ret = mt76_get_field(dev, MT_CONN_ON_MISC, MT_TOP_MISC2_FW_N9_RDY); 153 if (ret) { 154 mt7615_mcu_restart(&dev->mt76); 155 if (!mt76_poll_msec(dev, MT_CONN_ON_MISC, 156 MT_TOP_MISC2_FW_N9_RDY, 0, 500)) 157 return -EIO; 158 } 159 160 ret = __mt7663_load_firmware(dev); 161 if (ret) 162 return ret; 163 164 mcu_ops = devm_kmemdup(dev->mt76.dev, dev->mcu_ops, sizeof(*mcu_ops), 165 GFP_KERNEL); 166 if (!mcu_ops) 167 return -ENOMEM; 168 169 mcu_ops->set_drv_ctrl = mt7663s_mcu_drv_pmctrl; 170 mcu_ops->set_fw_ctrl = mt7663s_mcu_fw_pmctrl; 171 dev->mcu_ops = mcu_ops; 172 173 ret = mt7663s_mcu_init_sched(dev); 174 if (ret) 175 return ret; 176 177 set_bit(MT76_STATE_MCU_RUNNING, &dev->mphy.state); 178 179 return 0; 180 } 181