19274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggs#ifndef __NOUVEAU_SUBDEV_H__
29274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggs#define __NOUVEAU_SUBDEV_H__
39274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggs
49274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggs#include <core/object.h>
59274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggs
69274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggs#define NV_SUBDEV_(sub,var) (NV_SUBDEV_CLASS | ((var) << 8) | (sub))
79274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggs#define NV_SUBDEV(name,var)  NV_SUBDEV_(NVDEV_SUBDEV_##name, (var))
89274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggs
99274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggsstruct nouveau_subdev {
109274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggs	struct nouveau_object base;
119274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggs	struct mutex mutex;
129274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggs	const char *name;
139274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggs	void __iomem *mmio;
149274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggs	u32 debug;
159274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggs	u32 unit;
169274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggs
179274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggs	void (*intr)(struct nouveau_subdev *);
189274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggs};
199274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggs
209274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggsstatic inline struct nouveau_subdev *
219274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggsnv_subdev(void *obj)
229274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggs{
239274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggs#if CONFIG_NOUVEAU_DEBUG >= NV_DBG_PARANOIA
249274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggs	if (unlikely(!nv_iclass(obj, NV_SUBDEV_CLASS)))
259274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggs		nv_assert("BAD CAST -> NvSubDev, %08x", nv_hclass(obj));
269274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggs#endif
279274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggs	return obj;
289274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggs}
299274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggs
309274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggsstatic inline int
319274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggsnv_subidx(struct nouveau_object *object)
329274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggs{
339274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggs	return nv_hclass(nv_subdev(object)) & 0xff;
349274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggs}
359274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggs
369274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggs#define nouveau_subdev_create(p,e,o,v,s,f,d)                                   \
379274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggs	nouveau_subdev_create_((p), (e), (o), (v), (s), (f),                   \
389274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggs			       sizeof(**d),(void **)d)
399274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggs
409274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggsint  nouveau_subdev_create_(struct nouveau_object *, struct nouveau_object *,
419274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggs			    struct nouveau_oclass *, u32 pclass,
429274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggs			    const char *sname, const char *fname,
439274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggs			    int size, void **);
449274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggsvoid nouveau_subdev_destroy(struct nouveau_subdev *);
459274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggsint  nouveau_subdev_init(struct nouveau_subdev *);
469274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggsint  nouveau_subdev_fini(struct nouveau_subdev *, bool suspend);
479274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggsvoid nouveau_subdev_reset(struct nouveau_object *);
489274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggs
499274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggsvoid _nouveau_subdev_dtor(struct nouveau_object *);
509274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggsint  _nouveau_subdev_init(struct nouveau_object *);
519274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggsint  _nouveau_subdev_fini(struct nouveau_object *, bool suspend);
529274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggs
539274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggs#define s_printk(s,l,f,a...) do {                                              \
549274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggs	if ((s)->debug >= OS_DBG_##l) {                                        \
559274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggs		nv_printk((s)->base.parent, (s)->name, l, f, ##a);             \
569274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggs	}                                                                      \
579274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggs} while(0)
589274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggs
599274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggsstatic inline u8
609274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggsnv_rd08(void *obj, u32 addr)
619274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggs{
629274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggs	struct nouveau_subdev *subdev = nv_subdev(obj);
639274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggs	u8 data = ioread8(subdev->mmio + addr);
649274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggs	nv_spam(subdev, "nv_rd08 0x%06x 0x%02x\n", addr, data);
659274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggs	return data;
669274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggs}
679274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggs
689274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggsstatic inline u16
699274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggsnv_rd16(void *obj, u32 addr)
709274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggs{
719274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggs	struct nouveau_subdev *subdev = nv_subdev(obj);
729274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggs	u16 data = ioread16_native(subdev->mmio + addr);
739274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggs	nv_spam(subdev, "nv_rd16 0x%06x 0x%04x\n", addr, data);
749274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggs	return data;
759274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggs}
769274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggs
779274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggsstatic inline u32
789274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggsnv_rd32(void *obj, u32 addr)
799274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggs{
809274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggs	struct nouveau_subdev *subdev = nv_subdev(obj);
819274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggs	u32 data = ioread32_native(subdev->mmio + addr);
829274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggs	nv_spam(subdev, "nv_rd32 0x%06x 0x%08x\n", addr, data);
839274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggs	return data;
849274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggs}
859274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggs
869274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggsstatic inline void
879274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggsnv_wr08(void *obj, u32 addr, u8 data)
889274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggs{
899274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggs	struct nouveau_subdev *subdev = nv_subdev(obj);
909274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggs	nv_spam(subdev, "nv_wr08 0x%06x 0x%02x\n", addr, data);
919274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggs	iowrite8(data, subdev->mmio + addr);
929274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggs}
939274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggs
949274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggsstatic inline void
959274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggsnv_wr16(void *obj, u32 addr, u16 data)
969274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggs{
979274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggs	struct nouveau_subdev *subdev = nv_subdev(obj);
989274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggs	nv_spam(subdev, "nv_wr16 0x%06x 0x%04x\n", addr, data);
999274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggs	iowrite16_native(data, subdev->mmio + addr);
1009274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggs}
1019274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggs
1029274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggsstatic inline void
1039274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggsnv_wr32(void *obj, u32 addr, u32 data)
1049274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggs{
1059274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggs	struct nouveau_subdev *subdev = nv_subdev(obj);
1069274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggs	nv_spam(subdev, "nv_wr32 0x%06x 0x%08x\n", addr, data);
1079274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggs	iowrite32_native(data, subdev->mmio + addr);
1089274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggs}
1099274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggs
1109274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggsstatic inline u32
1119274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggsnv_mask(void *obj, u32 addr, u32 mask, u32 data)
1129274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggs{
1139274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggs	u32 temp = nv_rd32(obj, addr);
1149274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggs	nv_wr32(obj, addr, (temp & ~mask) | data);
1159274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggs	return temp;
1169274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggs}
1179274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggs
1189274f4a9ba7e70d1770e237fca16d52f27f0c728Ben Skeggs#endif
119