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