1  // SPDX-License-Identifier: ISC
2  /*
3   * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
4   */
5  
6  #include "mt76.h"
7  #include "dma.h"
8  #include "trace.h"
9  
mt76_mmio_rr(struct mt76_dev * dev,u32 offset)10  static u32 mt76_mmio_rr(struct mt76_dev *dev, u32 offset)
11  {
12  	u32 val;
13  
14  	val = readl(dev->mmio.regs + offset);
15  	trace_reg_rr(dev, offset, val);
16  
17  	return val;
18  }
19  
mt76_mmio_wr(struct mt76_dev * dev,u32 offset,u32 val)20  static void mt76_mmio_wr(struct mt76_dev *dev, u32 offset, u32 val)
21  {
22  	trace_reg_wr(dev, offset, val);
23  	writel(val, dev->mmio.regs + offset);
24  }
25  
mt76_mmio_rmw(struct mt76_dev * dev,u32 offset,u32 mask,u32 val)26  static u32 mt76_mmio_rmw(struct mt76_dev *dev, u32 offset, u32 mask, u32 val)
27  {
28  	val |= mt76_mmio_rr(dev, offset) & ~mask;
29  	mt76_mmio_wr(dev, offset, val);
30  	return val;
31  }
32  
mt76_mmio_write_copy(struct mt76_dev * dev,u32 offset,const void * data,int len)33  static void mt76_mmio_write_copy(struct mt76_dev *dev, u32 offset,
34  				 const void *data, int len)
35  {
36  	__iowrite32_copy(dev->mmio.regs + offset, data, DIV_ROUND_UP(len, 4));
37  }
38  
mt76_mmio_read_copy(struct mt76_dev * dev,u32 offset,void * data,int len)39  static void mt76_mmio_read_copy(struct mt76_dev *dev, u32 offset,
40  				void *data, int len)
41  {
42  	__ioread32_copy(data, dev->mmio.regs + offset, DIV_ROUND_UP(len, 4));
43  }
44  
mt76_mmio_wr_rp(struct mt76_dev * dev,u32 base,const struct mt76_reg_pair * data,int len)45  static int mt76_mmio_wr_rp(struct mt76_dev *dev, u32 base,
46  			   const struct mt76_reg_pair *data, int len)
47  {
48  	while (len > 0) {
49  		mt76_mmio_wr(dev, data->reg, data->value);
50  		data++;
51  		len--;
52  	}
53  
54  	return 0;
55  }
56  
mt76_mmio_rd_rp(struct mt76_dev * dev,u32 base,struct mt76_reg_pair * data,int len)57  static int mt76_mmio_rd_rp(struct mt76_dev *dev, u32 base,
58  			   struct mt76_reg_pair *data, int len)
59  {
60  	while (len > 0) {
61  		data->value = mt76_mmio_rr(dev, data->reg);
62  		data++;
63  		len--;
64  	}
65  
66  	return 0;
67  }
68  
mt76_set_irq_mask(struct mt76_dev * dev,u32 addr,u32 clear,u32 set)69  void mt76_set_irq_mask(struct mt76_dev *dev, u32 addr,
70  		       u32 clear, u32 set)
71  {
72  	unsigned long flags;
73  
74  	spin_lock_irqsave(&dev->mmio.irq_lock, flags);
75  	dev->mmio.irqmask &= ~clear;
76  	dev->mmio.irqmask |= set;
77  	if (addr) {
78  		if (mtk_wed_device_active(&dev->mmio.wed))
79  			mtk_wed_device_irq_set_mask(&dev->mmio.wed,
80  						    dev->mmio.irqmask);
81  		else
82  			mt76_mmio_wr(dev, addr, dev->mmio.irqmask);
83  	}
84  	spin_unlock_irqrestore(&dev->mmio.irq_lock, flags);
85  }
86  EXPORT_SYMBOL_GPL(mt76_set_irq_mask);
87  
mt76_mmio_init(struct mt76_dev * dev,void __iomem * regs)88  void mt76_mmio_init(struct mt76_dev *dev, void __iomem *regs)
89  {
90  	static const struct mt76_bus_ops mt76_mmio_ops = {
91  		.rr = mt76_mmio_rr,
92  		.rmw = mt76_mmio_rmw,
93  		.wr = mt76_mmio_wr,
94  		.write_copy = mt76_mmio_write_copy,
95  		.read_copy = mt76_mmio_read_copy,
96  		.wr_rp = mt76_mmio_wr_rp,
97  		.rd_rp = mt76_mmio_rd_rp,
98  		.type = MT76_BUS_MMIO,
99  	};
100  
101  	dev->bus = &mt76_mmio_ops;
102  	dev->mmio.regs = regs;
103  
104  	spin_lock_init(&dev->mmio.irq_lock);
105  }
106  EXPORT_SYMBOL_GPL(mt76_mmio_init);
107