162306a36Sopenharmony_ci/* Copyright 2008 - 2016 Freescale Semiconductor, Inc. 262306a36Sopenharmony_ci * 362306a36Sopenharmony_ci * Redistribution and use in source and binary forms, with or without 462306a36Sopenharmony_ci * modification, are permitted provided that the following conditions are met: 562306a36Sopenharmony_ci * * Redistributions of source code must retain the above copyright 662306a36Sopenharmony_ci * notice, this list of conditions and the following disclaimer. 762306a36Sopenharmony_ci * * Redistributions in binary form must reproduce the above copyright 862306a36Sopenharmony_ci * notice, this list of conditions and the following disclaimer in the 962306a36Sopenharmony_ci * documentation and/or other materials provided with the distribution. 1062306a36Sopenharmony_ci * * Neither the name of Freescale Semiconductor nor the 1162306a36Sopenharmony_ci * names of its contributors may be used to endorse or promote products 1262306a36Sopenharmony_ci * derived from this software without specific prior written permission. 1362306a36Sopenharmony_ci * 1462306a36Sopenharmony_ci * ALTERNATIVELY, this software may be distributed under the terms of the 1562306a36Sopenharmony_ci * GNU General Public License ("GPL") as published by the Free Software 1662306a36Sopenharmony_ci * Foundation, either version 2 of that License or (at your option) any 1762306a36Sopenharmony_ci * later version. 1862306a36Sopenharmony_ci * 1962306a36Sopenharmony_ci * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY 2062306a36Sopenharmony_ci * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 2162306a36Sopenharmony_ci * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 2262306a36Sopenharmony_ci * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY 2362306a36Sopenharmony_ci * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 2462306a36Sopenharmony_ci * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 2562306a36Sopenharmony_ci * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 2662306a36Sopenharmony_ci * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2762306a36Sopenharmony_ci * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 2862306a36Sopenharmony_ci * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2962306a36Sopenharmony_ci */ 3062306a36Sopenharmony_ci 3162306a36Sopenharmony_ci#include "bman_test.h" 3262306a36Sopenharmony_ci 3362306a36Sopenharmony_ci#define NUM_BUFS 93 3462306a36Sopenharmony_ci#define LOOPS 3 3562306a36Sopenharmony_ci#define BMAN_TOKEN_MASK 0x00FFFFFFFFFFLLU 3662306a36Sopenharmony_ci 3762306a36Sopenharmony_cistatic struct bman_pool *pool; 3862306a36Sopenharmony_cistatic struct bm_buffer bufs_in[NUM_BUFS] ____cacheline_aligned; 3962306a36Sopenharmony_cistatic struct bm_buffer bufs_out[NUM_BUFS] ____cacheline_aligned; 4062306a36Sopenharmony_cistatic int bufs_received; 4162306a36Sopenharmony_ci 4262306a36Sopenharmony_cistatic void bufs_init(void) 4362306a36Sopenharmony_ci{ 4462306a36Sopenharmony_ci int i; 4562306a36Sopenharmony_ci 4662306a36Sopenharmony_ci for (i = 0; i < NUM_BUFS; i++) 4762306a36Sopenharmony_ci bm_buffer_set64(&bufs_in[i], 0xfedc01234567LLU * i); 4862306a36Sopenharmony_ci bufs_received = 0; 4962306a36Sopenharmony_ci} 5062306a36Sopenharmony_ci 5162306a36Sopenharmony_cistatic inline int bufs_cmp(const struct bm_buffer *a, const struct bm_buffer *b) 5262306a36Sopenharmony_ci{ 5362306a36Sopenharmony_ci if (bman_ip_rev == BMAN_REV20 || bman_ip_rev == BMAN_REV21) { 5462306a36Sopenharmony_ci 5562306a36Sopenharmony_ci /* 5662306a36Sopenharmony_ci * On SoCs with BMan revison 2.0, BMan only respects the 40 5762306a36Sopenharmony_ci * LS-bits of buffer addresses, masking off the upper 8-bits on 5862306a36Sopenharmony_ci * release commands. The API provides for 48-bit addresses 5962306a36Sopenharmony_ci * because some SoCs support all 48-bits. When generating 6062306a36Sopenharmony_ci * garbage addresses for testing, we either need to zero the 6162306a36Sopenharmony_ci * upper 8-bits when releasing to BMan (otherwise we'll be 6262306a36Sopenharmony_ci * disappointed when the buffers we acquire back from BMan 6362306a36Sopenharmony_ci * don't match), or we need to mask the upper 8-bits off when 6462306a36Sopenharmony_ci * comparing. We do the latter. 6562306a36Sopenharmony_ci */ 6662306a36Sopenharmony_ci if ((bm_buffer_get64(a) & BMAN_TOKEN_MASK) < 6762306a36Sopenharmony_ci (bm_buffer_get64(b) & BMAN_TOKEN_MASK)) 6862306a36Sopenharmony_ci return -1; 6962306a36Sopenharmony_ci if ((bm_buffer_get64(a) & BMAN_TOKEN_MASK) > 7062306a36Sopenharmony_ci (bm_buffer_get64(b) & BMAN_TOKEN_MASK)) 7162306a36Sopenharmony_ci return 1; 7262306a36Sopenharmony_ci } else { 7362306a36Sopenharmony_ci if (bm_buffer_get64(a) < bm_buffer_get64(b)) 7462306a36Sopenharmony_ci return -1; 7562306a36Sopenharmony_ci if (bm_buffer_get64(a) > bm_buffer_get64(b)) 7662306a36Sopenharmony_ci return 1; 7762306a36Sopenharmony_ci } 7862306a36Sopenharmony_ci 7962306a36Sopenharmony_ci return 0; 8062306a36Sopenharmony_ci} 8162306a36Sopenharmony_ci 8262306a36Sopenharmony_cistatic void bufs_confirm(void) 8362306a36Sopenharmony_ci{ 8462306a36Sopenharmony_ci int i, j; 8562306a36Sopenharmony_ci 8662306a36Sopenharmony_ci for (i = 0; i < NUM_BUFS; i++) { 8762306a36Sopenharmony_ci int matches = 0; 8862306a36Sopenharmony_ci 8962306a36Sopenharmony_ci for (j = 0; j < NUM_BUFS; j++) 9062306a36Sopenharmony_ci if (!bufs_cmp(&bufs_in[i], &bufs_out[j])) 9162306a36Sopenharmony_ci matches++; 9262306a36Sopenharmony_ci WARN_ON(matches != 1); 9362306a36Sopenharmony_ci } 9462306a36Sopenharmony_ci} 9562306a36Sopenharmony_ci 9662306a36Sopenharmony_ci/* test */ 9762306a36Sopenharmony_civoid bman_test_api(void) 9862306a36Sopenharmony_ci{ 9962306a36Sopenharmony_ci int i, loops = LOOPS; 10062306a36Sopenharmony_ci 10162306a36Sopenharmony_ci bufs_init(); 10262306a36Sopenharmony_ci 10362306a36Sopenharmony_ci pr_info("%s(): Starting\n", __func__); 10462306a36Sopenharmony_ci 10562306a36Sopenharmony_ci pool = bman_new_pool(); 10662306a36Sopenharmony_ci if (!pool) { 10762306a36Sopenharmony_ci pr_crit("bman_new_pool() failed\n"); 10862306a36Sopenharmony_ci goto failed; 10962306a36Sopenharmony_ci } 11062306a36Sopenharmony_ci 11162306a36Sopenharmony_ci /* Release buffers */ 11262306a36Sopenharmony_cido_loop: 11362306a36Sopenharmony_ci i = 0; 11462306a36Sopenharmony_ci while (i < NUM_BUFS) { 11562306a36Sopenharmony_ci int num = 8; 11662306a36Sopenharmony_ci 11762306a36Sopenharmony_ci if (i + num > NUM_BUFS) 11862306a36Sopenharmony_ci num = NUM_BUFS - i; 11962306a36Sopenharmony_ci if (bman_release(pool, bufs_in + i, num)) { 12062306a36Sopenharmony_ci pr_crit("bman_release() failed\n"); 12162306a36Sopenharmony_ci goto failed; 12262306a36Sopenharmony_ci } 12362306a36Sopenharmony_ci i += num; 12462306a36Sopenharmony_ci } 12562306a36Sopenharmony_ci 12662306a36Sopenharmony_ci /* Acquire buffers */ 12762306a36Sopenharmony_ci while (i > 0) { 12862306a36Sopenharmony_ci int tmp, num = 8; 12962306a36Sopenharmony_ci 13062306a36Sopenharmony_ci if (num > i) 13162306a36Sopenharmony_ci num = i; 13262306a36Sopenharmony_ci tmp = bman_acquire(pool, bufs_out + i - num, num); 13362306a36Sopenharmony_ci WARN_ON(tmp != num); 13462306a36Sopenharmony_ci i -= num; 13562306a36Sopenharmony_ci } 13662306a36Sopenharmony_ci i = bman_acquire(pool, NULL, 1); 13762306a36Sopenharmony_ci WARN_ON(i > 0); 13862306a36Sopenharmony_ci 13962306a36Sopenharmony_ci bufs_confirm(); 14062306a36Sopenharmony_ci 14162306a36Sopenharmony_ci if (--loops) 14262306a36Sopenharmony_ci goto do_loop; 14362306a36Sopenharmony_ci 14462306a36Sopenharmony_ci /* Clean up */ 14562306a36Sopenharmony_ci bman_free_pool(pool); 14662306a36Sopenharmony_ci pr_info("%s(): Finished\n", __func__); 14762306a36Sopenharmony_ci return; 14862306a36Sopenharmony_ci 14962306a36Sopenharmony_cifailed: 15062306a36Sopenharmony_ci WARN_ON(1); 15162306a36Sopenharmony_ci} 152