Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/contrib/dev/mediatek/mt76/mmio.c
105952 views
1
// SPDX-License-Identifier: BSD-3-Clause-Clear
2
/*
3
* Copyright (C) 2016 Felix Fietkau <[email protected]>
4
*/
5
6
#include "mt76.h"
7
#include "dma.h"
8
#include "trace.h"
9
10
static u32 mt76_mmio_rr(struct mt76_dev *dev, u32 offset)
11
{
12
u32 val;
13
14
#if defined(__linux__)
15
val = readl(dev->mmio.regs + offset);
16
#elif defined(__FreeBSD__)
17
val = readl((u8 *)dev->mmio.regs + offset);
18
#endif
19
trace_reg_rr(dev, offset, val);
20
21
return val;
22
}
23
24
static void mt76_mmio_wr(struct mt76_dev *dev, u32 offset, u32 val)
25
{
26
trace_reg_wr(dev, offset, val);
27
#if defined(__linux__)
28
writel(val, dev->mmio.regs + offset);
29
#elif defined(__FreeBSD__)
30
writel(val, (u8 *)dev->mmio.regs + offset);
31
#endif
32
}
33
34
static u32 mt76_mmio_rmw(struct mt76_dev *dev, u32 offset, u32 mask, u32 val)
35
{
36
val |= mt76_mmio_rr(dev, offset) & ~mask;
37
mt76_mmio_wr(dev, offset, val);
38
return val;
39
}
40
41
static void mt76_mmio_write_copy(struct mt76_dev *dev, u32 offset,
42
const void *data, int len)
43
{
44
int i;
45
46
for (i = 0; i < ALIGN(len, 4); i += 4)
47
#if defined(__linux__)
48
writel(get_unaligned_le32(data + i),
49
dev->mmio.regs + offset + i);
50
#elif defined(__FreeBSD__)
51
writel(get_unaligned_le32((const u8 *)data + i),
52
(u8 *)dev->mmio.regs + offset + i);
53
#endif
54
}
55
56
static void mt76_mmio_read_copy(struct mt76_dev *dev, u32 offset,
57
void *data, int len)
58
{
59
int i;
60
61
for (i = 0; i < ALIGN(len, 4); i += 4)
62
#if defined(__linux__)
63
put_unaligned_le32(readl(dev->mmio.regs + offset + i),
64
data + i);
65
#elif defined(__FreeBSD__)
66
put_unaligned_le32(readl((u8 *)dev->mmio.regs + offset + i),
67
(u8 *)data + i);
68
#endif
69
}
70
71
static int mt76_mmio_wr_rp(struct mt76_dev *dev, u32 base,
72
const struct mt76_reg_pair *data, int len)
73
{
74
while (len > 0) {
75
mt76_mmio_wr(dev, data->reg, data->value);
76
data++;
77
len--;
78
}
79
80
return 0;
81
}
82
83
static int mt76_mmio_rd_rp(struct mt76_dev *dev, u32 base,
84
struct mt76_reg_pair *data, int len)
85
{
86
while (len > 0) {
87
data->value = mt76_mmio_rr(dev, data->reg);
88
data++;
89
len--;
90
}
91
92
return 0;
93
}
94
95
void mt76_set_irq_mask(struct mt76_dev *dev, u32 addr,
96
u32 clear, u32 set)
97
{
98
unsigned long flags;
99
100
spin_lock_irqsave(&dev->mmio.irq_lock, flags);
101
dev->mmio.irqmask &= ~clear;
102
dev->mmio.irqmask |= set;
103
if (addr) {
104
if (mtk_wed_device_active(&dev->mmio.wed))
105
mtk_wed_device_irq_set_mask(&dev->mmio.wed,
106
dev->mmio.irqmask);
107
else
108
mt76_mmio_wr(dev, addr, dev->mmio.irqmask);
109
}
110
spin_unlock_irqrestore(&dev->mmio.irq_lock, flags);
111
}
112
EXPORT_SYMBOL_GPL(mt76_set_irq_mask);
113
114
void mt76_mmio_init(struct mt76_dev *dev, void __iomem *regs)
115
{
116
static const struct mt76_bus_ops mt76_mmio_ops = {
117
.rr = mt76_mmio_rr,
118
.rmw = mt76_mmio_rmw,
119
.wr = mt76_mmio_wr,
120
.write_copy = mt76_mmio_write_copy,
121
.read_copy = mt76_mmio_read_copy,
122
.wr_rp = mt76_mmio_wr_rp,
123
.rd_rp = mt76_mmio_rd_rp,
124
.type = MT76_BUS_MMIO,
125
};
126
127
dev->bus = &mt76_mmio_ops;
128
dev->mmio.regs = regs;
129
130
spin_lock_init(&dev->mmio.irq_lock);
131
}
132
EXPORT_SYMBOL_GPL(mt76_mmio_init);
133
134