Skip to content

Commit

Permalink
V4L/DVB (9724): cx18: Streamline cx18-io[ch] wrappers and enforce MMI…
Browse files Browse the repository at this point in the history
…O 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>
  • Loading branch information
Andy Walls authored and Mauro Carvalho Chehab committed Dec 30, 2008
1 parent 72a4f80 commit 3f75c61
Show file tree
Hide file tree
Showing 9 changed files with 71 additions and 449 deletions.
5 changes: 0 additions & 5 deletions drivers/media/video/cx18/cx18-av-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -80,11 +80,6 @@ u32 cx18_av_read4(struct cx18 *cx, u16 addr)
return cx18_read_reg(cx, 0xc40000 + addr);
}

u32 cx18_av_read4_noretry(struct cx18 *cx, u16 addr)
{
return cx18_read_reg_noretry(cx, 0xc40000 + addr);
}

int cx18_av_and_or(struct cx18 *cx, u16 addr, unsigned and_mask,
u8 or_value)
{
Expand Down
1 change: 0 additions & 1 deletion drivers/media/video/cx18/cx18-av-core.h
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,6 @@ int cx18_av_write4_expect(struct cx18 *cx, u16 addr, u32 value, u32 eval,
u32 mask);
u8 cx18_av_read(struct cx18 *cx, u16 addr);
u32 cx18_av_read4(struct cx18 *cx, u16 addr);
u32 cx18_av_read4_noretry(struct cx18 *cx, u16 addr);
int cx18_av_and_or(struct cx18 *cx, u16 addr, unsigned mask, u8 value);
int cx18_av_and_or4(struct cx18 *cx, u16 addr, u32 mask, u32 value);
int cx18_av_cmd(struct cx18 *cx, unsigned int cmd, void *arg);
Expand Down
5 changes: 1 addition & 4 deletions drivers/media/video/cx18/cx18-av-firmware.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,7 @@ int cx18_av_loadfw(struct cx18 *cx)
cx18_av_write4_noretry(cx, CXADEC_DL_CTL,
dl_control);
udelay(10);
value = cx18_av_read4_noretry(cx,
CXADEC_DL_CTL);
value = cx18_av_read4(cx, CXADEC_DL_CTL);
if (value == dl_control)
break;
/* Check if we can correct the byte by changing
Expand All @@ -80,8 +79,6 @@ int cx18_av_loadfw(struct cx18 *cx)
break;
}
}
cx18_log_write_retries(cx, retries2,
cx->reg_mem + 0xc40000 + CXADEC_DL_CTL);
if (unrec_err || retries2 >= CX18_MAX_MMIO_WR_RETRIES)
break;
}
Expand Down
28 changes: 9 additions & 19 deletions drivers/media/video/cx18/cx18-driver.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,14 +78,9 @@ static int radio[CX18_MAX_CARDS] = { -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1 };
static int mmio_ndelay[CX18_MAX_CARDS] = { -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1 };
static unsigned cardtype_c = 1;
static unsigned tuner_c = 1;
static unsigned radio_c = 1;
static unsigned mmio_ndelay_c = 1;
static char pal[] = "--";
static char secam[] = "--";
static char ntsc[] = "-";
Expand All @@ -99,18 +94,20 @@ static int enc_pcm_buffers = CX18_DEFAULT_ENC_PCM_BUFFERS;

static int cx18_pci_latency = 1;

int cx18_retry_mmio = 1;
static int mmio_ndelay;
static int retry_mmio = 1;

int cx18_debug;

module_param_array(tuner, int, &tuner_c, 0644);
module_param_array(radio, bool, &radio_c, 0644);
module_param_array(cardtype, int, &cardtype_c, 0644);
module_param_array(mmio_ndelay, int, &mmio_ndelay_c, 0644);
module_param_string(pal, pal, sizeof(pal), 0644);
module_param_string(secam, secam, sizeof(secam), 0644);
module_param_string(ntsc, ntsc, sizeof(ntsc), 0644);
module_param_named(debug, cx18_debug, int, 0644);
module_param_named(retry_mmio, cx18_retry_mmio, int, 0644);
module_param(mmio_ndelay, int, 0644);
module_param(retry_mmio, int, 0644);
module_param(cx18_pci_latency, int, 0644);
module_param(cx18_first_minor, int, 0644);

Expand Down Expand Up @@ -155,13 +152,11 @@ MODULE_PARM_DESC(cx18_pci_latency,
"Change the PCI latency to 64 if lower: 0 = No, 1 = Yes,\n"
"\t\t\tDefault: Yes");
MODULE_PARM_DESC(retry_mmio,
"Check and retry memory mapped IO accesses\n"
"\t\t\tDefault: 1 [Yes]");
"(Deprecated) MMIO writes are now always checked and retried\n"
"\t\t\tEffectively: 1 [Yes]");
MODULE_PARM_DESC(mmio_ndelay,
"Delay (ns) for each CX23418 memory mapped IO access.\n"
"\t\t\tTry larger values that are close to a multiple of the\n"
"\t\t\tPCI clock period, 30.3 ns, if your card doesn't work.\n"
"\t\t\tDefault: " __stringify(CX18_DEFAULT_MMIO_NDELAY));
"(Deprecated) MMIO accesses are now never purposely delayed\n"
"\t\t\tEffectively: 0 ns");
MODULE_PARM_DESC(enc_mpg_buffers,
"Encoder MPG Buffers (in MB)\n"
"\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_MPG_BUFFERS));
Expand Down Expand Up @@ -378,11 +373,6 @@ static void cx18_process_options(struct cx18 *cx)
cx->options.tuner = tuner[cx->num];
cx->options.radio = radio[cx->num];

if (mmio_ndelay[cx->num] < 0)
cx->options.mmio_ndelay = CX18_DEFAULT_MMIO_NDELAY;
else
cx->options.mmio_ndelay = mmio_ndelay[cx->num];

cx->std = cx18_parse_std(cx);
if (cx->options.cardtype == -1) {
CX18_INFO("Ignore card\n");
Expand Down
13 changes: 0 additions & 13 deletions drivers/media/video/cx18/cx18-driver.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,6 @@
# error "This driver requires kernel PCI support."
#endif

/* Default delay to throttle mmio access to the CX23418 */
#define CX18_DEFAULT_MMIO_NDELAY 0 /* 0 ns = 0 PCI clock(s) / 33 MHz */

#define CX18_MEM_OFFSET 0x00000000
#define CX18_MEM_SIZE 0x04000000
#define CX18_REG_OFFSET 0x02000000
Expand Down Expand Up @@ -176,7 +173,6 @@

#define CX18_MAX_PGM_INDEX (400)

extern int cx18_retry_mmio; /* enable check & retry of mmio accesses */
extern int cx18_debug;


Expand All @@ -185,7 +181,6 @@ struct cx18_options {
int cardtype; /* force card type on load */
int tuner; /* set tuner on load */
int radio; /* enable/disable radio */
unsigned long mmio_ndelay; /* delay in ns after every PCI mmio access */
};

/* per-buffer bit flags */
Expand Down Expand Up @@ -371,13 +366,6 @@ struct cx18_i2c_algo_callback_data {
};

#define CX18_MAX_MMIO_WR_RETRIES 10
#define CX18_MAX_MMIO_RD_RETRIES 2

struct cx18_mmio_stats {
atomic_t retried_write[CX18_MAX_MMIO_WR_RETRIES+1];
atomic_t retried_read[CX18_MAX_MMIO_RD_RETRIES+1];
};

#define CX18_MAX_MB_ACK_DELAY 100

struct cx18_mbox_stats {
Expand Down Expand Up @@ -475,7 +463,6 @@ struct cx18 {
struct mutex gpio_lock;

/* Statistics */
struct cx18_mmio_stats mmio_stats;
struct cx18_mbox_stats mbox_stats;

/* v4l2 and User settings */
Expand Down
2 changes: 0 additions & 2 deletions drivers/media/video/cx18/cx18-gpio.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,6 @@ static void gpio_write(struct cx18 *cx)
CX18_REG_GPIO_DIR2, ~dir_hi, dir_hi);
cx18_write_reg_expect(cx, (dir_hi << 16) | val_hi,
CX18_REG_GPIO_OUT2, val_hi, dir_hi);
if (!cx18_retry_mmio)
(void) cx18_read_reg(cx, CX18_REG_GPIO_OUT2); /* sync */
}

void cx18_reset_i2c_slaves_gpio(struct cx18 *cx)
Expand Down
18 changes: 6 additions & 12 deletions drivers/media/video/cx18/cx18-i2c.c
Original file line number Diff line number Diff line change
Expand Up @@ -161,9 +161,9 @@ static void cx18_setscl(void *data, int state)
u32 r = cx18_read_reg(cx, addr);

if (state)
cx18_write_reg_sync(cx, r | SETSCL_BIT, addr);
cx18_write_reg(cx, r | SETSCL_BIT, addr);
else
cx18_write_reg_sync(cx, r & ~SETSCL_BIT, addr);
cx18_write_reg(cx, r & ~SETSCL_BIT, addr);
}

static void cx18_setsda(void *data, int state)
Expand All @@ -174,9 +174,9 @@ static void cx18_setsda(void *data, int state)
u32 r = cx18_read_reg(cx, addr);

if (state)
cx18_write_reg_sync(cx, r | SETSDL_BIT, addr);
cx18_write_reg(cx, r | SETSDL_BIT, addr);
else
cx18_write_reg_sync(cx, r & ~SETSDL_BIT, addr);
cx18_write_reg(cx, r & ~SETSDL_BIT, addr);
}

static int cx18_getscl(void *data)
Expand Down Expand Up @@ -405,16 +405,10 @@ int init_cx18_i2c(struct cx18 *cx)
}
/* courtesy of Steven Toth <stoth@hauppauge.com> */
cx18_write_reg_expect(cx, 0x00c00000, 0xc7001c, 0x00000000, 0x00c000c0);
if (!cx18_retry_mmio)
(void) cx18_read_reg(cx, 0xc7001c); /* sync */
mdelay(10);
cx18_write_reg_expect(cx, 0x00c000c0, 0xc7001c, 0x000000c0, 0x00c000c0);
if (!cx18_retry_mmio)
(void) cx18_read_reg(cx, 0xc7001c); /* sync */
mdelay(10);
cx18_write_reg_expect(cx, 0x00c00000, 0xc7001c, 0x00000000, 0x00c000c0);
if (!cx18_retry_mmio)
(void) cx18_read_reg(cx, 0xc7001c); /* sync */
mdelay(10);

/* Set to edge-triggered intrs. */
Expand All @@ -424,12 +418,12 @@ int init_cx18_i2c(struct cx18 *cx)
~(HW2_I2C1_INT|HW2_I2C2_INT), HW2_I2C1_INT|HW2_I2C2_INT);

/* Hw I2C1 Clock Freq ~100kHz */
cx18_write_reg_sync(cx, 0x00021c0f & ~4, CX18_REG_I2C_1_WR);
cx18_write_reg(cx, 0x00021c0f & ~4, CX18_REG_I2C_1_WR);
cx18_setscl(&cx->i2c_algo_cb_data[0], 1);
cx18_setsda(&cx->i2c_algo_cb_data[0], 1);

/* Hw I2C2 Clock Freq ~100kHz */
cx18_write_reg_sync(cx, 0x00021c0f & ~4, CX18_REG_I2C_2_WR);
cx18_write_reg(cx, 0x00021c0f & ~4, CX18_REG_I2C_2_WR);
cx18_setscl(&cx->i2c_algo_cb_data[1], 1);
cx18_setsda(&cx->i2c_algo_cb_data[1], 1);

Expand Down
128 changes: 0 additions & 128 deletions drivers/media/video/cx18/cx18-io.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,141 +31,13 @@ void cx18_log_statistics(struct cx18 *cx)
if (!(cx18_debug & CX18_DBGFLG_INFO))
return;

for (i = 0; i <= CX18_MAX_MMIO_WR_RETRIES; i++)
CX18_DEBUG_INFO("retried_write[%d] = %d\n", i,
atomic_read(&cx->mmio_stats.retried_write[i]));
for (i = 0; i <= CX18_MAX_MMIO_RD_RETRIES; i++)
CX18_DEBUG_INFO("retried_read[%d] = %d\n", i,
atomic_read(&cx->mmio_stats.retried_read[i]));
for (i = 0; i <= CX18_MAX_MB_ACK_DELAY; i++)
if (atomic_read(&cx->mbox_stats.mb_ack_delay[i]))
CX18_DEBUG_INFO("mb_ack_delay[%d] = %d\n", i,
atomic_read(&cx->mbox_stats.mb_ack_delay[i]));
return;
}

void cx18_raw_writel_retry(struct cx18 *cx, u32 val, void __iomem *addr)
{
int i;
for (i = 0; i < CX18_MAX_MMIO_WR_RETRIES; i++) {
cx18_raw_writel_noretry(cx, val, addr);
if (val == cx18_raw_readl_noretry(cx, addr))
break;
}
cx18_log_write_retries(cx, i, addr);
}

u32 cx18_raw_readl_retry(struct cx18 *cx, const void __iomem *addr)
{
int i;
u32 val;
for (i = 0; i < CX18_MAX_MMIO_RD_RETRIES; i++) {
val = cx18_raw_readl_noretry(cx, addr);
if (val != 0xffffffff) /* PCI bus read error */
break;
}
cx18_log_read_retries(cx, i, addr);
return val;
}

u16 cx18_raw_readw_retry(struct cx18 *cx, const void __iomem *addr)
{
int i;
u16 val;
for (i = 0; i < CX18_MAX_MMIO_RD_RETRIES; i++) {
val = cx18_raw_readw_noretry(cx, addr);
if (val != 0xffff) /* PCI bus read error */
break;
}
cx18_log_read_retries(cx, i, addr);
return val;
}

void cx18_writel_retry(struct cx18 *cx, u32 val, void __iomem *addr)
{
int i;
for (i = 0; i < CX18_MAX_MMIO_WR_RETRIES; i++) {
cx18_writel_noretry(cx, val, addr);
if (val == cx18_readl_noretry(cx, addr))
break;
}
cx18_log_write_retries(cx, i, addr);
}

void _cx18_writel_expect(struct cx18 *cx, u32 val, void __iomem *addr,
u32 eval, u32 mask)
{
int i;
eval &= mask;
for (i = 0; i < CX18_MAX_MMIO_WR_RETRIES; i++) {
cx18_writel_noretry(cx, val, addr);
if (eval == (cx18_readl_noretry(cx, addr) & mask))
break;
}
cx18_log_write_retries(cx, i, addr);
}

void cx18_writew_retry(struct cx18 *cx, u16 val, void __iomem *addr)
{
int i;
for (i = 0; i < CX18_MAX_MMIO_WR_RETRIES; i++) {
cx18_writew_noretry(cx, val, addr);
if (val == cx18_readw_noretry(cx, addr))
break;
}
cx18_log_write_retries(cx, i, addr);
}

void cx18_writeb_retry(struct cx18 *cx, u8 val, void __iomem *addr)
{
int i;
for (i = 0; i < CX18_MAX_MMIO_WR_RETRIES; i++) {
cx18_writeb_noretry(cx, val, addr);
if (val == cx18_readb_noretry(cx, addr))
break;
}
cx18_log_write_retries(cx, i, addr);
}

u32 cx18_readl_retry(struct cx18 *cx, const void __iomem *addr)
{
int i;
u32 val;
for (i = 0; i < CX18_MAX_MMIO_RD_RETRIES; i++) {
val = cx18_readl_noretry(cx, addr);
if (val != 0xffffffff) /* PCI bus read error */
break;
}
cx18_log_read_retries(cx, i, addr);
return val;
}

u16 cx18_readw_retry(struct cx18 *cx, const void __iomem *addr)
{
int i;
u16 val;
for (i = 0; i < CX18_MAX_MMIO_RD_RETRIES; i++) {
val = cx18_readw_noretry(cx, addr);
if (val != 0xffff) /* PCI bus read error */
break;
}
cx18_log_read_retries(cx, i, addr);
return val;
}

u8 cx18_readb_retry(struct cx18 *cx, const void __iomem *addr)
{
int i;
u8 val;
for (i = 0; i < CX18_MAX_MMIO_RD_RETRIES; i++) {
val = cx18_readb_noretry(cx, addr);
if (val != 0xff) /* PCI bus read error */
break;
}
cx18_log_read_retries(cx, i, addr);
return val;
}

void cx18_memset_io(struct cx18 *cx, void __iomem *addr, int val, size_t count)
{
u8 __iomem *dst = addr;
Expand Down
Loading

0 comments on commit 3f75c61

Please sign in to comment.