Commit 82906512 authored by Andrey Filippov's avatar Andrey Filippov

implemented run-time sequencer for the ahci_fsm, working on the actual sequence

parent 50d15e4c
...@@ -54,6 +54,11 @@ module ahci_ctrl_stat #( ...@@ -54,6 +54,11 @@ module ahci_ctrl_stat #(
input update_pcmd, input update_pcmd,
input update_pci, input update_pci,
// Next - obsolete?
output reg st01_pending, // software turned PxCMD.ST from 0 to 1
output reg st10_pending, // software turned PxCMD.ST from 1 to 0
input st_pending_reset,// reset both st01_pending and st10_pending
// PxCMD // PxCMD
input pcmd_clear_icc, // clear PxCMD.ICC field input pcmd_clear_icc, // clear PxCMD.ICC field
input pcmd_esp, // external SATA port (just forward value) input pcmd_esp, // external SATA port (just forward value)
...@@ -61,10 +66,15 @@ module ahci_ctrl_stat #( ...@@ -61,10 +66,15 @@ module ahci_ctrl_stat #(
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 - change to HAB set/reset (set, do, reset) input pcmd_fr, // ahci_fis_receive:get_fis_busy - change to HAB set/reset (set, do, reset)
output pcmd_fre, // FIS enable copy to memory
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
output pcmd_st, // current value output pcmd_st, // current value
input pfsm_started, // H: FSM done, P: FSM started (enable sensing pcmd_st_cleared)
output reg pcmd_st_cleared,// ST bit cleared by software; TODO: check not in H:Init (5.3.2.10)
//clear_bsy_drq //clear_bsy_drq
// Interrupt inputs // Interrupt inputs
input sirq_TFE, // RWC: Task File Error Status input sirq_TFE, // RWC: Task File Error Status
...@@ -96,7 +106,7 @@ module ahci_ctrl_stat #( ...@@ -96,7 +106,7 @@ module ahci_ctrl_stat #(
input serr_ET, // RWC: Transient Data Integrity Error (error not recovered by the interface) input serr_ET, // RWC: Transient Data Integrity Error (error not recovered by the interface)
input serr_EM, // RWC: Communication between the device and host was lost but re-established input serr_EM, // RWC: Communication between the device and host was lost but re-established
input serr_EI, // RWC: Recovered Data integrity Error input serr_EI, // RWC: Recovered Data integrity Error
output serr_diag_X, // value of PxSERR.DIAG.X
// SCR0: SStatus // SCR0: SStatus
...@@ -119,6 +129,8 @@ module ahci_ctrl_stat #( ...@@ -119,6 +129,8 @@ module ahci_ctrl_stat #(
output reg [3:0] sctl_ipm, // Interface power management transitions allowed output reg [3:0] sctl_ipm, // Interface power management transitions allowed
output reg [3:0] sctl_spd, // Interface maximal speed output reg [3:0] sctl_spd, // Interface maximal speed
output reg [3:0] sctl_det, // Device detection initialization requested output reg [3:0] sctl_det, // Device detection initialization requested
output reg sctl_det_changed, // Software had written new value to sctl_det
input sctl_det_reset, // clear sctl_det_changed
input pxci0_clear, // PxCI clear input pxci0_clear, // PxCI clear
output pxci0, // pxCI current value output pxci0, // pxCI current value
...@@ -235,14 +247,22 @@ module ahci_ctrl_stat #( ...@@ -235,14 +247,22 @@ module ahci_ctrl_stat #(
wire update_HBA_PORT__PxSERR = update_serr || update_first[3] || update_next[3]; 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__PxCMD = update_pcmd || update_first[4] || update_next[4];
wire update_HBA_PORT__PxCI = update_pci || update_first[5] || update_next[5]; wire update_HBA_PORT__PxCI = update_pci || update_first[5] || update_next[5];
reg pfsm_started_r;
assign update_busy = (update_all && (|regs_changed)) || (|updating[5:1]); assign update_busy = (update_all && (|regs_changed)) || (|updating[5:1]);
assign update_pending = | regs_changed; assign update_pending = | regs_changed;
assign pcmd_fre = |(HBA_PORT__PxCMD__FRE__MASK & PxCMD_r);
assign serr_diag_X = |(HBA_PORT__PxSERR__DIAG__X__MASK & PxSERR_r);
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;
HBA_PORT__PxIE__INFE__MASK | // 'h4000000; HBA_PORT__PxIE__INFE__MASK | // 'h4000000;
HBA_PORT__PxIE__OFE__MASK | // 'h1000000; HBA_PORT__PxIE__OFE__MASK | // 'h1000000;
HBA_PORT__PxIE__PRCE__MASK | // 'h400000; HBA_PORT__PxIE__PRCE__MASK | // 'h400000;
HBA_PORT__PxIE__PCE__MASK | // 'h40;
HBA_PORT__PxIE__DPE__MASK | // 'h20
HBA_PORT__PxIE__UFE__MASK | // 'h10; HBA_PORT__PxIE__UFE__MASK | // 'h10;
HBA_PORT__PxIE__SDBE__MASK | // 'h8; HBA_PORT__PxIE__SDBE__MASK | // 'h8;
HBA_PORT__PxIE__DSE__MASK | // 'h4; HBA_PORT__PxIE__DSE__MASK | // 'h4;
...@@ -254,6 +274,8 @@ localparam PxIS_MASK = HBA_PORT__PxIS__TFES__MASK | // 'h40000000; ...@@ -254,6 +274,8 @@ localparam PxIS_MASK = HBA_PORT__PxIS__TFES__MASK | // 'h40000000;
HBA_PORT__PxIS__INFS__MASK | // 'h4000000; HBA_PORT__PxIS__INFS__MASK | // 'h4000000;
HBA_PORT__PxIS__OFS__MASK | // 'h1000000; HBA_PORT__PxIS__OFS__MASK | // 'h1000000;
HBA_PORT__PxIS__PRCS__MASK | // 'h400000; HBA_PORT__PxIS__PRCS__MASK | // 'h400000;
HBA_PORT__PxIS__PCS__MASK | // 'h40;
HBA_PORT__PxIS__DPS__MASK | // 'h20
HBA_PORT__PxIS__UFS__MASK | // 'h10; HBA_PORT__PxIS__UFS__MASK | // 'h10;
HBA_PORT__PxIS__SDBS__MASK | // 'h8; HBA_PORT__PxIS__SDBS__MASK | // 'h8;
HBA_PORT__PxIS__DSS__MASK | // 'h4; HBA_PORT__PxIS__DSS__MASK | // 'h4;
...@@ -393,6 +415,9 @@ localparam PxCMD_MASK = HBA_PORT__PxCMD__ICC__MASK | // 'hf0000000; ...@@ -393,6 +415,9 @@ localparam PxCMD_MASK = HBA_PORT__PxCMD__ICC__MASK | // 'hf0000000;
always @ (posedge mclk) begin always @ (posedge mclk) begin
if (rst_por) {sctl_ipm, sctl_spd, sctl_det} <= 0; if (rst_por) {sctl_ipm, sctl_spd, sctl_det} <= 0;
else if (swr_HBA_PORT__PxSCTL) {sctl_ipm, sctl_spd, sctl_det} <= soft_write_data [11:0]; else if (swr_HBA_PORT__PxSCTL) {sctl_ipm, sctl_spd, sctl_det} <= soft_write_data [11:0];
if (rst_por || sctl_det_reset) sctl_det_changed <= 0;
else if (swr_HBA_PORT__PxSCTL && (soft_write_data[3:0] != sctl_det)) sctl_det_changed <= 1;
end end
// HBA_PORT__PxSERR register // HBA_PORT__PxSERR register
...@@ -420,6 +445,13 @@ localparam PxCMD_MASK = HBA_PORT__PxCMD__ICC__MASK | // 'hf0000000; ...@@ -420,6 +445,13 @@ localparam PxCMD_MASK = HBA_PORT__PxCMD__ICC__MASK | // 'hf0000000;
(HBA_PORT__PxCMD__FRE__MASK & PxCMD_r) | // no HBA control (HBA_PORT__PxCMD__FRE__MASK & PxCMD_r) | // no HBA control
(pcmd_clear_bsy_drq ? 0 : (PxCMD_r & HBA_PORT__PxCMD__CLO__MASK)) | (pcmd_clear_bsy_drq ? 0 : (PxCMD_r & HBA_PORT__PxCMD__CLO__MASK)) |
(pcmd_clear_st ? 0 : (PxCMD_r & HBA_PORT__PxCMD__ST__MASK)) ))); (pcmd_clear_st ? 0 : (PxCMD_r & HBA_PORT__PxCMD__ST__MASK)) )));
if (mrst) pfsm_started_r <= 0;
else if (pfsm_started) pfsm_started_r <= 1;
if (!pfsm_started_r) pcmd_st_cleared <= 0;
else if (swr_HBA_PORT__PxCMD) pcmd_st_cleared <= |(HBA_PORT__PxCMD__ST__MASK & PxCMD_r & ~soft_write_data);
end end
// Update AXI registers with the current local data // Update AXI registers with the current local data
...@@ -470,6 +502,16 @@ localparam PxCMD_MASK = HBA_PORT__PxCMD__ICC__MASK | // 'hf0000000; ...@@ -470,6 +502,16 @@ localparam PxCMD_MASK = HBA_PORT__PxCMD__ICC__MASK | // 'hf0000000;
else if (update_all) updating[5:1] <= regs_changed[5:1] & ~update_first[5:1]; 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]; else updating[5:1] <= updating[5:1] & ~ update_next[5:1];
// detect software setting for PxCMD.ST 0->1 and 1->0
if (mrst) st01_pending <= 0;
else if (swr_HBA_PORT__PxCMD && (HBA_PORT__PxCMD__ST__MASK & soft_write_data & ~PxCMD_r)) st01_pending <= 1;
if (st_pending_reset) st01_pending <= 0;
if (mrst) st10_pending <= 0;
else if (swr_HBA_PORT__PxCMD && (HBA_PORT__PxCMD__ST__MASK & ~soft_write_data & PxCMD_r)) st10_pending <= 1;
if (st_pending_reset) st10_pending <= 0;
end end
endmodule endmodule
......
...@@ -37,6 +37,8 @@ module ahci_fis_receive#( ...@@ -37,6 +37,8 @@ module ahci_fis_receive#(
// Control Interface // Control Interface
output reg fis_first_vld, // fis_first contains valid FIS header, reset by get_* output reg fis_first_vld, // fis_first contains valid FIS header, reset by get_*
// Receiving FIS // Receiving FIS
input set_update_sig, // when set, enables get_sig (and resets itself)
output pUpdateSig, // state variable
input get_sig, // update signature input get_sig, // update signature
input get_dsfis, input get_dsfis,
input get_psfis, input get_psfis,
...@@ -55,13 +57,17 @@ module ahci_fis_receive#( ...@@ -55,13 +57,17 @@ module ahci_fis_receive#(
input update_pio, // update PxTFD.STS and PxTFD.ERR from pio_* (entry PIO:Update) input update_pio, // update PxTFD.STS and PxTFD.ERR from pio_* (entry PIO:Update)
input update_prdbc, // update PRDBC in registers input update_prdbc, // update PRDBC in registers
input clear_bsy_drq, // clear PxTFD.STS.BSY and PxTFD.STS.DRQ, update input clear_bsy_drq, // clear PxTFD.STS.BSY and PxTFD.STS.DRQ, update
input clear_bsy_set_drq, // clear PxTFD.STS.BSY and sets PxTFD.STS.DRQ, update
input set_bsy, // set PxTFD.STS.BSY, update input set_bsy, // set PxTFD.STS.BSY, update
input set_sts_7f, // set PxTFD.STS = 0x7f, update input set_sts_7f, // set PxTFD.STS = 0x7f, update
input set_sts_80, // set PxTFD.STS = 0x80 (may be combined with set_sts_7f), update input set_sts_80, // set PxTFD.STS = 0x80 (may be combined with set_sts_7f), update
input clear_xfer_cntr, // clear pXferCntr (is it needed as a separate input)?
input decr_dwc, // decrement DMA Xfer counter // need pulse to 'update_prdbc' to write to registers input decr_dwc, // decrement DMA Xfer counter // need pulse to 'update_prdbc' to write to registers
input [11:0] decr_DXC_dw, // decrement value (in DWORDs) input [11:0] decr_DXC_dw, // decrement value (in DWORDs)
input pcmd_fre, // control bit enables saving FIS to memory (will be ignored for signature)
// TODO: Add writing PRDBC here? // TODO: Add writing PRDBC here?
output reg pPioXfer, // state variable output reg pPioXfer, // state variable
output [7:0] tfd_sts, // Current PxTFD status field (updated after regFIS and SDB - certain fields) output [7:0] tfd_sts, // Current PxTFD status field (updated after regFIS and SDB - certain fields)
...@@ -181,6 +187,7 @@ localparam DATA_TYPE_ERR = 3; ...@@ -181,6 +187,7 @@ localparam DATA_TYPE_ERR = 3;
reg [7:0] pio_es_r; // value of PIO E_Status reg [7:0] pio_es_r; // value of PIO E_Status
reg [7:0] pio_err_r; reg [7:0] pio_err_r;
reg pUpdateSig_r = 1; // state variable
// Forward data to DMA (dev->mem) engine // Forward data to DMA (dev->mem) engine
assign dma_in_valid = dma_in_ready && (hba_data_in_type == DATA_TYPE_DMA) && data_in_ready && !too_long_err; assign dma_in_valid = dma_in_ready && (hba_data_in_type == DATA_TYPE_DMA) && data_in_ready && !too_long_err;
...@@ -203,7 +210,7 @@ localparam DATA_TYPE_ERR = 3; ...@@ -203,7 +210,7 @@ localparam DATA_TYPE_ERR = 3;
assign data_in_dwords = data_in_dwords_r; assign data_in_dwords = data_in_dwords_r;
assign pio_es = pio_es_r; assign pio_es = pio_es_r;
assign pUpdateSig = pUpdateSig_r;
always @ (posedge mclk) begin always @ (posedge mclk) begin
if (hba_rst || dma_in_stop) dma_in <= 0; if (hba_rst || dma_in_stop) dma_in <= 0;
else if (dma_in_start) dma_in <= 1; else if (dma_in_start) dma_in <= 1;
...@@ -233,9 +240,13 @@ localparam DATA_TYPE_ERR = 3; ...@@ -233,9 +240,13 @@ localparam DATA_TYPE_ERR = 3;
({4{get_ufis}} & UFIS32_LENM1 ) | ({4{get_ufis}} & UFIS32_LENM1 ) |
({4{get_data_fis}} & DMAH_LENM1) | ({4{get_data_fis}} & DMAH_LENM1) |
({4{get_ignore}} & IGNORE_LENM1 ); ({4{get_ignore}} & IGNORE_LENM1 );
fis_save <= !get_data_fis && !get_ignore && !get_sig; // fis_save <= pcmd_fre && !get_data_fis && !get_ignore && !get_sig;
// save signature FIS to memory if waiting (if not - ignore FIS)
// for non-signature /non-data - obey pcmd_fre
fis_save <= get_sig? pUpdateSig_r : (pcmd_fre && !get_data_fis && !get_ignore);
is_data_fis <= get_data_fis; is_data_fis <= get_data_fis;
update_sig <= get_sig? 1 : 0; update_sig <= ((get_sig && pUpdateSig_r)? 1 : 0);
reg_ds <= get_dsfis ? 1 : 0; reg_ds <= get_dsfis ? 1 : 0;
reg_ps <= get_psfis ? 1 : 0; reg_ps <= get_psfis ? 1 : 0;
reg_d2h <= get_rfis ? 1 : 0; reg_d2h <= get_rfis ? 1 : 0;
...@@ -296,7 +307,8 @@ localparam DATA_TYPE_ERR = 3; ...@@ -296,7 +307,8 @@ localparam DATA_TYPE_ERR = 3;
else if (reg_ps[0]) tf_err_sts <= {hba_data_in[31:24],hba_data_in[23:16]}; else if (reg_ps[0]) tf_err_sts <= {hba_data_in[31:24],hba_data_in[23:16]};
else if (update_pio) tf_err_sts <= {pio_err_r, pio_es_r}; else if (update_pio) tf_err_sts <= {pio_err_r, pio_es_r};
else if (reg_sdb) tf_err_sts <= {hba_data_in[15:8], tf_err_sts[7], hba_data_in[6:4], tf_err_sts[3],hba_data_in[2:0]}; else if (reg_sdb) tf_err_sts <= {hba_data_in[15:8], tf_err_sts[7], hba_data_in[6:4], tf_err_sts[3],hba_data_in[2:0]};
else if (clear_bsy_drq || set_bsy) tf_err_sts <= tf_err_sts & {8'hff,clear_bsy_drq,3'h7,clear_bsy_drq,3'h7} | {8'h0,set_bsy,7'h0}; else if (clear_bsy_drq || set_bsy || clear_bsy_set_drq)
tf_err_sts <= tf_err_sts & {8'hff,clear_bsy_drq,3'h7,clear_bsy_drq,3'h7} | {8'h0,set_bsy,3'h0,clear_bsy_set_drq,3'h0};
else if (set_sts_7f || set_sts_80) tf_err_sts <= {tf_err_sts[15:8],set_sts_80,{7{set_sts_7f}}} ; else if (set_sts_7f || set_sts_80) tf_err_sts <= {tf_err_sts[15:8],set_sts_80,{7{set_sts_7f}}} ;
reg_we <= reg_we_w || update_sig[3] || update_err_sts_r || update_prdbc_r; reg_we <= reg_we_w || update_sig[3] || update_err_sts_r || update_prdbc_r;
...@@ -317,7 +329,7 @@ localparam DATA_TYPE_ERR = 3; ...@@ -317,7 +329,7 @@ localparam DATA_TYPE_ERR = 3;
if (hba_rst) pio_es_r <= 0; if (hba_rst) pio_es_r <= 0;
else if (reg_ps[3]) pio_es_r <= hba_data_in[31:24]; else if (reg_ps[3]) pio_es_r <= hba_data_in[31:24];
if (hba_rst || reg_sdb) xfer_cntr_r[31:2] <= 0; if (hba_rst || reg_sdb || clear_xfer_cntr) xfer_cntr_r[31:2] <= 0;
else if (reg_ps[4] || reg_ds[5]) xfer_cntr_r[31:2] <= {reg_ds[5]?hba_data_in[31:16]:16'b0, hba_data_in[15:2]} + hba_data_in[1]; // round up else if (reg_ps[4] || reg_ds[5]) xfer_cntr_r[31:2] <= {reg_ds[5]?hba_data_in[31:16]:16'b0, hba_data_in[15:2]} + hba_data_in[1]; // round up
else if (decr_dwc) xfer_cntr_r[31:2] <= {xfer_cntr_r[31:2]} - {18'b0, decr_DXC_dw[11:0]}; else if (decr_dwc) xfer_cntr_r[31:2] <= {xfer_cntr_r[31:2]} - {18'b0, decr_DXC_dw[11:0]};
...@@ -333,6 +345,8 @@ localparam DATA_TYPE_ERR = 3; ...@@ -333,6 +345,8 @@ localparam DATA_TYPE_ERR = 3;
if (hba_rst || update_pio) pPioXfer <= 0; if (hba_rst || update_pio) pPioXfer <= 0;
else if (reg_ps[4]) pPioXfer <= 1; else if (reg_ps[4]) pPioXfer <= 1;
if (hba_rst || set_update_sig) pUpdateSig_r <= 1;
else if (update_sig[3]) pUpdateSig_r <= 0;
// Maybe it is not needed if the fsm will send this pulse? // Maybe it is not needed if the fsm will send this pulse?
......
This diff is collapsed.
This diff is collapsed.
...@@ -100,6 +100,13 @@ module axi_ahci_regs#( ...@@ -100,6 +100,13 @@ module axi_ahci_regs#(
input [31:0] hba_din, input [31:0] hba_din,
output [31:0] hba_dout, output [31:0] hba_dout,
// Program FSM memory
output reg [17:0] pgm_ad, // @aclk, address/data to program the AHCI FSM
output reg pgm_wa, // @aclk, address strobe to program the AHCI FSM
output reg pgm_wd, // @aclk, data strobe to program the AHCI FSM
// other control signals // other control signals
output reg [ 3:0] afi_wcache, output reg [ 3:0] afi_wcache,
output reg [ 3:0] afi_rcache, output reg [ 3:0] afi_rcache,
...@@ -160,6 +167,8 @@ module axi_ahci_regs#( ...@@ -160,6 +167,8 @@ module axi_ahci_regs#(
wire high_sel = bram_waddr_r[ADDRESS_BITS-1]; // high addresses - use single-cycle writes without read-modify-write wire high_sel = bram_waddr_r[ADDRESS_BITS-1]; // high addresses - use single-cycle writes without read-modify-write
wire afi_cache_set_w = bram_wen_r && !high_sel && (bram_addr == HBA_PORT__AFI_CACHE__WR_CM__ADDR); wire afi_cache_set_w = bram_wen_r && !high_sel && (bram_addr == HBA_PORT__AFI_CACHE__WR_CM__ADDR);
wire pgm_fsm_set_w = bram_wen_r && !high_sel && (bram_addr == HBA_PORT__PGM_AHCI_SM__PGM_AD__ADDR);
wire pgm_fsm_and_w = |(ahci_regs_di & HBA_PORT__PGM_AHCI_SM__AnD__MASK);
wire set_hba_rst = bram_wen_r && !high_sel && (bram_addr == GHC__GHC__HR__ADDR) && (ahci_regs_di & GHC__GHC__HR__MASK); wire set_hba_rst = bram_wen_r && !high_sel && (bram_addr == GHC__GHC__HR__ADDR) && (ahci_regs_di & GHC__GHC__HR__MASK);
wire set_port_rst = bram_wen_r && !high_sel && (bram_addr == HBA_PORT__PxSCTL__DET__ADDR) && wire set_port_rst = bram_wen_r && !high_sel && (bram_addr == HBA_PORT__PxSCTL__DET__ADDR) &&
...@@ -228,7 +237,6 @@ module axi_ahci_regs#( ...@@ -228,7 +237,6 @@ module axi_ahci_regs#(
if (arst || set_hba_rst) was_port_rst_aclk <= 0; if (arst || set_hba_rst) was_port_rst_aclk <= 0;
else if (port_rst_on) was_port_rst_aclk <= 1; else if (port_rst_on) was_port_rst_aclk <= 1;
end end
always @ (hba_clk) begin always @ (hba_clk) begin
...@@ -243,6 +251,14 @@ module axi_ahci_regs#( ...@@ -243,6 +251,14 @@ module axi_ahci_regs#(
else if (afi_cache_set_w) {afi_wcache,afi_rcache} <= ahci_regs_di[7:0]; else if (afi_cache_set_w) {afi_wcache,afi_rcache} <= ahci_regs_di[7:0];
end end
always @(posedge aclk) begin
if (arst) {pgm_wa,pgm_wd} <= 0;
else {pgm_wa,pgm_wd} <= {2{pgm_fsm_set_w}} & {pgm_fsm_and_w, ~pgm_fsm_and_w};
if (pgm_fsm_set_w) pgm_ad <= ahci_regs_di[17:0];
end
/* /*
Will generate async reset on both HBA reset(for some time) and port reset (until released) Will generate async reset on both HBA reset(for some time) and port reset (until released)
until it is more clear about GTX reset options. Such reset will be applied to both PLL and GTX, until it is more clear about GTX reset options. Such reset will be applied to both PLL and GTX,
......
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import print_function
from __future__ import division
# Copyright (C) 2016, Elphel.inc.
# Helper module create AHCI registers type/default data
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
__author__ = "Andrey Filippov"
__copyright__ = "Copyright 2016, Elphel, Inc."
__license__ = "GPL"
__version__ = "3.0+"
__maintainer__ = "Andrey Filippov"
__email__ = "andrey@elphel.com"
__status__ = "Development"
import sys
LBL= "Label"
ACT="Action"
IF="If"
GOTO= "Goto"
ADR = "Address"
NOP = "NOP"
sequence = [{LBL:'POR', ADR: 0x0, ACT: NOP},
{ GOTO:'H:Init'},
{LBL:'HBA_RST', ADR: 0x2, ACT: NOP},
{ GOTO:'H:Init'},
{LBL:'PORT_RST', ADR: 0x4, ACT: NOP},
{ GOTO:'H:Init'},
{LBL:'COMINIT', ADR: 0x6, ACT: NOP},
{ GOTO:'P:Cominit'},
{LBL:'ST_CLEARED',ADR: 0x6, ACT: NOP}, # TODO: make sure this jump is not from P:Init
{ GOTO:'P:StartBitCleared'},
{LBL:'H:Init', ACT: NOP},
{ GOTO:'H:WaitForAhciEnable'},
{LBL:'H:WaitForAhciEnable', ACT: NOP},
{ GOTO:'H:Idle'}, # GHC.AE is always on
{LBL:'H:Idle', ACT: NOP},
{ GOTO:'P:Init'}, #All required actions for H* are done in hardware, just go to port initialization
{LBL:'P:Init', ACT: 'PFSM'}, # pfsm_started HBA init done, port FSM started
{ ACT: 'PSCI0'}, # pxci0_clear, reset both (pIssueSlot:=32) and PxCI[0]
{ ACT: 'CLEAR_BSY_SET_DRQ'}, # frcv_clear_bsy_set_drq
{ ACT: 'SET_STS_7F'}, # frcv_set_sts_7f
{ ACT: 'SET_UPDATE_SIG'}, # #frcv_set_update_sig
{ ACT: 'XMIT_COMRESET'}, # Now does it on reset. See if it is possible to transmit COMRESET w/o reset
{ GOTO:'P:NotRunning'},
{LBL:'P:NotRunning', ACT: 'NOP'}, # 'PSCI0'}, # pxci0_clear, - should not be here as it updates soft registers?
{IF:'SCTL_DET_CHANGED_TO_4',GOTO:'P:Offline'}, #4
{IF:'SCTL_DET_CHANGED_TO_1',GOTO:'P:StartComm'}, #5
# Transition 8. PxCMD.FRE written to ‘1’ from a ‘0’ and previously processed Register FIS is in receive FIFO and PxSERR.DIAG.X = ‘0’
# can not be implemented - it is too late, FIS is already gone. So as we do not move FIS receive area, there is no sense to disable FIS,
# and for the signature we'll always assume FRE is on
{IF:'ST_NB_ND', GOTO:'P:Idle'}, #12 : PxCMD.ST & !PxTBD.STS.BSY & !PxTBD.STS.DRQ
{IF:'FR_D2HR', GOTO:'NDR:Entry'}, #13 fis_first_vld & fis_type == 0x34 (D2H Register)
{ GOTO:'P:NotRunning'},#14
{LBL:'P:Cominit', ACT: 'NOP'}, # got here asynchronously from COMINIT label
{ ACT: 'SET_STS_80'}, # frcv_set_sts_80 (Not clear 0xff or 0x80 should be here?)
{ ACT: 'PXSSTS_DET_1'}, # ssts_det_dnp, // device detected, but phy communication not established
{ ACT: 'PXSERR_DIAG_X'}, # sirq_PC, // RO: Port Connect Change Status (pulse to set)
# {IF:'PXIE_PCE', GOTO:'P:CominitSetIS'}, # Not needed, interrupt
{ GOTO:'P:NotRunning'},
{LBL:'P:RegFisUpdate', ACT: 'NOP'}, #
{ ACT: 'GET_SIG'}, # get_sig
# {IF: 'pcmd_fre', GOTO:'P:RegFisPostToMem'}, # pcmd_fre hardware always copies signature FIS to 'memory' if expected
{ GOTO:'P:NotRunning'},
{LBL:'P:RegFisPostToMem', ACT: 'NOP'}, # Probably not needed, handled at lower level
{ GOTO:'P:NotRunning'},
{LBL:'P:Offline', ACT: 'SET_OFFLINE'}, # set_offline
{ GOTO:'P:NotRunning'},
{LBL:'P:StartBitCleared', ACT: 'PXCI0_CLEAR'}, # pxci0_clear
{ ACT: 'DMA_ABORT'}, # dma_cmd_abort (should eventually clear PxCMD.CR)?
{ ACT: 'PCMD_CR_CLEAR'}, # pcmd_cr_reset
{ ACT: 'XFER_CNTR_CLEAR'}, # clear_xfer_cntr
{LBL:'P:Idle', ACT: 'PCMD_CR_SET'}, # pcmd_cr_set
]
"""
pcmd_cr_set, // command list run set
clear_xfer_cntr
pcmd_cr_reset
frcv_clear_xfer_cntr
dma_cmd_abort
input fis_first_vld, // fis_first contains valid FIS header, reset by 'get_*'
input [7:0] fis_type, // FIS type (low byte in the first FIS DWORD), valid with 'fis_first_vld'
serr_diag_X ==0 , fis_first_vld,
(pIssueSlot==32) is the same as (pxci0 == 0), use pxci0_clear (pIssueSlot:=32)
localparam LABEL_POR = 11'h0;
localparam LABEL_HBA_RST = 11'h10;
localparam LABEL_PORT_RST = 11'h20;
"""
\ No newline at end of file
...@@ -423,15 +423,21 @@ src=[{gN:"PCI_Header", gS: PCIHEAD, gE:PCIHEAD+0x3f, gD:" PCI header emulation w ...@@ -423,15 +423,21 @@ src=[{gN:"PCI_Header", gS: PCIHEAD, gE:PCIHEAD+0x3f, gD:" PCI header emulation w
{fN:"MDAT", fS:10, fE:14, fT:RW, fC:0, fD:"Minimum Device Sleep Assertion Time"}, {fN:"MDAT", fS:10, fE:14, fT:RW, fC:0, fD:"Minimum Device Sleep Assertion Time"},
{fN:"DETO", fS: 2, fE: 9, fT:RW, fC:0, fD:"Device Sleep Exit Timeout"}, {fN:"DETO", fS: 2, fE: 9, fT:RW, fC:0, fD:"Device Sleep Exit Timeout"},
{fN:"DSP", fS: 1, fT:RO, fC:0, fD:"Device Sleep Present"}, {fN:"DSP", fS: 1, fT:RO, fC:0, fD:"Device Sleep Present"},
{fN:"ADSE", fS: 1, fT:RO, fC:0, fD:"Aggressive Device Sleep Enable"} {fN:"ADSE", fS: 0, fT:RO, fC:0, fD:"Aggressive Device Sleep Enable"}
]}, ]},
{rN:"AFI_CACHE", rS:0x70, rE:0x73, rD:"Port x Vendor Specific", rC: # 0x48..0x6f - reserved
{rN:"AFI_CACHE", rS:0x70, rE:0x73, rD:"Port x Vendor Specific, program AXI cache modes", rC:
[{ fS: 8, fE:31, fT:RO, fC:0, fD:"Reserved"}, [{ fS: 8, fE:31, fT:RO, fC:0, fD:"Reserved"},
{fN:"WR_CM", fS: 4, fE: 7, fT:RW, fC:3, fD:"SAXIHP write channel cache mode "}, {fN:"WR_CM", fS: 4, fE: 7, fT:RW, fC:3, fD:"SAXIHP write channel cache mode "},
{fN:"RD_CM", fS: 0, fE: 3, fT:RW, fC:3, fD:"SAXIHP read channel cache mode "}, {fN:"RD_CM", fS: 0, fE: 3, fT:RW, fC:3, fD:"SAXIHP read channel cache mode "},
]}, ]},
# 0x48..0x6f - reserved {rN:"PGM_AHCI_SM",rS:0x74, rE:0x77, rD:"Port x Vendor Specific, AHCI state machine", rC:
{rN:"PxVS", rS:0x74, rE:0x7f, rD:"Other Port x Vendor Specific", rC: [{ fS:25, fE:31, fT:RO, fC:0, fD:"Reserved"},
{fN:"AnD", fS:24, fT:RW, fC:0, fD:"Address/not data for programming AHCI state machine"},
{ fS:18, fE:23, fT:RO, fC:0, fD:"Reserved"},
{fN:"PGM_AD",fS: 0, fE:17, fT:RW, fC:3, fD:"Program address/data for programming AHCI state machine"},
]},
{rN:"PxVS", rS:0x78, rE:0x7f, rD:"Other Port x Vendor Specific", rC:
[{ fT:RW, fC:0, fD:"Vendor-specific data - 96 bits"} [{ fT:RW, fC:0, fD:"Vendor-specific data - 96 bits"}
]}, ]},
......
, .INIT_00 (256'h0000000000000000000000000001030100000001000000008000000000240020) , .INIT_00 (256'h0000000000000000000000000001030100000001000000008000000000240020)
, .INIT_08 (256'h000000000024000600000000000000000000000080000C000000000080000800) , .INIT_08 (256'h000000000024000600000000000000000000000080000C000000000080000800)
, .INIT_09 (256'h000000000000000000000000000000000000000000000000FFFFFFFF00000000) , .INIT_09 (256'h000000000000000000000000000000000000000000000000FFFFFFFF00000000)
, .INIT_0B (256'h0000000000000000000000000000003300000000000000000000000000000000) , .INIT_0B (256'h0000000000000000000000030000003300000000000000000000000000000000)
, .INIT_0C (256'h000000000000000000000000000000000000000001010001001000000001FFFE) , .INIT_0C (256'h000000000000000000000000000000000000000001010001001000000001FFFE)
, .INIT_0D (256'h000001000000000000000040000000000001FFFE000000008000000000000000) , .INIT_0D (256'h000001000000000000000040000000000001FFFE000000008000000000000000)
, .INIT_0E (256'h0000000000000000000000000000000000000000000000000000000040000001) , .INIT_0E (256'h0000000000000000000000000000000000000000000000000000000040000001)
...@@ -776,7 +776,7 @@ ...@@ -776,7 +776,7 @@
localparam HBA_PORT__PxDEVSLP__DSP__DFLT = 'h0; localparam HBA_PORT__PxDEVSLP__DSP__DFLT = 'h0;
// RO: Aggressive Device Sleep Enable // RO: Aggressive Device Sleep Enable
localparam HBA_PORT__PxDEVSLP__ADSE__ADDR = 'h51; localparam HBA_PORT__PxDEVSLP__ADSE__ADDR = 'h51;
localparam HBA_PORT__PxDEVSLP__ADSE__MASK = 'h2; localparam HBA_PORT__PxDEVSLP__ADSE__MASK = 'h1;
localparam HBA_PORT__PxDEVSLP__ADSE__DFLT = 'h0; localparam HBA_PORT__PxDEVSLP__ADSE__DFLT = 'h0;
// RW: SAXIHP write channel cache mode // RW: SAXIHP write channel cache mode
localparam HBA_PORT__AFI_CACHE__WR_CM__ADDR = 'h5c; localparam HBA_PORT__AFI_CACHE__WR_CM__ADDR = 'h5c;
...@@ -786,4 +786,12 @@ ...@@ -786,4 +786,12 @@
localparam HBA_PORT__AFI_CACHE__RD_CM__ADDR = 'h5c; localparam HBA_PORT__AFI_CACHE__RD_CM__ADDR = 'h5c;
localparam HBA_PORT__AFI_CACHE__RD_CM__MASK = 'hf; localparam HBA_PORT__AFI_CACHE__RD_CM__MASK = 'hf;
localparam HBA_PORT__AFI_CACHE__RD_CM__DFLT = 'h3; localparam HBA_PORT__AFI_CACHE__RD_CM__DFLT = 'h3;
// RW: Address/not data for programming AHCI state machine
localparam HBA_PORT__PGM_AHCI_SM__AnD__ADDR = 'h5d;
localparam HBA_PORT__PGM_AHCI_SM__AnD__MASK = 'h1000000;
localparam HBA_PORT__PGM_AHCI_SM__AnD__DFLT = 'h0;
// RW: Program address/data for programming AHCI state machine
localparam HBA_PORT__PGM_AHCI_SM__PGM_AD__ADDR = 'h5d;
localparam HBA_PORT__PGM_AHCI_SM__PGM_AD__MASK = 'h3ffff;
localparam HBA_PORT__PGM_AHCI_SM__PGM_AD__DFLT = 'h3;
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
, .INIT_12 (256'h0000000000550000000000000000000000000000000000000000000000000000) , .INIT_12 (256'h0000000000550000000000000000000000000000000000000000000000000000)
, .INIT_13 (256'h00000000AAAAAAAAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF002AAAAA00AA000A) , .INIT_13 (256'h00000000AAAAAAAAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF002AAAAA00AA000A)
, .INIT_14 (256'h000000000000000000000000000000000001555555555550000000000055000D) , .INIT_14 (256'h000000000000000000000000000000000001555555555550000000000055000D)
, .INIT_17 (256'h5555555555555555555555555555555555555555555555550000000000005555) , .INIT_17 (256'h5555555555555555555555555555555500010005555555550000000000005555)
, .INIT_18 (256'h00000000000055550000000000000000AA820000001000140000000000000000) , .INIT_18 (256'h00000000000055550000000000000000AA820000001000140000000000000000)
, .INIT_1B (256'h0000000000005555000000000000000000000000000000000000000000000000) , .INIT_1B (256'h0000000000005555000000000000000000000000000000000000000000000000)
, .INIT_1C (256'h0000000000000000000000000000000000000000800100050000000000000000) , .INIT_1C (256'h0000000000000000000000000000000000000000800100050000000000000000)
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