18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci *  cx18 driver PCI memory mapped IO access routines
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci *  Copyright (C) 2007  Hans Verkuil <hverkuil@xs4all.nl>
68c2ecf20Sopenharmony_ci *  Copyright (C) 2008  Andy Walls <awalls@md.metrocast.net>
78c2ecf20Sopenharmony_ci */
88c2ecf20Sopenharmony_ci
98c2ecf20Sopenharmony_ci#ifndef CX18_IO_H
108c2ecf20Sopenharmony_ci#define CX18_IO_H
118c2ecf20Sopenharmony_ci
128c2ecf20Sopenharmony_ci#include "cx18-driver.h"
138c2ecf20Sopenharmony_ci
148c2ecf20Sopenharmony_ci/*
158c2ecf20Sopenharmony_ci * Readback and retry of MMIO access for reliability:
168c2ecf20Sopenharmony_ci * The concept was suggested by Steve Toth <stoth@linuxtv.org>.
178c2ecf20Sopenharmony_ci * The implementation is the fault of Andy Walls <awalls@md.metrocast.net>.
188c2ecf20Sopenharmony_ci *
198c2ecf20Sopenharmony_ci * *write* functions are implied to retry the mmio unless suffixed with _noretry
208c2ecf20Sopenharmony_ci * *read* functions never retry the mmio (it never helps to do so)
218c2ecf20Sopenharmony_ci */
228c2ecf20Sopenharmony_ci
238c2ecf20Sopenharmony_ci/* Non byteswapping memory mapped IO */
248c2ecf20Sopenharmony_cistatic inline u32 cx18_raw_readl(struct cx18 *cx, const void __iomem *addr)
258c2ecf20Sopenharmony_ci{
268c2ecf20Sopenharmony_ci	return __raw_readl(addr);
278c2ecf20Sopenharmony_ci}
288c2ecf20Sopenharmony_ci
298c2ecf20Sopenharmony_cistatic inline
308c2ecf20Sopenharmony_civoid cx18_raw_writel_noretry(struct cx18 *cx, u32 val, void __iomem *addr)
318c2ecf20Sopenharmony_ci{
328c2ecf20Sopenharmony_ci	__raw_writel(val, addr);
338c2ecf20Sopenharmony_ci}
348c2ecf20Sopenharmony_ci
358c2ecf20Sopenharmony_cistatic inline void cx18_raw_writel(struct cx18 *cx, u32 val, void __iomem *addr)
368c2ecf20Sopenharmony_ci{
378c2ecf20Sopenharmony_ci	int i;
388c2ecf20Sopenharmony_ci	for (i = 0; i < CX18_MAX_MMIO_WR_RETRIES; i++) {
398c2ecf20Sopenharmony_ci		cx18_raw_writel_noretry(cx, val, addr);
408c2ecf20Sopenharmony_ci		if (val == cx18_raw_readl(cx, addr))
418c2ecf20Sopenharmony_ci			break;
428c2ecf20Sopenharmony_ci	}
438c2ecf20Sopenharmony_ci}
448c2ecf20Sopenharmony_ci
458c2ecf20Sopenharmony_ci/* Normal memory mapped IO */
468c2ecf20Sopenharmony_cistatic inline u32 cx18_readl(struct cx18 *cx, const void __iomem *addr)
478c2ecf20Sopenharmony_ci{
488c2ecf20Sopenharmony_ci	return readl(addr);
498c2ecf20Sopenharmony_ci}
508c2ecf20Sopenharmony_ci
518c2ecf20Sopenharmony_cistatic inline
528c2ecf20Sopenharmony_civoid cx18_writel_noretry(struct cx18 *cx, u32 val, void __iomem *addr)
538c2ecf20Sopenharmony_ci{
548c2ecf20Sopenharmony_ci	writel(val, addr);
558c2ecf20Sopenharmony_ci}
568c2ecf20Sopenharmony_ci
578c2ecf20Sopenharmony_cistatic inline void cx18_writel(struct cx18 *cx, u32 val, void __iomem *addr)
588c2ecf20Sopenharmony_ci{
598c2ecf20Sopenharmony_ci	int i;
608c2ecf20Sopenharmony_ci	for (i = 0; i < CX18_MAX_MMIO_WR_RETRIES; i++) {
618c2ecf20Sopenharmony_ci		cx18_writel_noretry(cx, val, addr);
628c2ecf20Sopenharmony_ci		if (val == cx18_readl(cx, addr))
638c2ecf20Sopenharmony_ci			break;
648c2ecf20Sopenharmony_ci	}
658c2ecf20Sopenharmony_ci}
668c2ecf20Sopenharmony_ci
678c2ecf20Sopenharmony_cistatic inline
688c2ecf20Sopenharmony_civoid cx18_writel_expect(struct cx18 *cx, u32 val, void __iomem *addr,
698c2ecf20Sopenharmony_ci			u32 eval, u32 mask)
708c2ecf20Sopenharmony_ci{
718c2ecf20Sopenharmony_ci	int i;
728c2ecf20Sopenharmony_ci	u32 r;
738c2ecf20Sopenharmony_ci	eval &= mask;
748c2ecf20Sopenharmony_ci	for (i = 0; i < CX18_MAX_MMIO_WR_RETRIES; i++) {
758c2ecf20Sopenharmony_ci		cx18_writel_noretry(cx, val, addr);
768c2ecf20Sopenharmony_ci		r = cx18_readl(cx, addr);
778c2ecf20Sopenharmony_ci		if (r == 0xffffffff && eval != 0xffffffff)
788c2ecf20Sopenharmony_ci			continue;
798c2ecf20Sopenharmony_ci		if (eval == (r & mask))
808c2ecf20Sopenharmony_ci			break;
818c2ecf20Sopenharmony_ci	}
828c2ecf20Sopenharmony_ci}
838c2ecf20Sopenharmony_ci
848c2ecf20Sopenharmony_cistatic inline u16 cx18_readw(struct cx18 *cx, const void __iomem *addr)
858c2ecf20Sopenharmony_ci{
868c2ecf20Sopenharmony_ci	return readw(addr);
878c2ecf20Sopenharmony_ci}
888c2ecf20Sopenharmony_ci
898c2ecf20Sopenharmony_cistatic inline
908c2ecf20Sopenharmony_civoid cx18_writew_noretry(struct cx18 *cx, u16 val, void __iomem *addr)
918c2ecf20Sopenharmony_ci{
928c2ecf20Sopenharmony_ci	writew(val, addr);
938c2ecf20Sopenharmony_ci}
948c2ecf20Sopenharmony_ci
958c2ecf20Sopenharmony_cistatic inline void cx18_writew(struct cx18 *cx, u16 val, void __iomem *addr)
968c2ecf20Sopenharmony_ci{
978c2ecf20Sopenharmony_ci	int i;
988c2ecf20Sopenharmony_ci	for (i = 0; i < CX18_MAX_MMIO_WR_RETRIES; i++) {
998c2ecf20Sopenharmony_ci		cx18_writew_noretry(cx, val, addr);
1008c2ecf20Sopenharmony_ci		if (val == cx18_readw(cx, addr))
1018c2ecf20Sopenharmony_ci			break;
1028c2ecf20Sopenharmony_ci	}
1038c2ecf20Sopenharmony_ci}
1048c2ecf20Sopenharmony_ci
1058c2ecf20Sopenharmony_cistatic inline u8 cx18_readb(struct cx18 *cx, const void __iomem *addr)
1068c2ecf20Sopenharmony_ci{
1078c2ecf20Sopenharmony_ci	return readb(addr);
1088c2ecf20Sopenharmony_ci}
1098c2ecf20Sopenharmony_ci
1108c2ecf20Sopenharmony_cistatic inline
1118c2ecf20Sopenharmony_civoid cx18_writeb_noretry(struct cx18 *cx, u8 val, void __iomem *addr)
1128c2ecf20Sopenharmony_ci{
1138c2ecf20Sopenharmony_ci	writeb(val, addr);
1148c2ecf20Sopenharmony_ci}
1158c2ecf20Sopenharmony_ci
1168c2ecf20Sopenharmony_cistatic inline void cx18_writeb(struct cx18 *cx, u8 val, void __iomem *addr)
1178c2ecf20Sopenharmony_ci{
1188c2ecf20Sopenharmony_ci	int i;
1198c2ecf20Sopenharmony_ci	for (i = 0; i < CX18_MAX_MMIO_WR_RETRIES; i++) {
1208c2ecf20Sopenharmony_ci		cx18_writeb_noretry(cx, val, addr);
1218c2ecf20Sopenharmony_ci		if (val == cx18_readb(cx, addr))
1228c2ecf20Sopenharmony_ci			break;
1238c2ecf20Sopenharmony_ci	}
1248c2ecf20Sopenharmony_ci}
1258c2ecf20Sopenharmony_ci
1268c2ecf20Sopenharmony_cistatic inline
1278c2ecf20Sopenharmony_civoid cx18_memcpy_fromio(struct cx18 *cx, void *to,
1288c2ecf20Sopenharmony_ci			const void __iomem *from, unsigned int len)
1298c2ecf20Sopenharmony_ci{
1308c2ecf20Sopenharmony_ci	memcpy_fromio(to, from, len);
1318c2ecf20Sopenharmony_ci}
1328c2ecf20Sopenharmony_ci
1338c2ecf20Sopenharmony_civoid cx18_memset_io(struct cx18 *cx, void __iomem *addr, int val, size_t count);
1348c2ecf20Sopenharmony_ci
1358c2ecf20Sopenharmony_ci
1368c2ecf20Sopenharmony_ci/* Access "register" region of CX23418 memory mapped I/O */
1378c2ecf20Sopenharmony_cistatic inline void cx18_write_reg_noretry(struct cx18 *cx, u32 val, u32 reg)
1388c2ecf20Sopenharmony_ci{
1398c2ecf20Sopenharmony_ci	cx18_writel_noretry(cx, val, cx->reg_mem + reg);
1408c2ecf20Sopenharmony_ci}
1418c2ecf20Sopenharmony_ci
1428c2ecf20Sopenharmony_cistatic inline void cx18_write_reg(struct cx18 *cx, u32 val, u32 reg)
1438c2ecf20Sopenharmony_ci{
1448c2ecf20Sopenharmony_ci	cx18_writel(cx, val, cx->reg_mem + reg);
1458c2ecf20Sopenharmony_ci}
1468c2ecf20Sopenharmony_ci
1478c2ecf20Sopenharmony_cistatic inline void cx18_write_reg_expect(struct cx18 *cx, u32 val, u32 reg,
1488c2ecf20Sopenharmony_ci					 u32 eval, u32 mask)
1498c2ecf20Sopenharmony_ci{
1508c2ecf20Sopenharmony_ci	cx18_writel_expect(cx, val, cx->reg_mem + reg, eval, mask);
1518c2ecf20Sopenharmony_ci}
1528c2ecf20Sopenharmony_ci
1538c2ecf20Sopenharmony_cistatic inline u32 cx18_read_reg(struct cx18 *cx, u32 reg)
1548c2ecf20Sopenharmony_ci{
1558c2ecf20Sopenharmony_ci	return cx18_readl(cx, cx->reg_mem + reg);
1568c2ecf20Sopenharmony_ci}
1578c2ecf20Sopenharmony_ci
1588c2ecf20Sopenharmony_ci
1598c2ecf20Sopenharmony_ci/* Access "encoder memory" region of CX23418 memory mapped I/O */
1608c2ecf20Sopenharmony_cistatic inline void cx18_write_enc(struct cx18 *cx, u32 val, u32 addr)
1618c2ecf20Sopenharmony_ci{
1628c2ecf20Sopenharmony_ci	cx18_writel(cx, val, cx->enc_mem + addr);
1638c2ecf20Sopenharmony_ci}
1648c2ecf20Sopenharmony_ci
1658c2ecf20Sopenharmony_cistatic inline u32 cx18_read_enc(struct cx18 *cx, u32 addr)
1668c2ecf20Sopenharmony_ci{
1678c2ecf20Sopenharmony_ci	return cx18_readl(cx, cx->enc_mem + addr);
1688c2ecf20Sopenharmony_ci}
1698c2ecf20Sopenharmony_ci
1708c2ecf20Sopenharmony_civoid cx18_sw1_irq_enable(struct cx18 *cx, u32 val);
1718c2ecf20Sopenharmony_civoid cx18_sw1_irq_disable(struct cx18 *cx, u32 val);
1728c2ecf20Sopenharmony_civoid cx18_sw2_irq_enable(struct cx18 *cx, u32 val);
1738c2ecf20Sopenharmony_civoid cx18_sw2_irq_disable(struct cx18 *cx, u32 val);
1748c2ecf20Sopenharmony_civoid cx18_sw2_irq_disable_cpu(struct cx18 *cx, u32 val);
1758c2ecf20Sopenharmony_civoid cx18_setup_page(struct cx18 *cx, u32 addr);
1768c2ecf20Sopenharmony_ci
1778c2ecf20Sopenharmony_ci#endif /* CX18_IO_H */
178