aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/media/video/cx18/cx18-av-core.c5
-rw-r--r--drivers/media/video/cx18/cx18-av-core.h1
-rw-r--r--drivers/media/video/cx18/cx18-av-firmware.c5
-rw-r--r--drivers/media/video/cx18/cx18-driver.c28
-rw-r--r--drivers/media/video/cx18/cx18-driver.h13
-rw-r--r--drivers/media/video/cx18/cx18-gpio.c2
-rw-r--r--drivers/media/video/cx18/cx18-i2c.c18
-rw-r--r--drivers/media/video/cx18/cx18-io.c128
-rw-r--r--drivers/media/video/cx18/cx18-io.h320
9 files changed, 71 insertions, 449 deletions
diff --git a/drivers/media/video/cx18/cx18-av-core.c b/drivers/media/video/cx18/cx18-av-core.c
index 518bd701d393..13a4adaa1004 100644
--- a/drivers/media/video/cx18/cx18-av-core.c
+++ b/drivers/media/video/cx18/cx18-av-core.c
@@ -80,11 +80,6 @@ u32 cx18_av_read4(struct cx18 *cx, u16 addr)
80 return cx18_read_reg(cx, 0xc40000 + addr); 80 return cx18_read_reg(cx, 0xc40000 + addr);
81} 81}
82 82
83u32 cx18_av_read4_noretry(struct cx18 *cx, u16 addr)
84{
85 return cx18_read_reg_noretry(cx, 0xc40000 + addr);
86}
87
88int cx18_av_and_or(struct cx18 *cx, u16 addr, unsigned and_mask, 83int cx18_av_and_or(struct cx18 *cx, u16 addr, unsigned and_mask,
89 u8 or_value) 84 u8 or_value)
90{ 85{
diff --git a/drivers/media/video/cx18/cx18-av-core.h b/drivers/media/video/cx18/cx18-av-core.h
index a07988c6f5cd..455761fce2fd 100644
--- a/drivers/media/video/cx18/cx18-av-core.h
+++ b/drivers/media/video/cx18/cx18-av-core.h
@@ -307,7 +307,6 @@ int cx18_av_write4_expect(struct cx18 *cx, u16 addr, u32 value, u32 eval,
307 u32 mask); 307 u32 mask);
308u8 cx18_av_read(struct cx18 *cx, u16 addr); 308u8 cx18_av_read(struct cx18 *cx, u16 addr);
309u32 cx18_av_read4(struct cx18 *cx, u16 addr); 309u32 cx18_av_read4(struct cx18 *cx, u16 addr);
310u32 cx18_av_read4_noretry(struct cx18 *cx, u16 addr);
311int cx18_av_and_or(struct cx18 *cx, u16 addr, unsigned mask, u8 value); 310int cx18_av_and_or(struct cx18 *cx, u16 addr, unsigned mask, u8 value);
312int cx18_av_and_or4(struct cx18 *cx, u16 addr, u32 mask, u32 value); 311int cx18_av_and_or4(struct cx18 *cx, u16 addr, u32 mask, u32 value);
313int cx18_av_cmd(struct cx18 *cx, unsigned int cmd, void *arg); 312int cx18_av_cmd(struct cx18 *cx, unsigned int cmd, void *arg);
diff --git a/drivers/media/video/cx18/cx18-av-firmware.c b/drivers/media/video/cx18/cx18-av-firmware.c
index 924691dcaeb7..cf52e08c2878 100644
--- a/drivers/media/video/cx18/cx18-av-firmware.c
+++ b/drivers/media/video/cx18/cx18-av-firmware.c
@@ -68,8 +68,7 @@ int cx18_av_loadfw(struct cx18 *cx)
68 cx18_av_write4_noretry(cx, CXADEC_DL_CTL, 68 cx18_av_write4_noretry(cx, CXADEC_DL_CTL,
69 dl_control); 69 dl_control);
70 udelay(10); 70 udelay(10);
71 value = cx18_av_read4_noretry(cx, 71 value = cx18_av_read4(cx, CXADEC_DL_CTL);
72 CXADEC_DL_CTL);
73 if (value == dl_control) 72 if (value == dl_control)
74 break; 73 break;
75 /* Check if we can correct the byte by changing 74 /* Check if we can correct the byte by changing
@@ -80,8 +79,6 @@ int cx18_av_loadfw(struct cx18 *cx)
80 break; 79 break;
81 } 80 }
82 } 81 }
83 cx18_log_write_retries(cx, retries2,
84 cx->reg_mem + 0xc40000 + CXADEC_DL_CTL);
85 if (unrec_err || retries2 >= CX18_MAX_MMIO_WR_RETRIES) 82 if (unrec_err || retries2 >= CX18_MAX_MMIO_WR_RETRIES)
86 break; 83 break;
87 } 84 }
diff --git a/drivers/media/video/cx18/cx18-driver.c b/drivers/media/video/cx18/cx18-driver.c
index 752ca908ccb1..88ce1e831221 100644
--- a/drivers/media/video/cx18/cx18-driver.c
+++ b/drivers/media/video/cx18/cx18-driver.c
@@ -78,14 +78,9 @@ static int radio[CX18_MAX_CARDS] = { -1, -1, -1, -1, -1, -1, -1, -1,
78 -1, -1, -1, -1, -1, -1, -1, -1, 78 -1, -1, -1, -1, -1, -1, -1, -1,
79 -1, -1, -1, -1, -1, -1, -1, -1, 79 -1, -1, -1, -1, -1, -1, -1, -1,
80 -1, -1, -1, -1, -1, -1, -1, -1 }; 80 -1, -1, -1, -1, -1, -1, -1, -1 };
81static int mmio_ndelay[CX18_MAX_CARDS] = { -1, -1, -1, -1, -1, -1, -1, -1,
82 -1, -1, -1, -1, -1, -1, -1, -1,
83 -1, -1, -1, -1, -1, -1, -1, -1,
84 -1, -1, -1, -1, -1, -1, -1, -1 };
85static unsigned cardtype_c = 1; 81static unsigned cardtype_c = 1;
86static unsigned tuner_c = 1; 82static unsigned tuner_c = 1;
87static unsigned radio_c = 1; 83static unsigned radio_c = 1;
88static unsigned mmio_ndelay_c = 1;
89static char pal[] = "--"; 84static char pal[] = "--";
90static char secam[] = "--"; 85static char secam[] = "--";
91static char ntsc[] = "-"; 86static char ntsc[] = "-";
@@ -99,18 +94,20 @@ static int enc_pcm_buffers = CX18_DEFAULT_ENC_PCM_BUFFERS;
99 94
100static int cx18_pci_latency = 1; 95static int cx18_pci_latency = 1;
101 96
102int cx18_retry_mmio = 1; 97static int mmio_ndelay;
98static int retry_mmio = 1;
99
103int cx18_debug; 100int cx18_debug;
104 101
105module_param_array(tuner, int, &tuner_c, 0644); 102module_param_array(tuner, int, &tuner_c, 0644);
106module_param_array(radio, bool, &radio_c, 0644); 103module_param_array(radio, bool, &radio_c, 0644);
107module_param_array(cardtype, int, &cardtype_c, 0644); 104module_param_array(cardtype, int, &cardtype_c, 0644);
108module_param_array(mmio_ndelay, int, &mmio_ndelay_c, 0644);
109module_param_string(pal, pal, sizeof(pal), 0644); 105module_param_string(pal, pal, sizeof(pal), 0644);
110module_param_string(secam, secam, sizeof(secam), 0644); 106module_param_string(secam, secam, sizeof(secam), 0644);
111module_param_string(ntsc, ntsc, sizeof(ntsc), 0644); 107module_param_string(ntsc, ntsc, sizeof(ntsc), 0644);
112module_param_named(debug, cx18_debug, int, 0644); 108module_param_named(debug, cx18_debug, int, 0644);
113module_param_named(retry_mmio, cx18_retry_mmio, int, 0644); 109module_param(mmio_ndelay, int, 0644);
110module_param(retry_mmio, int, 0644);
114module_param(cx18_pci_latency, int, 0644); 111module_param(cx18_pci_latency, int, 0644);
115module_param(cx18_first_minor, int, 0644); 112module_param(cx18_first_minor, int, 0644);
116 113
@@ -155,13 +152,11 @@ MODULE_PARM_DESC(cx18_pci_latency,
155 "Change the PCI latency to 64 if lower: 0 = No, 1 = Yes,\n" 152 "Change the PCI latency to 64 if lower: 0 = No, 1 = Yes,\n"
156 "\t\t\tDefault: Yes"); 153 "\t\t\tDefault: Yes");
157MODULE_PARM_DESC(retry_mmio, 154MODULE_PARM_DESC(retry_mmio,
158 "Check and retry memory mapped IO accesses\n" 155 "(Deprecated) MMIO writes are now always checked and retried\n"
159 "\t\t\tDefault: 1 [Yes]"); 156 "\t\t\tEffectively: 1 [Yes]");
160MODULE_PARM_DESC(mmio_ndelay, 157MODULE_PARM_DESC(mmio_ndelay,
161 "Delay (ns) for each CX23418 memory mapped IO access.\n" 158 "(Deprecated) MMIO accesses are now never purposely delayed\n"
162 "\t\t\tTry larger values that are close to a multiple of the\n" 159 "\t\t\tEffectively: 0 ns");
163 "\t\t\tPCI clock period, 30.3 ns, if your card doesn't work.\n"
164 "\t\t\tDefault: " __stringify(CX18_DEFAULT_MMIO_NDELAY));
165MODULE_PARM_DESC(enc_mpg_buffers, 160MODULE_PARM_DESC(enc_mpg_buffers,
166 "Encoder MPG Buffers (in MB)\n" 161 "Encoder MPG Buffers (in MB)\n"
167 "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_MPG_BUFFERS)); 162 "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_MPG_BUFFERS));
@@ -378,11 +373,6 @@ static void cx18_process_options(struct cx18 *cx)
378 cx->options.tuner = tuner[cx->num]; 373 cx->options.tuner = tuner[cx->num];
379 cx->options.radio = radio[cx->num]; 374 cx->options.radio = radio[cx->num];
380 375
381 if (mmio_ndelay[cx->num] < 0)
382 cx->options.mmio_ndelay = CX18_DEFAULT_MMIO_NDELAY;
383 else
384 cx->options.mmio_ndelay = mmio_ndelay[cx->num];
385
386 cx->std = cx18_parse_std(cx); 376 cx->std = cx18_parse_std(cx);
387 if (cx->options.cardtype == -1) { 377 if (cx->options.cardtype == -1) {
388 CX18_INFO("Ignore card\n"); 378 CX18_INFO("Ignore card\n");
diff --git a/drivers/media/video/cx18/cx18-driver.h b/drivers/media/video/cx18/cx18-driver.h
index 749bbb60a292..02a82c3b7a32 100644
--- a/drivers/media/video/cx18/cx18-driver.h
+++ b/drivers/media/video/cx18/cx18-driver.h
@@ -64,9 +64,6 @@
64# error "This driver requires kernel PCI support." 64# error "This driver requires kernel PCI support."
65#endif 65#endif
66 66
67/* Default delay to throttle mmio access to the CX23418 */
68#define CX18_DEFAULT_MMIO_NDELAY 0 /* 0 ns = 0 PCI clock(s) / 33 MHz */
69
70#define CX18_MEM_OFFSET 0x00000000 67#define CX18_MEM_OFFSET 0x00000000
71#define CX18_MEM_SIZE 0x04000000 68#define CX18_MEM_SIZE 0x04000000
72#define CX18_REG_OFFSET 0x02000000 69#define CX18_REG_OFFSET 0x02000000
@@ -176,7 +173,6 @@
176 173
177#define CX18_MAX_PGM_INDEX (400) 174#define CX18_MAX_PGM_INDEX (400)
178 175
179extern int cx18_retry_mmio; /* enable check & retry of mmio accesses */
180extern int cx18_debug; 176extern int cx18_debug;
181 177
182 178
@@ -185,7 +181,6 @@ struct cx18_options {
185 int cardtype; /* force card type on load */ 181 int cardtype; /* force card type on load */
186 int tuner; /* set tuner on load */ 182 int tuner; /* set tuner on load */
187 int radio; /* enable/disable radio */ 183 int radio; /* enable/disable radio */
188 unsigned long mmio_ndelay; /* delay in ns after every PCI mmio access */
189}; 184};
190 185
191/* per-buffer bit flags */ 186/* per-buffer bit flags */
@@ -371,13 +366,6 @@ struct cx18_i2c_algo_callback_data {
371}; 366};
372 367
373#define CX18_MAX_MMIO_WR_RETRIES 10 368#define CX18_MAX_MMIO_WR_RETRIES 10
374#define CX18_MAX_MMIO_RD_RETRIES 2
375
376struct cx18_mmio_stats {
377 atomic_t retried_write[CX18_MAX_MMIO_WR_RETRIES+1];
378 atomic_t retried_read[CX18_MAX_MMIO_RD_RETRIES+1];
379};
380
381#define CX18_MAX_MB_ACK_DELAY 100 369#define CX18_MAX_MB_ACK_DELAY 100
382 370
383struct cx18_mbox_stats { 371struct cx18_mbox_stats {
@@ -475,7 +463,6 @@ struct cx18 {
475 struct mutex gpio_lock; 463 struct mutex gpio_lock;
476 464
477 /* Statistics */ 465 /* Statistics */
478 struct cx18_mmio_stats mmio_stats;
479 struct cx18_mbox_stats mbox_stats; 466 struct cx18_mbox_stats mbox_stats;
480 467
481 /* v4l2 and User settings */ 468 /* v4l2 and User settings */
diff --git a/drivers/media/video/cx18/cx18-gpio.c b/drivers/media/video/cx18/cx18-gpio.c
index 17b7a32fcc31..a1625c8e0179 100644
--- a/drivers/media/video/cx18/cx18-gpio.c
+++ b/drivers/media/video/cx18/cx18-gpio.c
@@ -60,8 +60,6 @@ static void gpio_write(struct cx18 *cx)
60 CX18_REG_GPIO_DIR2, ~dir_hi, dir_hi); 60 CX18_REG_GPIO_DIR2, ~dir_hi, dir_hi);
61 cx18_write_reg_expect(cx, (dir_hi << 16) | val_hi, 61 cx18_write_reg_expect(cx, (dir_hi << 16) | val_hi,
62 CX18_REG_GPIO_OUT2, val_hi, dir_hi); 62 CX18_REG_GPIO_OUT2, val_hi, dir_hi);
63 if (!cx18_retry_mmio)
64 (void) cx18_read_reg(cx, CX18_REG_GPIO_OUT2); /* sync */
65} 63}
66 64
67void cx18_reset_i2c_slaves_gpio(struct cx18 *cx) 65void cx18_reset_i2c_slaves_gpio(struct cx18 *cx)
diff --git a/drivers/media/video/cx18/cx18-i2c.c b/drivers/media/video/cx18/cx18-i2c.c
index 824efbecb34c..098635072543 100644
--- a/drivers/media/video/cx18/cx18-i2c.c
+++ b/drivers/media/video/cx18/cx18-i2c.c
@@ -161,9 +161,9 @@ static void cx18_setscl(void *data, int state)
161 u32 r = cx18_read_reg(cx, addr); 161 u32 r = cx18_read_reg(cx, addr);
162 162
163 if (state) 163 if (state)
164 cx18_write_reg_sync(cx, r | SETSCL_BIT, addr); 164 cx18_write_reg(cx, r | SETSCL_BIT, addr);
165 else 165 else
166 cx18_write_reg_sync(cx, r & ~SETSCL_BIT, addr); 166 cx18_write_reg(cx, r & ~SETSCL_BIT, addr);
167} 167}
168 168
169static void cx18_setsda(void *data, int state) 169static void cx18_setsda(void *data, int state)
@@ -174,9 +174,9 @@ static void cx18_setsda(void *data, int state)
174 u32 r = cx18_read_reg(cx, addr); 174 u32 r = cx18_read_reg(cx, addr);
175 175
176 if (state) 176 if (state)
177 cx18_write_reg_sync(cx, r | SETSDL_BIT, addr); 177 cx18_write_reg(cx, r | SETSDL_BIT, addr);
178 else 178 else
179 cx18_write_reg_sync(cx, r & ~SETSDL_BIT, addr); 179 cx18_write_reg(cx, r & ~SETSDL_BIT, addr);
180} 180}
181 181
182static int cx18_getscl(void *data) 182static int cx18_getscl(void *data)
@@ -405,16 +405,10 @@ int init_cx18_i2c(struct cx18 *cx)
405 } 405 }
406 /* courtesy of Steven Toth <stoth@hauppauge.com> */ 406 /* courtesy of Steven Toth <stoth@hauppauge.com> */
407 cx18_write_reg_expect(cx, 0x00c00000, 0xc7001c, 0x00000000, 0x00c000c0); 407 cx18_write_reg_expect(cx, 0x00c00000, 0xc7001c, 0x00000000, 0x00c000c0);
408 if (!cx18_retry_mmio)
409 (void) cx18_read_reg(cx, 0xc7001c); /* sync */
410 mdelay(10); 408 mdelay(10);
411 cx18_write_reg_expect(cx, 0x00c000c0, 0xc7001c, 0x000000c0, 0x00c000c0); 409 cx18_write_reg_expect(cx, 0x00c000c0, 0xc7001c, 0x000000c0, 0x00c000c0);
412 if (!cx18_retry_mmio)
413 (void) cx18_read_reg(cx, 0xc7001c); /* sync */
414 mdelay(10); 410 mdelay(10);
415 cx18_write_reg_expect(cx, 0x00c00000, 0xc7001c, 0x00000000, 0x00c000c0); 411 cx18_write_reg_expect(cx, 0x00c00000, 0xc7001c, 0x00000000, 0x00c000c0);
416 if (!cx18_retry_mmio)
417 (void) cx18_read_reg(cx, 0xc7001c); /* sync */
418 mdelay(10); 412 mdelay(10);
419 413
420 /* Set to edge-triggered intrs. */ 414 /* Set to edge-triggered intrs. */
@@ -424,12 +418,12 @@ int init_cx18_i2c(struct cx18 *cx)
424 ~(HW2_I2C1_INT|HW2_I2C2_INT), HW2_I2C1_INT|HW2_I2C2_INT); 418 ~(HW2_I2C1_INT|HW2_I2C2_INT), HW2_I2C1_INT|HW2_I2C2_INT);
425 419
426 /* Hw I2C1 Clock Freq ~100kHz */ 420 /* Hw I2C1 Clock Freq ~100kHz */
427 cx18_write_reg_sync(cx, 0x00021c0f & ~4, CX18_REG_I2C_1_WR); 421 cx18_write_reg(cx, 0x00021c0f & ~4, CX18_REG_I2C_1_WR);
428 cx18_setscl(&cx->i2c_algo_cb_data[0], 1); 422 cx18_setscl(&cx->i2c_algo_cb_data[0], 1);
429 cx18_setsda(&cx->i2c_algo_cb_data[0], 1); 423 cx18_setsda(&cx->i2c_algo_cb_data[0], 1);
430 424
431 /* Hw I2C2 Clock Freq ~100kHz */ 425 /* Hw I2C2 Clock Freq ~100kHz */
432 cx18_write_reg_sync(cx, 0x00021c0f & ~4, CX18_REG_I2C_2_WR); 426 cx18_write_reg(cx, 0x00021c0f & ~4, CX18_REG_I2C_2_WR);
433 cx18_setscl(&cx->i2c_algo_cb_data[1], 1); 427 cx18_setscl(&cx->i2c_algo_cb_data[1], 1);
434 cx18_setsda(&cx->i2c_algo_cb_data[1], 1); 428 cx18_setsda(&cx->i2c_algo_cb_data[1], 1);
435 429
diff --git a/drivers/media/video/cx18/cx18-io.c b/drivers/media/video/cx18/cx18-io.c
index c67694f63d0e..a2b5e807faca 100644
--- a/drivers/media/video/cx18/cx18-io.c
+++ b/drivers/media/video/cx18/cx18-io.c
@@ -31,12 +31,6 @@ void cx18_log_statistics(struct cx18 *cx)
31 if (!(cx18_debug & CX18_DBGFLG_INFO)) 31 if (!(cx18_debug & CX18_DBGFLG_INFO))
32 return; 32 return;
33 33
34 for (i = 0; i <= CX18_MAX_MMIO_WR_RETRIES; i++)
35 CX18_DEBUG_INFO("retried_write[%d] = %d\n", i,
36 atomic_read(&cx->mmio_stats.retried_write[i]));
37 for (i = 0; i <= CX18_MAX_MMIO_RD_RETRIES; i++)
38 CX18_DEBUG_INFO("retried_read[%d] = %d\n", i,
39 atomic_read(&cx->mmio_stats.retried_read[i]));
40 for (i = 0; i <= CX18_MAX_MB_ACK_DELAY; i++) 34 for (i = 0; i <= CX18_MAX_MB_ACK_DELAY; i++)
41 if (atomic_read(&cx->mbox_stats.mb_ack_delay[i])) 35 if (atomic_read(&cx->mbox_stats.mb_ack_delay[i]))
42 CX18_DEBUG_INFO("mb_ack_delay[%d] = %d\n", i, 36 CX18_DEBUG_INFO("mb_ack_delay[%d] = %d\n", i,
@@ -44,128 +38,6 @@ void cx18_log_statistics(struct cx18 *cx)
44 return; 38 return;
45} 39}
46 40
47void cx18_raw_writel_retry(struct cx18 *cx, u32 val, void __iomem *addr)
48{
49 int i;
50 for (i = 0; i < CX18_MAX_MMIO_WR_RETRIES; i++) {
51 cx18_raw_writel_noretry(cx, val, addr);
52 if (val == cx18_raw_readl_noretry(cx, addr))
53 break;
54 }
55 cx18_log_write_retries(cx, i, addr);
56}
57
58u32 cx18_raw_readl_retry(struct cx18 *cx, const void __iomem *addr)
59{
60 int i;
61 u32 val;
62 for (i = 0; i < CX18_MAX_MMIO_RD_RETRIES; i++) {
63 val = cx18_raw_readl_noretry(cx, addr);
64 if (val != 0xffffffff) /* PCI bus read error */
65 break;
66 }
67 cx18_log_read_retries(cx, i, addr);
68 return val;
69}
70
71u16 cx18_raw_readw_retry(struct cx18 *cx, const void __iomem *addr)
72{
73 int i;
74 u16 val;
75 for (i = 0; i < CX18_MAX_MMIO_RD_RETRIES; i++) {
76 val = cx18_raw_readw_noretry(cx, addr);
77 if (val != 0xffff) /* PCI bus read error */
78 break;
79 }
80 cx18_log_read_retries(cx, i, addr);
81 return val;
82}
83
84void cx18_writel_retry(struct cx18 *cx, u32 val, void __iomem *addr)
85{
86 int i;
87 for (i = 0; i < CX18_MAX_MMIO_WR_RETRIES; i++) {
88 cx18_writel_noretry(cx, val, addr);
89 if (val == cx18_readl_noretry(cx, addr))
90 break;
91 }
92 cx18_log_write_retries(cx, i, addr);
93}
94
95void _cx18_writel_expect(struct cx18 *cx, u32 val, void __iomem *addr,
96 u32 eval, u32 mask)
97{
98 int i;
99 eval &= mask;
100 for (i = 0; i < CX18_MAX_MMIO_WR_RETRIES; i++) {
101 cx18_writel_noretry(cx, val, addr);
102 if (eval == (cx18_readl_noretry(cx, addr) & mask))
103 break;
104 }
105 cx18_log_write_retries(cx, i, addr);
106}
107
108void cx18_writew_retry(struct cx18 *cx, u16 val, void __iomem *addr)
109{
110 int i;
111 for (i = 0; i < CX18_MAX_MMIO_WR_RETRIES; i++) {
112 cx18_writew_noretry(cx, val, addr);
113 if (val == cx18_readw_noretry(cx, addr))
114 break;
115 }
116 cx18_log_write_retries(cx, i, addr);
117}
118
119void cx18_writeb_retry(struct cx18 *cx, u8 val, void __iomem *addr)
120{
121 int i;
122 for (i = 0; i < CX18_MAX_MMIO_WR_RETRIES; i++) {
123 cx18_writeb_noretry(cx, val, addr);
124 if (val == cx18_readb_noretry(cx, addr))
125 break;
126 }
127 cx18_log_write_retries(cx, i, addr);
128}
129
130u32 cx18_readl_retry(struct cx18 *cx, const void __iomem *addr)
131{
132 int i;
133 u32 val;
134 for (i = 0; i < CX18_MAX_MMIO_RD_RETRIES; i++) {
135 val = cx18_readl_noretry(cx, addr);
136 if (val != 0xffffffff) /* PCI bus read error */
137 break;
138 }
139 cx18_log_read_retries(cx, i, addr);
140 return val;
141}
142
143u16 cx18_readw_retry(struct cx18 *cx, const void __iomem *addr)
144{
145 int i;
146 u16 val;
147 for (i = 0; i < CX18_MAX_MMIO_RD_RETRIES; i++) {
148 val = cx18_readw_noretry(cx, addr);
149 if (val != 0xffff) /* PCI bus read error */
150 break;
151 }
152 cx18_log_read_retries(cx, i, addr);
153 return val;
154}
155
156u8 cx18_readb_retry(struct cx18 *cx, const void __iomem *addr)
157{
158 int i;
159 u8 val;
160 for (i = 0; i < CX18_MAX_MMIO_RD_RETRIES; i++) {
161 val = cx18_readb_noretry(cx, addr);
162 if (val != 0xff) /* PCI bus read error */
163 break;
164 }
165 cx18_log_read_retries(cx, i, addr);
166 return val;
167}
168
169void cx18_memset_io(struct cx18 *cx, void __iomem *addr, int val, size_t count) 41void cx18_memset_io(struct cx18 *cx, void __iomem *addr, int val, size_t count)
170{ 42{
171 u8 __iomem *dst = addr; 43 u8 __iomem *dst = addr;
diff --git a/drivers/media/video/cx18/cx18-io.h b/drivers/media/video/cx18/cx18-io.h
index fdc2bcc92fca..73321fb4cbf5 100644
--- a/drivers/media/video/cx18/cx18-io.h
+++ b/drivers/media/video/cx18/cx18-io.h
@@ -25,230 +25,118 @@
25 25
26#include "cx18-driver.h" 26#include "cx18-driver.h"
27 27
28static inline void cx18_io_delay(struct cx18 *cx)
29{
30 if (cx->options.mmio_ndelay)
31 ndelay(cx->options.mmio_ndelay);
32}
33
34/* 28/*
35 * Readback and retry of MMIO access for reliability: 29 * Readback and retry of MMIO access for reliability:
36 * The concept was suggested by Steve Toth <stoth@linuxtv.org>. 30 * The concept was suggested by Steve Toth <stoth@linuxtv.org>.
37 * The implmentation is the fault of Andy Walls <awalls@radix.net>. 31 * The implmentation is the fault of Andy Walls <awalls@radix.net>.
32 *
33 * *write* functions are implied to retry the mmio unless suffixed with _noretry
34 * *read* functions never retry the mmio (it never helps to do so)
38 */ 35 */
39 36
40/* Statistics gathering */ 37/* Statistics gathering */
41static inline
42void cx18_log_write_retries(struct cx18 *cx, int i, const void __iomem *addr)
43{
44 if (i > CX18_MAX_MMIO_WR_RETRIES)
45 i = CX18_MAX_MMIO_WR_RETRIES;
46 atomic_inc(&cx->mmio_stats.retried_write[i]);
47 return;
48}
49
50static inline
51void cx18_log_read_retries(struct cx18 *cx, int i, const void __iomem *addr)
52{
53 if (i > CX18_MAX_MMIO_RD_RETRIES)
54 i = CX18_MAX_MMIO_RD_RETRIES;
55 atomic_inc(&cx->mmio_stats.retried_read[i]);
56 return;
57}
58 38
59void cx18_log_statistics(struct cx18 *cx); 39void cx18_log_statistics(struct cx18 *cx);
60 40
61/* Non byteswapping memory mapped IO */ 41/* Non byteswapping memory mapped IO */
42static inline u32 cx18_raw_readl(struct cx18 *cx, const void __iomem *addr)
43{
44 return __raw_readl(addr);
45}
46
62static inline 47static inline
63void cx18_raw_writel_noretry(struct cx18 *cx, u32 val, void __iomem *addr) 48void cx18_raw_writel_noretry(struct cx18 *cx, u32 val, void __iomem *addr)
64{ 49{
65 __raw_writel(val, addr); 50 __raw_writel(val, addr);
66 cx18_io_delay(cx);
67} 51}
68 52
69void cx18_raw_writel_retry(struct cx18 *cx, u32 val, void __iomem *addr);
70
71static inline void cx18_raw_writel(struct cx18 *cx, u32 val, void __iomem *addr) 53static inline void cx18_raw_writel(struct cx18 *cx, u32 val, void __iomem *addr)
72{ 54{
73 if (cx18_retry_mmio) 55 int i;
74 cx18_raw_writel_retry(cx, val, addr); 56 for (i = 0; i < CX18_MAX_MMIO_WR_RETRIES; i++) {
75 else
76 cx18_raw_writel_noretry(cx, val, addr); 57 cx18_raw_writel_noretry(cx, val, addr);
58 if (val == cx18_raw_readl(cx, addr))
59 break;
60 }
77} 61}
78 62
79 63/* Normal memory mapped IO */
80static inline 64static inline u32 cx18_readl(struct cx18 *cx, const void __iomem *addr)
81u32 cx18_raw_readl_noretry(struct cx18 *cx, const void __iomem *addr)
82{
83 u32 ret = __raw_readl(addr);
84 cx18_io_delay(cx);
85 return ret;
86}
87
88u32 cx18_raw_readl_retry(struct cx18 *cx, const void __iomem *addr);
89
90static inline u32 cx18_raw_readl(struct cx18 *cx, const void __iomem *addr)
91{ 65{
92 if (cx18_retry_mmio) 66 return readl(addr);
93 return cx18_raw_readl_retry(cx, addr);
94
95 return cx18_raw_readl_noretry(cx, addr);
96} 67}
97 68
98
99static inline 69static inline
100u16 cx18_raw_readw_noretry(struct cx18 *cx, const void __iomem *addr) 70void cx18_writel_noretry(struct cx18 *cx, u32 val, void __iomem *addr)
101{ 71{
102 u16 ret = __raw_readw(addr); 72 writel(val, addr);
103 cx18_io_delay(cx);
104 return ret;
105} 73}
106 74
107u16 cx18_raw_readw_retry(struct cx18 *cx, const void __iomem *addr); 75static inline void cx18_writel(struct cx18 *cx, u32 val, void __iomem *addr)
108
109static inline u16 cx18_raw_readw(struct cx18 *cx, const void __iomem *addr)
110{ 76{
111 if (cx18_retry_mmio) 77 int i;
112 return cx18_raw_readw_retry(cx, addr); 78 for (i = 0; i < CX18_MAX_MMIO_WR_RETRIES; i++) {
113 79 cx18_writel_noretry(cx, val, addr);
114 return cx18_raw_readw_noretry(cx, addr); 80 if (val == cx18_readl(cx, addr))
81 break;
82 }
115} 83}
116 84
117
118/* Normal memory mapped IO */
119static inline 85static inline
120void cx18_writel_noretry(struct cx18 *cx, u32 val, void __iomem *addr) 86void cx18_writel_expect(struct cx18 *cx, u32 val, void __iomem *addr,
87 u32 eval, u32 mask)
121{ 88{
122 writel(val, addr); 89 int i;
123 cx18_io_delay(cx); 90 eval &= mask;
91 for (i = 0; i < CX18_MAX_MMIO_WR_RETRIES; i++) {
92 cx18_writel_noretry(cx, val, addr);
93 if (eval == (cx18_readl(cx, addr) & mask))
94 break;
95 }
124} 96}
125 97
126void cx18_writel_retry(struct cx18 *cx, u32 val, void __iomem *addr); 98static inline u16 cx18_readw(struct cx18 *cx, const void __iomem *addr)
127
128static inline void cx18_writel(struct cx18 *cx, u32 val, void __iomem *addr)
129{ 99{
130 if (cx18_retry_mmio) 100 return readw(addr);
131 cx18_writel_retry(cx, val, addr);
132 else
133 cx18_writel_noretry(cx, val, addr);
134} 101}
135 102
136void _cx18_writel_expect(struct cx18 *cx, u32 val, void __iomem *addr,
137 u32 eval, u32 mask);
138
139static inline 103static inline
140void cx18_writew_noretry(struct cx18 *cx, u16 val, void __iomem *addr) 104void cx18_writew_noretry(struct cx18 *cx, u16 val, void __iomem *addr)
141{ 105{
142 writew(val, addr); 106 writew(val, addr);
143 cx18_io_delay(cx);
144} 107}
145 108
146void cx18_writew_retry(struct cx18 *cx, u16 val, void __iomem *addr);
147
148static inline void cx18_writew(struct cx18 *cx, u16 val, void __iomem *addr) 109static inline void cx18_writew(struct cx18 *cx, u16 val, void __iomem *addr)
149{ 110{
150 if (cx18_retry_mmio) 111 int i;
151 cx18_writew_retry(cx, val, addr); 112 for (i = 0; i < CX18_MAX_MMIO_WR_RETRIES; i++) {
152 else
153 cx18_writew_noretry(cx, val, addr); 113 cx18_writew_noretry(cx, val, addr);
114 if (val == cx18_readw(cx, addr))
115 break;
116 }
154} 117}
155 118
119static inline u8 cx18_readb(struct cx18 *cx, const void __iomem *addr)
120{
121 return readb(addr);
122}
156 123
157static inline 124static inline
158void cx18_writeb_noretry(struct cx18 *cx, u8 val, void __iomem *addr) 125void cx18_writeb_noretry(struct cx18 *cx, u8 val, void __iomem *addr)
159{ 126{
160 writeb(val, addr); 127 writeb(val, addr);
161 cx18_io_delay(cx);
162} 128}
163 129
164void cx18_writeb_retry(struct cx18 *cx, u8 val, void __iomem *addr);
165
166static inline void cx18_writeb(struct cx18 *cx, u8 val, void __iomem *addr) 130static inline void cx18_writeb(struct cx18 *cx, u8 val, void __iomem *addr)
167{ 131{
168 if (cx18_retry_mmio) 132 int i;
169 cx18_writeb_retry(cx, val, addr); 133 for (i = 0; i < CX18_MAX_MMIO_WR_RETRIES; i++) {
170 else
171 cx18_writeb_noretry(cx, val, addr); 134 cx18_writeb_noretry(cx, val, addr);
135 if (val == cx18_readb(cx, addr))
136 break;
137 }
172} 138}
173 139
174
175static inline u32 cx18_readl_noretry(struct cx18 *cx, const void __iomem *addr)
176{
177 u32 ret = readl(addr);
178 cx18_io_delay(cx);
179 return ret;
180}
181
182u32 cx18_readl_retry(struct cx18 *cx, const void __iomem *addr);
183
184static inline u32 cx18_readl(struct cx18 *cx, const void __iomem *addr)
185{
186 if (cx18_retry_mmio)
187 return cx18_readl_retry(cx, addr);
188
189 return cx18_readl_noretry(cx, addr);
190}
191
192
193static inline u16 cx18_readw_noretry(struct cx18 *cx, const void __iomem *addr)
194{
195 u16 ret = readw(addr);
196 cx18_io_delay(cx);
197 return ret;
198}
199
200u16 cx18_readw_retry(struct cx18 *cx, const void __iomem *addr);
201
202static inline u16 cx18_readw(struct cx18 *cx, const void __iomem *addr)
203{
204 if (cx18_retry_mmio)
205 return cx18_readw_retry(cx, addr);
206
207 return cx18_readw_noretry(cx, addr);
208}
209
210
211static inline u8 cx18_readb_noretry(struct cx18 *cx, const void __iomem *addr)
212{
213 u8 ret = readb(addr);
214 cx18_io_delay(cx);
215 return ret;
216}
217
218u8 cx18_readb_retry(struct cx18 *cx, const void __iomem *addr);
219
220static inline u8 cx18_readb(struct cx18 *cx, const void __iomem *addr)
221{
222 if (cx18_retry_mmio)
223 return cx18_readb_retry(cx, addr);
224
225 return cx18_readb_noretry(cx, addr);
226}
227
228
229static inline
230u32 cx18_write_sync_noretry(struct cx18 *cx, u32 val, void __iomem *addr)
231{
232 cx18_writel_noretry(cx, val, addr);
233 return cx18_readl_noretry(cx, addr);
234}
235
236static inline
237u32 cx18_write_sync_retry(struct cx18 *cx, u32 val, void __iomem *addr)
238{
239 cx18_writel_retry(cx, val, addr);
240 return cx18_readl_retry(cx, addr);
241}
242
243static inline u32 cx18_write_sync(struct cx18 *cx, u32 val, void __iomem *addr)
244{
245 if (cx18_retry_mmio)
246 return cx18_write_sync_retry(cx, val, addr);
247
248 return cx18_write_sync_noretry(cx, val, addr);
249}
250
251
252static inline 140static inline
253void cx18_memcpy_fromio(struct cx18 *cx, void *to, 141void cx18_memcpy_fromio(struct cx18 *cx, void *to,
254 const void __iomem *from, unsigned int len) 142 const void __iomem *from, unsigned int len)
@@ -265,130 +153,32 @@ static inline void cx18_write_reg_noretry(struct cx18 *cx, u32 val, u32 reg)
265 cx18_writel_noretry(cx, val, cx->reg_mem + reg); 153 cx18_writel_noretry(cx, val, cx->reg_mem + reg);
266} 154}
267 155
268static inline void cx18_write_reg_retry(struct cx18 *cx, u32 val, u32 reg)
269{
270 cx18_writel_retry(cx, val, cx->reg_mem + reg);
271}
272
273static inline void cx18_write_reg(struct cx18 *cx, u32 val, u32 reg) 156static inline void cx18_write_reg(struct cx18 *cx, u32 val, u32 reg)
274{ 157{
275 if (cx18_retry_mmio) 158 cx18_writel(cx, val, cx->reg_mem + reg);
276 cx18_write_reg_retry(cx, val, reg);
277 else
278 cx18_write_reg_noretry(cx, val, reg);
279}
280
281static inline void _cx18_write_reg_expect(struct cx18 *cx, u32 val, u32 reg,
282 u32 eval, u32 mask)
283{
284 _cx18_writel_expect(cx, val, cx->reg_mem + reg, eval, mask);
285} 159}
286 160
287static inline void cx18_write_reg_expect(struct cx18 *cx, u32 val, u32 reg, 161static inline void cx18_write_reg_expect(struct cx18 *cx, u32 val, u32 reg,
288 u32 eval, u32 mask) 162 u32 eval, u32 mask)
289{ 163{
290 if (cx18_retry_mmio) 164 cx18_writel_expect(cx, val, cx->reg_mem + reg, eval, mask);
291 _cx18_write_reg_expect(cx, val, reg, eval, mask);
292 else
293 cx18_write_reg_noretry(cx, val, reg);
294}
295
296
297static inline u32 cx18_read_reg_noretry(struct cx18 *cx, u32 reg)
298{
299 return cx18_readl_noretry(cx, cx->reg_mem + reg);
300}
301
302static inline u32 cx18_read_reg_retry(struct cx18 *cx, u32 reg)
303{
304 return cx18_readl_retry(cx, cx->reg_mem + reg);
305} 165}
306 166
307static inline u32 cx18_read_reg(struct cx18 *cx, u32 reg) 167static inline u32 cx18_read_reg(struct cx18 *cx, u32 reg)
308{ 168{
309 if (cx18_retry_mmio) 169 return cx18_readl(cx, cx->reg_mem + reg);
310 return cx18_read_reg_retry(cx, reg);
311
312 return cx18_read_reg_noretry(cx, reg);
313}
314
315
316static inline u32 cx18_write_reg_sync_noretry(struct cx18 *cx, u32 val, u32 reg)
317{
318 return cx18_write_sync_noretry(cx, val, cx->reg_mem + reg);
319}
320
321static inline u32 cx18_write_reg_sync_retry(struct cx18 *cx, u32 val, u32 reg)
322{
323 return cx18_write_sync_retry(cx, val, cx->reg_mem + reg);
324}
325
326static inline u32 cx18_write_reg_sync(struct cx18 *cx, u32 val, u32 reg)
327{
328 if (cx18_retry_mmio)
329 return cx18_write_reg_sync_retry(cx, val, reg);
330
331 return cx18_write_reg_sync_noretry(cx, val, reg);
332} 170}
333 171
334 172
335/* Access "encoder memory" region of CX23418 memory mapped I/O */ 173/* Access "encoder memory" region of CX23418 memory mapped I/O */
336static inline void cx18_write_enc_noretry(struct cx18 *cx, u32 val, u32 addr)
337{
338 cx18_writel_noretry(cx, val, cx->enc_mem + addr);
339}
340
341static inline void cx18_write_enc_retry(struct cx18 *cx, u32 val, u32 addr)
342{
343 cx18_writel_retry(cx, val, cx->enc_mem + addr);
344}
345
346static inline void cx18_write_enc(struct cx18 *cx, u32 val, u32 addr) 174static inline void cx18_write_enc(struct cx18 *cx, u32 val, u32 addr)
347{ 175{
348 if (cx18_retry_mmio) 176 cx18_writel(cx, val, cx->enc_mem + addr);
349 cx18_write_enc_retry(cx, val, addr);
350 else
351 cx18_write_enc_noretry(cx, val, addr);
352}
353
354
355static inline u32 cx18_read_enc_noretry(struct cx18 *cx, u32 addr)
356{
357 return cx18_readl_noretry(cx, cx->enc_mem + addr);
358}
359
360static inline u32 cx18_read_enc_retry(struct cx18 *cx, u32 addr)
361{
362 return cx18_readl_retry(cx, cx->enc_mem + addr);
363} 177}
364 178
365static inline u32 cx18_read_enc(struct cx18 *cx, u32 addr) 179static inline u32 cx18_read_enc(struct cx18 *cx, u32 addr)
366{ 180{
367 if (cx18_retry_mmio) 181 return cx18_readl(cx, cx->enc_mem + addr);
368 return cx18_read_enc_retry(cx, addr);
369
370 return cx18_read_enc_noretry(cx, addr);
371}
372
373static inline
374u32 cx18_write_enc_sync_noretry(struct cx18 *cx, u32 val, u32 addr)
375{
376 return cx18_write_sync_noretry(cx, val, cx->enc_mem + addr);
377}
378
379static inline
380u32 cx18_write_enc_sync_retry(struct cx18 *cx, u32 val, u32 addr)
381{
382 return cx18_write_sync_retry(cx, val, cx->enc_mem + addr);
383}
384
385static inline
386u32 cx18_write_enc_sync(struct cx18 *cx, u32 val, u32 addr)
387{
388 if (cx18_retry_mmio)
389 return cx18_write_enc_sync_retry(cx, val, addr);
390
391 return cx18_write_enc_sync_noretry(cx, val, addr);
392} 182}
393 183
394void cx18_sw1_irq_enable(struct cx18 *cx, u32 val); 184void cx18_sw1_irq_enable(struct cx18 *cx, u32 val);