xref: /freebsd-src/sys/dev/pms/freebsd/driver/common/lxutil.c (revision 71625ec9ad2a9bc8c09784fbd23b759830e0ee5f)
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