Commit 09386747 authored by Andrey Filippov's avatar Andrey Filippov
Browse files

connecting AHCI to link/phy layers

parent 0f0cf866
Loading
Loading
Loading
Loading
+31 −14
Original line number Diff line number Diff line
@@ -33,21 +33,25 @@ module ahci_fis_transmit #(
    input                         fetch_cmd,   // Enter p:FetchCmd, fetch command header (from the register memory, prefetch command FIS)
                                               // wait for either fetch_cmd_busy == 0 or pCmdToIssue ==1 after fetch_cmd
    input                         cfis_xmit,    // transmit command (wait for dma_ct_busy == 0)
    input                         dx_transmit,  // send FIS header DWORD, (just 0x46), then forward DMA data
    input                         dx_xmit,  // send FIS header DWORD, (just 0x46), then forward DMA data
                                                // transmit until error, 2048DWords or pDmaXferCnt 
    input                         atapi_xmit,   // trasmit ATAPI command FIS
    
    
    output reg                    done,
    output reg                    done, // for fetch_cmd - dma_start, for *_xmit - xmit_ok, xmit_err, syncesc_recv or xrdy_collision
    output reg                    busy,

    input                         clearCmdToIssue, // From CFIS:SUCCESS 
    output                        pCmdToIssue, // AHCI port variable
//    output                        dmaCntrZero, // DMA counter is zero - would be a duplicate to the one in receive module and dwords_sent output
//    output reg                    fetch_cmd_busy, // does not include prefetching CT - now just use busy/done
    input                         syncesc_recv, // These two inputs interrupt transmit

// Should wait for xmit_ok? Timeout? Timeout will be handled by software, so just wait for OK or some error
    input                         xmit_ok,      // FIS transmission acknowledged OK
    input                         xmit_err,     // 
    output                 [ 1:0] dx_err,       // bit 0 - syncesc_recv, 1 - xmit_err  (valid @ xmit_err and later, reset by new command)
    input                         syncesc_recv, // These two inputs interrupt transmit
    input                         xrdy_collision, 
    output                 [ 2:0] dx_err,       // bit 0 - syncesc_recv, 1 - xmit_err, 2 - collision  (valid @ xmit_err and later, reset by new command)
    
    output                 [15:0] ch_prdtl,    // Physical region descriptor table length (in entries, 0 is 0)
    output                        ch_c,        // Clear busy upon R_OK for this FIS
@@ -89,7 +93,7 @@ module ahci_fis_transmit #(
    
    // Data System memory or FIS -> device
    output reg             [31:0] todev_data,     // 32-bit data from the system memory to HBA (dma data)
    output reg             [ 1:0] todev_type,     // 0 - data, 1 - FIS head, 2 - FIS END (make FIS_Last?)
    output reg             [ 1:0] todev_type,     // 0 - data, 1 - FIS head, 2 - FIS LAST)
    output                        todev_valid,    // output register full
    input                         todev_ready     // send FIFO has room for data (>= 8? dwords)
    
@@ -152,13 +156,16 @@ module ahci_fis_transmit #(
    reg                      dx_fis_pend_r; // waiting to send first DWORD of the  H2D data transfer
    wire                     dx_dma_last_w; // sending last adat word
    reg                      dx_busy_r;
    reg               [ 1:0] dx_err_r;
    wire                     any_cmd_start = fetch_cmd || cfis_xmit || dx_transmit || atapi_xmit;
    wire                     done_w = dx_dma_last_w || ((|dx_err_r) && dx_busy_r) || chead_done_w || acfis_xmit_end || dma_start; // done on last transmit or error
    reg               [ 2:0] dx_err_r;
    reg                      xmit_ok_r;
    wire                     any_cmd_start = fetch_cmd || cfis_xmit || dx_xmit || atapi_xmit;
//    wire                     done_w = dx_dma_last_w || ((|dx_err_r) && dx_busy_r) || chead_done_w || acfis_xmit_end || dma_start; // done on last transmit or error
                             // dma_start ends 'fetch_cmd'
    wire                     done_w = xmit_ok_r || ((|dx_err_r) && dx_busy_r) || dma_start; // done on last transmit or error
    
    reg                      fetch_cmd_busy_r;
    
    
    assign todev_valid = todev_full_r;
    assign dma_re =   dma_re_w;
    assign reg_re =   reg_re_r[1:0]; 
@@ -283,15 +290,15 @@ module ahci_fis_transmit #(
       
       //TODO: update xfer length, prdtl (only after R_OK) - yes, do it outside
       
       if   (dx_transmit) dx_dwords_left[11:2] <= (|xfer_cntr[31:11])?10'h200:{1'b0,xfer_cntr[10:2]};
       if   (dx_xmit)     dx_dwords_left[11:2] <= (|xfer_cntr[31:11])?10'h200:{1'b0,xfer_cntr[10:2]};
       else if (dma_re_w) dx_dwords_left[11:2] <= dx_dwords_left[11:2] - 1;
       
       if   (dx_transmit) dwords_sent <= 0;
       if   (dx_xmit)     dwords_sent <= 0;
       else if (dma_re_w) dwords_sent <= dwords_sent + 1;

       // send FIS header
       if (hba_rst || write_or_w) dx_fis_pend_r <= 0;
       else if (dx_transmit)      dx_fis_pend_r <= 1;
       else if (dx_xmit)          dx_fis_pend_r <= 1;
       
       if (hba_rst || dx_dma_last_w || (|dx_err_r)) dma_en_r  <= 0;
       else if (dx_fis_pend_r &&  write_or_w)       dma_en_r  <= 1;
@@ -303,9 +310,14 @@ module ahci_fis_transmit #(
       if (hba_rst || any_cmd_start) dx_err_r[1] <= 0;
       else if (xmit_err)            dx_err_r[1] <= 1;
       
       if      (hba_rst)                      dx_busy_r <= 0;
       else if (dx_transmit)                  dx_busy_r <= 1;
       else if (dx_dma_last_w || (|dx_err_r)) dx_busy_r <= 0;
       if (hba_rst || any_cmd_start) dx_err_r[2] <= 0;
       else if (xrdy_collision)      dx_err_r[2] <= 1;

       if      (hba_rst)                           dx_busy_r <= 0;   // sending CFIS, AFIS or data FIS (until error or R_OK)
//       else if (dx_xmit)                  dx_busy_r <= 1;
//       else if (dx_dma_last_w || (|dx_err_r)) dx_busy_r <= 0;
       else if (dx_xmit || acfis_xmit_start_r) dx_busy_r <= 1;
       else if (xmit_ok || (|dx_err_r))        dx_busy_r <= 0;

       dma_prd_start <= (dma_start && (PREFETCH_ALWAYS || ch_p_r || !ch_w_r)) ||  // device read may prefetch just prd addresses
                        (dx_fis_pend_r &&  write_or_w); // enable PRD read now (if it was not already done)
@@ -317,6 +329,11 @@ module ahci_fis_transmit #(
       else if (any_cmd_start)                busy <= 1;
       else if (done_w)                       busy <= 0;
       
       if      (hba_rst)                      xmit_ok_r <= 0;
       else                                   xmit_ok_r <= dx_busy_r && !(|dx_err_r) && xmit_ok;
       
       

       dma_cmd_abort <= done_w && (|dx_err_r);


+10 −10
Original line number Diff line number Diff line
@@ -48,7 +48,7 @@ module ahci_fsm
    output                        comreset_send,     // Not possible yet?
    input                         cominit_got,   // asynchronously jumps to P:Cominit state
    output                        set_offline, // electrically idle
    input                         x_rdy_collision, // X_RDY/X_RDY collision on interface 
//    input                         x_rdy_collision, // X_RDY/X_RDY collision on interface 
    output                        send_R_OK,    // Should it be originated in this layer SM?
    output                        send_R_ERR,
    
@@ -213,7 +213,7 @@ module ahci_fsm
    output                        fetch_cmd,    // Enter p:FetchCmd, fetch command header (from the register memory, prefetch command FIS)
                                                // wait for either fetch_cmd_busy == 0 or pCmdToIssue ==1 after fetch_cmd
    output                        cfis_xmit,    // transmit command (wait for dma_ct_busy == 0)
    output                        dx_transmit,  // send FIS header DWORD, (just 0x46), then forward DMA data
    output                        dx_xmit,      // send FIS header DWORD, (just 0x46), then forward DMA data
                                                // transmit until error, 2048DWords or pDmaXferCnt 
    output                        atapi_xmit,   // tarsmit ATAPI command FIS
    input                         xmit_done,
@@ -224,7 +224,7 @@ module ahci_fsm
//    output                        dmaCntrZero, // DMA counter is zero - would be a duplicate to the one in receive module and dwords_sent output
//    input                         syncesc_recv, // These two inputs interrupt transmit
//    input                         xmit_err,     // 
    input                  [ 1:0] dx_err,       // bit 0 - syncesc_recv, 1 - xmit_err  (valid @ xmit_err and later, reset by new command)
    input                  [ 2:0] dx_err,       // bit 0 - syncesc_recv, 1 - xmit_err, 2 - X_RDY/X_RDY collision (valid @ xmit_err and later, reset by new command)
    
///    input                  [15:0] ch_prdtl,    // Physical region descriptor table length (in entries, 0 is 0)
    input                         ch_c,        // Clear busy upon R_OK for this FIS
@@ -272,7 +272,7 @@ module ahci_fsm
    reg                            async_from_st; // chnge to multi-bit if there will be more sources for async transitions
    wire                           asynq_rq = cominit_got || pcmd_st_cleared;
    wire                           async_ackn = !fsm_preload && async_pend_r[0] && ((fsm_actions && !update_busy && !fsm_act_busy) || fsm_transitions[0]);   // OK to process async jump
    reg                            x_rdy_collision_pend;
//    reg                            x_rdy_collision_pend;
    reg                            syncesc_send_pend; // waiting for 'syncesc_send' confiramtion 'syncesc_send_done'
    reg                      [1:0] phy_ready_prev;    // previous state of phy_ready / speed
    reg                            phy_ready_chng_r;  // pulse when phy_ready changes
@@ -353,8 +353,8 @@ module ahci_fsm
        else async_pend_r <= {async_pend_r[0], asynq_rq | (async_pend_r[0] & ~async_ackn)};  
        
        
        if (hba_rst || pcmd_cr_set) x_rdy_collision_pend <= 0;
        else if (x_rdy_collision)   x_rdy_collision_pend <= 1;
//        if (hba_rst || pcmd_cr_set) x_rdy_collision_pend <= 0;
//        else if (x_rdy_collision)   x_rdy_collision_pend <= 1;
        
        if (hba_rst || syncesc_send_done) syncesc_send_pend <= 0;
        else if (syncesc_send)            syncesc_send_pend <= 1;
@@ -435,7 +435,7 @@ module ahci_fsm
        .FETCH_CMD          (fetch_cmd),         // output reg 
        .ATAPI_XMIT         (atapi_xmit),        // output reg 
        .CFIS_XMIT          (cfis_xmit),         // output reg 
        .DX_XMIT            (dx_transmit),       // output reg
        .DX_XMIT            (dx_xmit),           // output reg
    //FIS RECEIVE/WAIT DONE
        .GET_DATA_FIS       (get_data_fis),      // output reg 
        .GET_DSFIS          (get_dsfis),         // output reg 
@@ -500,7 +500,7 @@ module ahci_fsm
    // DMA
        .DMA_PRD_IRQ_PEND      (dma_prd_irq_pend),                        // input
    // SATA TRANSPORT/LINK/PHY        
        .X_RDY_COLLISION       (x_rdy_collision_pend)                     // input
        .X_RDY_COLLISION       (dx_err[2]) //x_rdy_collision_pend)                     // input
    );


Loading