1 /* SPDX-License-Identifier: GPL-2.0-or-later */ 2 /* 3 * cx18 driver PCI memory mapped IO access routines 4 * 5 * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> 6 * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net> 7 */ 8 9 #ifndef CX18_IO_H 10 #define CX18_IO_H 11 12 #include "cx18-driver.h" 13 14 /* 15 * Readback and retry of MMIO access for reliability: 16 * The concept was suggested by Steve Toth <stoth@linuxtv.org>. 17 * The implementation is the fault of Andy Walls <awalls@md.metrocast.net>. 18 * 19 * *write* functions are implied to retry the mmio unless suffixed with _noretry 20 * *read* functions never retry the mmio (it never helps to do so) 21 */ 22 23 /* Non byteswapping memory mapped IO */ 24 static inline u32 cx18_raw_readl(struct cx18 *cx, const void __iomem *addr) 25 { 26 return __raw_readl(addr); 27 } 28 29 static inline 30 void cx18_raw_writel_noretry(struct cx18 *cx, u32 val, void __iomem *addr) 31 { 32 __raw_writel(val, addr); 33 } 34 35 static inline void cx18_raw_writel(struct cx18 *cx, u32 val, void __iomem *addr) 36 { 37 int i; 38 for (i = 0; i < CX18_MAX_MMIO_WR_RETRIES; i++) { 39 cx18_raw_writel_noretry(cx, val, addr); 40 if (val == cx18_raw_readl(cx, addr)) 41 break; 42 } 43 } 44 45 /* Normal memory mapped IO */ 46 static inline u32 cx18_readl(struct cx18 *cx, const void __iomem *addr) 47 { 48 return readl(addr); 49 } 50 51 static inline 52 void cx18_writel_noretry(struct cx18 *cx, u32 val, void __iomem *addr) 53 { 54 writel(val, addr); 55 } 56 57 static inline void cx18_writel(struct cx18 *cx, u32 val, void __iomem *addr) 58 { 59 int i; 60 for (i = 0; i < CX18_MAX_MMIO_WR_RETRIES; i++) { 61 cx18_writel_noretry(cx, val, addr); 62 if (val == cx18_readl(cx, addr)) 63 break; 64 } 65 } 66 67 static inline 68 void cx18_writel_expect(struct cx18 *cx, u32 val, void __iomem *addr, 69 u32 eval, u32 mask) 70 { 71 int i; 72 u32 r; 73 eval &= mask; 74 for (i = 0; i < CX18_MAX_MMIO_WR_RETRIES; i++) { 75 cx18_writel_noretry(cx, val, addr); 76 r = cx18_readl(cx, addr); 77 if (r == 0xffffffff && eval != 0xffffffff) 78 continue; 79 if (eval == (r & mask)) 80 break; 81 } 82 } 83 84 static inline u16 cx18_readw(struct cx18 *cx, const void __iomem *addr) 85 { 86 return readw(addr); 87 } 88 89 static inline 90 void cx18_writew_noretry(struct cx18 *cx, u16 val, void __iomem *addr) 91 { 92 writew(val, addr); 93 } 94 95 static inline void cx18_writew(struct cx18 *cx, u16 val, void __iomem *addr) 96 { 97 int i; 98 for (i = 0; i < CX18_MAX_MMIO_WR_RETRIES; i++) { 99 cx18_writew_noretry(cx, val, addr); 100 if (val == cx18_readw(cx, addr)) 101 break; 102 } 103 } 104 105 static inline u8 cx18_readb(struct cx18 *cx, const void __iomem *addr) 106 { 107 return readb(addr); 108 } 109 110 static inline 111 void cx18_writeb_noretry(struct cx18 *cx, u8 val, void __iomem *addr) 112 { 113 writeb(val, addr); 114 } 115 116 static inline void cx18_writeb(struct cx18 *cx, u8 val, void __iomem *addr) 117 { 118 int i; 119 for (i = 0; i < CX18_MAX_MMIO_WR_RETRIES; i++) { 120 cx18_writeb_noretry(cx, val, addr); 121 if (val == cx18_readb(cx, addr)) 122 break; 123 } 124 } 125 126 static inline 127 void cx18_memcpy_fromio(struct cx18 *cx, void *to, 128 const void __iomem *from, unsigned int len) 129 { 130 memcpy_fromio(to, from, len); 131 } 132 133 void cx18_memset_io(struct cx18 *cx, void __iomem *addr, int val, size_t count); 134 135 136 /* Access "register" region of CX23418 memory mapped I/O */ 137 static inline void cx18_write_reg_noretry(struct cx18 *cx, u32 val, u32 reg) 138 { 139 cx18_writel_noretry(cx, val, cx->reg_mem + reg); 140 } 141 142 static inline void cx18_write_reg(struct cx18 *cx, u32 val, u32 reg) 143 { 144 cx18_writel(cx, val, cx->reg_mem + reg); 145 } 146 147 static inline void cx18_write_reg_expect(struct cx18 *cx, u32 val, u32 reg, 148 u32 eval, u32 mask) 149 { 150 cx18_writel_expect(cx, val, cx->reg_mem + reg, eval, mask); 151 } 152 153 static inline u32 cx18_read_reg(struct cx18 *cx, u32 reg) 154 { 155 return cx18_readl(cx, cx->reg_mem + reg); 156 } 157 158 159 /* Access "encoder memory" region of CX23418 memory mapped I/O */ 160 static inline void cx18_write_enc(struct cx18 *cx, u32 val, u32 addr) 161 { 162 cx18_writel(cx, val, cx->enc_mem + addr); 163 } 164 165 static inline u32 cx18_read_enc(struct cx18 *cx, u32 addr) 166 { 167 return cx18_readl(cx, cx->enc_mem + addr); 168 } 169 170 void cx18_sw1_irq_enable(struct cx18 *cx, u32 val); 171 void cx18_sw1_irq_disable(struct cx18 *cx, u32 val); 172 void cx18_sw2_irq_enable(struct cx18 *cx, u32 val); 173 void cx18_sw2_irq_disable(struct cx18 *cx, u32 val); 174 void cx18_sw2_irq_disable_cpu(struct cx18 *cx, u32 val); 175 void cx18_setup_page(struct cx18 *cx, u32 addr); 176 177 #endif /* CX18_IO_H */ 178