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