14e1bc9a0SAchim Leubner /******************************************************************************
24e1bc9a0SAchim Leubner *Copyright (c) 2014 PMC-Sierra, Inc. All rights reserved.
34e1bc9a0SAchim Leubner *
44e1bc9a0SAchim Leubner *Redistribution and use in source and binary forms, with or without modification, are permitted provided
54e1bc9a0SAchim Leubner *that the following conditions are met:
64e1bc9a0SAchim Leubner *1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
74e1bc9a0SAchim Leubner *following disclaimer.
84e1bc9a0SAchim Leubner *2. Redistributions in binary form must reproduce the above copyright notice,
94e1bc9a0SAchim Leubner *this list of conditions and the following disclaimer in the documentation and/or other materials provided
104e1bc9a0SAchim Leubner *with the distribution.
114e1bc9a0SAchim Leubner *
124e1bc9a0SAchim Leubner *THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED
134e1bc9a0SAchim Leubner *WARRANTIES,INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
144e1bc9a0SAchim Leubner *FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
154e1bc9a0SAchim Leubner *FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
164e1bc9a0SAchim Leubner *NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
174e1bc9a0SAchim Leubner *BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
184e1bc9a0SAchim Leubner *LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
194e1bc9a0SAchim Leubner *SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
204e1bc9a0SAchim Leubner
214e1bc9a0SAchim Leubner ******************************************************************************/
224e1bc9a0SAchim Leubner /******************************************************************************
234e1bc9a0SAchim Leubner This program is part of PMC-Sierra initiator/target device driver.
244e1bc9a0SAchim Leubner The functions here are commonly used by different type of drivers that support
254e1bc9a0SAchim Leubner PMC-Sierra storage network initiator hardware.
264e1bc9a0SAchim Leubner ******************************************************************************/
274e1bc9a0SAchim Leubner
284e1bc9a0SAchim Leubner
294e1bc9a0SAchim Leubner MALLOC_DEFINE( M_PMC_MMAL, "agtiapi_MemAlloc malloc",
304e1bc9a0SAchim Leubner "allocated from agtiapi_MemAlloc as simple malloc case" );
314e1bc9a0SAchim Leubner
324e1bc9a0SAchim Leubner
334e1bc9a0SAchim Leubner /*****************************************************************************
344e1bc9a0SAchim Leubner agtiapi_DelayMSec()
354e1bc9a0SAchim Leubner
364e1bc9a0SAchim Leubner Purpose:
374e1bc9a0SAchim Leubner Busy wait for number of mili-seconds
384e1bc9a0SAchim Leubner Parameters:
394e1bc9a0SAchim Leubner U32 MiliSeconds (IN) Number of mili-seconds to delay
404e1bc9a0SAchim Leubner Return:
414e1bc9a0SAchim Leubner Note:
424e1bc9a0SAchim Leubner *****************************************************************************/
agtiapi_DelayMSec(U32 MiliSeconds)434e1bc9a0SAchim Leubner STATIC void agtiapi_DelayMSec( U32 MiliSeconds )
444e1bc9a0SAchim Leubner {
454e1bc9a0SAchim Leubner DELAY(MiliSeconds * 1000); // DELAY takes in usecs
464e1bc9a0SAchim Leubner }
474e1bc9a0SAchim Leubner
484e1bc9a0SAchim Leubner /******************************************************************************
494e1bc9a0SAchim Leubner agtiapi_typhAlloc()
504e1bc9a0SAchim Leubner Purpose:
514e1bc9a0SAchim Leubner Preallocation handling
524e1bc9a0SAchim Leubner Allocate DMA memory which will be divided among proper pointers in
534e1bc9a0SAchim Leubner agtiapi_MemAlloc() later
544e1bc9a0SAchim Leubner Parameters:
554e1bc9a0SAchim Leubner ag_card_info_t *thisCardInst (IN)
564e1bc9a0SAchim Leubner Return:
574e1bc9a0SAchim Leubner AGTIAPI_SUCCESS - success
584e1bc9a0SAchim Leubner AGTIAPI_FAIL - fail
594e1bc9a0SAchim Leubner ******************************************************************************/
agtiapi_typhAlloc(ag_card_info_t * thisCardInst)604e1bc9a0SAchim Leubner STATIC agBOOLEAN agtiapi_typhAlloc( ag_card_info_t *thisCardInst )
614e1bc9a0SAchim Leubner {
624e1bc9a0SAchim Leubner struct agtiapi_softc *pmsc = thisCardInst->pCard;
634e1bc9a0SAchim Leubner int wait = 0;
644e1bc9a0SAchim Leubner
65*41f6c3f0STycho Nightingale if( bus_dma_tag_create( bus_get_dma_tag(pmsc->my_dev), // parent
664e1bc9a0SAchim Leubner 32, // alignment
674e1bc9a0SAchim Leubner 0, // boundary
684e1bc9a0SAchim Leubner BUS_SPACE_MAXADDR, // lowaddr
694e1bc9a0SAchim Leubner BUS_SPACE_MAXADDR, // highaddr
704e1bc9a0SAchim Leubner NULL, // filter
714e1bc9a0SAchim Leubner NULL, // filterarg
724e1bc9a0SAchim Leubner pmsc->typhn, // maxsize (size)
734e1bc9a0SAchim Leubner 1, // number of segments
744e1bc9a0SAchim Leubner pmsc->typhn, // maxsegsize
754e1bc9a0SAchim Leubner 0, // flags
764e1bc9a0SAchim Leubner NULL, // lockfunc
774e1bc9a0SAchim Leubner NULL, // lockarg
784e1bc9a0SAchim Leubner &pmsc->typh_dmat ) ) {
794e1bc9a0SAchim Leubner printf( "agtiapi_typhAlloc: Can't create no-cache mem tag\n" );
804e1bc9a0SAchim Leubner return AGTIAPI_FAIL;
814e1bc9a0SAchim Leubner }
824e1bc9a0SAchim Leubner
834e1bc9a0SAchim Leubner if( bus_dmamem_alloc( pmsc->typh_dmat,
844e1bc9a0SAchim Leubner &pmsc->typh_mem,
854e1bc9a0SAchim Leubner BUS_DMA_WAITOK | BUS_DMA_ZERO | BUS_DMA_NOCACHE,
864e1bc9a0SAchim Leubner &pmsc->typh_mapp ) ) {
874e1bc9a0SAchim Leubner printf( "agtiapi_typhAlloc: Cannot allocate cache mem %d\n",
884e1bc9a0SAchim Leubner pmsc->typhn );
894e1bc9a0SAchim Leubner return AGTIAPI_FAIL;
904e1bc9a0SAchim Leubner }
914e1bc9a0SAchim Leubner
924e1bc9a0SAchim Leubner if ( bus_dmamap_load( pmsc->typh_dmat,
934e1bc9a0SAchim Leubner pmsc->typh_mapp,
944e1bc9a0SAchim Leubner pmsc->typh_mem,
954e1bc9a0SAchim Leubner pmsc->typhn,
964e1bc9a0SAchim Leubner agtiapi_MemoryCB, // try reuse of CB for same goal
974e1bc9a0SAchim Leubner &pmsc->typh_busaddr,
984e1bc9a0SAchim Leubner 0 ) || !pmsc->typh_busaddr ) {
994e1bc9a0SAchim Leubner for( ; wait < 20; wait++ ) {
1004e1bc9a0SAchim Leubner if( pmsc->typh_busaddr ) break;
1014e1bc9a0SAchim Leubner DELAY( 50000 );
1024e1bc9a0SAchim Leubner }
1034e1bc9a0SAchim Leubner
1044e1bc9a0SAchim Leubner if( ! pmsc->typh_busaddr ) {
1054e1bc9a0SAchim Leubner printf( "agtiapi_typhAlloc: cache mem won't load %d\n",
1064e1bc9a0SAchim Leubner pmsc->typhn );
1074e1bc9a0SAchim Leubner return AGTIAPI_FAIL;
1084e1bc9a0SAchim Leubner }
1094e1bc9a0SAchim Leubner }
1104e1bc9a0SAchim Leubner
1114e1bc9a0SAchim Leubner pmsc->typhIdx = 0;
1124e1bc9a0SAchim Leubner pmsc->tyPhsIx = 0;
1134e1bc9a0SAchim Leubner
1144e1bc9a0SAchim Leubner return AGTIAPI_SUCCESS;
1154e1bc9a0SAchim Leubner }
1164e1bc9a0SAchim Leubner
1174e1bc9a0SAchim Leubner
1184e1bc9a0SAchim Leubner /******************************************************************************
1194e1bc9a0SAchim Leubner agtiapi_InitResource()
1204e1bc9a0SAchim Leubner Purpose:
1214e1bc9a0SAchim Leubner Mapping PCI memory space
1224e1bc9a0SAchim Leubner Allocate and initialize per card based resource
1234e1bc9a0SAchim Leubner Parameters:
1244e1bc9a0SAchim Leubner ag_card_info_t *pCardInfo (IN)
1254e1bc9a0SAchim Leubner Return:
1264e1bc9a0SAchim Leubner AGTIAPI_SUCCESS - success
1274e1bc9a0SAchim Leubner AGTIAPI_FAIL - fail
1284e1bc9a0SAchim Leubner Note:
1294e1bc9a0SAchim Leubner ******************************************************************************/
agtiapi_InitResource(ag_card_info_t * thisCardInst)1304e1bc9a0SAchim Leubner STATIC agBOOLEAN agtiapi_InitResource( ag_card_info_t *thisCardInst )
1314e1bc9a0SAchim Leubner {
1324e1bc9a0SAchim Leubner struct agtiapi_softc *pmsc = thisCardInst->pCard;
1334e1bc9a0SAchim Leubner device_t devx = thisCardInst->pPCIDev;
1344e1bc9a0SAchim Leubner
1354e1bc9a0SAchim Leubner //AGTIAPI_PRINTK( "agtiapi_InitResource: begin; pointer values %p / %p \n",
1364e1bc9a0SAchim Leubner // devx, thisCardInst );
1374e1bc9a0SAchim Leubner // no IO mapped card implementation, we'll implement memory mapping
1384e1bc9a0SAchim Leubner
1394e1bc9a0SAchim Leubner if( agtiapi_typhAlloc( thisCardInst ) == AGTIAPI_FAIL ) {
1404e1bc9a0SAchim Leubner printf( "agtiapi_InitResource: failed call to agtiapi_typhAlloc \n" );
1414e1bc9a0SAchim Leubner return AGTIAPI_FAIL;
1424e1bc9a0SAchim Leubner }
1434e1bc9a0SAchim Leubner
1444e1bc9a0SAchim Leubner AGTIAPI_PRINTK( "agtiapi_InitResource: dma alloc MemSpan %p -- %p\n",
1454e1bc9a0SAchim Leubner (void*) pmsc->typh_busaddr,
1464e1bc9a0SAchim Leubner (void*) ( (U32_64)pmsc->typh_busaddr + pmsc->typhn ) );
1474e1bc9a0SAchim Leubner
1484e1bc9a0SAchim Leubner // logical BARs for SPC:
1494e1bc9a0SAchim Leubner // bar 0 and 1 - logical BAR0
1504e1bc9a0SAchim Leubner // bar 2 and 3 - logical BAR1
1514e1bc9a0SAchim Leubner // bar4 - logical BAR2
1524e1bc9a0SAchim Leubner // bar5 - logical BAR3
1534e1bc9a0SAchim Leubner // Skiping the assignments for bar 1 and bar 3 (making bar 0, 2 64-bit):
1544e1bc9a0SAchim Leubner U32 bar;
1554e1bc9a0SAchim Leubner U32 lBar = 0; // logicalBar
1564e1bc9a0SAchim Leubner for (bar = 0; bar < PCI_NUMBER_BARS; bar++) {
1574e1bc9a0SAchim Leubner if ((bar==1) || (bar==3))
1584e1bc9a0SAchim Leubner continue;
1594e1bc9a0SAchim Leubner thisCardInst->pciMemBaseRIDSpc[lBar] = PCIR_BAR(bar);
1604e1bc9a0SAchim Leubner thisCardInst->pciMemBaseRscSpc[lBar] =
1614e1bc9a0SAchim Leubner bus_alloc_resource_any( devx,
1624e1bc9a0SAchim Leubner SYS_RES_MEMORY,
1634e1bc9a0SAchim Leubner &(thisCardInst->pciMemBaseRIDSpc[lBar]),
1644e1bc9a0SAchim Leubner RF_ACTIVE );
1654e1bc9a0SAchim Leubner AGTIAPI_PRINTK( "agtiapi_InitResource: bus_alloc_resource_any rtn %p \n",
1664e1bc9a0SAchim Leubner thisCardInst->pciMemBaseRscSpc[lBar] );
1674e1bc9a0SAchim Leubner if ( thisCardInst->pciMemBaseRscSpc[lBar] != NULL ) {
1684e1bc9a0SAchim Leubner thisCardInst->pciMemVirtAddrSpc[lBar] =
1694e1bc9a0SAchim Leubner (caddr_t)rman_get_virtual(
1704e1bc9a0SAchim Leubner thisCardInst->pciMemBaseRscSpc[lBar] );
1714e1bc9a0SAchim Leubner thisCardInst->pciMemBaseSpc[lBar] =
1724e1bc9a0SAchim Leubner bus_get_resource_start( devx, SYS_RES_MEMORY,
1734e1bc9a0SAchim Leubner thisCardInst->pciMemBaseRIDSpc[lBar]);
1744e1bc9a0SAchim Leubner thisCardInst->pciMemSizeSpc[lBar] =
1754e1bc9a0SAchim Leubner bus_get_resource_count( devx, SYS_RES_MEMORY,
1764e1bc9a0SAchim Leubner thisCardInst->pciMemBaseRIDSpc[lBar] );
1774e1bc9a0SAchim Leubner AGTIAPI_PRINTK( "agtiapi_InitResource: PCI: bar %d, lBar %d "
1784e1bc9a0SAchim Leubner "VirtAddr=%lx, len=%d\n", bar, lBar,
1794e1bc9a0SAchim Leubner (long unsigned int)thisCardInst->pciMemVirtAddrSpc[lBar],
1804e1bc9a0SAchim Leubner thisCardInst->pciMemSizeSpc[lBar] );
1814e1bc9a0SAchim Leubner }
1824e1bc9a0SAchim Leubner else {
1834e1bc9a0SAchim Leubner thisCardInst->pciMemVirtAddrSpc[lBar] = 0;
1844e1bc9a0SAchim Leubner thisCardInst->pciMemBaseSpc[lBar] = 0;
1854e1bc9a0SAchim Leubner thisCardInst->pciMemSizeSpc[lBar] = 0;
1864e1bc9a0SAchim Leubner }
1874e1bc9a0SAchim Leubner lBar++;
1884e1bc9a0SAchim Leubner }
1894e1bc9a0SAchim Leubner thisCardInst->pciMemVirtAddr = thisCardInst->pciMemVirtAddrSpc[0];
1904e1bc9a0SAchim Leubner thisCardInst->pciMemSize = thisCardInst->pciMemSizeSpc[0];
1914e1bc9a0SAchim Leubner thisCardInst->pciMemBase = thisCardInst->pciMemBaseSpc[0];
1924e1bc9a0SAchim Leubner
1934e1bc9a0SAchim Leubner // Allocate all TI data structure required resources.
1944e1bc9a0SAchim Leubner // tiLoLevelResource
1954e1bc9a0SAchim Leubner U32 numVal;
1964e1bc9a0SAchim Leubner ag_resource_info_t *pRscInfo;
1974e1bc9a0SAchim Leubner pRscInfo = &thisCardInst->tiRscInfo;
1984e1bc9a0SAchim Leubner pRscInfo->tiLoLevelResource.loLevelOption.pciFunctionNumber =
1994e1bc9a0SAchim Leubner pci_get_function( devx );
2004e1bc9a0SAchim Leubner
2014e1bc9a0SAchim Leubner struct timeval tv;
2024e1bc9a0SAchim Leubner tv.tv_sec = 1;
2034e1bc9a0SAchim Leubner tv.tv_usec = 0;
2044e1bc9a0SAchim Leubner int ticksPerSec;
2054e1bc9a0SAchim Leubner ticksPerSec = tvtohz( &tv );
2064e1bc9a0SAchim Leubner int uSecPerTick = 1000000/USEC_PER_TICK;
2074e1bc9a0SAchim Leubner
2084e1bc9a0SAchim Leubner if (pRscInfo->tiLoLevelResource.loLevelMem.count != 0) {
2094e1bc9a0SAchim Leubner //AGTIAPI_INIT("agtiapi_InitResource: loLevelMem count = %d\n",
2104e1bc9a0SAchim Leubner // pRscInfo->tiLoLevelResource.loLevelMem.count);
2114e1bc9a0SAchim Leubner
2124e1bc9a0SAchim Leubner // adjust tick value to meet Linux requirement
2134e1bc9a0SAchim Leubner pRscInfo->tiLoLevelResource.loLevelOption.usecsPerTick = uSecPerTick;
2144e1bc9a0SAchim Leubner AGTIAPI_PRINTK( "agtiapi_InitResource: "
2154e1bc9a0SAchim Leubner "pRscInfo->tiLoLevelResource.loLevelOption.usecsPerTick"
2164e1bc9a0SAchim Leubner " 0x%x\n",
2174e1bc9a0SAchim Leubner pRscInfo->tiLoLevelResource.loLevelOption.usecsPerTick );
2184e1bc9a0SAchim Leubner for( numVal = 0; numVal < pRscInfo->tiLoLevelResource.loLevelMem.count;
2194e1bc9a0SAchim Leubner numVal++ ) {
2204e1bc9a0SAchim Leubner if( pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].totalLength ==
2214e1bc9a0SAchim Leubner 0 ) {
2224e1bc9a0SAchim Leubner AGTIAPI_PRINTK("agtiapi_InitResource: skip ZERO %d\n", numVal);
2234e1bc9a0SAchim Leubner continue;
2244e1bc9a0SAchim Leubner }
2254e1bc9a0SAchim Leubner
2264e1bc9a0SAchim Leubner // check for 64 bit alignment
2274e1bc9a0SAchim Leubner if ( pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].alignment <
2284e1bc9a0SAchim Leubner AGTIAPI_64BIT_ALIGN ) {
2294e1bc9a0SAchim Leubner AGTIAPI_PRINTK("agtiapi_InitResource: set ALIGN %d\n", numVal);
2304e1bc9a0SAchim Leubner pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].alignment =
2314e1bc9a0SAchim Leubner AGTIAPI_64BIT_ALIGN;
2324e1bc9a0SAchim Leubner }
2334e1bc9a0SAchim Leubner if( ((pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].type
2344e1bc9a0SAchim Leubner & (BIT(0) | BIT(1))) == TI_DMA_MEM) ||
2354e1bc9a0SAchim Leubner ((pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].type
2364e1bc9a0SAchim Leubner & (BIT(0) | BIT(1))) == TI_CACHED_DMA_MEM)) {
2374e1bc9a0SAchim Leubner if ( thisCardInst->dmaIndex >=
2384e1bc9a0SAchim Leubner sizeof(thisCardInst->tiDmaMem) /
2394e1bc9a0SAchim Leubner sizeof(thisCardInst->tiDmaMem[0]) ) {
2404e1bc9a0SAchim Leubner AGTIAPI_PRINTK( "Invalid dmaIndex %d ERROR\n",
2414e1bc9a0SAchim Leubner thisCardInst->dmaIndex );
2424e1bc9a0SAchim Leubner return AGTIAPI_FAIL;
2434e1bc9a0SAchim Leubner }
2444e1bc9a0SAchim Leubner thisCardInst->tiDmaMem[thisCardInst->dmaIndex].type =
2454e1bc9a0SAchim Leubner #ifdef CACHED_DMA
2464e1bc9a0SAchim Leubner pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].type
2474e1bc9a0SAchim Leubner & (BIT(0) | BIT(1));
2484e1bc9a0SAchim Leubner #else
2494e1bc9a0SAchim Leubner TI_DMA_MEM;
2504e1bc9a0SAchim Leubner #endif
2514e1bc9a0SAchim Leubner if( agtiapi_MemAlloc( thisCardInst,
2524e1bc9a0SAchim Leubner &thisCardInst->tiDmaMem[thisCardInst->dmaIndex].dmaVirtAddr,
2534e1bc9a0SAchim Leubner &thisCardInst->tiDmaMem[thisCardInst->dmaIndex].dmaPhysAddr,
2544e1bc9a0SAchim Leubner &pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].virtPtr,
2554e1bc9a0SAchim Leubner &pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].
2564e1bc9a0SAchim Leubner physAddrUpper,
2574e1bc9a0SAchim Leubner &pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].
2584e1bc9a0SAchim Leubner physAddrLower,
2594e1bc9a0SAchim Leubner pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].totalLength,
2604e1bc9a0SAchim Leubner thisCardInst->tiDmaMem[thisCardInst->dmaIndex].type,
2614e1bc9a0SAchim Leubner pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].alignment)
2624e1bc9a0SAchim Leubner != AGTIAPI_SUCCESS ) {
2634e1bc9a0SAchim Leubner return AGTIAPI_FAIL;
2644e1bc9a0SAchim Leubner }
2654e1bc9a0SAchim Leubner thisCardInst->tiDmaMem[thisCardInst->dmaIndex].memSize =
2664e1bc9a0SAchim Leubner pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].totalLength;
2674e1bc9a0SAchim Leubner //AGTIAPI_INIT("agtiapi_InitResource: LoMem %d dmaIndex=%d DMA virt"
2684e1bc9a0SAchim Leubner // " %p, phys 0x%x, length %d align %d\n",
2694e1bc9a0SAchim Leubner // numVal, pCardInfo->dmaIndex,
2704e1bc9a0SAchim Leubner // pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].virtPtr,
2714e1bc9a0SAchim Leubner // pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].physAddrLower,
2724e1bc9a0SAchim Leubner // pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].totalLength,
2734e1bc9a0SAchim Leubner // pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].alignment);
2744e1bc9a0SAchim Leubner thisCardInst->dmaIndex++;
2754e1bc9a0SAchim Leubner }
2764e1bc9a0SAchim Leubner else if ( (pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].type &
2774e1bc9a0SAchim Leubner (BIT(0) | BIT(1))) == TI_CACHED_MEM) {
2784e1bc9a0SAchim Leubner if (thisCardInst->cacheIndex >=
2794e1bc9a0SAchim Leubner sizeof(thisCardInst->tiCachedMem) /
2804e1bc9a0SAchim Leubner sizeof(thisCardInst->tiCachedMem[0])) {
2814e1bc9a0SAchim Leubner AGTIAPI_PRINTK( "Invalid cacheIndex %d ERROR\n",
2824e1bc9a0SAchim Leubner thisCardInst->cacheIndex );
2834e1bc9a0SAchim Leubner return AGTIAPI_FAIL;
2844e1bc9a0SAchim Leubner }
2854e1bc9a0SAchim Leubner if ( agtiapi_MemAlloc( thisCardInst,
2864e1bc9a0SAchim Leubner &thisCardInst->tiCachedMem[thisCardInst->cacheIndex],
2874e1bc9a0SAchim Leubner (vm_paddr_t *)agNULL,
2884e1bc9a0SAchim Leubner &pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].virtPtr,
2894e1bc9a0SAchim Leubner (U32 *)agNULL,
2904e1bc9a0SAchim Leubner (U32 *)agNULL,
2914e1bc9a0SAchim Leubner pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].totalLength,
2924e1bc9a0SAchim Leubner TI_CACHED_MEM,
2934e1bc9a0SAchim Leubner pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].alignment)
2944e1bc9a0SAchim Leubner != AGTIAPI_SUCCESS ) {
2954e1bc9a0SAchim Leubner return AGTIAPI_FAIL;
2964e1bc9a0SAchim Leubner }
2974e1bc9a0SAchim Leubner
2984e1bc9a0SAchim Leubner //AGTIAPI_INIT("agtiapi_InitResource: LoMem %d cacheIndex=%d CACHED "
2994e1bc9a0SAchim Leubner // "vaddr %p / %p, length %d align %d\n",
3004e1bc9a0SAchim Leubner // numVal, pCardInfo->cacheIndex,
3014e1bc9a0SAchim Leubner // pCardInfo->tiCachedMem[pCardInfo->cacheIndex],
3024e1bc9a0SAchim Leubner // pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].virtPtr,
3034e1bc9a0SAchim Leubner // pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].totalLength,
3044e1bc9a0SAchim Leubner // pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].alignment);
3054e1bc9a0SAchim Leubner
3064e1bc9a0SAchim Leubner thisCardInst->cacheIndex++;
3074e1bc9a0SAchim Leubner }
3084e1bc9a0SAchim Leubner else if ( ((pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].type
3094e1bc9a0SAchim Leubner & (BIT(0) | BIT(1))) == TI_DMA_MEM_CHIP)) {
3104e1bc9a0SAchim Leubner // not expecting this case, print warning that should get attention
3114e1bc9a0SAchim Leubner printf( "RED ALARM: we need a BAR for TI_DMA_MEM_CHIP, ignoring!" );
3124e1bc9a0SAchim Leubner }
3134e1bc9a0SAchim Leubner else {
3144e1bc9a0SAchim Leubner printf( "agtiapi_InitResource: Unknown required memory type %d "
3154e1bc9a0SAchim Leubner "ERROR!\n",
3164e1bc9a0SAchim Leubner pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].type);
3174e1bc9a0SAchim Leubner return AGTIAPI_FAIL;
3184e1bc9a0SAchim Leubner }
3194e1bc9a0SAchim Leubner }
3204e1bc9a0SAchim Leubner }
3214e1bc9a0SAchim Leubner // end: TI data structure resources ...
3224e1bc9a0SAchim Leubner
3234e1bc9a0SAchim Leubner // begin: tiInitiatorResource
3244e1bc9a0SAchim Leubner if ( pmsc->flags & AGTIAPI_INITIATOR ) {
3254e1bc9a0SAchim Leubner if ( pRscInfo->tiInitiatorResource.initiatorMem.count != 0 ) {
3264e1bc9a0SAchim Leubner //AGTIAPI_INIT("agtiapi_InitResource: initiatorMem count = %d\n",
3274e1bc9a0SAchim Leubner // pRscInfo->tiInitiatorResource.initiatorMem.count);
3284e1bc9a0SAchim Leubner numVal =
3294e1bc9a0SAchim Leubner (U32)( pRscInfo->tiInitiatorResource.initiatorOption.usecsPerTick
3304e1bc9a0SAchim Leubner / uSecPerTick );
3314e1bc9a0SAchim Leubner if( pRscInfo->tiInitiatorResource.initiatorOption.usecsPerTick
3324e1bc9a0SAchim Leubner % uSecPerTick > 0 )
3334e1bc9a0SAchim Leubner pRscInfo->tiInitiatorResource.initiatorOption.usecsPerTick =
3344e1bc9a0SAchim Leubner (numVal + 1) * uSecPerTick;
3354e1bc9a0SAchim Leubner else
3364e1bc9a0SAchim Leubner pRscInfo->tiInitiatorResource.initiatorOption.usecsPerTick =
3374e1bc9a0SAchim Leubner numVal * uSecPerTick;
3384e1bc9a0SAchim Leubner for ( numVal = 0;
3394e1bc9a0SAchim Leubner numVal < pRscInfo->tiInitiatorResource.initiatorMem.count;
3404e1bc9a0SAchim Leubner numVal++ ) {
3414e1bc9a0SAchim Leubner // check for 64 bit alignment
3424e1bc9a0SAchim Leubner if( pRscInfo->tiInitiatorResource.initiatorMem.tdCachedMem[numVal].
3434e1bc9a0SAchim Leubner alignment < AGTIAPI_64BIT_ALIGN ) {
3444e1bc9a0SAchim Leubner pRscInfo->tiInitiatorResource.initiatorMem.tdCachedMem[numVal].
3454e1bc9a0SAchim Leubner alignment = AGTIAPI_64BIT_ALIGN;
3464e1bc9a0SAchim Leubner }
3474e1bc9a0SAchim Leubner if( thisCardInst->cacheIndex >=
3484e1bc9a0SAchim Leubner sizeof( thisCardInst->tiCachedMem) /
3494e1bc9a0SAchim Leubner sizeof( thisCardInst->tiCachedMem[0])) {
3504e1bc9a0SAchim Leubner AGTIAPI_PRINTK( "Invalid cacheIndex %d ERROR\n",
3514e1bc9a0SAchim Leubner thisCardInst->cacheIndex );
3524e1bc9a0SAchim Leubner return AGTIAPI_FAIL;
3534e1bc9a0SAchim Leubner }
3544e1bc9a0SAchim Leubner // initiator memory is cached, no check is needed
3554e1bc9a0SAchim Leubner if( agtiapi_MemAlloc( thisCardInst,
3564e1bc9a0SAchim Leubner (void *)&thisCardInst->tiCachedMem[thisCardInst->cacheIndex],
3574e1bc9a0SAchim Leubner (vm_paddr_t *)agNULL,
3584e1bc9a0SAchim Leubner &pRscInfo->tiInitiatorResource.initiatorMem.
3594e1bc9a0SAchim Leubner tdCachedMem[numVal].virtPtr,
3604e1bc9a0SAchim Leubner (U32 *)agNULL,
3614e1bc9a0SAchim Leubner (U32 *)agNULL,
3624e1bc9a0SAchim Leubner pRscInfo->tiInitiatorResource.initiatorMem.tdCachedMem[numVal].
3634e1bc9a0SAchim Leubner totalLength,
3644e1bc9a0SAchim Leubner TI_CACHED_MEM,
3654e1bc9a0SAchim Leubner pRscInfo->tiInitiatorResource.initiatorMem.tdCachedMem[numVal].
3664e1bc9a0SAchim Leubner alignment)
3674e1bc9a0SAchim Leubner != AGTIAPI_SUCCESS) {
3684e1bc9a0SAchim Leubner return AGTIAPI_FAIL;
3694e1bc9a0SAchim Leubner }
3704e1bc9a0SAchim Leubner // AGTIAPI_INIT("agtiapi_InitResource: IniMem %d cacheIndex=%d CACHED "
3714e1bc9a0SAchim Leubner // "vaddr %p / %p, length %d align 0x%x\n",
3724e1bc9a0SAchim Leubner // numVal,
3734e1bc9a0SAchim Leubner // pCardInfo->cacheIndex,
3744e1bc9a0SAchim Leubner // pCardInfo->tiCachedMem[pCardInfo->cacheIndex],
3754e1bc9a0SAchim Leubner // pRscInfo->tiInitiatorResource.initiatorMem.tdCachedMem[numVal].
3764e1bc9a0SAchim Leubner // virtPtr,
3774e1bc9a0SAchim Leubner //pRscInfo->tiInitiatorResource.initiatorMem.tdCachedMem[numVal].
3784e1bc9a0SAchim Leubner // totalLength,
3794e1bc9a0SAchim Leubner // pRscInfo->tiInitiatorResource.initiatorMem.tdCachedMem[numVal].
3804e1bc9a0SAchim Leubner // alignment);
3814e1bc9a0SAchim Leubner thisCardInst->cacheIndex++;
3824e1bc9a0SAchim Leubner }
3834e1bc9a0SAchim Leubner }
3844e1bc9a0SAchim Leubner }
3854e1bc9a0SAchim Leubner // end: tiInitiatorResource
3864e1bc9a0SAchim Leubner
3874e1bc9a0SAchim Leubner // begin: tiTdSharedMem
3884e1bc9a0SAchim Leubner if (pRscInfo->tiSharedMem.tdSharedCachedMem1.totalLength != 0) {
3894e1bc9a0SAchim Leubner // check for 64 bit alignment
3904e1bc9a0SAchim Leubner if( pRscInfo->tiSharedMem.tdSharedCachedMem1.alignment <
3914e1bc9a0SAchim Leubner AGTIAPI_64BIT_ALIGN ) {
3924e1bc9a0SAchim Leubner pRscInfo->tiSharedMem.tdSharedCachedMem1.alignment = AGTIAPI_64BIT_ALIGN;
3934e1bc9a0SAchim Leubner }
3944e1bc9a0SAchim Leubner if( (pRscInfo->tiSharedMem.tdSharedCachedMem1.type & (BIT(0) | BIT(1)))
3954e1bc9a0SAchim Leubner == TI_DMA_MEM ) {
3964e1bc9a0SAchim Leubner if( thisCardInst->dmaIndex >=
3974e1bc9a0SAchim Leubner sizeof(thisCardInst->tiDmaMem) / sizeof(thisCardInst->tiDmaMem[0]) ) {
3984e1bc9a0SAchim Leubner AGTIAPI_PRINTK( "Invalid dmaIndex %d ERROR\n", thisCardInst->dmaIndex);
3994e1bc9a0SAchim Leubner return AGTIAPI_FAIL;
4004e1bc9a0SAchim Leubner }
4014e1bc9a0SAchim Leubner if( agtiapi_MemAlloc( thisCardInst, (void *)&thisCardInst->
4024e1bc9a0SAchim Leubner tiDmaMem[thisCardInst->dmaIndex].dmaVirtAddr,
4034e1bc9a0SAchim Leubner &thisCardInst->tiDmaMem[thisCardInst->dmaIndex].
4044e1bc9a0SAchim Leubner dmaPhysAddr,
4054e1bc9a0SAchim Leubner &pRscInfo->tiSharedMem.tdSharedCachedMem1.virtPtr,
4064e1bc9a0SAchim Leubner &pRscInfo->tiSharedMem.tdSharedCachedMem1.
4074e1bc9a0SAchim Leubner physAddrUpper,
4084e1bc9a0SAchim Leubner &pRscInfo->tiSharedMem.tdSharedCachedMem1.
4094e1bc9a0SAchim Leubner physAddrLower,
4104e1bc9a0SAchim Leubner pRscInfo->tiSharedMem.tdSharedCachedMem1.
4114e1bc9a0SAchim Leubner totalLength,
4124e1bc9a0SAchim Leubner TI_DMA_MEM,
4134e1bc9a0SAchim Leubner pRscInfo->tiSharedMem.tdSharedCachedMem1.alignment)
4144e1bc9a0SAchim Leubner != AGTIAPI_SUCCESS )
4154e1bc9a0SAchim Leubner return AGTIAPI_FAIL;
4164e1bc9a0SAchim Leubner
4174e1bc9a0SAchim Leubner thisCardInst->tiDmaMem[thisCardInst->dmaIndex].memSize =
4184e1bc9a0SAchim Leubner pRscInfo->tiSharedMem.tdSharedCachedMem1.totalLength +
4194e1bc9a0SAchim Leubner pRscInfo->tiSharedMem.tdSharedCachedMem1.alignment;
4204e1bc9a0SAchim Leubner // printf( "agtiapi_InitResource: SharedMem DmaIndex=%d DMA "
4214e1bc9a0SAchim Leubner // "virt %p / %p, phys 0x%x, align %d\n",
4224e1bc9a0SAchim Leubner // thisCardInst->dmaIndex,
4234e1bc9a0SAchim Leubner // thisCardInst->tiDmaMem[thisCardInst->dmaIndex].dmaVirtAddr,
4244e1bc9a0SAchim Leubner // pRscInfo->tiSharedMem.tdSharedCachedMem1.virtPtr,
4254e1bc9a0SAchim Leubner // pRscInfo->tiSharedMem.tdSharedCachedMem1.physAddrLower,
4264e1bc9a0SAchim Leubner // pRscInfo->tiSharedMem.tdSharedCachedMem1.alignment);
4274e1bc9a0SAchim Leubner thisCardInst->dmaIndex++;
4284e1bc9a0SAchim Leubner }
4294e1bc9a0SAchim Leubner else if( (pRscInfo->tiSharedMem.tdSharedCachedMem1.type &
4304e1bc9a0SAchim Leubner (BIT(0) | BIT(1)))
4314e1bc9a0SAchim Leubner == TI_CACHED_MEM ) {
4324e1bc9a0SAchim Leubner if( thisCardInst->cacheIndex >=
4334e1bc9a0SAchim Leubner sizeof(thisCardInst->tiCachedMem) /
4344e1bc9a0SAchim Leubner sizeof(thisCardInst->tiCachedMem[0]) ) {
4354e1bc9a0SAchim Leubner AGTIAPI_PRINTK( "Invalid cacheIndex %d ERROR\n", thisCardInst->cacheIndex);
4364e1bc9a0SAchim Leubner return AGTIAPI_FAIL;
4374e1bc9a0SAchim Leubner }
4384e1bc9a0SAchim Leubner if( agtiapi_MemAlloc( thisCardInst, (void *)&thisCardInst->
4394e1bc9a0SAchim Leubner tiCachedMem[thisCardInst->cacheIndex],
4404e1bc9a0SAchim Leubner (vm_paddr_t *)agNULL,
4414e1bc9a0SAchim Leubner &pRscInfo->tiSharedMem.tdSharedCachedMem1.virtPtr,
4424e1bc9a0SAchim Leubner (U32 *)agNULL,
4434e1bc9a0SAchim Leubner (U32 *)agNULL,
4444e1bc9a0SAchim Leubner pRscInfo->
4454e1bc9a0SAchim Leubner tiSharedMem.tdSharedCachedMem1.totalLength,
4464e1bc9a0SAchim Leubner TI_CACHED_MEM,
4474e1bc9a0SAchim Leubner pRscInfo->tiSharedMem.tdSharedCachedMem1.alignment)
4484e1bc9a0SAchim Leubner != AGTIAPI_SUCCESS )
4494e1bc9a0SAchim Leubner return AGTIAPI_FAIL;
4504e1bc9a0SAchim Leubner // printf( "agtiapi_InitResource: SharedMem cacheIndex=%d CACHED "
4514e1bc9a0SAchim Leubner // "vaddr %p / %p, length %d align 0x%x\n",
4524e1bc9a0SAchim Leubner // thisCardInst->cacheIndex,
4534e1bc9a0SAchim Leubner // thisCardInst->tiCachedMem[thisCardInst->cacheIndex],
4544e1bc9a0SAchim Leubner // pRscInfo->tiSharedMem.tdSharedCachedMem1.virtPtr,
4554e1bc9a0SAchim Leubner // pRscInfo->tiSharedMem.tdSharedCachedMem1.totalLength,
4564e1bc9a0SAchim Leubner // pRscInfo->tiSharedMem.tdSharedCachedMem1.alignment);
4574e1bc9a0SAchim Leubner AGTIAPI_PRINTK( "agtiapi_InitResource: SharedMem cacheIndex=%d CACHED "
4584e1bc9a0SAchim Leubner "vaddr %p / %p, length %d align 0x%x\n",
4594e1bc9a0SAchim Leubner thisCardInst->cacheIndex,
4604e1bc9a0SAchim Leubner thisCardInst->tiCachedMem[thisCardInst->cacheIndex],
4614e1bc9a0SAchim Leubner pRscInfo->tiSharedMem.tdSharedCachedMem1.virtPtr,
4624e1bc9a0SAchim Leubner pRscInfo->tiSharedMem.tdSharedCachedMem1.totalLength,
4634e1bc9a0SAchim Leubner pRscInfo->tiSharedMem.tdSharedCachedMem1.alignment );
4644e1bc9a0SAchim Leubner thisCardInst->cacheIndex++;
4654e1bc9a0SAchim Leubner }
4664e1bc9a0SAchim Leubner else {
4674e1bc9a0SAchim Leubner AGTIAPI_PRINTK( "agtiapi_InitResource: "
4684e1bc9a0SAchim Leubner "Unknown required memory type ERROR!\n" );
4694e1bc9a0SAchim Leubner return AGTIAPI_FAIL;
4704e1bc9a0SAchim Leubner }
4714e1bc9a0SAchim Leubner }
4724e1bc9a0SAchim Leubner // end: tiTdSharedMem
4734e1bc9a0SAchim Leubner DELAY( 200000 ); // or use AGTIAPI_INIT_MDELAY(200);
4744e1bc9a0SAchim Leubner return AGTIAPI_SUCCESS;
4754e1bc9a0SAchim Leubner } // agtiapi_InitResource() ends here
4764e1bc9a0SAchim Leubner
4774e1bc9a0SAchim Leubner /******************************************************************************
4784e1bc9a0SAchim Leubner agtiapi_ScopeDMARes()
4794e1bc9a0SAchim Leubner Purpose:
4804e1bc9a0SAchim Leubner Determine the amount of DMA (non-cache) memory resources which will be
4814e1bc9a0SAchim Leubner required for a card ( and necessarily allocated in agtiapi_InitResource() )
4824e1bc9a0SAchim Leubner Parameters:
4834e1bc9a0SAchim Leubner ag_card_info_t *thisCardInst (IN)
4844e1bc9a0SAchim Leubner Return:
4854e1bc9a0SAchim Leubner size of DMA memory which call to agtiapi_InitResource() will consume
4864e1bc9a0SAchim Leubner Note:
4874e1bc9a0SAchim Leubner this funcion mirrors the flow of agtiapi_InitResource()
4884e1bc9a0SAchim Leubner results are stored in agtiapi_softc fields
4894e1bc9a0SAchim Leubner ******************************************************************************/
agtiapi_ScopeDMARes(ag_card_info_t * thisCardInst)4904e1bc9a0SAchim Leubner STATIC int agtiapi_ScopeDMARes( ag_card_info_t *thisCardInst )
4914e1bc9a0SAchim Leubner {
4924e1bc9a0SAchim Leubner struct agtiapi_softc *pmsc = thisCardInst->pCard;
4934e1bc9a0SAchim Leubner U32 lAllMem = 0; // total memory count; typhn
4944e1bc9a0SAchim Leubner U32 lTmpAlign, lTmpType, lTmpLen;
4954e1bc9a0SAchim Leubner
4964e1bc9a0SAchim Leubner // tiLoLevelResource
4974e1bc9a0SAchim Leubner U32 numVal;
4984e1bc9a0SAchim Leubner ag_resource_info_t *pRscInfo;
4994e1bc9a0SAchim Leubner pRscInfo = &thisCardInst->tiRscInfo;
5004e1bc9a0SAchim Leubner
5014e1bc9a0SAchim Leubner if (pRscInfo->tiLoLevelResource.loLevelMem.count != 0) {
5024e1bc9a0SAchim Leubner for( numVal = 0; numVal < pRscInfo->tiLoLevelResource.loLevelMem.count;
5034e1bc9a0SAchim Leubner numVal++ ) {
5044e1bc9a0SAchim Leubner if( pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].totalLength ==
5054e1bc9a0SAchim Leubner 0 ) {
5064e1bc9a0SAchim Leubner printf( "agtiapi_ScopeDMARes: skip ZERO %d\n", numVal );
5074e1bc9a0SAchim Leubner continue;
5084e1bc9a0SAchim Leubner }
5094e1bc9a0SAchim Leubner // check for 64 bit alignment
5104e1bc9a0SAchim Leubner lTmpAlign = pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].alignment;
5114e1bc9a0SAchim Leubner if( lTmpAlign < AGTIAPI_64BIT_ALIGN ) {
5124e1bc9a0SAchim Leubner AGTIAPI_PRINTK("agtiapi_ScopeDMARes: set ALIGN %d\n", numVal);
5134e1bc9a0SAchim Leubner //pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].alignment =
5144e1bc9a0SAchim Leubner lTmpAlign = AGTIAPI_64BIT_ALIGN;
5154e1bc9a0SAchim Leubner }
5164e1bc9a0SAchim Leubner if( ((pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].type
5174e1bc9a0SAchim Leubner & (BIT(0) | BIT(1))) == TI_DMA_MEM) ||
5184e1bc9a0SAchim Leubner ((pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].type
5194e1bc9a0SAchim Leubner & (BIT(0) | BIT(1))) == TI_CACHED_DMA_MEM)) {
5204e1bc9a0SAchim Leubner //thisCardInst->tiDmaMem[thisCardInst->dmaIndex].type =
5214e1bc9a0SAchim Leubner lTmpType =
5224e1bc9a0SAchim Leubner #ifdef CACHED_DMA
5234e1bc9a0SAchim Leubner pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].type
5244e1bc9a0SAchim Leubner & (BIT(0) | BIT(1));
5254e1bc9a0SAchim Leubner #else
5264e1bc9a0SAchim Leubner TI_DMA_MEM;
5274e1bc9a0SAchim Leubner #endif
5284e1bc9a0SAchim Leubner if( lTmpType == TI_DMA_MEM ) {
5294e1bc9a0SAchim Leubner lTmpLen =
5304e1bc9a0SAchim Leubner pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].totalLength;
5314e1bc9a0SAchim Leubner lAllMem += lTmpLen + lTmpAlign;
5324e1bc9a0SAchim Leubner }
5334e1bc9a0SAchim Leubner //printf( "agtiapi_ScopeDMARes: call 1 0x%x\n", lAllMem );
5344e1bc9a0SAchim Leubner }
5354e1bc9a0SAchim Leubner else if ( ( pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].type &
5364e1bc9a0SAchim Leubner (BIT(0) | BIT(1)) ) == TI_CACHED_MEM ) {
5374e1bc9a0SAchim Leubner // these are not the droids we're looking for
5384e1bc9a0SAchim Leubner if( thisCardInst->cacheIndex >=
5394e1bc9a0SAchim Leubner sizeof(thisCardInst->tiCachedMem) /
5404e1bc9a0SAchim Leubner sizeof(thisCardInst->tiCachedMem[0]) ) {
5414e1bc9a0SAchim Leubner AGTIAPI_PRINTK( "agtiapi_ScopeDMARes: Invalid cacheIndex %d ERROR\n",
5424e1bc9a0SAchim Leubner thisCardInst->cacheIndex );
5434e1bc9a0SAchim Leubner return lAllMem;
5444e1bc9a0SAchim Leubner }
5454e1bc9a0SAchim Leubner }
5464e1bc9a0SAchim Leubner else {
5474e1bc9a0SAchim Leubner printf( "agtiapi_ScopeDMARes: Unknown required memory type %d "
5484e1bc9a0SAchim Leubner "ERROR!\n",
5494e1bc9a0SAchim Leubner pRscInfo->tiLoLevelResource.loLevelMem.mem[numVal].type );
5504e1bc9a0SAchim Leubner return lAllMem;
5514e1bc9a0SAchim Leubner }
5524e1bc9a0SAchim Leubner }
5534e1bc9a0SAchim Leubner }
5544e1bc9a0SAchim Leubner // end: TI data structure resources ...
5554e1bc9a0SAchim Leubner
5564e1bc9a0SAchim Leubner // nothing for tiInitiatorResource
5574e1bc9a0SAchim Leubner
5584e1bc9a0SAchim Leubner // begin: tiTdSharedMem
5594e1bc9a0SAchim Leubner if (pRscInfo->tiSharedMem.tdSharedCachedMem1.totalLength != 0) {
5604e1bc9a0SAchim Leubner // check for 64 bit alignment
5614e1bc9a0SAchim Leubner lTmpAlign = pRscInfo->tiSharedMem.tdSharedCachedMem1.alignment;
5624e1bc9a0SAchim Leubner if( lTmpAlign < AGTIAPI_64BIT_ALIGN ) {
5634e1bc9a0SAchim Leubner //pRscInfo->tiSharedMem.tdSharedCachedMem1.alignment=AGTIAPI_64BIT_ALIGN;
5644e1bc9a0SAchim Leubner lTmpAlign = AGTIAPI_64BIT_ALIGN;
5654e1bc9a0SAchim Leubner }
5664e1bc9a0SAchim Leubner if( (pRscInfo->tiSharedMem.tdSharedCachedMem1.type & (BIT(0) | BIT(1)))
5674e1bc9a0SAchim Leubner == TI_DMA_MEM ) {
5684e1bc9a0SAchim Leubner lTmpLen = pRscInfo->tiSharedMem.tdSharedCachedMem1.totalLength;
5694e1bc9a0SAchim Leubner lAllMem += lTmpLen + lTmpAlign;
5704e1bc9a0SAchim Leubner // printf( "agtiapi_ScopeDMARes: call 4D 0x%x\n", lAllMem );
5714e1bc9a0SAchim Leubner }
5724e1bc9a0SAchim Leubner else if( (pRscInfo->tiSharedMem.tdSharedCachedMem1.type &
5734e1bc9a0SAchim Leubner (BIT(0) | BIT(1)))
5744e1bc9a0SAchim Leubner != TI_CACHED_MEM ) {
5754e1bc9a0SAchim Leubner printf( "agtiapi_ScopeDMARes: Unknown required memory type ERROR!\n" );
5764e1bc9a0SAchim Leubner }
5774e1bc9a0SAchim Leubner }
5784e1bc9a0SAchim Leubner // end: tiTdSharedMem
5794e1bc9a0SAchim Leubner
5804e1bc9a0SAchim Leubner pmsc->typhn = lAllMem;
5814e1bc9a0SAchim Leubner return lAllMem;
5824e1bc9a0SAchim Leubner
5834e1bc9a0SAchim Leubner } // agtiapi_ScopeDMARes() ends here
5844e1bc9a0SAchim Leubner
5854e1bc9a0SAchim Leubner
agtiapi_ReleasePCIMem(ag_card_info_t * pCardInfo)5864e1bc9a0SAchim Leubner STATIC void agtiapi_ReleasePCIMem( ag_card_info_t *pCardInfo ) {
5874e1bc9a0SAchim Leubner U32 bar = 0;
5884e1bc9a0SAchim Leubner int tmpRid = 0;
5894e1bc9a0SAchim Leubner struct resource *tmpRsc = NULL;
5904e1bc9a0SAchim Leubner device_t dev;
5914e1bc9a0SAchim Leubner dev = pCardInfo->pPCIDev;
5924e1bc9a0SAchim Leubner
5934e1bc9a0SAchim Leubner for (bar=0; bar < PCI_NUMBER_BARS; bar++) { // clean up PCI resource
5944e1bc9a0SAchim Leubner tmpRid = pCardInfo->pciMemBaseRIDSpc[bar];
5954e1bc9a0SAchim Leubner tmpRsc = pCardInfo->pciMemBaseRscSpc[bar];
5964e1bc9a0SAchim Leubner if (tmpRsc != NULL) { // Release PCI resources
5974e1bc9a0SAchim Leubner bus_release_resource( dev, SYS_RES_MEMORY, tmpRid, tmpRsc );
5984e1bc9a0SAchim Leubner }
5994e1bc9a0SAchim Leubner }
6004e1bc9a0SAchim Leubner return;
6014e1bc9a0SAchim Leubner }
6024e1bc9a0SAchim Leubner
6034e1bc9a0SAchim Leubner
6044e1bc9a0SAchim Leubner /******************************************************************************
6054e1bc9a0SAchim Leubner agtiapi_MemAlloc()
6064e1bc9a0SAchim Leubner Purpose:
6074e1bc9a0SAchim Leubner Handle various memory allocation requests.
6084e1bc9a0SAchim Leubner Parameters:
6094e1bc9a0SAchim Leubner ag_card_info_t *pCardInfo (IN) Pointer to card info structure
6104e1bc9a0SAchim Leubner void **VirtAlloc (OUT) Allocated memory virtual address
6114e1bc9a0SAchim Leubner dma_addr_t *pDmaAddr (OUT) Allocated dma memory physical address
6124e1bc9a0SAchim Leubner void **VirtAddr (OUT) Aligned memory virtual address
6134e1bc9a0SAchim Leubner U32 *pPhysAddrUp (OUT) Allocated memory physical upper 32 bits
6144e1bc9a0SAchim Leubner U32 *pPhysAddrLow (OUT) Allocated memory physical lower 32 bits
6154e1bc9a0SAchim Leubner U32 MemSize (IN) Allocated memory size
6164e1bc9a0SAchim Leubner U32 Type (IN) Type of memory required
6174e1bc9a0SAchim Leubner U32 Align (IN) Required memory alignment
6184e1bc9a0SAchim Leubner Return:
6194e1bc9a0SAchim Leubner AGTIAPI_SUCCESS - success
6204e1bc9a0SAchim Leubner AGTIAPI_FAIL - fail
6214e1bc9a0SAchim Leubner ******************************************************************************/
agtiapi_MemAlloc(ag_card_info_t * thisCardInst,void ** VirtAlloc,vm_paddr_t * pDmaAddr,void ** VirtAddr,U32 * pPhysAddrUp,U32 * pPhysAddrLow,U32 MemSize,U32 Type,U32 Align)6224e1bc9a0SAchim Leubner STATIC agBOOLEAN agtiapi_MemAlloc( ag_card_info_t *thisCardInst,
6234e1bc9a0SAchim Leubner void **VirtAlloc,
6244e1bc9a0SAchim Leubner vm_paddr_t *pDmaAddr,
6254e1bc9a0SAchim Leubner void **VirtAddr,
6264e1bc9a0SAchim Leubner U32 *pPhysAddrUp,
6274e1bc9a0SAchim Leubner U32 *pPhysAddrLow,
6284e1bc9a0SAchim Leubner U32 MemSize,
6294e1bc9a0SAchim Leubner U32 Type,
6304e1bc9a0SAchim Leubner U32 Align )
6314e1bc9a0SAchim Leubner {
6324e1bc9a0SAchim Leubner U32_64 alignOffset = 0;
6334e1bc9a0SAchim Leubner if( Align )
6344e1bc9a0SAchim Leubner alignOffset = Align - 1;
6354e1bc9a0SAchim Leubner
6364e1bc9a0SAchim Leubner // printf( "agtiapi_MemAlloc: debug find mem TYPE, %d vs. CACHE %d, DMA %d \n",
6374e1bc9a0SAchim Leubner // ( Type & ( BIT(0) | BIT(1) ) ), TI_CACHED_MEM, TI_DMA_MEM );
6384e1bc9a0SAchim Leubner
6394e1bc9a0SAchim Leubner if ((Type & (BIT(0) | BIT(1))) == TI_CACHED_MEM) {
6404e1bc9a0SAchim Leubner *VirtAlloc = malloc( MemSize + Align, M_PMC_MMAL, M_ZERO | M_NOWAIT );
6414e1bc9a0SAchim Leubner *VirtAddr = (void *)(((U32_64)*VirtAlloc + alignOffset) & ~alignOffset);
6424e1bc9a0SAchim Leubner }
6434e1bc9a0SAchim Leubner else {
6444e1bc9a0SAchim Leubner struct agtiapi_softc *pmsc = thisCardInst->pCard; // get card reference
6454e1bc9a0SAchim Leubner U32 residAlign = 0;
6464e1bc9a0SAchim Leubner // find virt index value
6474e1bc9a0SAchim Leubner *VirtAlloc = (void*)( (U64)pmsc->typh_mem + pmsc->typhIdx );
6484e1bc9a0SAchim Leubner *VirtAddr = (void *)( ( (U32_64)*VirtAlloc + alignOffset) & ~alignOffset );
6494e1bc9a0SAchim Leubner if( *VirtAddr != *VirtAlloc )
6504e1bc9a0SAchim Leubner residAlign = (U64)*VirtAddr - (U64)*VirtAlloc; // find alignment needed
6514e1bc9a0SAchim Leubner pmsc->typhIdx += residAlign + MemSize; // update index
6524e1bc9a0SAchim Leubner residAlign = 0; // reset variable for reuse
6534e1bc9a0SAchim Leubner // find phys index val
6544e1bc9a0SAchim Leubner pDmaAddr = (vm_paddr_t*)( (U64)pmsc->typh_busaddr + pmsc->tyPhsIx );
6554e1bc9a0SAchim Leubner vm_paddr_t *lPhysAligned =
6564e1bc9a0SAchim Leubner (vm_paddr_t*)( ( (U64)pDmaAddr + alignOffset ) & ~alignOffset );
6574e1bc9a0SAchim Leubner if( lPhysAligned != pDmaAddr )
6584e1bc9a0SAchim Leubner residAlign = (U64)lPhysAligned - (U64)pDmaAddr; // find alignment needed
6594e1bc9a0SAchim Leubner pmsc->tyPhsIx += residAlign + MemSize; // update index
6604e1bc9a0SAchim Leubner *pPhysAddrUp = HIGH_32_BITS( (U64)lPhysAligned );
6614e1bc9a0SAchim Leubner *pPhysAddrLow = LOW_32_BITS( (U64)lPhysAligned );
6624e1bc9a0SAchim Leubner //printf( "agtiapi_MemAlloc: physIx 0x%x size 0x%x resid:0x%x "
6634e1bc9a0SAchim Leubner // "addr:0x%p addrAligned:0x%p Align:0x%x\n",
6644e1bc9a0SAchim Leubner // pmsc->tyPhsIx, MemSize, residAlign, pDmaAddr, lPhysAligned,
6654e1bc9a0SAchim Leubner // Align );
6664e1bc9a0SAchim Leubner }
6674e1bc9a0SAchim Leubner if ( !*VirtAlloc ) {
6684e1bc9a0SAchim Leubner AGTIAPI_PRINTK( "agtiapi_MemAlloc memory allocation ERROR x%x\n",
6694e1bc9a0SAchim Leubner Type & (U32)(BIT(0) | BIT(1)));
6704e1bc9a0SAchim Leubner return AGTIAPI_FAIL;
6714e1bc9a0SAchim Leubner }
6724e1bc9a0SAchim Leubner return AGTIAPI_SUCCESS;
6734e1bc9a0SAchim Leubner }
6744e1bc9a0SAchim Leubner
6754e1bc9a0SAchim Leubner
6764e1bc9a0SAchim Leubner /******************************************************************************
6774e1bc9a0SAchim Leubner agtiapi_MemFree()
6784e1bc9a0SAchim Leubner
6794e1bc9a0SAchim Leubner Purpose:
6804e1bc9a0SAchim Leubner Free agtiapi_MemAlloc() allocated memory
6814e1bc9a0SAchim Leubner Parameters:
6824e1bc9a0SAchim Leubner ag_card_info_t *pCardInfo (IN) Pointer to card info structure
6834e1bc9a0SAchim Leubner Return: none
6844e1bc9a0SAchim Leubner ******************************************************************************/
agtiapi_MemFree(ag_card_info_t * pCardInfo)6854e1bc9a0SAchim Leubner STATIC void agtiapi_MemFree( ag_card_info_t *pCardInfo )
6864e1bc9a0SAchim Leubner {
6874e1bc9a0SAchim Leubner U32 idx;
6884e1bc9a0SAchim Leubner
6894e1bc9a0SAchim Leubner // release memory vs. alloc in agtiapi_MemAlloc; cached case
6904e1bc9a0SAchim Leubner for( idx = 0; idx < pCardInfo->cacheIndex; idx++ ) {
6914e1bc9a0SAchim Leubner if( pCardInfo->tiCachedMem[idx] ) {
6924e1bc9a0SAchim Leubner free( pCardInfo->tiCachedMem[idx], M_PMC_MMAL );
6934e1bc9a0SAchim Leubner AGTIAPI_PRINTK( "agtiapi_MemFree: TI_CACHED_MEM Mem[%d] %p\n",
6944e1bc9a0SAchim Leubner idx, pCardInfo->tiCachedMem[idx] );
6954e1bc9a0SAchim Leubner }
6964e1bc9a0SAchim Leubner }
6974e1bc9a0SAchim Leubner
6984e1bc9a0SAchim Leubner // release memory vs. alloc in agtiapi_typhAlloc; used in agtiapi_MemAlloc
6994e1bc9a0SAchim Leubner struct agtiapi_softc *pmsc = pCardInfo->pCard; // get card reference
7004e1bc9a0SAchim Leubner if( pmsc->typh_busaddr != 0 ) {
7014e1bc9a0SAchim Leubner bus_dmamap_unload( pmsc->typh_dmat, pmsc->typh_mapp );
7024e1bc9a0SAchim Leubner }
7034e1bc9a0SAchim Leubner if( pmsc->typh_mem != NULL ) {
7044e1bc9a0SAchim Leubner bus_dmamem_free( pmsc->typh_dmat, pmsc->typh_mem, pmsc->typh_mapp );
7054e1bc9a0SAchim Leubner }
7064e1bc9a0SAchim Leubner if( pmsc->typh_dmat != NULL ) {
7074e1bc9a0SAchim Leubner bus_dma_tag_destroy( pmsc->typh_dmat );
7084e1bc9a0SAchim Leubner }
7094e1bc9a0SAchim Leubner //reference values:
7104e1bc9a0SAchim Leubner // pCardInfo->dmaIndex
7114e1bc9a0SAchim Leubner // pCardInfo->tiDmaMem[idx].dmaVirtAddr
7124e1bc9a0SAchim Leubner // pCardInfo->tiDmaMem[idx].memSize
7134e1bc9a0SAchim Leubner // pCardInfo->tiDmaMem[idx].type == TI_CACHED_DMA_MEM
7144e1bc9a0SAchim Leubner // pCardInfo->tiDmaMem[idx].type == TI_DMA_MEM
7154e1bc9a0SAchim Leubner
7164e1bc9a0SAchim Leubner /* This code is redundant. Commenting out for now to maintain a placekeeper.
7174e1bc9a0SAchim Leubner Free actually takes place in agtiapi_ReleaseHBA as calls on osti_dmat. dm
7184e1bc9a0SAchim Leubner // release possible lower layer dynamic memory
7194e1bc9a0SAchim Leubner for( idx = 0; idx < AGTIAPI_DYNAMIC_MAX; idx++ ) {
7204e1bc9a0SAchim Leubner if( pCardInfo->dynamicMem[idx].dmaVirtAddr != NULL ) {
7214e1bc9a0SAchim Leubner printf( "agtiapi_MemFree: dynMem[%d] virtAddr"
7224e1bc9a0SAchim Leubner " %p / %lx size: %d\n",
7234e1bc9a0SAchim Leubner idx, pCardInfo->dynamicMem[idx].dmaVirtAddr,
7244e1bc9a0SAchim Leubner (long unsigned int)pCardInfo->dynamicMem[idx].dmaPhysAddr,
7254e1bc9a0SAchim Leubner pCardInfo->dynamicMem[idx].memSize );
7264e1bc9a0SAchim Leubner if( pCardInfo->dynamicMem[idx].dmaPhysAddr )
7274e1bc9a0SAchim Leubner some form of free call would go here (
7284e1bc9a0SAchim Leubner pCardInfo->dynamicMem[idx].dmaVirtAddr,
7294e1bc9a0SAchim Leubner pCardInfo->dynamicMem[idx].memSize, ... );
7304e1bc9a0SAchim Leubner else
7314e1bc9a0SAchim Leubner free case for cacheable memory would go here
7324e1bc9a0SAchim Leubner }
7334e1bc9a0SAchim Leubner }
7344e1bc9a0SAchim Leubner */
7354e1bc9a0SAchim Leubner return;
7364e1bc9a0SAchim Leubner }
7374e1bc9a0SAchim Leubner
7384e1bc9a0SAchim Leubner /******************************************************************************
7394e1bc9a0SAchim Leubner agtiapi_ProbeCard()
7404e1bc9a0SAchim Leubner Purpose:
7414e1bc9a0SAchim Leubner sets thisCardInst->cardIdIndex to structure variant consistent with card.
7424e1bc9a0SAchim Leubner ag_card_type[idx].vendorId we already determined is PCI_VENDOR_ID_PMC_SIERRA.
7434e1bc9a0SAchim Leubner Parameters:
7444e1bc9a0SAchim Leubner device_t dev,
7454e1bc9a0SAchim Leubner ag_card_info_t *thisCardInst,
7464e1bc9a0SAchim Leubner int thisCard
7474e1bc9a0SAchim Leubner Return:
7484e1bc9a0SAchim Leubner 0 - success
7494e1bc9a0SAchim Leubner other values are not as good
7504e1bc9a0SAchim Leubner Note:
7514e1bc9a0SAchim Leubner This implementation is tailored to FreeBSD in alignment with the probe
7524e1bc9a0SAchim Leubner functionality of the FreeBSD environment.
7534e1bc9a0SAchim Leubner ******************************************************************************/
agtiapi_ProbeCard(device_t dev,ag_card_info_t * thisCardInst,int thisCard)7544e1bc9a0SAchim Leubner STATIC int agtiapi_ProbeCard( device_t dev,
7554e1bc9a0SAchim Leubner ag_card_info_t *thisCardInst,
7564e1bc9a0SAchim Leubner int thisCard )
7574e1bc9a0SAchim Leubner {
7584e1bc9a0SAchim Leubner int idx;
759123049cfSWarner Losh u_int16_t agtiapi_vendor; // PCI vendor ID
7604e1bc9a0SAchim Leubner u_int16_t agtiapi_dev; // PCI device ID
7614e1bc9a0SAchim Leubner AGTIAPI_PRINTK("agtiapi_ProbeCard: start\n");
7624e1bc9a0SAchim Leubner
763123049cfSWarner Losh agtiapi_vendor = pci_get_vendor( dev ); // get PCI vendor ID
7644e1bc9a0SAchim Leubner agtiapi_dev = pci_get_device( dev ); // get PCI device ID
7654e1bc9a0SAchim Leubner for( idx = 0; idx < COUNT(ag_card_type); idx++ )
7664e1bc9a0SAchim Leubner {
767123049cfSWarner Losh if ( ag_card_type[idx].deviceId == agtiapi_dev &&
768123049cfSWarner Losh ag_card_type[idx].vendorId == agtiapi_vendor)
7694e1bc9a0SAchim Leubner { // device ID match
7704e1bc9a0SAchim Leubner memset( (void *)&agCardInfoList[ thisCard ], 0,
7714e1bc9a0SAchim Leubner sizeof(ag_card_info_t) );
7724e1bc9a0SAchim Leubner thisCardInst->cardIdIndex = idx;
7734e1bc9a0SAchim Leubner thisCardInst->pPCIDev = dev;
7744e1bc9a0SAchim Leubner thisCardInst->cardNameIndex = ag_card_type[idx].cardNameIndex;
7754e1bc9a0SAchim Leubner thisCardInst->cardID =
7764e1bc9a0SAchim Leubner pci_read_config( dev, ag_card_type[idx].membar, 4 ); // memAddr
7774e1bc9a0SAchim Leubner AGTIAPI_PRINTK("agtiapi_ProbeCard: We've got PMC SAS, probe successful %p / %p\n",
7784e1bc9a0SAchim Leubner thisCardInst->pPCIDev, thisCardInst );
7794e1bc9a0SAchim Leubner device_set_desc( dev, ag_card_names[ag_card_type[idx].cardNameIndex] );
7804e1bc9a0SAchim Leubner return 0;
7814e1bc9a0SAchim Leubner }
7824e1bc9a0SAchim Leubner }
783123049cfSWarner Losh return 1;
7844e1bc9a0SAchim Leubner }
7854e1bc9a0SAchim Leubner
786