1 // SPDX-License-Identifier: BSD-3-Clause-Clear 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 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 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 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 33 static void mt76_mmio_write_copy(struct mt76_dev *dev, u32 offset, 34 const void *data, int len) 35 { 36 int i; 37 38 for (i = 0; i < ALIGN(len, 4); i += 4) 39 writel(get_unaligned_le32(data + i), 40 dev->mmio.regs + offset + i); 41 } 42 43 static void mt76_mmio_read_copy(struct mt76_dev *dev, u32 offset, 44 void *data, int len) 45 { 46 int i; 47 48 for (i = 0; i < ALIGN(len, 4); i += 4) 49 put_unaligned_le32(readl(dev->mmio.regs + offset + i), 50 data + i); 51 } 52 53 static int mt76_mmio_wr_rp(struct mt76_dev *dev, u32 base, 54 const struct mt76_reg_pair *data, int len) 55 { 56 while (len > 0) { 57 mt76_mmio_wr(dev, data->reg, data->value); 58 data++; 59 len--; 60 } 61 62 return 0; 63 } 64 65 static int mt76_mmio_rd_rp(struct mt76_dev *dev, u32 base, 66 struct mt76_reg_pair *data, int len) 67 { 68 while (len > 0) { 69 data->value = mt76_mmio_rr(dev, data->reg); 70 data++; 71 len--; 72 } 73 74 return 0; 75 } 76 77 void mt76_set_irq_mask(struct mt76_dev *dev, u32 addr, 78 u32 clear, u32 set) 79 { 80 unsigned long flags; 81 82 spin_lock_irqsave(&dev->mmio.irq_lock, flags); 83 dev->mmio.irqmask &= ~clear; 84 dev->mmio.irqmask |= set; 85 if (addr) { 86 if (mtk_wed_device_active(&dev->mmio.wed)) 87 mtk_wed_device_irq_set_mask(&dev->mmio.wed, 88 dev->mmio.irqmask); 89 else 90 mt76_mmio_wr(dev, addr, dev->mmio.irqmask); 91 } 92 spin_unlock_irqrestore(&dev->mmio.irq_lock, flags); 93 } 94 EXPORT_SYMBOL_GPL(mt76_set_irq_mask); 95 96 void mt76_mmio_init(struct mt76_dev *dev, void __iomem *regs) 97 { 98 static const struct mt76_bus_ops mt76_mmio_ops = { 99 .rr = mt76_mmio_rr, 100 .rmw = mt76_mmio_rmw, 101 .wr = mt76_mmio_wr, 102 .write_copy = mt76_mmio_write_copy, 103 .read_copy = mt76_mmio_read_copy, 104 .wr_rp = mt76_mmio_wr_rp, 105 .rd_rp = mt76_mmio_rd_rp, 106 .type = MT76_BUS_MMIO, 107 }; 108 109 dev->bus = &mt76_mmio_ops; 110 dev->mmio.regs = regs; 111 112 spin_lock_init(&dev->mmio.irq_lock); 113 } 114 EXPORT_SYMBOL_GPL(mt76_mmio_init); 115