blob: 03d466c3753548455e4ee5954af2aa112c60be74 [file] [log] [blame]
// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
{ name: "usbdev",
clock_primary: "clk_i",
other_clock_list: [ "clk_aon_i", "clk_usb_48mhz_i" ]
reset_primary: "rst_ni",
other_reset_list: [ "rst_aon_ni", "rst_usb_48mhz_ni" ]
bus_interfaces: [
{ protocol: "tlul", direction: "device" }
],
available_inout_list: [
{ name: "d", desc: "USB data differential" }
{ name: "dp", desc: "USB data D+" }
{ name: "dn", desc: "USB data D-" }
],
available_input_list: [
{ name: "sense", desc: "USB host VBUS sense" }
],
available_output_list: [
{ name: "se0", desc: "USB single-ended zero link state" }
{ name: "dp_pullup", desc: "USB D+ pullup control" }
{ name: "dn_pullup", desc: "USB D- pullup control" }
{ name: "tx_mode_se", desc: "USB single-ended transmit mode control" }
{ name: "suspend", desc: "USB link suspend state" }
],
inter_signal_list: [
{ name: "usb_ref_val",
type: "uni",
act: "req",
package: "",
struct: "logic",
width: "1"
}
{ name: "usb_ref_pulse",
type: "uni",
act: "req",
package: "",
struct: "logic",
width: "1"
},
{ name: "usb_out_of_rst",
type: "uni",
act: "req",
package: "",
struct: "logic",
width: "1"
},
{ name: "usb_aon_wake_en",
type: "uni",
act: "req",
package: "",
struct: "logic",
width: "1"
},
{ name: "usb_aon_wake_ack",
type: "uni",
act: "req",
package: "",
struct: "logic",
width: "1"
},
{ name: "usb_suspend",
type: "uni",
act: "req",
package: "",
struct: "logic",
width: "1"
},
{ name: "usb_state_debug",
type: "uni",
act: "rcv",
package: "usbdev_pkg",
struct: "awk_state",
},
{ struct: "ram_2p_cfg",
package: "prim_ram_2p_pkg",
type: "uni",
name: "ram_cfg",
act: "rcv"
}
]
param_list: [
{ name: "NEndpoints",
type: "int",
default: "12",
desc: "Number of endpoints",
local: "true"
}
],
interrupt_list: [
{ name: "pkt_received"
desc: '''
Raised if a packet was received using an OUT or SETUP transaction.
'''
}
{ name: "pkt_sent"
desc: '''
Raised if a packet was sent as part of an IN transaction.
'''
}
{ name: "disconnected",
desc: '''
Raised if VBUS is lost thus the link is disconnected.
'''
}
{ name: "host_lost",
desc: '''
Raised if link is active but SOF was not received from host for 4.096 ms. The SOF should be every 1 ms.
'''
}
{ name: "link_reset",
desc: '''
Raised if the link is at SE0 longer than 3 us indicating a link reset (host asserts for min 10 ms, device can react after 2.5 us).
'''
}
{ name: "link_suspend",
desc: '''
Raised if the line has signaled J for longer than 3ms and is therefore in suspend state.
'''
}
{ name: "link_resume",
desc: '''
Raised when the link becomes active again after being suspended.
'''
}
{ name: "av_empty",
desc: '''
Raised when a transaction is NACKed because the Available Buffer FIFO for OUT or SETUP transactions is empty.
'''
}
{ name: "rx_full",
desc: '''
Raised when a transaction is NACKed because the Received Buffer FIFO for OUT or SETUP transactions is full.
'''
}
{ name: "av_overflow",
desc: '''
Raised if a write was done to the Available Buffer FIFO when the FIFO was full.
'''
}
{ name: "link_in_err",
desc: '''
Raised if a packet to an IN endpoint started to be received but was
then dropped due to an error. After transmitting the IN payload,
the USB device expects a valid ACK handshake packet. This error is
raised if either the packet or CRC is invalid or a different token
was received.
'''
}
{ name: "rx_crc_err",
desc: '''
Raised if a CRC error occured.
'''
}
{ name: "rx_pid_err",
desc: '''
Raised if an invalid packed identifier (PID) was received.
'''
}
{ name: "rx_bitstuff_err",
desc: '''
Raised if an invalid bitstuffing was received.
'''
}
{ name: "frame",
desc: '''
Raised when the USB frame number is updated with a valid SOF.
'''
}
{ name: "connected",
desc: "Raised if VBUS is applied."
}
{ name: "link_out_err",
desc: '''
Raised if a packet to an OUT endpoint started to be received but was then dropped due to an error.
This error is raised if either the data toggle, token, packet or CRC is invalid or if there is no buffer available in the Received Buffer FIFO.
'''
}
]
regwidth: "32",
registers: [
{ name: "usbctrl",
desc: "USB Control",
swaccess: "rw",
hwaccess: "hro",
fields: [
{
bits: "0",
name: "enable",
desc: '''
Set to enable the USB interface and assert the pullup.
'''
tags: [// Prevent usb from being enabled to avoid other unforeseen side effects.
"excl:CsrNonInitTests:CsrExclWrite"]
}
{
bits: "22:16",
name: "device_address",
hwaccess: "hrw",
desc: '''
Device address set by host (this should be copied from
the Set Device ID SETUP packet).
This will be zeroed by the hardware when the link resets.
'''
tags: [// This field is reset to 0 if usb is not enabled.
"excl:CsrNonInitTests:CsrExclWriteCheck"]
}
]
}
{ name: "usbstat",
desc: "USB Status",
swaccess: "ro",
hwaccess: "hwo",
hwext: "true",
fields: [
{
bits: "10:0",
name: "frame",
desc: '''
Frame index received from host. On an active link, this will increment every milisecond.
'''
}
{
bits: "11",
name: "host_lost",
desc: '''
Start of frame not received from host for 4.096 ms and the line is active.
'''
}
{
bits: "14:12",
name: "link_state",
desc: '''
State of USB link, decoded from line.
'''
enum: [
{ value: "0",
name: "disconnect",
desc: "Link disconnected (no VBUS)"
},
{ value: "1",
name: "powered",
desc: "Link powered, but not reset yet"
},
{ value: "2",
name: "powered_suspend",
desc: "Link suspended (constant idle/J for > 3 ms), but not reset yet"
},
{ value: "3",
name: "active",
desc: "Link active"
},
{ value: "4",
name: "suspend",
desc: "Link suspended (constant idle for > 3 ms), was active before becoming suspended"
},
{ value: "5",
name: "active_nosof",
desc: "Link active but no SOF has been received since the last reset."
},
]
}
{
bits: "15",
name: "sense",
desc: '''
Reflects the state of the sense pin.
1 indicates that the host is providing VBUS.
Note that this bit always shows the state of the actual pin and does not take account of the override control.
'''
}
{
bits: "18:16",
name: "av_depth",
desc: '''
Number of buffers in the Available Buffer FIFO.
These buffers are available for receiving packets.
'''
}
{
bits: "23",
name: "av_full",
desc: '''
Available Buffer FIFO is full.
'''
}
{
bits: "26:24",
name: "rx_depth",
desc: '''
Number of buffers in the Received Buffer FIFO.
These buffers have packets that have been received and
should be popped from the FIFO and processed.
'''
}
{
bits: "31",
name: "rx_empty",
resval: "1",
desc: '''
Received Buffer FIFO is empty.
'''
}
]
}
{ name: "avbuffer",
desc: "Available Buffer FIFO",
swaccess: "wo",
hwaccess: "hro",
hwqe: "true",
fields: [
{
bits: "4:0",
name: "buffer",
desc: '''
This field contains the buffer ID being passed to the USB receive engine.
If the Available Buffer FIFO is full, any write operations are discarded.
'''
}
]
tags: [// Writing this CSR affects the ral.usbstat.av_depth field.
"excl:CsrNonInitTests:CsrExclWrite"]
}
{ name: "rxfifo",
desc: "Received Buffer FIFO",
swaccess: "ro",
hwaccess: "hrw",
hwext: "true",
hwre: "true",
fields: [
{
bits: "4:0",
name: "buffer",
desc: '''
This field contains the buffer ID that data was received into.
On read the buffer ID is popped from the Received Buffer FIFO and returned to software.
'''
}
{
bits: "14:8",
name: "size",
desc: '''
This field contains the data length in bytes of the packet written to the buffer.
'''
}
{
bits: "19",
name: "setup",
desc: '''
This bit indicates if the received transaction is of type SETUP (1) or OUT (0).
'''
}
{
bits: "23:20",
name: "ep",
desc: '''
This field contains the endpoint ID to which the packet was directed.
'''
}
]
}
{ multireg: {
name: "rxenable_setup",
count: "NEndpoints"
cname: "Endpoint"
desc: "Receive SETUP transaction enable",
swaccess: "rw",
hwaccess: "hro",
fields: [
{
bits: "0",
name: "setup",
desc: '''
This bit must be set to enable SETUP transactions to be
received on the endpoint. If the bit is clear then a
SETUP request will be responded to with a NACK.
'''
}
]
}
}
{ multireg: {
name: "rxenable_out",
count: "NEndpoints"
cname: "Endpoint"
desc: "Receive OUT transaction enable",
swaccess: "rw",
hwaccess: "hro",
fields: [
{
bits: "0",
name: "out",
desc: '''
This bit must be set to enable OUT transactions to be
received on the endpoint. If the bit is clear then an
OUT request will be responded to with a NACK.
'''
}
]
}
}
{ multireg: {
name: "in_sent",
count: "NEndpoints"
cname: "Endpoint"
desc: "IN Transaction Sent",
swaccess: "rw1c",
hwaccess: "hwo",
fields: [
{
bits: "0",
name: "sent",
desc: '''
This bit will be set when the ACK is received from
the host to indicate successful packet delivery
as part of an IN transaction.
'''
}
]
}
}
{ multireg: {
name: "stall",
count: "NEndpoints"
cname: "Endpoint"
desc: "Endpoint STALL control",
swaccess: "rw",
hwaccess: "hrw",
fields: [
{
bits: "0",
name: "stall",
desc: '''
If this bit is set then an IN or OUT transaction to this endpoint will be responded to with a STALL return.
This is used when the endpoint is disabled (functional stall) or when a control transfer is not supported (protocol stall).
SETUP transactions are always accepted and a SETUP will clear the stall flag (this is necessary for protocol stalls, to avoid sending stalls on subsequent IN/OUT transfers).
'''
}
]
}
}
{ multireg: {
name: "configin",
count: "NEndpoints"
cname: "Endpoint"
desc: "Configure IN Transaction",
swaccess: "rw",
hwaccess: "hro",
fields: [
{
bits: "4:0",
name: "buffer",
desc: '''
The buffer ID containing the data to send when an IN transaction is received on the endpoint.
'''
}
{
bits: "14:8",
name: "size",
desc: '''
The number of bytes to send from the buffer.
If this is 0 then a CRC only packet is sent.
If this is greater than 64 then 64 bytes are sent.
'''
}
{
bits: "30",
name: "pend",
swaccess: "rw1c"
hwaccess: "hrw"
desc: '''
This bit indicates a pending transaction was canceled by the hardware.
The bit is set when the rdy bit is cleared by hardware because of a
SETUP packet being received or a link reset being detected.
The bit remains set until cleared by being written with a 1.
'''
}
{
bits: "31",
name: "rdy",
hwaccess: "hrw"
desc: '''
This bit should be set to indicate the buffer is ready for sending.
It will be cleared when the ACK is received indicating the host has accepted the data.
This bit will also be cleared if an enabled SETUP transaction is received on the endpoint.
This allows use of the IN channel for transfer of SETUP information.
The original buffer must be resubmitted after the SETUP sequence is complete.
A link reset also clears the bit.
In either of the cases where the hardware cancels the transaction it will also set the pend bit.
'''
}
]
}
}
{ multireg: {
name: "iso",
count: "NEndpoints"
cname: "Endpoint"
desc: "Endpoint ISO setting",
swaccess: "rw",
hwaccess: "hro",
fields: [
{
bits: "0",
name: "iso",
desc: '''
If this bit is set then the endpoint will be treated as an ISO endpoint.
No handshake packet will be sent for an OUT transaction and no handshake packet will be expected for an IN transaction.
'''
}
]
}
}
{ multireg: {
name: "data_toggle_clear",
count: "NEndpoints"
cname: "Endpoint"
desc: "Clear the data toggle flag",
swaccess: "wo",
hwaccess: "hro",
hwqe: "true",
fields: [
{
bits: "0",
name: "clear",
desc: '''
Writing 1 to this bit will clear the data toggle bit for this endpoint to Data0 in both IN and OUT directions.
The register must no be written again within 200 ns.
'''
}
]
}
}
{ name: "phy_pins_sense",
desc: '''
USB PHY pins sense.
This register can be used to read out the state of the USB device inputs and outputs from software.
This is designed to be used for debugging purposes or during chip testing.
'''
swaccess: "ro",
hwaccess: "hwo",
hwext: "true",
fields: [
{
bits: "0",
name: "rx_dp_i",
desc: "USB D+ input."
}
{
bits: "1",
name: "rx_dn_i",
desc: "USB D- input."
}
{
bits: "2",
name: "rx_d_i",
desc: "USB differential input."
}
{
bits: "8",
name: "tx_dp_o",
desc: "USB D+ output (readback)."
}
{
bits: "9",
name: "tx_dn_o",
desc: "USB D- output (readback)."
}
{
bits: "10",
name: "tx_d_o",
desc: "USB differential output (readback)."
}
{
bits: "11",
name: "tx_se0_o",
desc: "USB SE0 output (readback)."
}
{
bits: "12",
name: "tx_oe_o",
desc: "USB OE output (readback)."
}
{
bits: "13",
name: "suspend_o",
desc: "USB suspend output (readback)."
}
{
bits: "16",
name: "pwr_sense",
desc: "USB power sense signal."
}
]
tags: [// Updated by HW based on observed USB PHY signals, comprises also readbacks.
// Exclude all read checks in all tests including reset tests.
"excl:CsrAllTests:CsrExclCheck"]
}
{ name: "phy_pins_drive",
desc: '''
USB PHY pins drive.
This register can be used to control the USB device inputs and outputs from software.
This is designed to be used for debugging purposes or during chip testing.
'''
swaccess: "rw",
hwaccess: "hro",
fields: [
{
bits: "0",
name: "dp_o",
desc: "USB D+ output."
}
{
bits: "1",
name: "dn_o",
desc: "USB D- output."
}
{
bits: "2",
name: "d_o",
desc: "USB differential output."
}
{
bits: "3",
name: "se0_o",
desc: "USB SE0 output."
}
{
bits: "4",
name: "oe_o",
desc: "USB OE output."
}
{
bits: "5",
name: "tx_mode_se_o",
desc: "USB TX mode. 0: Differential, 1: Single-ended."
}
{
bits: "6",
name: "dp_pullup_en_o",
desc: "USB D+ pullup enable output."
}
{
bits: "7",
name: "dn_pullup_en_o",
desc: "USB D- pullup enable output."
}
{
bits: "8",
name: "suspend_o",
desc: "USB suspend output."
}
{
bits: "16",
name: "en",
desc: '''
0: Outputs are controlled by the hardware block.
1: Outputs are controlled with this register.
'''
}
]
}
{ name: "phy_config",
desc: "USB PHY Configuration",
swaccess: "rw",
hwaccess: "hro",
fields: [
{
bits: "0",
resval: "0",
name: "rx_differential_mode",
desc: '''
Use the differential RX signal instead of the single-ended signals.
Currently only 0 (single-ended operation) is supported.
'''
}
{
bits: "1",
resval: "0",
name: "tx_differential_mode",
desc: '''
Use the differential TX signal instead of the single-ended signals.
Currently only 0 (single-ended operation) is supported.
'''
}
{
bits: "2",
name: "eop_single_bit",
resval: "1",
desc: '''
Recognize a single SE0 bit as an end of packet, otherwise two successive bits are required.
'''
}
{
bits: "3",
name: "override_pwr_sense_en",
desc: '''
Override the USB power sense value with override_pwr_sense_val.
'''
tags: [// Overriding pwr sense will cause the usbdev to think the link is powered up.
"excl:CsrNonInitTests:CsrExclWrite"]
}
{
bits: "4",
name: "override_pwr_sense_val",
desc: '''
0: USB power not present, 1: present.
'''
}
{
bits: "5",
resval: "0",
name: "pinflip",
desc: '''
Flip the D+/D- pins.
Particularly useful if D+/D- are mapped to SBU1/SBU2 pins of USB-C.
'''
}
{
bits: "6",
resval: "0",
name: "usb_ref_disable",
desc: '''
0: Enable reference signal generation for clock synchronization, 1: disable it by forcing the associated signals to zero.
'''
}
{
bits: "7",
resval: "0",
name: "tx_osc_test_mode",
desc: '''
Disable (0) or enable (1) oscillator test mode.
If enabled, the device constantly transmits a J/K pattern, which is useful for testing the USB clock.
Note that while in oscillator test mode, the device no longer receives SOFs and consequently does not generate the reference signal for clock synchronization.
The clock might drift off.
'''
}
]
}
{ name: "wake_config",
desc: "USB wake configuration for suspend / resume",
swaccess: "rw",
hwaccess: "hro",
fields: [
{
bits: "0",
resval: "0",
name: "wake_en",
desc: '''
Enable the usb resume wake function. When this is set, a resume indication from
a usb host can be used to drive a wake from sleep event.
Note this function is meant to be set as a mode and not toggled on/off every time
usb enters / exit suspend.
'''
tags: [// Prevent usb wake functions from being turned on outside of directed tests
"excl:CsrNonInitTests:CsrExclWrite"]
}
{
bits: "1",
resval: "0",
name: "wake_ack",
desc: '''
Wake acknowledgement. Once the usb device resumes from suspend, this acknowledgement is used
to transition the module back to normal operation.
Note wake acknowledgement is only necessary if wake_en was '1' when the usb device was suspended.
However, setting/clearing this bit during other conditions has no side effects.
'''
},
]
}
{ name: "wake_debug",
desc: "USB wake module debug",
swaccess: "ro",
hwaccess: "hwo",
fields: [
{
bits: "2:0",
resval: "0",
name: "state",
desc: '''
USB aon wake module state read back
'''
}
]
}
{ window: {
name: "buffer",
items: "512",
validbits: "32",
byte-write: "false",
unusual: "false"
swaccess: "rw",
desc: '''
2 kB packet buffer. Divided into 32 64-byte buffers.
The packet buffer is used for sending and receiveing packets.
'''
},
},
]
}