Commit 50d15e4c authored by Andrey Filippov's avatar Andrey Filippov

added priority registers updating

parent 6063fb75
...@@ -43,11 +43,16 @@ module ahci_ctrl_stat #( ...@@ -43,11 +43,16 @@ module ahci_ctrl_stat #(
output reg [31:0] regs_din, output reg [31:0] regs_din,
// input [31:0] regs_dout, // input [31:0] regs_dout,
// update register inputs (will write to register memory current value of the corresponding register) // update register inputs (will write to register memory current value of the corresponding register)
input update_GHC__IS, output update_pending,
input update_HBA_PORT__PxIS, input update_all,
input update_HBA_PORT__PxSSTS, output update_busy, // valid same cycle as update_all
input update_HBA_PORT__PxSERR,
input update_HBA_PORT__PxCMD, input update_gis, // these following individual may be unneeded - just use universal update_all
input update_pis,
input update_ssts,
input update_serr,
input update_pcmd,
input update_pci,
// PxCMD // PxCMD
input pcmd_clear_icc, // clear PxCMD.ICC field input pcmd_clear_icc, // clear PxCMD.ICC field
...@@ -55,7 +60,7 @@ module ahci_ctrl_stat #( ...@@ -55,7 +60,7 @@ module ahci_ctrl_stat #(
output pcmd_cr, // command list run - current output pcmd_cr, // command list run - current
input pcmd_cr_set, // command list run set input pcmd_cr_set, // command list run set
input pcmd_cr_reset, // command list run reset input pcmd_cr_reset, // command list run reset
input pcmd_fr, // ahci_fis_receive:get_fis_busy input pcmd_fr, // ahci_fis_receive:get_fis_busy - change to HAB set/reset (set, do, reset)
input pcmd_clear_bsy_drq, // == ahci_fis_receive:clear_bsy_drq input pcmd_clear_bsy_drq, // == ahci_fis_receive:clear_bsy_drq
output pcmd_clo, //RW1, causes ahci_fis_receive:clear_bsy_drq, that in turn resets this bit output pcmd_clo, //RW1, causes ahci_fis_receive:clear_bsy_drq, that in turn resets this bit
input pcmd_clear_st, // RW clear ST (start) bit input pcmd_clear_st, // RW clear ST (start) bit
...@@ -194,6 +199,44 @@ module ahci_ctrl_stat #( ...@@ -194,6 +199,44 @@ module ahci_ctrl_stat #(
({4{ssts_det_dp}} & 4'h3) | ({4{ssts_det_dp}} & 4'h3) |
({4{ssts_det_offline}} & 4'h4); ({4{ssts_det_offline}} & 4'h4);
// to update only HAB/async changed bits (not by the software)
wire set_ssts_ipm = ssts_ipm_dnp || ssts_ipm_active || ssts_ipm_part || ssts_ipm_slumb || ssts_ipm_devsleep;
wire set_ssts_spd = ssts_spd_dnp || ssts_spd_gen1 || ssts_spd_gen2|| ssts_spd_gen3;
wire set_ssts_det = ssts_det_ndnp || ssts_det_dnp || ssts_det_dp || ssts_det_offline;
wire set_pxcmd = pcmd_clear_icc || pcmd_esp || pcmd_cr_reset || pcmd_fr || pcmd_clear_bsy_drq || pcmd_clear_st ;
reg pxci_changed;
reg ssts_changed;
reg serr_changed;
reg sirq_changed;
reg pxcmd_changed;
reg ghc_is_changed;
wire [5:0] regs_changed={pxcmd_changed, serr_changed, ssts_changed, pxci_changed, sirq_changed,ghc_is_changed };
// wire [5:0] update;
reg [5:1] updating;
wire [5:0] update_first = {6{update_all}} &
{regs_changed[5] && ~(|regs_changed[4:0]),
regs_changed[4] && ~(|regs_changed[3:0]),
regs_changed[3] && ~(|regs_changed[2:0]),
regs_changed[2] && ~(|regs_changed[1:0]),
regs_changed[1] && ~ regs_changed[0],
regs_changed[0]};
wire [5:1] update_next = {updating[5] && ~(|updating[4:1]),
updating[4] && ~(|updating[3:1]),
updating[3] && ~(|updating[2:1]),
updating[2] && ~ updating[1],
updating[1]};
wire update_GHC__IS = update_gis || update_first[0];
wire update_HBA_PORT__PxIS = update_pis || update_first[1] || update_next[1];
wire update_HBA_PORT__PxSSTS = update_ssts || update_first[2] || update_next[2];
wire update_HBA_PORT__PxSERR = update_serr || update_first[3] || update_next[3];
wire update_HBA_PORT__PxCMD = update_pcmd || update_first[4] || update_next[4];
wire update_HBA_PORT__PxCI = update_pci || update_first[5] || update_next[5];
assign update_busy = (update_all && (|regs_changed)) || (|updating[5:1]);
assign update_pending = | regs_changed;
localparam PxIE_MASK = HBA_PORT__PxIE__TFEE__MASK | // 'h40000000; localparam PxIE_MASK = HBA_PORT__PxIE__TFEE__MASK | // 'h40000000;
HBA_PORT__PxIE__IFE__MASK | // 'h8000000; HBA_PORT__PxIE__IFE__MASK | // 'h8000000;
...@@ -337,13 +380,13 @@ localparam PxCMD_MASK = HBA_PORT__PxCMD__ICC__MASK | // 'hf0000000; ...@@ -337,13 +380,13 @@ localparam PxCMD_MASK = HBA_PORT__PxCMD__ICC__MASK | // 'hf0000000;
// HBA_PORT__PxSSTS register - updated from the HOST only // HBA_PORT__PxSSTS register - updated from the HOST only
always @(posedge mclk) begin always @(posedge mclk) begin
if (mrst) PxSSTS_r[11:8] <= 0; if (mrst) PxSSTS_r[11:8] <= 0;
else if (ssts_ipm_dnp || ssts_ipm_active || ssts_ipm_part || ssts_ipm_slumb || ssts_ipm_devsleep) PxSSTS_r[11:8] <= sssts_ipm[11:8]; else if (set_ssts_ipm) PxSSTS_r[11:8] <= sssts_ipm[11:8];
if (mrst) PxSSTS_r[ 7:4] <= 0; if (mrst) PxSSTS_r[ 7:4] <= 0;
else if (ssts_spd_dnp || ssts_spd_gen1 || ssts_spd_gen2|| ssts_spd_gen3) PxSSTS_r[ 7:4] <= sssts_spd[ 7:4]; else if (set_ssts_spd) PxSSTS_r[ 7:4] <= sssts_spd[ 7:4];
if (mrst) PxSSTS_r[ 3:0] <= 0; if (mrst) PxSSTS_r[ 3:0] <= 0;
else if (ssts_det_ndnp || ssts_det_dnp || ssts_det_dp || ssts_det_offline) PxSSTS_r[ 3:0] <= sssts_det[ 3:0]; else if (set_ssts_det) PxSSTS_r[ 3:0] <= sssts_det[ 3:0];
end end
// HBA_PORT__PxSCTL register - updated by the software only // HBA_PORT__PxSCTL register - updated by the software only
...@@ -385,15 +428,48 @@ localparam PxCMD_MASK = HBA_PORT__PxCMD__ICC__MASK | // 'hf0000000; ...@@ -385,15 +428,48 @@ localparam PxCMD_MASK = HBA_PORT__PxCMD__ICC__MASK | // 'hf0000000;
({ADDRESS_BITS{update_HBA_PORT__PxIS}} & HBA_PORT__PxIS__CPDS__ADDR) | ({ADDRESS_BITS{update_HBA_PORT__PxIS}} & HBA_PORT__PxIS__CPDS__ADDR) |
({ADDRESS_BITS{update_HBA_PORT__PxSSTS}} & HBA_PORT__PxSSTS__SPD__ADDR) | ({ADDRESS_BITS{update_HBA_PORT__PxSSTS}} & HBA_PORT__PxSSTS__SPD__ADDR) |
({ADDRESS_BITS{update_HBA_PORT__PxSERR}} & HBA_PORT__PxSERR__DIAG__X__ADDR) | ({ADDRESS_BITS{update_HBA_PORT__PxSERR}} & HBA_PORT__PxSERR__DIAG__X__ADDR) |
({ADDRESS_BITS{update_HBA_PORT__PxCMD}} & HBA_PORT__PxCMD__ICC__ADDR); ({ADDRESS_BITS{update_HBA_PORT__PxCMD}} & HBA_PORT__PxCMD__ICC__ADDR) |
({ADDRESS_BITS{update_HBA_PORT__PxCI}} & HBA_PORT__PxCI__CI__ADDR) ;
//update_HBA_PORT__PxCI
regs_din <= ({32{update_GHC__IS}} & {31'b0, ghc_is_r}) | regs_din <= ({32{update_GHC__IS}} & {31'b0, ghc_is_r}) |
({32{update_HBA_PORT__PxIS}} & PxIS_r) | ({32{update_HBA_PORT__PxIS}} & PxIS_r) |
({32{update_HBA_PORT__PxSSTS}} & {20'b0, PxSSTS_r[11:0]}) | ({32{update_HBA_PORT__PxSSTS}} & {20'b0, PxSSTS_r[11:0]}) |
({32{update_HBA_PORT__PxSERR}} & PxSERR_r) | ({32{update_HBA_PORT__PxSERR}} & PxSERR_r) |
({32{update_HBA_PORT__PxCMD}} & PxCMD_r); ({32{update_HBA_PORT__PxCMD}} & PxCMD_r) |
({32{update_HBA_PORT__PxCI}} & {31'b0, pxci0});
regs_we <= update_GHC__IS || update_HBA_PORT__PxIS || update_HBA_PORT__PxSSTS || update_HBA_PORT__PxSERR | update_HBA_PORT__PxCMD; regs_we <= update_GHC__IS || update_HBA_PORT__PxIS || update_HBA_PORT__PxSSTS || update_HBA_PORT__PxSERR | update_HBA_PORT__PxCMD;
// pending updates
if (mrst) pxci_changed <= 1; //0;
else if (pxci0_clear) pxci_changed <= 1;
else if (update_HBA_PORT__PxCI) pxci_changed <= 0;
if (mrst) ssts_changed <= 1; //0;
else if (set_ssts_ipm || set_ssts_spd || set_ssts_det) ssts_changed <= 1;
else if (update_HBA_PORT__PxSSTS) ssts_changed <= 0;
if (mrst) serr_changed <= 1; //0;
else if (serr) serr_changed <= 1;
else if (update_HBA_PORT__PxSERR) serr_changed <= 0;
if (mrst) sirq_changed <= 1; //0;
else if (sirq) sirq_changed <= 1;
else if (update_HBA_PORT__PxIS) sirq_changed <= 0;
if (mrst) pxcmd_changed <= 1; //0;
else if (set_pxcmd) pxcmd_changed <= 1;
else if (update_HBA_PORT__PxCMD) pxcmd_changed <= 0;
if (mrst) ghc_is_changed <= 1; //0;
else if (set_ghc_is_r) ghc_is_changed <= 1;
else if (update_GHC__IS) ghc_is_changed <= 0;
// updating registers if needed, 0 to 6 cycles, in priority sequence
if (mrst) updating[5:1] <= 0;
else if (update_all) updating[5:1] <= regs_changed[5:1] & ~update_first[5:1];
else updating[5:1] <= updating[5:1] & ~ update_next[5:1];
end end
endmodule endmodule
......
...@@ -53,11 +53,17 @@ module ahci_fsm #( ...@@ -53,11 +53,17 @@ module ahci_fsm #(
// Communication with ahci_ctrl_stat (some are not needed) // Communication with ahci_ctrl_stat (some are not needed)
// update register inputs (will write to register memory current value of the corresponding register) // update register inputs (will write to register memory current value of the corresponding register)
output update_GHC__IS,
output update_HBA_PORT__PxIS, // update register inputs (will write to register memory current value of the corresponding register)
output update_HBA_PORT__PxSSTS, input update_pending,
output update_HBA_PORT__PxSERR, output update_all,
output update_HBA_PORT__PxCMD, input update_busy, // valid same cycle as update_all
output update_gis, // these following individual may be unneeded - just use universal update_all
output update_pis,
output update_ssts,
output update_serr,
output update_pcmd,
output update_pci,
// PxCMD // PxCMD
output pcmd_clear_icc, // clear PxCMD.ICC field output pcmd_clear_icc, // clear PxCMD.ICC field
......
...@@ -289,14 +289,18 @@ module ahci_top#( ...@@ -289,14 +289,18 @@ module ahci_top#(
wire was_hba_rst; wire was_hba_rst;
wire was_port_rst; wire was_port_rst;
// signals between ahci_fsm and ahci_ctrl_stat // signals between ahci_fsm and ahci_ctrl_stat
wire update_regs_pending;
wire update_all_regs;
wire update_regs_busy; // valid same cycle as update_all_regs
// these following individual signals may be unneded - use update_all_regs -> update_regs_busy
wire update_GHC__IS; wire update_GHC__IS;
wire update_HBA_PORT__PxIS; wire update_HBA_PORT__PxIS;
wire update_HBA_PORT__PxSSTS; wire update_HBA_PORT__PxSSTS;
wire update_HBA_PORT__PxSERR; wire update_HBA_PORT__PxSERR;
wire update_HBA_PORT__PxCMD; wire update_HBA_PORT__PxCMD;
wire update_HBA_PORT__PxCI;
// PxCMD // PxCMD
wire pcmd_clear_icc; // clear PxCMD.ICC field wire pcmd_clear_icc; // clear PxCMD.ICC field
...@@ -381,11 +385,16 @@ module ahci_top#( ...@@ -381,11 +385,16 @@ module ahci_top#(
.phy_ready (phy_ready), // input .phy_ready (phy_ready), // input
.syncesc_send (syncesc_send), // output .syncesc_send (syncesc_send), // output
.update_GHC__IS (update_GHC__IS), // output .update_pending (update_regs_pending), // input
.update_HBA_PORT__PxIS (update_HBA_PORT__PxIS), // output .update_all (update_all_regs), // output
.update_HBA_PORT__PxSSTS (update_HBA_PORT__PxSSTS), // output .update_busy (update_regs_busy), // input
.update_HBA_PORT__PxSERR (update_HBA_PORT__PxSERR), // output .update_gis (update_GHC__IS), // output
.update_HBA_PORT__PxCMD (update_HBA_PORT__PxCMD), // output .update_pis (update_HBA_PORT__PxIS), // output
.update_ssts (update_HBA_PORT__PxSSTS), // output
.update_serr (update_HBA_PORT__PxSERR), // output
.update_pcmd (update_HBA_PORT__PxCMD), // output
.update_pci (update_HBA_PORT__PxCI), // output
.pcmd_clear_icc (pcmd_clear_icc), // output .pcmd_clear_icc (pcmd_clear_icc), // output
.pcmd_esp (pcmd_esp), // output .pcmd_esp (pcmd_esp), // output
.pcmd_cr (pcmd_cr), // input .pcmd_cr (pcmd_cr), // input
...@@ -574,11 +583,17 @@ module ahci_top#( ...@@ -574,11 +583,17 @@ module ahci_top#(
.regs_addr (regs_saddr), // output[9:0] reg .regs_addr (regs_saddr), // output[9:0] reg
.regs_we (regs_we_acs), // output reg .regs_we (regs_we_acs), // output reg
.regs_din (regs_din_from_acs), // output[31:0] reg .regs_din (regs_din_from_acs), // output[31:0] reg
.update_GHC__IS (update_GHC__IS), // input .update_pending (update_regs_pending), // output
.update_HBA_PORT__PxIS (update_HBA_PORT__PxIS), // input .update_all (update_all_regs), // input
.update_HBA_PORT__PxSSTS (update_HBA_PORT__PxSSTS), // input .update_busy (update_regs_busy), // output
.update_HBA_PORT__PxSERR (update_HBA_PORT__PxSERR), // input // input update_pending,
.update_HBA_PORT__PxCMD (update_HBA_PORT__PxCMD), // input
.update_gis (update_GHC__IS), // input
.update_pis (update_HBA_PORT__PxIS), // input
.update_ssts (update_HBA_PORT__PxSSTS), // input
.update_serr (update_HBA_PORT__PxSERR), // input
.update_pcmd (update_HBA_PORT__PxCMD), // input
.update_pci (update_HBA_PORT__PxCI), // input
.pcmd_clear_icc (pcmd_clear_icc), // input .pcmd_clear_icc (pcmd_clear_icc), // input
.pcmd_esp (pcmd_esp), // input .pcmd_esp (pcmd_esp), // input
.pcmd_cr (pcmd_cr), // output .pcmd_cr (pcmd_cr), // output
......
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