Linux Audio

Check our new training course

Loading...
 1// SPDX-License-Identifier: ISC
 2/* Copyright (C) 2021 MediaTek Inc. */
 3
 4#include "mt7921.h"
 5#include "mcu.h"
 6
 7int mt7921e_driver_own(struct mt792x_dev *dev)
 8{
 9	u32 reg = mt7921_reg_map_l1(dev, MT_TOP_LPCR_HOST_BAND0);
10
11	mt76_wr(dev, reg, MT_TOP_LPCR_HOST_DRV_OWN);
12	if (!mt76_poll_msec(dev, reg, MT_TOP_LPCR_HOST_FW_OWN,
13			    0, 500)) {
14		dev_err(dev->mt76.dev, "Timeout for driver own\n");
15		return -EIO;
16	}
17
18	return 0;
19}
20
21static int
22mt7921_mcu_send_message(struct mt76_dev *mdev, struct sk_buff *skb,
23			int cmd, int *seq)
24{
25	struct mt792x_dev *dev = container_of(mdev, struct mt792x_dev, mt76);
26	enum mt76_mcuq_id txq = MT_MCUQ_WM;
27	int ret;
28
29	ret = mt76_connac2_mcu_fill_message(mdev, skb, cmd, seq);
30	if (ret)
31		return ret;
32
33	mdev->mcu.timeout = 3 * HZ;
34
35	if (cmd == MCU_CMD(FW_SCATTER))
36		txq = MT_MCUQ_FWDL;
37
38	return mt76_tx_queue_skb_raw(dev, mdev->q_mcu[txq], skb, 0);
39}
40
41int mt7921e_mcu_init(struct mt792x_dev *dev)
42{
43	static const struct mt76_mcu_ops mt7921_mcu_ops = {
44		.headroom = sizeof(struct mt76_connac2_mcu_txd),
45		.mcu_skb_send_msg = mt7921_mcu_send_message,
46		.mcu_parse_response = mt7921_mcu_parse_response,
47	};
48	int err;
49
50	dev->mt76.mcu_ops = &mt7921_mcu_ops;
51
52	err = mt7921e_driver_own(dev);
53	if (err)
54		return err;
55
56	mt76_rmw_field(dev, MT_PCIE_MAC_PM, MT_PCIE_MAC_PM_L0S_DIS, 1);
57
58	err = mt7921_run_firmware(dev);
59
60	mt76_queue_tx_cleanup(dev, dev->mt76.q_mcu[MT_MCUQ_FWDL], false);
61
62	return err;
63}