Commit e0e8e29c authored by Benoit Rat's avatar Benoit Rat Committed by Alessandro Rubini

dio: update the mode of wr-nic with new gateware.

This also updates the links to binaries in the documentation.
Signed-off-by: Alessandro Rubini's avatarAlessandro Rubini <rubini@gnudd.com>
parent 7044d545
...@@ -602,8 +602,8 @@ the @i{files} tab of the Open Hardware Repository. The direct ...@@ -602,8 +602,8 @@ the @i{files} tab of the Open Hardware Repository. The direct
links are as follows (the former is required, the latter is optional): links are as follows (the former is required, the latter is optional):
@example @example
http://www.ohwr.org/attachments/download/1757/wr_nic_dio.bin-2012-12-14 http://www.ohwr.org/attachments/download/2687/wr_nic_dio.bin-2014-02-14
http://www.ohwr.org/attachments/download/1758/wr_nic_dio-wrc.bin-2012-12-14 http://www.ohwr.org/attachments/download/2688/wr_nic_dio-wrc.bin-2014-02-14
@end example @end example
The date is included in the binary name so we won't need to remove the The date is included in the binary name so we won't need to remove the
...@@ -618,9 +618,9 @@ needed to run @i{wr-nic}: ...@@ -618,9 +618,9 @@ needed to run @i{wr-nic}:
@smallexample @smallexample
cd /tmp cd /tmp
wget -O wr_nic_dio.bin \ wget -O wr_nic_dio.bin \
http://www.ohwr.org/attachments/download/1757/wr_nic_dio.bin-2012-12-14 http://www.ohwr.org/attachments/download/2687/wr_nic_dio.bin-2014-02-14
wget -O wr_nic_dio-wrc.bin \ wget -O wr_nic_dio-wrc.bin \
http://www.ohwr.org/attachments/download/1758/wr_nic_dio-wrc.bin-2012-12-14 http://www.ohwr.org/attachments/download/2688/wr_nic_dio-wrc.bin-2014-02-14
sudo mv wr_nic_dio wr_nic_dio-wrc /lib/firmware/fmc sudo mv wr_nic_dio wr_nic_dio-wrc /lib/firmware/fmc
@end smallexample @end smallexample
......
...@@ -155,13 +155,37 @@ ...@@ -155,13 +155,37 @@
#define DIO_CYC4_CYC_W(value) WBGEN2_GEN_WRITE(value, 0, 28) #define DIO_CYC4_CYC_W(value) WBGEN2_GEN_WRITE(value, 0, 28)
#define DIO_CYC4_CYC_R(reg) WBGEN2_GEN_READ(reg, 0, 28) #define DIO_CYC4_CYC_R(reg) WBGEN2_GEN_READ(reg, 0, 28)
/* definitions for register: FMC-DIO output configuration register. */ /* definitions for register: FMC-DIO input/output configuration register. */
/* definitions for field: outmode in reg: FMC-DIO output configuration register. */ /* definitions for field: channel0 in reg: FMC-DIO input/output configuration register. */
#define DIO_OUT_MODE_MASK WBGEN2_GEN_MASK(0, 5) #define DIO_IOMODE_CH0_MASK WBGEN2_GEN_MASK(0, 4)
#define DIO_OUT_MODE_SHIFT 0 #define DIO_IOMODE_CH0_SHIFT 0
#define DIO_OUT_MODE_W(value) WBGEN2_GEN_WRITE(value, 0, 5) #define DIO_IOMODE_CH0_W(value) WBGEN2_GEN_WRITE(value, 0, 4)
#define DIO_OUT_MODE_R(reg) WBGEN2_GEN_READ(reg, 0, 5) #define DIO_IOMODE_CH0_R(reg) WBGEN2_GEN_READ(reg, 0, 4)
/* definitions for field: channel1 in reg: FMC-DIO input/output configuration register. */
#define DIO_IOMODE_CH1_MASK WBGEN2_GEN_MASK(4, 4)
#define DIO_IOMODE_CH1_SHIFT 4
#define DIO_IOMODE_CH1_W(value) WBGEN2_GEN_WRITE(value, 4, 4)
#define DIO_IOMODE_CH1_R(reg) WBGEN2_GEN_READ(reg, 4, 4)
/* definitions for field: channel2 in reg: FMC-DIO input/output configuration register. */
#define DIO_IOMODE_CH2_MASK WBGEN2_GEN_MASK(8, 4)
#define DIO_IOMODE_CH2_SHIFT 8
#define DIO_IOMODE_CH2_W(value) WBGEN2_GEN_WRITE(value, 8, 4)
#define DIO_IOMODE_CH2_R(reg) WBGEN2_GEN_READ(reg, 8, 4)
/* definitions for field: channel3 in reg: FMC-DIO input/output configuration register. */
#define DIO_IOMODE_CH3_MASK WBGEN2_GEN_MASK(12, 4)
#define DIO_IOMODE_CH3_SHIFT 12
#define DIO_IOMODE_CH3_W(value) WBGEN2_GEN_WRITE(value, 12, 4)
#define DIO_IOMODE_CH3_R(reg) WBGEN2_GEN_READ(reg, 12, 4)
/* definitions for field: channel4 in reg: FMC-DIO input/output configuration register. */
#define DIO_IOMODE_CH4_MASK WBGEN2_GEN_MASK(16, 4)
#define DIO_IOMODE_CH4_SHIFT 16
#define DIO_IOMODE_CH4_W(value) WBGEN2_GEN_WRITE(value, 16, 4)
#define DIO_IOMODE_CH4_R(reg) WBGEN2_GEN_READ(reg, 16, 4)
/* definitions for register: Time-programmable output strobe signal */ /* definitions for register: Time-programmable output strobe signal */
...@@ -594,8 +618,8 @@ PACKED struct DIO_WB { ...@@ -594,8 +618,8 @@ PACKED struct DIO_WB {
uint32_t TRIGH4; uint32_t TRIGH4;
/* [0x38]: REG fmc-dio 4 cycles to trigger a pulse generation */ /* [0x38]: REG fmc-dio 4 cycles to trigger a pulse generation */
uint32_t CYC4; uint32_t CYC4;
/* [0x3c]: REG FMC-DIO output configuration register. */ /* [0x3c]: REG FMC-DIO input/output configuration register. */
uint32_t OUT; uint32_t IOMODE;
/* [0x40]: REG Time-programmable output strobe signal */ /* [0x40]: REG Time-programmable output strobe signal */
uint32_t R_LATCH; uint32_t R_LATCH;
/* [0x44]: REG FMC-DIO time trigger is ready to accept a new trigger generation request */ /* [0x44]: REG FMC-DIO time trigger is ready to accept a new trigger generation request */
......
...@@ -531,20 +531,63 @@ peripheral { ...@@ -531,20 +531,63 @@ peripheral {
-- OUTPUT CONFIGURATION/CONTROL REGISTERS -- OUTPUT CONFIGURATION/CONTROL REGISTERS
----------------------------------------- -----------------------------------------
-- Programmable output or GPIO selection -- Programmable IO mode selection
reg { reg {
name = "FMC-DIO output configuration register. "; name = "FMC-DIO input/output configuration register. ";
description = "It allows to choose a programmable output or a standard GPIO output."; description = "It allows to choose the I/0 mode for each channel. \
prefix = "out"; - [0-1]: The two first bit correspond to which signal its connected: 0 (00) GPIO, 1 (01) DIO core, 2 (10) WRPC core, 3 Undefined\
- [2]: Output Enable Negative (Input enable)\
- [3]: 50 Ohm termination enable";
prefix = "iomode";
field {
name = "channel0";
description = "Channel 0";
prefix = "ch0";
type = SLV;
size = 4;
access_bus = READ_WRITE;
access_dev = READ_WRITE;
load = LOAD_EXT;
};
field { field {
name = "outmode"; name = "channel1";
description = "1 for programmable, 0 for GPIO output mode"; description = "Channel 1";
prefix = "mode"; prefix = "ch1";
type = SLV; type = SLV;
size = 5; size = 4;
access_bus = READ_WRITE; access_bus = READ_WRITE;
access_dev = READ_ONLY; access_dev = READ_WRITE;
load = LOAD_EXT;
};
field {
name = "channel2";
description = "Channel 2";
prefix = "ch2";
type = SLV;
size = 4;
access_bus = READ_WRITE;
access_dev = READ_WRITE;
load = LOAD_EXT;
};
field {
name = "channel3";
description = "Channel 3";
prefix = "ch3";
type = SLV;
size = 4;
access_bus = READ_WRITE;
access_dev = READ_WRITE;
load = LOAD_EXT;
};
field {
name = "channel4";
description = "Channel 4: Can be used in clock mode";
prefix = "ch4";
type = SLV;
size = 4;
access_bus = READ_WRITE;
access_dev = READ_WRITE;
load = LOAD_EXT;
}; };
}; };
......
...@@ -24,8 +24,6 @@ struct wrn_gpio_block { ...@@ -24,8 +24,6 @@ struct wrn_gpio_block {
/* And this is our bit mapping */ /* And this is our bit mapping */
#define WRN_GPIO_VALUE(bit) (1 << ((4 * (bit)) + 0)) #define WRN_GPIO_VALUE(bit) (1 << ((4 * (bit)) + 0))
#define WRN_GPIO_OE_N(bit) (1 << ((4 * (bit)) + 1))
#define WRN_GPIO_TERM(bit) (1 << ((4 * (bit)) + 2))
extern irqreturn_t wrn_dio_interrupt(struct fmc_device *fmc); extern irqreturn_t wrn_dio_interrupt(struct fmc_device *fmc);
......
...@@ -162,9 +162,9 @@ static int wrn_dio_cmd_pulse(struct wrn_drvdata *drvdata, ...@@ -162,9 +162,9 @@ static int wrn_dio_cmd_pulse(struct wrn_drvdata *drvdata,
map = regmap + ch; map = regmap + ch;
ts = cmd->t; ts = cmd->t;
/* First, configure this bit as output */ /* First, configure this bit as DIO output */
reg = readl(&dio->OUT) | (1 << ch); reg = readl(&dio->IOMODE);
writel(reg, &dio->OUT); writel(reg | (1 << 4*ch), &dio->IOMODE);
writel(ts[1].tv_nsec / 8, base + map->pulse); /* width */ writel(ts[1].tv_nsec / 8, base + map->pulse); /* width */
...@@ -208,7 +208,7 @@ static int wrn_dio_cmd_stamp(struct wrn_drvdata *drvdata, ...@@ -208,7 +208,7 @@ static int wrn_dio_cmd_stamp(struct wrn_drvdata *drvdata,
struct wr_dio_cmd *cmd) struct wr_dio_cmd *cmd)
{ {
struct dio_device *d = drvdata->mezzanine_data; struct dio_device *d = drvdata->mezzanine_data;
struct dio_channel *c; struct dio_channel *c = 0;
struct timespec *ts = cmd->t; struct timespec *ts = cmd->t;
struct regmap *map; struct regmap *map;
int mask, ch, last; int mask, ch, last;
...@@ -280,7 +280,7 @@ static int wrn_dio_cmd_inout(struct wrn_drvdata *drvdata, ...@@ -280,7 +280,7 @@ static int wrn_dio_cmd_inout(struct wrn_drvdata *drvdata,
struct DIO_WB __iomem *dio = drvdata->wrdio_base; struct DIO_WB __iomem *dio = drvdata->wrdio_base;
struct wrn_gpio_block __iomem *gpio = drvdata->gpio_base; struct wrn_gpio_block __iomem *gpio = drvdata->gpio_base;
int mask, ch, last, bits; int mask, ch, last, bits;
uint32_t reg; uint32_t reg, iomode;
if (cmd->flags & WR_DIO_F_MASK) { if (cmd->flags & WR_DIO_F_MASK) {
ch = 0; ch = 0;
...@@ -300,35 +300,29 @@ static int wrn_dio_cmd_inout(struct wrn_drvdata *drvdata, ...@@ -300,35 +300,29 @@ static int wrn_dio_cmd_inout(struct wrn_drvdata *drvdata,
/* select the bits by shifting back the value field */ /* select the bits by shifting back the value field */
bits = cmd->value >> ch; bits = cmd->value >> ch;
/* termination is bit 2 (0x4); register 0 clears, reg 4 sets */ /* Obtain the current value in iomode */
if (bits & WR_DIO_INOUT_TERM) reg = readl(&dio->IOMODE) & ~(0xF << 4*ch);
writel(WRN_GPIO_TERM(ch), &gpio->set);
else
writel(WRN_GPIO_TERM(ch), &gpio->clear);
reg = readl(&dio->OUT) & ~(1 << ch); /* Select IO mode */
if (bits & WR_DIO_INOUT_DIO) { if (bits & WR_DIO_INOUT_DIO) {
writel(reg | (1 << ch), &dio->OUT); if(bits & WR_DIO_INOUT_VALUE)
continue; /* if DIO, nothing more to do */ iomode = 2; /* WRPC connection */
else
iomode = 1; /* DIO connection */
} else {
iomode = 0; /* GPIO connection */
/* Output value is bit 0 (0x1) */
if (bits & WR_DIO_INOUT_VALUE)
writel(WRN_GPIO_VALUE(ch), &gpio->set);
else
writel(WRN_GPIO_VALUE(ch), &gpio->clear);
} }
/* If not DIO, wait after we know if input or output */
if (!(bits & WR_DIO_INOUT_OUTPUT)) {
/* output-enable is low-active, so set bit 1 (0x2) */
writel(WRN_GPIO_OE_N(ch), &gpio->set);
writel(reg, &dio->OUT); /* not DIO */
continue; /* input, no value to be set */
}
/* Output value is bit 0 (0x1) */
if (bits & WR_DIO_INOUT_VALUE)
writel(WRN_GPIO_VALUE(ch), &gpio->set);
else
writel(WRN_GPIO_VALUE(ch), &gpio->clear);
/* Then clear the low-active output enable, bit 1 (0x2) */
writel(WRN_GPIO_OE_N(ch), &gpio->clear);
writel(reg, &dio->OUT); /* not DIO */ /* Appends to iomode TERM and OUTPUT_ENABLE_N bits */
iomode |= (((bits & WR_DIO_INOUT_TERM) != 0) << 3)
| (((bits & WR_DIO_INOUT_OUTPUT) == 0) << 2);
writel(reg | (iomode << 4*ch), &dio->IOMODE);
} }
return 0; return 0;
} }
......
...@@ -205,12 +205,25 @@ static int one_mode(int c, int index) ...@@ -205,12 +205,25 @@ static int one_mode(int c, int index)
switch(c) { switch(c) {
case 'D': case 'D':
cmd->value |= WR_DIO_INOUT_TERM << index;
case 'd':
cmd->value |= WR_DIO_INOUT_DIO << index; cmd->value |= WR_DIO_INOUT_DIO << index;
cmd->value |= WR_DIO_INOUT_OUTPUT << index;
break;
case 'C':
cmd->value |= WR_DIO_INOUT_TERM << index; cmd->value |= WR_DIO_INOUT_TERM << index;
case 'c':
cmd->value |= WR_DIO_INOUT_DIO << index;
cmd->value |= WR_DIO_INOUT_VALUE << index;
break; break;
case 'd': case 'P':
cmd->value |= WR_DIO_INOUT_TERM << index;
case 'p':
cmd->value |= WR_DIO_INOUT_DIO << index; cmd->value |= WR_DIO_INOUT_DIO << index;
cmd->value |= WR_DIO_INOUT_VALUE << index;
cmd->value |= WR_DIO_INOUT_OUTPUT << index;
break; break;
case 'I': case 'I':
...@@ -223,6 +236,7 @@ static int one_mode(int c, int index) ...@@ -223,6 +236,7 @@ static int one_mode(int c, int index)
case '0': case '0':
cmd->value |= WR_DIO_INOUT_OUTPUT << index; cmd->value |= WR_DIO_INOUT_OUTPUT << index;
break; break;
default: default:
fprintf(stderr, "%s: mode: invalid mode '%c'\n", fprintf(stderr, "%s: mode: invalid mode '%c'\n",
prgname, c); prgname, c);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment