icE1usb fw: E1 core config update depending on state
Store Rx/Tx config separately so we can change some of the config bit depending on current state while still keeping what the user asked for. Not really used ATM since state is never IDLE, but for future use. Signed-off-by: Sylvain Munaut <tnt@246tNt.com> Change-Id: I0b4cbf88abc4af801054ba5d6779dede5649852a
This commit is contained in:
parent
e98c0334ec
commit
9410bdf8dd
|
@ -234,14 +234,20 @@ enum e1_pipe_state {
|
||||||
|
|
||||||
struct e1_state {
|
struct e1_state {
|
||||||
struct {
|
struct {
|
||||||
uint32_t cr;
|
struct {
|
||||||
|
uint32_t cfg;
|
||||||
|
uint32_t val;
|
||||||
|
} cr;
|
||||||
struct e1_fifo fifo;
|
struct e1_fifo fifo;
|
||||||
int in_flight;
|
int in_flight;
|
||||||
enum e1_pipe_state state;
|
enum e1_pipe_state state;
|
||||||
} rx;
|
} rx;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
uint32_t cr;
|
struct {
|
||||||
|
uint32_t cfg;
|
||||||
|
uint32_t val;
|
||||||
|
} cr;
|
||||||
struct e1_fifo fifo;
|
struct e1_fifo fifo;
|
||||||
int in_flight;
|
int in_flight;
|
||||||
enum e1_pipe_state state;
|
enum e1_pipe_state state;
|
||||||
|
@ -280,6 +286,30 @@ _get_state(int port)
|
||||||
E1_TX_CR_LOOPBACK | \
|
E1_TX_CR_LOOPBACK | \
|
||||||
E1_TX_CR_LOOPBACK_CROSS )
|
E1_TX_CR_LOOPBACK_CROSS )
|
||||||
|
|
||||||
|
static void
|
||||||
|
_e1_update_cr_val(int port)
|
||||||
|
{
|
||||||
|
struct e1_state *e1 = _get_state(port);
|
||||||
|
|
||||||
|
/* RX */
|
||||||
|
if (e1->rx.state == IDLE) {
|
||||||
|
/* "Off" state: Force MFA mode to detect remote side */
|
||||||
|
e1->rx.cr.val = (e1->rx.cr.cfg & ~E1_RX_CR_MODE_MASK) | E1_RX_CR_ENABLE | E1_RX_CR_MODE_MFA;
|
||||||
|
} else {
|
||||||
|
/* "On state: Enabled + User config */
|
||||||
|
e1->rx.cr.val = e1->rx.cr.cfg | E1_RX_CR_ENABLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TX */
|
||||||
|
if (e1->tx.state == IDLE) {
|
||||||
|
/* "Off" state: We TX only OIS */
|
||||||
|
e1->tx.cr.val = (e1->tx.cr.cfg & ~(E1_TX_CR_MODE_MASK | E1_TX_CR_ALARM)) | E1_TX_CR_ENABLE | E1_TX_CR_MODE_TRSP;
|
||||||
|
} else {
|
||||||
|
/* "On state: Enabled + User config */
|
||||||
|
e1->tx.cr.val = e1->tx.cr.cfg | E1_TX_CR_ENABLE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
e1_init(int port, uint16_t rx_cr, uint16_t tx_cr)
|
e1_init(int port, uint16_t rx_cr, uint16_t tx_cr)
|
||||||
{
|
{
|
||||||
|
@ -293,17 +323,18 @@ e1_init(int port, uint16_t rx_cr, uint16_t tx_cr)
|
||||||
e1f_init(&e1->rx.fifo, (512 * port) + 0, 256);
|
e1f_init(&e1->rx.fifo, (512 * port) + 0, 256);
|
||||||
e1f_init(&e1->tx.fifo, (512 * port) + 256, 256);
|
e1f_init(&e1->tx.fifo, (512 * port) + 256, 256);
|
||||||
|
|
||||||
/* Enable Rx */
|
/* Flow state */
|
||||||
e1->rx.cr = E1_RX_CR_ENABLE | (rx_cr & RXCR_PERMITTED);
|
|
||||||
e1_regs->rx.csr = E1_RX_CR_OVFL_CLR | e1->rx.cr;
|
|
||||||
|
|
||||||
/* Enable Tx */
|
|
||||||
e1->tx.cr = E1_TX_CR_ENABLE | (tx_cr & TXCR_PERMITTED);
|
|
||||||
e1_regs->tx.csr = E1_TX_CR_UNFL_CLR | e1->tx.cr;
|
|
||||||
|
|
||||||
/* State */
|
|
||||||
e1->rx.state = BOOT;
|
e1->rx.state = BOOT;
|
||||||
e1->tx.state = BOOT;
|
e1->tx.state = BOOT;
|
||||||
|
|
||||||
|
/* Set config registers */
|
||||||
|
e1->rx.cr.cfg = rx_cr & RXCR_PERMITTED;
|
||||||
|
e1->tx.cr.cfg = tx_cr & TXCR_PERMITTED;
|
||||||
|
|
||||||
|
_e1_update_cr_val(port);
|
||||||
|
|
||||||
|
e1_regs->rx.csr = e1->rx.cr.val;
|
||||||
|
e1_regs->tx.csr = e1->tx.cr.val;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -311,8 +342,9 @@ e1_rx_config(int port, uint16_t cr)
|
||||||
{
|
{
|
||||||
volatile struct e1_core *e1_regs = _get_regs(port);
|
volatile struct e1_core *e1_regs = _get_regs(port);
|
||||||
struct e1_state *e1 = _get_state(port);
|
struct e1_state *e1 = _get_state(port);
|
||||||
e1->rx.cr = (e1->rx.cr & ~RXCR_PERMITTED) | (cr & RXCR_PERMITTED);
|
e1->rx.cr.cfg = cr & RXCR_PERMITTED;
|
||||||
e1_regs->rx.csr = e1->rx.cr;
|
_e1_update_cr_val(port);
|
||||||
|
e1_regs->rx.csr = e1->rx.cr.val;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -320,8 +352,9 @@ e1_tx_config(int port, uint16_t cr)
|
||||||
{
|
{
|
||||||
volatile struct e1_core *e1_regs = _get_regs(port);
|
volatile struct e1_core *e1_regs = _get_regs(port);
|
||||||
struct e1_state *e1 = _get_state(port);
|
struct e1_state *e1 = _get_state(port);
|
||||||
e1->tx.cr = (e1->tx.cr & ~TXCR_PERMITTED) | (cr & TXCR_PERMITTED);
|
e1->tx.cr.cfg = cr & TXCR_PERMITTED;
|
||||||
e1_regs->tx.csr = e1->tx.cr;
|
_e1_update_cr_val(port);
|
||||||
|
e1_regs->tx.csr = e1->tx.cr.val;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int
|
unsigned int
|
||||||
|
@ -523,7 +556,7 @@ e1_poll(int port)
|
||||||
|
|
||||||
/* Clear overflow if needed */
|
/* Clear overflow if needed */
|
||||||
if (e1->rx.state != RUN) {
|
if (e1->rx.state != RUN) {
|
||||||
e1_regs->rx.csr = e1->rx.cr | E1_RX_CR_OVFL_CLR;
|
e1_regs->rx.csr = e1->rx.cr.val | E1_RX_CR_OVFL_CLR;
|
||||||
e1->rx.state = RUN;
|
e1->rx.state = RUN;
|
||||||
}
|
}
|
||||||
done_rx:
|
done_rx:
|
||||||
|
@ -554,7 +587,7 @@ done_rx:
|
||||||
|
|
||||||
/* Clear underflow if needed */
|
/* Clear underflow if needed */
|
||||||
if (e1->tx.state != RUN) {
|
if (e1->tx.state != RUN) {
|
||||||
e1_regs->tx.csr = e1->tx.cr | E1_TX_CR_UNFL_CLR;
|
e1_regs->tx.csr = e1->tx.cr.val | E1_TX_CR_UNFL_CLR;
|
||||||
e1->tx.state = RUN;
|
e1->tx.state = RUN;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue