Skip to content

Commit

Permalink
[usb,aon_wake] Report 'bus not idle' status to usbdev
Browse files Browse the repository at this point in the history
The 'bus not idle' condition had to be inferred by software,
from the absence of Bus Reset and Disconnect indications;
less than ideal from a robustness perspective even when returning
from Deep Sleep, but it afforded no opportunity to indicate a
non-idle bus state whilst still suspending/entering sleep.
Introduce an explicit indication for increased robustness and
error recovery.

Signed-off-by: Adrian Lees <[email protected]>
  • Loading branch information
alees24 committed Mar 14, 2024
1 parent 73dc5ea commit d254749
Show file tree
Hide file tree
Showing 19 changed files with 216 additions and 41 deletions.
8 changes: 8 additions & 0 deletions hw/ip/pinmux/data/pinmux.hjson
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,14 @@
struct: "logic",
width: "1"
},
{ name: "usbdev_bus_not_idle",
type: "uni",
act: "req",
package: "",
struct: "logic",
width: "1",
default: "1'b0"
},
{ name: "usbdev_bus_reset",
type: "uni",
act: "req",
Expand Down
15 changes: 13 additions & 2 deletions hw/ip/pinmux/data/pinmux.hjson.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -286,12 +286,23 @@
struct: "logic",
width: "1"
},
{ name: "usbdev_bus_not_idle",
type: "uni",
act: "req",
package: "",
desc: '''
Event signal that indicates that the USB was not idle while monitoring.
''',
struct: "logic",
width: "1",
default: "1'b0"
},
{ name: "usbdev_bus_reset",
type: "uni",
act: "req",
package: "",
desc: '''
Event signal that indicates what happened while monitoring.
Event signal that indicates that the USB issued a Bus Reset while monitoring.
''',
struct: "logic",
width: "1",
Expand All @@ -302,7 +313,7 @@
act: "req",
package: "",
desc: '''
Event signal that indicates what happened while monitoring.
Event signal that indicates that USB SENSE signal was lost while monitoring.
''',
struct: "logic",
width: "1",
Expand Down
5 changes: 3 additions & 2 deletions hw/ip/pinmux/doc/interfaces.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,9 @@ Referring to the [Comportable guideline for peripheral device functionality](htt
| usb_wkup_req | logic | uni | req | 1 | Wakeup request from USB wakeup detector, going to the power manager, running on the AON clock. |
| usbdev_suspend_req | logic | uni | rcv | 1 | Indicates whether USB is in suspended state, coming from the USB device. |
| usbdev_wake_ack | logic | uni | rcv | 1 | Acknowledges the USB wakeup request, coming from the USB device. |
| usbdev_bus_reset | logic | uni | req | 1 | Event signal that indicates what happened while monitoring. |
| usbdev_sense_lost | logic | uni | req | 1 | Event signal that indicates what happened while monitoring. |
| usbdev_bus_not_idle | logic | uni | req | 1 | Event signal that indicates that the USB was not idle while monitoring. |
| usbdev_bus_reset | logic | uni | req | 1 | Event signal that indicates that the USB issued a Bus Reset while monitoring. |
| usbdev_sense_lost | logic | uni | req | 1 | Event signal that indicates what USB SENSE was lost while monitoring. |
| usbdev_wake_detect_active | logic | uni | req | 1 | State debug information. |
| tl | tlul_pkg::tl | req_rsp | rsp | 1 | |

Expand Down
1 change: 1 addition & 0 deletions hw/ip/pinmux/fpv/tb/pinmux_bind_fpv.sv
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ module pinmux_bind_fpv;
.usb_dnpullup_en_o,
.usbdev_suspend_req_i,
.usbdev_wake_ack_i,
.usbdev_bus_not_idle_o,
.usbdev_bus_reset_o,
.usbdev_sense_lost_o,
.usbdev_wake_detect_active_o,
Expand Down
1 change: 1 addition & 0 deletions hw/ip/pinmux/fpv/tb/pinmux_tb.sv
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ module pinmux_tb
output logic usb_dnpullup_en_o,
input usbdev_suspend_req_i,
input usbdev_wake_ack_i,
output logic usbdev_bus_not_idle_o,
output logic usbdev_bus_reset_o,
output logic usbdev_sense_lost_o,
output logic usbdev_wake_detect_active_o,
Expand Down
2 changes: 2 additions & 0 deletions hw/ip/pinmux/rtl/pinmux.sv
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ module pinmux
output usb_dnpullup_en_o,
input usbdev_suspend_req_i,
input usbdev_wake_ack_i,
output usbdev_bus_not_idle_o,
output usbdev_bus_reset_o,
output usbdev_sense_lost_o,
output usbdev_wake_detect_active_o,
Expand Down Expand Up @@ -387,6 +388,7 @@ module pinmux

// wake/powerup request
.wake_req_aon_o(usb_wkup_req_o),
.bus_not_idle_aon_o(usbdev_bus_not_idle_o),
.bus_reset_aon_o(usbdev_bus_reset_o),
.sense_lost_aon_o(usbdev_sense_lost_o),
.wake_detect_active_aon_o(usbdev_wake_detect_active_o)
Expand Down
15 changes: 15 additions & 0 deletions hw/ip/usbdev/data/usbdev.hjson
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,13 @@
struct: "logic",
width: "1"
},
{ name: "usb_aon_bus_not_idle",
type: "uni",
act: "rcv",
package: "",
struct: "logic",
width: "1"
},
{ name: "usb_aon_wake_detect_active",
type: "uni",
act: "rcv",
Expand Down Expand Up @@ -1241,6 +1248,14 @@
USB aon wake module detected a bus reset while monitoring events.
'''
}
{
bits: "10",
resval: "0",
name: "bus_not_idle",
desc: '''
USB aon wake module detected a non-idle bus while monitoring events.
'''
}
]
}
{ name: "fifo_ctrl",
Expand Down
1 change: 1 addition & 0 deletions hw/ip/usbdev/doc/interfaces.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ Referring to the [Comportable guideline for peripheral device functionality](htt
| usb_aon_wake_ack | logic | uni | req | 1 | |
| usb_aon_bus_reset | logic | uni | rcv | 1 | |
| usb_aon_sense_lost | logic | uni | rcv | 1 | |
| usb_aon_bus_not_idle | logic | uni | rcv | 1 | |
| usb_aon_wake_detect_active | logic | uni | rcv | 1 | |
| ram_cfg | prim_ram_1p_pkg::ram_1p_cfg | uni | rcv | 1 | |
| tl | tlul_pkg::tl | req_rsp | rsp | 1 | |
Expand Down
7 changes: 4 additions & 3 deletions hw/ip/usbdev/doc/registers.md
Original file line number Diff line number Diff line change
Expand Up @@ -1328,17 +1328,18 @@ Activation may not happen immediately, and its status can be verified by checkin
USB wake module events and debug
- Offset: `0x94`
- Reset default: `0x0`
- Reset mask: `0x301`
- Reset mask: `0x701`

### Fields

```wavejson
{"reg": [{"name": "module_active", "bits": 1, "attr": ["ro"], "rotate": -90}, {"bits": 7}, {"name": "disconnected", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "bus_reset", "bits": 1, "attr": ["ro"], "rotate": -90}, {"bits": 22}], "config": {"lanes": 1, "fontsize": 10, "vspace": 150}}
{"reg": [{"name": "module_active", "bits": 1, "attr": ["ro"], "rotate": -90}, {"bits": 7}, {"name": "disconnected", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "bus_reset", "bits": 1, "attr": ["ro"], "rotate": -90}, {"name": "bus_not_idle", "bits": 1, "attr": ["ro"], "rotate": -90}, {"bits": 21}], "config": {"lanes": 1, "fontsize": 10, "vspace": 150}}
```

| Bits | Type | Reset | Name | Description |
|:------:|:------:|:-------:|:--------------|:-------------------------------------------------------------------------------|
| 31:10 | | | | Reserved |
| 31:11 | | | | Reserved |
| 10 | ro | 0x0 | bus_not_idle | USB aon wake module detected a non-idle bus while monitoring events. |
| 9 | ro | 0x0 | bus_reset | USB aon wake module detected a bus reset while monitoring events. |
| 8 | ro | 0x0 | disconnected | USB aon wake module detected VBUS was interrupted while monitoring events. |
| 7:1 | | | | Reserved |
Expand Down
1 change: 1 addition & 0 deletions hw/ip/usbdev/dv/tb/tb.sv
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ module tb;
.usb_aon_suspend_req_o (),
.usb_aon_wake_ack_o (),
// Events and debug info from wakeup module
.usb_aon_bus_not_idle_i ('0),
.usb_aon_bus_reset_i ('0),
.usb_aon_sense_lost_i ('0),
.usb_aon_wake_detect_active_i ('0),
Expand Down
3 changes: 3 additions & 0 deletions hw/ip/usbdev/rtl/usbdev.sv
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ module usbdev
// Events and state from wakeup module
input logic usb_aon_bus_reset_i,
input logic usb_aon_sense_lost_i,
input logic usb_aon_bus_not_idle_i,
input logic usb_aon_wake_detect_active_i,

// SOF reference for clock calibration
Expand Down Expand Up @@ -1252,6 +1253,8 @@ module usbdev

assign hw2reg.wake_events.module_active.de = 1'b1;
assign hw2reg.wake_events.module_active.d = usb_aon_wake_detect_active_i;
assign hw2reg.wake_events.bus_not_idle.de = 1'b1;
assign hw2reg.wake_events.bus_not_idle.d = usb_aon_bus_not_idle_i;
assign hw2reg.wake_events.disconnected.de = 1'b1;
assign hw2reg.wake_events.disconnected.d = usb_aon_sense_lost_i;
assign hw2reg.wake_events.bus_reset.de = 1'b1;
Expand Down
10 changes: 10 additions & 0 deletions hw/ip/usbdev/rtl/usbdev_aon_wake.sv
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ module usbdev_aon_wake import usbdev_pkg::*;(
output logic wake_req_aon_o,

// Event signals that indicate what happened while monitoring
output logic bus_not_idle_aon_o,
output logic bus_reset_aon_o,
output logic sense_lost_aon_o,

Expand Down Expand Up @@ -72,6 +73,7 @@ module usbdev_aon_wake import usbdev_pkg::*;(
// active.
logic se0_async, sense_lost_async;
logic event_bus_reset, event_sense_lost;
logic bus_not_idle_d, bus_not_idle_q;
logic bus_reset_d, bus_reset_q;
logic sense_lost_d, sense_lost_q;

Expand Down Expand Up @@ -100,9 +102,15 @@ module usbdev_aon_wake import usbdev_pkg::*;(
.filter_o (event_sense_lost)
);

// USB has become non-idle while monitoring.
assign bus_not_idle_d = (event_not_idle | bus_not_idle_q) & wake_detect_active_q;
// USB has issued a Bus Reset condition while monitoring.
assign bus_reset_d = (event_bus_reset | bus_reset_q) & wake_detect_active_q;
// USB SENSE signal has been lost (Disconnection) while monitoring.
assign sense_lost_d = (event_sense_lost | sense_lost_q) & wake_detect_active_q;

// Detected events
assign bus_not_idle_aon_o = bus_not_idle_q;
assign bus_reset_aon_o = bus_reset_q;
assign sense_lost_aon_o = sense_lost_q;

Expand All @@ -113,10 +121,12 @@ module usbdev_aon_wake import usbdev_pkg::*;(

always_ff @(posedge clk_aon_i or negedge rst_aon_ni) begin : proc_reg_events
if (!rst_aon_ni) begin
bus_not_idle_q <= 1'b0;
bus_reset_q <= 1'b0;
sense_lost_q <= 1'b0;
wake_req_q <= 1'b0;
end else begin
bus_not_idle_q <= bus_not_idle_d;
bus_reset_q <= bus_reset_d;
sense_lost_q <= sense_lost_d;
wake_req_q <= wake_req_d;
Expand Down
30 changes: 17 additions & 13 deletions hw/ip/usbdev/rtl/usbdev_reg_pkg.sv
Original file line number Diff line number Diff line change
Expand Up @@ -633,6 +633,10 @@ package usbdev_reg_pkg;
logic d;
logic de;
} bus_reset;
struct packed {
logic d;
logic de;
} bus_not_idle;
} usbdev_hw2reg_wake_events_reg_t;

// Register -> HW type
Expand Down Expand Up @@ -666,19 +670,19 @@ package usbdev_reg_pkg;

// HW -> register type
typedef struct packed {
usbdev_hw2reg_intr_state_reg_t intr_state; // [321:286]
usbdev_hw2reg_usbctrl_reg_t usbctrl; // [285:278]
usbdev_hw2reg_usbstat_reg_t usbstat; // [277:248]
usbdev_hw2reg_rxfifo_reg_t rxfifo; // [247:231]
usbdev_hw2reg_rxenable_out_mreg_t [11:0] rxenable_out; // [230:207]
usbdev_hw2reg_in_sent_mreg_t [11:0] in_sent; // [206:183]
usbdev_hw2reg_out_stall_mreg_t [11:0] out_stall; // [182:159]
usbdev_hw2reg_in_stall_mreg_t [11:0] in_stall; // [158:135]
usbdev_hw2reg_configin_mreg_t [11:0] configin; // [134:63]
usbdev_hw2reg_out_data_toggle_reg_t out_data_toggle; // [62:39]
usbdev_hw2reg_in_data_toggle_reg_t in_data_toggle; // [38:15]
usbdev_hw2reg_phy_pins_sense_reg_t phy_pins_sense; // [14:6]
usbdev_hw2reg_wake_events_reg_t wake_events; // [5:0]
usbdev_hw2reg_intr_state_reg_t intr_state; // [323:288]
usbdev_hw2reg_usbctrl_reg_t usbctrl; // [287:280]
usbdev_hw2reg_usbstat_reg_t usbstat; // [279:250]
usbdev_hw2reg_rxfifo_reg_t rxfifo; // [249:233]
usbdev_hw2reg_rxenable_out_mreg_t [11:0] rxenable_out; // [232:209]
usbdev_hw2reg_in_sent_mreg_t [11:0] in_sent; // [208:185]
usbdev_hw2reg_out_stall_mreg_t [11:0] out_stall; // [184:161]
usbdev_hw2reg_in_stall_mreg_t [11:0] in_stall; // [160:137]
usbdev_hw2reg_configin_mreg_t [11:0] configin; // [136:65]
usbdev_hw2reg_out_data_toggle_reg_t out_data_toggle; // [64:41]
usbdev_hw2reg_in_data_toggle_reg_t in_data_toggle; // [40:17]
usbdev_hw2reg_phy_pins_sense_reg_t phy_pins_sense; // [16:8]
usbdev_hw2reg_wake_events_reg_t wake_events; // [7:0]
} usbdev_hw2reg_t;

// Register offsets
Expand Down
49 changes: 40 additions & 9 deletions hw/ip/usbdev/rtl/usbdev_reg_top.sv
Original file line number Diff line number Diff line change
Expand Up @@ -727,7 +727,7 @@ module usbdev_reg_top (
logic wake_control_we;
logic [1:0] wake_control_qs;
logic wake_control_busy;
logic [9:0] wake_events_qs;
logic [10:0] wake_events_qs;
logic wake_events_busy;
logic fifo_ctrl_we;
logic fifo_ctrl_avout_rst_wd;
Expand Down Expand Up @@ -778,25 +778,29 @@ module usbdev_reg_top (
logic aon_wake_events_disconnected_qs_int;
logic aon_wake_events_bus_reset_ds_int;
logic aon_wake_events_bus_reset_qs_int;
logic [9:0] aon_wake_events_ds;
logic aon_wake_events_bus_not_idle_ds_int;
logic aon_wake_events_bus_not_idle_qs_int;
logic [10:0] aon_wake_events_ds;
logic aon_wake_events_qe;
logic [9:0] aon_wake_events_qs;
logic [10:0] aon_wake_events_qs;

always_comb begin
aon_wake_events_qs = 10'h0;
aon_wake_events_ds = 10'h0;
aon_wake_events_qs = 11'h0;
aon_wake_events_ds = 11'h0;
aon_wake_events_ds[0] = aon_wake_events_module_active_ds_int;
aon_wake_events_qs[0] = aon_wake_events_module_active_qs_int;
aon_wake_events_ds[8] = aon_wake_events_disconnected_ds_int;
aon_wake_events_qs[8] = aon_wake_events_disconnected_qs_int;
aon_wake_events_ds[9] = aon_wake_events_bus_reset_ds_int;
aon_wake_events_qs[9] = aon_wake_events_bus_reset_qs_int;
aon_wake_events_ds[10] = aon_wake_events_bus_not_idle_ds_int;
aon_wake_events_qs[10] = aon_wake_events_bus_not_idle_qs_int;
end

prim_reg_cdc #(
.DataWidth(10),
.ResetVal(10'h0),
.BitMask(10'h301),
.DataWidth(11),
.ResetVal(11'h0),
.BitMask(11'h701),
.DstWrReq(1)
) u_wake_events_cdc (
.clk_src_i (clk_i),
Expand Down Expand Up @@ -8081,7 +8085,7 @@ module usbdev_reg_top (


// R[wake_events]: V(False)
logic [2:0] wake_events_flds_we;
logic [3:0] wake_events_flds_we;
assign aon_wake_events_qe = |wake_events_flds_we;
// F[module_active]: 0:0
prim_subreg #(
Expand Down Expand Up @@ -8164,6 +8168,33 @@ module usbdev_reg_top (
.qs (aon_wake_events_bus_reset_qs_int)
);

// F[bus_not_idle]: 10:10
prim_subreg #(
.DW (1),
.SwAccess(prim_subreg_pkg::SwAccessRO),
.RESVAL (1'h0),
.Mubi (1'b0)
) u_wake_events_bus_not_idle (
.clk_i (clk_aon_i),
.rst_ni (rst_aon_ni),

// from register interface
.we (1'b0),
.wd ('0),

// from internal hardware
.de (hw2reg.wake_events.bus_not_idle.de),
.d (hw2reg.wake_events.bus_not_idle.d),

// to internal hardware
.qe (wake_events_flds_we[3]),
.q (),
.ds (aon_wake_events_bus_not_idle_ds_int),

// to register interface (read)
.qs (aon_wake_events_bus_not_idle_qs_int)
);


// R[fifo_ctrl]: V(False)
logic fifo_ctrl_qe;
Expand Down
Loading

0 comments on commit d254749

Please sign in to comment.