0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022 #define tu102_mc(p) container_of((p), struct tu102_mc, base)
0023 #include "priv.h"
0024
0025 struct tu102_mc {
0026 struct nvkm_mc base;
0027 spinlock_t lock;
0028 bool intr;
0029 u32 mask;
0030 };
0031
0032 static void
0033 tu102_mc_intr_update(struct tu102_mc *mc)
0034 {
0035 struct nvkm_device *device = mc->base.subdev.device;
0036 u32 mask = mc->intr ? mc->mask : 0, i;
0037
0038 for (i = 0; i < 2; i++) {
0039 nvkm_wr32(device, 0x000180 + (i * 0x04), ~mask);
0040 nvkm_wr32(device, 0x000160 + (i * 0x04), mask);
0041 }
0042
0043 if (mask & 0x00000200)
0044 nvkm_wr32(device, 0xb81608, 0x6);
0045 else
0046 nvkm_wr32(device, 0xb81610, 0x6);
0047 }
0048
0049 static void
0050 tu102_mc_intr_unarm(struct nvkm_mc *base)
0051 {
0052 struct tu102_mc *mc = tu102_mc(base);
0053 unsigned long flags;
0054
0055 spin_lock_irqsave(&mc->lock, flags);
0056 mc->intr = false;
0057 tu102_mc_intr_update(mc);
0058 spin_unlock_irqrestore(&mc->lock, flags);
0059 }
0060
0061 static void
0062 tu102_mc_intr_rearm(struct nvkm_mc *base)
0063 {
0064 struct tu102_mc *mc = tu102_mc(base);
0065 unsigned long flags;
0066
0067 spin_lock_irqsave(&mc->lock, flags);
0068 mc->intr = true;
0069 tu102_mc_intr_update(mc);
0070 spin_unlock_irqrestore(&mc->lock, flags);
0071 }
0072
0073 static void
0074 tu102_mc_intr_mask(struct nvkm_mc *base, u32 mask, u32 intr)
0075 {
0076 struct tu102_mc *mc = tu102_mc(base);
0077 unsigned long flags;
0078
0079 spin_lock_irqsave(&mc->lock, flags);
0080 mc->mask = (mc->mask & ~mask) | intr;
0081 tu102_mc_intr_update(mc);
0082 spin_unlock_irqrestore(&mc->lock, flags);
0083 }
0084
0085 static u32
0086 tu102_mc_intr_stat(struct nvkm_mc *mc)
0087 {
0088 struct nvkm_device *device = mc->subdev.device;
0089 u32 intr0 = nvkm_rd32(device, 0x000100);
0090 u32 intr1 = nvkm_rd32(device, 0x000104);
0091 u32 intr_top = nvkm_rd32(device, 0xb81600);
0092
0093
0094
0095
0096
0097 if (intr_top & 0x00000006)
0098 intr0 |= 0x00000200;
0099
0100 return intr0 | intr1;
0101 }
0102
0103
0104 static const struct nvkm_mc_func
0105 tu102_mc = {
0106 .init = nv50_mc_init,
0107 .intr = gp100_mc_intr,
0108 .intr_unarm = tu102_mc_intr_unarm,
0109 .intr_rearm = tu102_mc_intr_rearm,
0110 .intr_mask = tu102_mc_intr_mask,
0111 .intr_stat = tu102_mc_intr_stat,
0112 .reset = gk104_mc_reset,
0113 };
0114
0115 static int
0116 tu102_mc_new_(const struct nvkm_mc_func *func, struct nvkm_device *device,
0117 enum nvkm_subdev_type type, int inst, struct nvkm_mc **pmc)
0118 {
0119 struct tu102_mc *mc;
0120
0121 if (!(mc = kzalloc(sizeof(*mc), GFP_KERNEL)))
0122 return -ENOMEM;
0123 nvkm_mc_ctor(func, device, type, inst, &mc->base);
0124 *pmc = &mc->base;
0125
0126 spin_lock_init(&mc->lock);
0127 mc->intr = false;
0128 mc->mask = 0x7fffffff;
0129 return 0;
0130 }
0131
0132 int
0133 tu102_mc_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, struct nvkm_mc **pmc)
0134 {
0135 return tu102_mc_new_(&tu102_mc, device, type, inst, pmc);
0136 }