99 * Author: Gary R Hook <gary.hook@amd.com>
1010 */
1111
12+ #include <linux/bitfield.h>
1213#include "ptdma.h"
1314#include "../ae4dma/ae4dma.h"
1415#include "../../dmaengine.h"
@@ -110,6 +111,53 @@ static struct pt_cmd_queue *pt_get_cmd_queue(struct pt_device *pt, struct pt_dma
110111 return cmd_q ;
111112}
112113
114+ static int ae4_core_execute_cmd (struct ae4dma_desc * desc , struct ae4_cmd_queue * ae4cmd_q )
115+ {
116+ bool soc = FIELD_GET (DWORD0_SOC , desc -> dwouv .dw0 );
117+ struct pt_cmd_queue * cmd_q = & ae4cmd_q -> cmd_q ;
118+
119+ if (soc ) {
120+ desc -> dwouv .dw0 |= FIELD_PREP (DWORD0_IOC , desc -> dwouv .dw0 );
121+ desc -> dwouv .dw0 &= ~DWORD0_SOC ;
122+ }
123+
124+ mutex_lock (& ae4cmd_q -> cmd_lock );
125+ memcpy (& cmd_q -> qbase [ae4cmd_q -> tail_wi ], desc , sizeof (struct ae4dma_desc ));
126+ ae4cmd_q -> q_cmd_count ++ ;
127+ ae4cmd_q -> tail_wi = (ae4cmd_q -> tail_wi + 1 ) % CMD_Q_LEN ;
128+ writel (ae4cmd_q -> tail_wi , cmd_q -> reg_control + AE4_WR_IDX_OFF );
129+ mutex_unlock (& ae4cmd_q -> cmd_lock );
130+
131+ wake_up (& ae4cmd_q -> q_w );
132+
133+ return 0 ;
134+ }
135+
136+ static int pt_core_perform_passthru_ae4 (struct pt_cmd_queue * cmd_q ,
137+ struct pt_passthru_engine * pt_engine )
138+ {
139+ struct ae4_cmd_queue * ae4cmd_q = container_of (cmd_q , struct ae4_cmd_queue , cmd_q );
140+ struct ae4dma_desc desc ;
141+
142+ cmd_q -> cmd_error = 0 ;
143+ cmd_q -> total_pt_ops ++ ;
144+ memset (& desc , 0 , sizeof (desc ));
145+ desc .dwouv .dws .byte0 = CMD_AE4_DESC_DW0_VAL ;
146+
147+ desc .dw1 .status = 0 ;
148+ desc .dw1 .err_code = 0 ;
149+ desc .dw1 .desc_id = 0 ;
150+
151+ desc .length = pt_engine -> src_len ;
152+
153+ desc .src_lo = upper_32_bits (pt_engine -> src_dma );
154+ desc .src_hi = lower_32_bits (pt_engine -> src_dma );
155+ desc .dst_lo = upper_32_bits (pt_engine -> dst_dma );
156+ desc .dst_hi = lower_32_bits (pt_engine -> dst_dma );
157+
158+ return ae4_core_execute_cmd (& desc , ae4cmd_q );
159+ }
160+
113161static int pt_dma_start_desc (struct pt_dma_desc * desc , struct pt_dma_chan * chan )
114162{
115163 struct pt_passthru_engine * pt_engine ;
@@ -129,7 +177,10 @@ static int pt_dma_start_desc(struct pt_dma_desc *desc, struct pt_dma_chan *chan)
129177 pt -> tdata .cmd = pt_cmd ;
130178
131179 /* Execute the command */
132- pt_cmd -> ret = pt_core_perform_passthru (cmd_q , pt_engine );
180+ if (pt -> ver == AE4_DMA_VERSION )
181+ pt_cmd -> ret = pt_core_perform_passthru_ae4 (cmd_q , pt_engine );
182+ else
183+ pt_cmd -> ret = pt_core_perform_passthru (cmd_q , pt_engine );
133184
134185 return 0 ;
135186}
@@ -336,6 +387,15 @@ static void pt_issue_pending(struct dma_chan *dma_chan)
336387 pt_cmd_callback (desc , 0 );
337388}
338389
390+ static void pt_check_status_trans_ae4 (struct pt_device * pt , struct pt_cmd_queue * cmd_q )
391+ {
392+ struct ae4_cmd_queue * ae4cmd_q = container_of (cmd_q , struct ae4_cmd_queue , cmd_q );
393+ int i ;
394+
395+ for (i = 0 ; i < CMD_Q_LEN ; i ++ )
396+ ae4_check_status_error (ae4cmd_q , i );
397+ }
398+
339399static enum dma_status
340400pt_tx_status (struct dma_chan * c , dma_cookie_t cookie ,
341401 struct dma_tx_state * txstate )
@@ -346,7 +406,11 @@ pt_tx_status(struct dma_chan *c, dma_cookie_t cookie,
346406
347407 cmd_q = pt_get_cmd_queue (pt , chan );
348408
349- pt_check_status_trans (pt , cmd_q );
409+ if (pt -> ver == AE4_DMA_VERSION )
410+ pt_check_status_trans_ae4 (pt , cmd_q );
411+ else
412+ pt_check_status_trans (pt , cmd_q );
413+
350414 return dma_cookie_status (c , cookie , txstate );
351415}
352416
@@ -512,6 +576,7 @@ int pt_dmaengine_register(struct pt_device *pt)
512576
513577 return ret ;
514578}
579+ EXPORT_SYMBOL_GPL (pt_dmaengine_register );
515580
516581void pt_dmaengine_unregister (struct pt_device * pt )
517582{
0 commit comments