4444#define TBAI_FLUSH_RD_LEN 0x4 /* flush buffer read length */
4545#define MAX_PROTO_RD_SZ 32 /* Maximum bytes read in one transaction */
4646#define DWORD_TO_BYTES 0x4 /* Number of bytes in dword */
47+
48+ /* TBAI Input structure index */
49+ #define TBAI_IN_LUT_INDEX 0 /* LUT index */
50+ #define TBAI_IN_OFF_LO 1 /* Low offset index */
51+ #define TBAI_IN_OFF_HI 2 /* Hi offset index */
52+ #define TBAI_IN_DWORD_COUNT 3 /* Number of Dwords index */
53+
4754/* Maximum dwords possible to read in one transaction */
4855#define MAX_DWORDS_READ 0x8
4956
@@ -260,43 +267,48 @@ static int tbai_protocol(struct apml_sbtsi_device *tsi_dev, u8 cmd, u8 *input,
260267
261268static int flush_trace_buffer (struct apml_sbtsi_device * tsi_dev , struct apml_tbai_msg * tbai_msg )
262269{
263- u8 input [4 ] = {0 };
264- u8 output [4 ] = {0 };
265- int ret , i ;
270+ u8 input [TBAI_WR_LEN ] = {0 };
271+ u8 output [TBAI_FLUSH_RD_LEN ] = {0 };
272+ int ret ;
266273
267- ret = tbai_protocol (tsi_dev , tbai_msg -> reg_in [TBAI_CMD_INDEX ], input , 4 , output );
274+ ret = tbai_protocol (tsi_dev , tbai_msg -> reg_in [TBAI_CMD_INDEX ], input ,
275+ TBAI_FLUSH_RD_LEN , output );
268276 if (ret )
269277 return ret ;
270- for ( i = 0 ; i < TBAI_FLUSH_RD_LEN ; i ++ )
271- tbai_msg -> data_out .bytes_out [ i ] = output [ i ] ;
278+
279+ memcpy ( tbai_msg -> data_out .bytes_out , output , TBAI_FLUSH_RD_LEN ) ;
272280 return ret ;
273281}
274282
275283static int acquire_trace_buffer (struct apml_sbtsi_device * tsi_dev , struct apml_tbai_msg * tbai_msg )
276284{
277- int dword_read , dword_remain , i , j , ret ;
285+ int dword_read , dword_remain , i , ret ;
286+ u32 total_dwords ;
278287 u16 offset , offset_new ;
279288 u8 input [TBAI_WR_LEN ] = {0 };
280- /* TODO: static memory as max supported is 8 Dwords */
281289 u8 * output ;
282290
283291 /* Dwords to read from user*/
284- dword_remain = tbai_msg -> reg_in [TBAI_DWORD_RD_INDEX ];
292+ total_dwords = tbai_msg -> reg_in [TBAI_DWORD_RD_INDEX ];
293+ dword_remain = total_dwords ;
285294 /* Extract the offset to update, if more than 8 Dwords require to read */
286295 offset = tbai_msg -> reg_in [TBAI_OFFSET_HI ] << 8 |
287296 tbai_msg -> reg_in [TBAI_OFFSET_LO ];
288297
289298 /* If Dwords to read is 0 or more than 32, return */
290- if (tbai_msg -> reg_in [TBAI_DWORD_RD_INDEX ] == 0 ||
291- tbai_msg -> reg_in [TBAI_DWORD_RD_INDEX ] > MAX_TBAI_DWORDS )
299+ if (total_dwords == 0 || total_dwords > MAX_TBAI_DWORDS )
292300 return - EINVAL ;
293301
302+ /* Allocate memory at once for all dwords to be read */
303+ output = kcalloc (total_dwords * DWORD_TO_BYTES , sizeof (u8 ), GFP_KERNEL );
304+ if (!output )
305+ return - ENOMEM ;
306+
294307 /*
295308 * Set required variables to read dwords
296309 * Maximum dwords supported from i3c protocol is 8
297310 */
298- for (i = 0 ; i <= tbai_msg -> reg_in [TBAI_DWORD_RD_INDEX ] / 8 &&
299- dword_remain > 0 ; i ++ ) {
311+ for (i = 0 ; i <= total_dwords / MAX_DWORDS_READ && dword_remain > 0 ; i ++ ) {
300312 if (dword_remain > MAX_DWORDS_READ ) {
301313 dword_remain -= MAX_DWORDS_READ ;
302314 dword_read = MAX_DWORDS_READ ;
@@ -306,36 +318,23 @@ static int acquire_trace_buffer(struct apml_sbtsi_device *tsi_dev, struct apml_t
306318 }
307319 /* update offset if more than 8 Dwords require to read */
308320 offset_new = i * MAX_PROTO_RD_SZ + offset ;
309- input [0 ] = tbai_msg -> reg_in [TBAI_LUT_INDEX ];
310- input [1 ] = offset_new & 0xFF ;
311- input [2 ] = (offset_new >> 8 ) & 0xFF ;
312- input [3 ] = dword_read - 1 ;
321+ input [TBAI_IN_LUT_INDEX ] = tbai_msg -> reg_in [TBAI_LUT_INDEX ];
322+ input [TBAI_IN_OFF_LO ] = offset_new & 0xFF ;
323+ input [TBAI_IN_OFF_HI ] = (offset_new >> 8 ) & 0xFF ;
324+ input [TBAI_IN_DWORD_COUNT ] = dword_read - 1 ;
313325
314- /*
315- * TODO: Optimize to allocate memory at once as per user request
316- * Currently in A0, only one Dword can be read, due to bug.
317- * Optimize in B0.
318- */
319- output = kcalloc (dword_read * DWORD_TO_BYTES , sizeof (u8 ), GFP_KERNEL );
320- if (!output )
321- return - ENOMEM ;
322-
323- ret = tbai_protocol (tsi_dev , tbai_msg -> reg_in [TBAI_CMD_INDEX ],
324- input , dword_read * DWORD_TO_BYTES , output );
326+ ret = tbai_protocol (tsi_dev , tbai_msg -> reg_in [TBAI_CMD_INDEX ], input ,
327+ dword_read * DWORD_TO_BYTES , & output [i * MAX_PROTO_RD_SZ ]);
325328 if (ret ) {
326329 kfree (output );
327330 return ret ;
328331 }
329- for (j = 0 ; j < dword_read * DWORD_TO_BYTES ; j ++ ) {
330- /*
331- * TODO: In A0, only one Dword is supported
332- * APML module is optimized to read max of 32 Dwords at a time.
333- * dwords exceeding 8 need to be tested in B0 platform.
334- */
335- tbai_msg -> data_out .bytes_out [j + (i * MAX_PROTO_RD_SZ )] = output [j ];
336- }
337- kfree (output );
338332 }
333+
334+ /* Copy data to user */
335+ memcpy (tbai_msg -> data_out .bytes_out , output , total_dwords * DWORD_TO_BYTES );
336+ kfree (output );
337+
339338 return 0 ;
340339}
341340
0 commit comments