aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/cx18/cx18-io.h
diff options
context:
space:
mode:
authorAndy Walls <awalls@radix.net>2008-08-31 23:40:41 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2008-10-12 07:36:58 -0400
commitc641d09c60bfa36c7cf70444f24265090e51f5ce (patch)
tree2f3a9cc7d86aed3e0d5f1c7631a7354bb490fb29 /drivers/media/video/cx18/cx18-io.h
parentb1526421eac9a912b2cda7e147f1da2aa31be278 (diff)
V4L/DVB (8914): cx18: Throttle mmio to/from the CX23418 so boards work in older systems
cx18: Throttle mmio to/from the CX23418 so boards work in older systems. The CX23418 couldn't reliably handle mmio at the rate at which the cx18 driver was attempting to access the chip. The PCI bridge arrangements and settings on modern motherboards still allowed the CX23418 to work OK, but it didn't work well on many older motherboards: mysterious I2C errors, firmware loading errors, etc. This patch adds a throttle to *all* mmio access to the CX23418. It defaults to a delay of 31 ns, but is adjustable by the mmio_ndelay module parm. My HVR-1600 and Raptor PAL/SECAM card now function for analog capture on a motherboard with an Intel 82810E Northbridge and 82801AA Southbridge. Signed-off-by: Andy Walls <awalls@radix.net> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/cx18/cx18-io.h')
-rw-r--r--drivers/media/video/cx18/cx18-io.h115
1 files changed, 93 insertions, 22 deletions
diff --git a/drivers/media/video/cx18/cx18-io.h b/drivers/media/video/cx18/cx18-io.h
index 7c08c0add490..7ab7be2531ca 100644
--- a/drivers/media/video/cx18/cx18-io.h
+++ b/drivers/media/video/cx18/cx18-io.h
@@ -25,38 +25,109 @@
25 25
26#include "cx18-driver.h" 26#include "cx18-driver.h"
27 27
28/* This is a PCI post thing, where if the pci register is not read, then 28static inline void cx18_io_delay(struct cx18 *cx)
29 the write doesn't always take effect right away. By reading back the 29{
30 register any pending PCI writes will be performed (in order), and so 30 if (cx->options.mmio_ndelay)
31 you can be sure that the writes are guaranteed to be done. 31 ndelay(cx->options.mmio_ndelay);
32}
32 33
33 Rarely needed, only in some timing sensitive cases. 34/* Non byteswapping memory mapped IO */
34 Apparently if this is not done some motherboards seem 35static inline void cx18_raw_writel(struct cx18 *cx, u32 val, void __iomem *addr)
35 to kill the firmware and get into the broken state until computer is 36{
36 rebooted. */ 37 __raw_writel(val, addr);
37u32 cx18_write_sync(struct cx18 *cx, u32 val, void __iomem *addr); 38 cx18_io_delay(cx);
39}
38 40
39void cx18_writel(struct cx18 *cx, u32 val, void __iomem *addr); 41static inline u32 cx18_raw_readl(struct cx18 *cx, const void __iomem *addr)
40u32 cx18_readl(struct cx18 *cx, const void __iomem *addr); 42{
43 u32 ret = __raw_readl(addr);
44 cx18_io_delay(cx);
45 return ret;
46}
41 47
42/* No endiannes conversion calls */ 48static inline u16 cx18_raw_readw(struct cx18 *cx, const void __iomem *addr)
43void cx18_raw_writel(struct cx18 *cx, u32 val, void __iomem *addr); 49{
44u32 cx18_raw_readl(struct cx18 *cx, const void __iomem *addr); 50 u16 ret = __raw_readw(addr);
51 cx18_io_delay(cx);
52 return ret;
53}
45 54
46/* Access "register" region of CX23418 memory mapped I/O */ 55/* Normal memory mapped IO */
47u32 cx18_read_reg(struct cx18 *cx, u32 reg); 56static inline void cx18_writel(struct cx18 *cx, u32 val, void __iomem *addr)
48void cx18_write_reg(struct cx18 *cx, u32 val, u32 reg); 57{
49u32 cx18_write_reg_sync(struct cx18 *cx, u32 val, u32 reg); 58 writel(val, addr);
59 cx18_io_delay(cx);
60}
50 61
51/* Access "encoder memory" region of CX23418 memory mapped I/O */ 62static inline void cx18_writew(struct cx18 *cx, u16 val, void __iomem *addr)
52u32 cx18_read_enc(struct cx18 *cx, u32 addr); 63{
53void cx18_write_enc(struct cx18 *cx, u32 val, u32 addr); 64 writew(val, addr);
54u32 cx18_write_enc_sync(struct cx18 *cx, u32 val, u32 addr); 65 cx18_io_delay(cx);
66}
67
68static inline void cx18_writeb(struct cx18 *cx, u8 val, void __iomem *addr)
69{
70 writeb(val, addr);
71 cx18_io_delay(cx);
72}
73
74static inline u32 cx18_readl(struct cx18 *cx, const void __iomem *addr)
75{
76 u32 ret = readl(addr);
77 cx18_io_delay(cx);
78 return ret;
79}
80
81static inline u8 cx18_readb(struct cx18 *cx, const void __iomem *addr)
82{
83 u8 ret = readb(addr);
84 cx18_io_delay(cx);
85 return ret;
86}
87
88static inline u32 cx18_write_sync(struct cx18 *cx, u32 val, void __iomem *addr)
89{
90 cx18_writel(cx, val, addr);
91 return cx18_readl(cx, addr);
92}
55 93
56void cx18_memcpy_fromio(struct cx18 *cx, void *to, 94void cx18_memcpy_fromio(struct cx18 *cx, void *to,
57 const void __iomem *from, unsigned int len); 95 const void __iomem *from, unsigned int len);
58void cx18_memset_io(struct cx18 *cx, void __iomem *addr, int val, size_t count); 96void cx18_memset_io(struct cx18 *cx, void __iomem *addr, int val, size_t count);
59 97
98/* Access "register" region of CX23418 memory mapped I/O */
99static inline void cx18_write_reg(struct cx18 *cx, u32 val, u32 reg)
100{
101 cx18_writel(cx, val, cx->reg_mem + reg);
102}
103
104static inline u32 cx18_read_reg(struct cx18 *cx, u32 reg)
105{
106 return cx18_readl(cx, cx->reg_mem + reg);
107}
108
109static inline u32 cx18_write_reg_sync(struct cx18 *cx, u32 val, u32 reg)
110{
111 return cx18_write_sync(cx, val, cx->reg_mem + reg);
112}
113
114/* Access "encoder memory" region of CX23418 memory mapped I/O */
115static inline void cx18_write_enc(struct cx18 *cx, u32 val, u32 addr)
116{
117 cx18_writel(cx, val, cx->enc_mem + addr);
118}
119
120static inline u32 cx18_read_enc(struct cx18 *cx, u32 addr)
121{
122 return cx18_readl(cx, cx->enc_mem + addr);
123}
124
125static inline u32 cx18_write_enc_sync(struct cx18 *cx, u32 val, u32 addr)
126{
127 return cx18_write_sync(cx, val, cx->enc_mem + addr);
128}
129
130
60void cx18_sw1_irq_enable(struct cx18 *cx, u32 val); 131void cx18_sw1_irq_enable(struct cx18 *cx, u32 val);
61void cx18_sw1_irq_disable(struct cx18 *cx, u32 val); 132void cx18_sw1_irq_disable(struct cx18 *cx, u32 val);
62void cx18_sw2_irq_enable(struct cx18 *cx, u32 val); 133void cx18_sw2_irq_enable(struct cx18 *cx, u32 val);