162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci *  cx18 driver PCI memory mapped IO access routines
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci *  Copyright (C) 2007  Hans Verkuil <hverkuil@xs4all.nl>
662306a36Sopenharmony_ci *  Copyright (C) 2008  Andy Walls <awalls@md.metrocast.net>
762306a36Sopenharmony_ci */
862306a36Sopenharmony_ci
962306a36Sopenharmony_ci#ifndef CX18_IO_H
1062306a36Sopenharmony_ci#define CX18_IO_H
1162306a36Sopenharmony_ci
1262306a36Sopenharmony_ci#include "cx18-driver.h"
1362306a36Sopenharmony_ci
1462306a36Sopenharmony_ci/*
1562306a36Sopenharmony_ci * Readback and retry of MMIO access for reliability:
1662306a36Sopenharmony_ci * The concept was suggested by Steve Toth <stoth@linuxtv.org>.
1762306a36Sopenharmony_ci * The implementation is the fault of Andy Walls <awalls@md.metrocast.net>.
1862306a36Sopenharmony_ci *
1962306a36Sopenharmony_ci * *write* functions are implied to retry the mmio unless suffixed with _noretry
2062306a36Sopenharmony_ci * *read* functions never retry the mmio (it never helps to do so)
2162306a36Sopenharmony_ci */
2262306a36Sopenharmony_ci
2362306a36Sopenharmony_ci/* Non byteswapping memory mapped IO */
2462306a36Sopenharmony_cistatic inline u32 cx18_raw_readl(struct cx18 *cx, const void __iomem *addr)
2562306a36Sopenharmony_ci{
2662306a36Sopenharmony_ci	return __raw_readl(addr);
2762306a36Sopenharmony_ci}
2862306a36Sopenharmony_ci
2962306a36Sopenharmony_cistatic inline
3062306a36Sopenharmony_civoid cx18_raw_writel_noretry(struct cx18 *cx, u32 val, void __iomem *addr)
3162306a36Sopenharmony_ci{
3262306a36Sopenharmony_ci	__raw_writel(val, addr);
3362306a36Sopenharmony_ci}
3462306a36Sopenharmony_ci
3562306a36Sopenharmony_cistatic inline void cx18_raw_writel(struct cx18 *cx, u32 val, void __iomem *addr)
3662306a36Sopenharmony_ci{
3762306a36Sopenharmony_ci	int i;
3862306a36Sopenharmony_ci	for (i = 0; i < CX18_MAX_MMIO_WR_RETRIES; i++) {
3962306a36Sopenharmony_ci		cx18_raw_writel_noretry(cx, val, addr);
4062306a36Sopenharmony_ci		if (val == cx18_raw_readl(cx, addr))
4162306a36Sopenharmony_ci			break;
4262306a36Sopenharmony_ci	}
4362306a36Sopenharmony_ci}
4462306a36Sopenharmony_ci
4562306a36Sopenharmony_ci/* Normal memory mapped IO */
4662306a36Sopenharmony_cistatic inline u32 cx18_readl(struct cx18 *cx, const void __iomem *addr)
4762306a36Sopenharmony_ci{
4862306a36Sopenharmony_ci	return readl(addr);
4962306a36Sopenharmony_ci}
5062306a36Sopenharmony_ci
5162306a36Sopenharmony_cistatic inline
5262306a36Sopenharmony_civoid cx18_writel_noretry(struct cx18 *cx, u32 val, void __iomem *addr)
5362306a36Sopenharmony_ci{
5462306a36Sopenharmony_ci	writel(val, addr);
5562306a36Sopenharmony_ci}
5662306a36Sopenharmony_ci
5762306a36Sopenharmony_cistatic inline void cx18_writel(struct cx18 *cx, u32 val, void __iomem *addr)
5862306a36Sopenharmony_ci{
5962306a36Sopenharmony_ci	int i;
6062306a36Sopenharmony_ci	for (i = 0; i < CX18_MAX_MMIO_WR_RETRIES; i++) {
6162306a36Sopenharmony_ci		cx18_writel_noretry(cx, val, addr);
6262306a36Sopenharmony_ci		if (val == cx18_readl(cx, addr))
6362306a36Sopenharmony_ci			break;
6462306a36Sopenharmony_ci	}
6562306a36Sopenharmony_ci}
6662306a36Sopenharmony_ci
6762306a36Sopenharmony_cistatic inline
6862306a36Sopenharmony_civoid cx18_writel_expect(struct cx18 *cx, u32 val, void __iomem *addr,
6962306a36Sopenharmony_ci			u32 eval, u32 mask)
7062306a36Sopenharmony_ci{
7162306a36Sopenharmony_ci	int i;
7262306a36Sopenharmony_ci	u32 r;
7362306a36Sopenharmony_ci	eval &= mask;
7462306a36Sopenharmony_ci	for (i = 0; i < CX18_MAX_MMIO_WR_RETRIES; i++) {
7562306a36Sopenharmony_ci		cx18_writel_noretry(cx, val, addr);
7662306a36Sopenharmony_ci		r = cx18_readl(cx, addr);
7762306a36Sopenharmony_ci		if (r == 0xffffffff && eval != 0xffffffff)
7862306a36Sopenharmony_ci			continue;
7962306a36Sopenharmony_ci		if (eval == (r & mask))
8062306a36Sopenharmony_ci			break;
8162306a36Sopenharmony_ci	}
8262306a36Sopenharmony_ci}
8362306a36Sopenharmony_ci
8462306a36Sopenharmony_cistatic inline u16 cx18_readw(struct cx18 *cx, const void __iomem *addr)
8562306a36Sopenharmony_ci{
8662306a36Sopenharmony_ci	return readw(addr);
8762306a36Sopenharmony_ci}
8862306a36Sopenharmony_ci
8962306a36Sopenharmony_cistatic inline
9062306a36Sopenharmony_civoid cx18_writew_noretry(struct cx18 *cx, u16 val, void __iomem *addr)
9162306a36Sopenharmony_ci{
9262306a36Sopenharmony_ci	writew(val, addr);
9362306a36Sopenharmony_ci}
9462306a36Sopenharmony_ci
9562306a36Sopenharmony_cistatic inline void cx18_writew(struct cx18 *cx, u16 val, void __iomem *addr)
9662306a36Sopenharmony_ci{
9762306a36Sopenharmony_ci	int i;
9862306a36Sopenharmony_ci	for (i = 0; i < CX18_MAX_MMIO_WR_RETRIES; i++) {
9962306a36Sopenharmony_ci		cx18_writew_noretry(cx, val, addr);
10062306a36Sopenharmony_ci		if (val == cx18_readw(cx, addr))
10162306a36Sopenharmony_ci			break;
10262306a36Sopenharmony_ci	}
10362306a36Sopenharmony_ci}
10462306a36Sopenharmony_ci
10562306a36Sopenharmony_cistatic inline u8 cx18_readb(struct cx18 *cx, const void __iomem *addr)
10662306a36Sopenharmony_ci{
10762306a36Sopenharmony_ci	return readb(addr);
10862306a36Sopenharmony_ci}
10962306a36Sopenharmony_ci
11062306a36Sopenharmony_cistatic inline
11162306a36Sopenharmony_civoid cx18_writeb_noretry(struct cx18 *cx, u8 val, void __iomem *addr)
11262306a36Sopenharmony_ci{
11362306a36Sopenharmony_ci	writeb(val, addr);
11462306a36Sopenharmony_ci}
11562306a36Sopenharmony_ci
11662306a36Sopenharmony_cistatic inline void cx18_writeb(struct cx18 *cx, u8 val, void __iomem *addr)
11762306a36Sopenharmony_ci{
11862306a36Sopenharmony_ci	int i;
11962306a36Sopenharmony_ci	for (i = 0; i < CX18_MAX_MMIO_WR_RETRIES; i++) {
12062306a36Sopenharmony_ci		cx18_writeb_noretry(cx, val, addr);
12162306a36Sopenharmony_ci		if (val == cx18_readb(cx, addr))
12262306a36Sopenharmony_ci			break;
12362306a36Sopenharmony_ci	}
12462306a36Sopenharmony_ci}
12562306a36Sopenharmony_ci
12662306a36Sopenharmony_cistatic inline
12762306a36Sopenharmony_civoid cx18_memcpy_fromio(struct cx18 *cx, void *to,
12862306a36Sopenharmony_ci			const void __iomem *from, unsigned int len)
12962306a36Sopenharmony_ci{
13062306a36Sopenharmony_ci	memcpy_fromio(to, from, len);
13162306a36Sopenharmony_ci}
13262306a36Sopenharmony_ci
13362306a36Sopenharmony_civoid cx18_memset_io(struct cx18 *cx, void __iomem *addr, int val, size_t count);
13462306a36Sopenharmony_ci
13562306a36Sopenharmony_ci
13662306a36Sopenharmony_ci/* Access "register" region of CX23418 memory mapped I/O */
13762306a36Sopenharmony_cistatic inline void cx18_write_reg_noretry(struct cx18 *cx, u32 val, u32 reg)
13862306a36Sopenharmony_ci{
13962306a36Sopenharmony_ci	cx18_writel_noretry(cx, val, cx->reg_mem + reg);
14062306a36Sopenharmony_ci}
14162306a36Sopenharmony_ci
14262306a36Sopenharmony_cistatic inline void cx18_write_reg(struct cx18 *cx, u32 val, u32 reg)
14362306a36Sopenharmony_ci{
14462306a36Sopenharmony_ci	cx18_writel(cx, val, cx->reg_mem + reg);
14562306a36Sopenharmony_ci}
14662306a36Sopenharmony_ci
14762306a36Sopenharmony_cistatic inline void cx18_write_reg_expect(struct cx18 *cx, u32 val, u32 reg,
14862306a36Sopenharmony_ci					 u32 eval, u32 mask)
14962306a36Sopenharmony_ci{
15062306a36Sopenharmony_ci	cx18_writel_expect(cx, val, cx->reg_mem + reg, eval, mask);
15162306a36Sopenharmony_ci}
15262306a36Sopenharmony_ci
15362306a36Sopenharmony_cistatic inline u32 cx18_read_reg(struct cx18 *cx, u32 reg)
15462306a36Sopenharmony_ci{
15562306a36Sopenharmony_ci	return cx18_readl(cx, cx->reg_mem + reg);
15662306a36Sopenharmony_ci}
15762306a36Sopenharmony_ci
15862306a36Sopenharmony_ci
15962306a36Sopenharmony_ci/* Access "encoder memory" region of CX23418 memory mapped I/O */
16062306a36Sopenharmony_cistatic inline void cx18_write_enc(struct cx18 *cx, u32 val, u32 addr)
16162306a36Sopenharmony_ci{
16262306a36Sopenharmony_ci	cx18_writel(cx, val, cx->enc_mem + addr);
16362306a36Sopenharmony_ci}
16462306a36Sopenharmony_ci
16562306a36Sopenharmony_cistatic inline u32 cx18_read_enc(struct cx18 *cx, u32 addr)
16662306a36Sopenharmony_ci{
16762306a36Sopenharmony_ci	return cx18_readl(cx, cx->enc_mem + addr);
16862306a36Sopenharmony_ci}
16962306a36Sopenharmony_ci
17062306a36Sopenharmony_civoid cx18_sw1_irq_enable(struct cx18 *cx, u32 val);
17162306a36Sopenharmony_civoid cx18_sw1_irq_disable(struct cx18 *cx, u32 val);
17262306a36Sopenharmony_civoid cx18_sw2_irq_enable(struct cx18 *cx, u32 val);
17362306a36Sopenharmony_civoid cx18_sw2_irq_disable(struct cx18 *cx, u32 val);
17462306a36Sopenharmony_civoid cx18_sw2_irq_disable_cpu(struct cx18 *cx, u32 val);
17562306a36Sopenharmony_civoid cx18_setup_page(struct cx18 *cx, u32 addr);
17662306a36Sopenharmony_ci
17762306a36Sopenharmony_ci#endif /* CX18_IO_H */
178