aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndy Walls <awalls@radix.net>2008-11-16 21:33:41 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2008-12-30 06:38:09 -0500
commit3f75c6161f28e6a17c547daf552c1127c805c5e7 (patch)
tree1e4db5013c05946832221bfdca743720091f6582
parent72a4f8081af1c53a1673c173ce0fdd85c4b7d403 (diff)
V4L/DVB (9724): cx18: Streamline cx18-io[ch] wrappers and enforce MMIO retry strategy
cx18: Streamline cx18-io[ch] wrappers and enforce MMIO retry strategy so that write retries always occur and read retries never occur (as they never help). Remove MMIO statistics logging to speed up MMIO accesses. Deprecate & ignore retry_mmio and mmio_ndelay module parameters, to essentially force retry_mmio=1 and mmio_ndelay=0. Signed-off-by: Andy Walls <awalls@radix.net> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-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);