xref: /openbsd-src/sys/dev/pci/drm/include/linux/iosys-map.h (revision be5961cd091db7a69bfc4ccd00bc2a01c2f19097)
11bb76ff1Sjsg /* Public domain. */
21bb76ff1Sjsg 
31bb76ff1Sjsg #ifndef _LINUX_IOSYS_MAP_H
41bb76ff1Sjsg #define _LINUX_IOSYS_MAP_H
51bb76ff1Sjsg 
61bb76ff1Sjsg #include <linux/io.h>
71bb76ff1Sjsg #include <linux/string.h>
81bb76ff1Sjsg 
91bb76ff1Sjsg struct iosys_map {
101bb76ff1Sjsg 	union {
111bb76ff1Sjsg 		void *vaddr_iomem;
121bb76ff1Sjsg 		void *vaddr;
131bb76ff1Sjsg 	};
141bb76ff1Sjsg 	bool is_iomem;
151bb76ff1Sjsg 	bus_space_handle_t bsh;
161bb76ff1Sjsg 	bus_size_t size;
171bb76ff1Sjsg };
181bb76ff1Sjsg 
191bb76ff1Sjsg static inline void
iosys_map_incr(struct iosys_map * ism,size_t n)201bb76ff1Sjsg iosys_map_incr(struct iosys_map *ism, size_t n)
211bb76ff1Sjsg {
221bb76ff1Sjsg 	if (ism->is_iomem)
231bb76ff1Sjsg 		ism->vaddr_iomem += n;
241bb76ff1Sjsg 	else
251bb76ff1Sjsg 		ism->vaddr += n;
261bb76ff1Sjsg }
271bb76ff1Sjsg 
281bb76ff1Sjsg static inline void
iosys_map_memcpy_to(struct iosys_map * ism,size_t off,const void * src,size_t len)291bb76ff1Sjsg iosys_map_memcpy_to(struct iosys_map *ism, size_t off, const void *src,
301bb76ff1Sjsg     size_t len)
311bb76ff1Sjsg {
321bb76ff1Sjsg 	if (ism->is_iomem)
331bb76ff1Sjsg 		memcpy_toio(ism->vaddr_iomem + off, src, len);
341bb76ff1Sjsg 	else
351bb76ff1Sjsg 		memcpy(ism->vaddr + off, src, len);
361bb76ff1Sjsg }
371bb76ff1Sjsg 
38*be5961cdSjsg static inline void
iosys_map_memset(struct iosys_map * ism,size_t off,int c,size_t len)39*be5961cdSjsg iosys_map_memset(struct iosys_map *ism, size_t off, int c, size_t len)
40*be5961cdSjsg {
41*be5961cdSjsg 	if (ism->is_iomem)
42*be5961cdSjsg 		memset_io(ism->vaddr_iomem + off, c, len);
43*be5961cdSjsg 	else
44*be5961cdSjsg 		memset(ism->vaddr + off, c, len);
45*be5961cdSjsg }
46*be5961cdSjsg 
471bb76ff1Sjsg static inline bool
iosys_map_is_null(const struct iosys_map * ism)481bb76ff1Sjsg iosys_map_is_null(const struct iosys_map *ism)
491bb76ff1Sjsg {
501bb76ff1Sjsg 	if (ism->is_iomem)
511bb76ff1Sjsg 		return (ism->vaddr_iomem == NULL);
521bb76ff1Sjsg 	else
531bb76ff1Sjsg 		return (ism->vaddr == NULL);
541bb76ff1Sjsg }
551bb76ff1Sjsg 
561bb76ff1Sjsg static inline bool
iosys_map_is_set(const struct iosys_map * ism)571bb76ff1Sjsg iosys_map_is_set(const struct iosys_map *ism)
581bb76ff1Sjsg {
591bb76ff1Sjsg 	if (ism->is_iomem)
601bb76ff1Sjsg 		return (ism->vaddr_iomem != NULL);
611bb76ff1Sjsg 	else
621bb76ff1Sjsg 		return (ism->vaddr != NULL);
631bb76ff1Sjsg }
641bb76ff1Sjsg 
651bb76ff1Sjsg static inline void
iosys_map_clear(struct iosys_map * ism)661bb76ff1Sjsg iosys_map_clear(struct iosys_map *ism)
671bb76ff1Sjsg {
681bb76ff1Sjsg 	if (ism->is_iomem) {
691bb76ff1Sjsg 		ism->vaddr_iomem = NULL;
701bb76ff1Sjsg 		ism->is_iomem = false;
711bb76ff1Sjsg 	} else {
721bb76ff1Sjsg 		ism->vaddr = NULL;
731bb76ff1Sjsg 	}
741bb76ff1Sjsg }
751bb76ff1Sjsg 
761bb76ff1Sjsg static inline void
iosys_map_set_vaddr_iomem(struct iosys_map * ism,void * addr)771bb76ff1Sjsg iosys_map_set_vaddr_iomem(struct iosys_map *ism, void *addr)
781bb76ff1Sjsg {
791bb76ff1Sjsg 	ism->vaddr_iomem = addr;
801bb76ff1Sjsg 	ism->is_iomem = true;
811bb76ff1Sjsg }
821bb76ff1Sjsg 
831bb76ff1Sjsg static inline void
iosys_map_set_vaddr(struct iosys_map * ism,void * addr)841bb76ff1Sjsg iosys_map_set_vaddr(struct iosys_map *ism, void *addr)
851bb76ff1Sjsg {
861bb76ff1Sjsg 	ism->vaddr = addr;
871bb76ff1Sjsg 	ism->is_iomem = false;
881bb76ff1Sjsg }
891bb76ff1Sjsg 
90*be5961cdSjsg static inline struct iosys_map
IOSYS_MAP_INIT_OFFSET(struct iosys_map * ism,size_t off)91*be5961cdSjsg IOSYS_MAP_INIT_OFFSET(struct iosys_map *ism, size_t off)
92*be5961cdSjsg {
93*be5961cdSjsg 	struct iosys_map nism = *ism;
94*be5961cdSjsg 	iosys_map_incr(&nism, off);
95*be5961cdSjsg 	return nism;
96*be5961cdSjsg }
97*be5961cdSjsg 
98*be5961cdSjsg #if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112
99*be5961cdSjsg 
100*be5961cdSjsg #define iosys_map_rd(_ism, _o, _t) ({					\
101*be5961cdSjsg 	_t v;								\
102*be5961cdSjsg 	if ((_ism)->is_iomem) {						\
103*be5961cdSjsg 		void *addr = (_ism)->vaddr_iomem + (_o);		\
104*be5961cdSjsg 		v = _Generic(v,						\
105*be5961cdSjsg 		    uint8_t : ioread8(addr),				\
106*be5961cdSjsg 		    uint16_t: ioread16(addr),				\
107*be5961cdSjsg 		    uint32_t: ioread32(addr),				\
108*be5961cdSjsg 		    uint64_t: ioread64(addr));				\
109*be5961cdSjsg 	} else								\
110*be5961cdSjsg 		v = READ_ONCE(*(_t *)((_ism)->vaddr + (_o)));		\
111*be5961cdSjsg 	v;								\
112*be5961cdSjsg })
113*be5961cdSjsg 
114*be5961cdSjsg #define iosys_map_wr(_ism, _o, _t, _v) ({				\
115*be5961cdSjsg 	_t v = (_v);							\
116*be5961cdSjsg 	if ((_ism)->is_iomem) {						\
117*be5961cdSjsg 		void *addr = (_ism)->vaddr_iomem + (_o);		\
118*be5961cdSjsg 		_Generic(v,						\
119*be5961cdSjsg 		    uint8_t : iowrite8(v, addr),			\
120*be5961cdSjsg 		    uint16_t: iowrite16(v, addr),			\
121*be5961cdSjsg 		    uint32_t: iowrite32(v, addr),			\
122*be5961cdSjsg 		    uint64_t: iowrite64(v, addr));			\
123*be5961cdSjsg 	} else								\
124*be5961cdSjsg 		WRITE_ONCE(*(_t *)((_ism)->vaddr + (_o)), v);		\
125*be5961cdSjsg })
126*be5961cdSjsg 
127*be5961cdSjsg #define iosys_map_rd_field(_ism, _o, _t, _f) ({				\
128*be5961cdSjsg 	_t *t;								\
129*be5961cdSjsg 	iosys_map_rd(_ism, _o + offsetof(_t, _f), __typeof(t->_f));	\
130*be5961cdSjsg })
131*be5961cdSjsg 
132*be5961cdSjsg #define iosys_map_wr_field(_ism, _o, _t, _f, _v) ({			\
133*be5961cdSjsg         _t *t;								\
134*be5961cdSjsg         iosys_map_wr(_ism, _o + offsetof(_t, _f), __typeof(t->_f), _v); \
135*be5961cdSjsg })
136*be5961cdSjsg 
137*be5961cdSjsg #endif /* C11 */
138*be5961cdSjsg 
1391bb76ff1Sjsg #endif
140