11739a20eSAndy Ritger /*
21739a20eSAndy Ritger * SPDX-FileCopyrightText: Copyright (c) 2018-2020 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
31739a20eSAndy Ritger * SPDX-License-Identifier: MIT
41739a20eSAndy Ritger *
51739a20eSAndy Ritger * Permission is hereby granted, free of charge, to any person obtaining a
61739a20eSAndy Ritger * copy of this software and associated documentation files (the "Software"),
71739a20eSAndy Ritger * to deal in the Software without restriction, including without limitation
81739a20eSAndy Ritger * the rights to use, copy, modify, merge, publish, distribute, sublicense,
91739a20eSAndy Ritger * and/or sell copies of the Software, and to permit persons to whom the
101739a20eSAndy Ritger * Software is furnished to do so, subject to the following conditions:
111739a20eSAndy Ritger *
121739a20eSAndy Ritger * The above copyright notice and this permission notice shall be included in
131739a20eSAndy Ritger * all copies or substantial portions of the Software.
141739a20eSAndy Ritger *
151739a20eSAndy Ritger * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
161739a20eSAndy Ritger * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
171739a20eSAndy Ritger * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
181739a20eSAndy Ritger * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
191739a20eSAndy Ritger * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
201739a20eSAndy Ritger * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
211739a20eSAndy Ritger * DEALINGS IN THE SOFTWARE.
221739a20eSAndy Ritger */
231739a20eSAndy Ritger
241739a20eSAndy Ritger #include "common_nvswitch.h"
251739a20eSAndy Ritger
261739a20eSAndy Ritger #include "flcn/flcn_nvswitch.h"
271739a20eSAndy Ritger #include "flcn/flcnable_nvswitch.h"
281739a20eSAndy Ritger
291739a20eSAndy Ritger static void flcnSetupIpHal(nvswitch_device *device, PFLCN pFlcn);
301739a20eSAndy Ritger
311739a20eSAndy Ritger /*!
321739a20eSAndy Ritger * @brief Get the falcon core revision and subversion.
331739a20eSAndy Ritger *
341739a20eSAndy Ritger * @param[in] device nvswitch device pointer
351739a20eSAndy Ritger * @param[in] pFlcn FLCN object pointer
361739a20eSAndy Ritger *
371739a20eSAndy Ritger * @return the falcon core revision in the format of NV_FLCN_CORE_REV_X_Y.
381739a20eSAndy Ritger */
391739a20eSAndy Ritger static NvU8
_flcnCoreRevisionGet_IMPL(nvswitch_device * device,PFLCN pFlcn)401739a20eSAndy Ritger _flcnCoreRevisionGet_IMPL
411739a20eSAndy Ritger (
421739a20eSAndy Ritger nvswitch_device *device,
431739a20eSAndy Ritger PFLCN pFlcn
441739a20eSAndy Ritger )
451739a20eSAndy Ritger {
461739a20eSAndy Ritger if (pFlcn->coreRev == 0x00)
471739a20eSAndy Ritger {
481739a20eSAndy Ritger // Falcon core revision has not yet been set. Set it now.
491739a20eSAndy Ritger flcnGetCoreInfo_HAL(device, pFlcn);
501739a20eSAndy Ritger }
511739a20eSAndy Ritger
521739a20eSAndy Ritger return pFlcn->coreRev;
531739a20eSAndy Ritger }
541739a20eSAndy Ritger
551739a20eSAndy Ritger /*!
561739a20eSAndy Ritger * @brief Mark the falcon as not ready and inaccessible from RM.
571739a20eSAndy Ritger * osHandleGpuSurpriseRemoval will use this routine to prevent access to the
581739a20eSAndy Ritger * Falcon, which could crash due to absense of GPU, during driver cleanup.
591739a20eSAndy Ritger *
601739a20eSAndy Ritger * @param[in] device nvswitch_device pointer
611739a20eSAndy Ritger * @param[in] pFlcn FLCN pointer
621739a20eSAndy Ritger *
631739a20eSAndy Ritger * @returns nothing
641739a20eSAndy Ritger */
651739a20eSAndy Ritger static void
_flcnMarkNotReady_IMPL(nvswitch_device * device,PFLCN pFlcn)661739a20eSAndy Ritger _flcnMarkNotReady_IMPL
671739a20eSAndy Ritger (
681739a20eSAndy Ritger nvswitch_device *device,
691739a20eSAndy Ritger PFLCN pFlcn
701739a20eSAndy Ritger )
711739a20eSAndy Ritger {
721739a20eSAndy Ritger pFlcn->bOSReady = NV_FALSE;
731739a20eSAndy Ritger }
741739a20eSAndy Ritger
751739a20eSAndy Ritger /*!
761739a20eSAndy Ritger * Retrieves the current head pointer for given physical command queue index.
771739a20eSAndy Ritger *
781739a20eSAndy Ritger * @param[in] device nvswitch device pointer
791739a20eSAndy Ritger * @param[in] pFlcn FLCN object pointer
801739a20eSAndy Ritger * @param[in] pQueue Pointer to the queue
811739a20eSAndy Ritger * @param[out] pHead Pointer to write with the queue's head pointer
821739a20eSAndy Ritger *
831739a20eSAndy Ritger * @return 'NV_OK' if head value was successfully retrieved.
841739a20eSAndy Ritger */
851739a20eSAndy Ritger static NV_STATUS
_flcnCmdQueueHeadGet_IMPL(nvswitch_device * device,PFLCN pFlcn,FLCNQUEUE * pQueue,NvU32 * pHead)861739a20eSAndy Ritger _flcnCmdQueueHeadGet_IMPL
871739a20eSAndy Ritger (
881739a20eSAndy Ritger nvswitch_device *device,
891739a20eSAndy Ritger PFLCN pFlcn,
901739a20eSAndy Ritger FLCNQUEUE *pQueue,
911739a20eSAndy Ritger NvU32 *pHead
921739a20eSAndy Ritger )
931739a20eSAndy Ritger {
941739a20eSAndy Ritger PFALCON_QUEUE_INFO pQueueInfo = pFlcn->pQueueInfo;
951739a20eSAndy Ritger
961739a20eSAndy Ritger NVSWITCH_ASSERT(pQueueInfo != NULL);
971739a20eSAndy Ritger NVSWITCH_ASSERT(pQueue->queuePhyId < pQueueInfo->cmdQHeadSize);
981739a20eSAndy Ritger NVSWITCH_ASSERT(pHead != NULL);
991739a20eSAndy Ritger
1001739a20eSAndy Ritger *pHead = flcnRegRead_HAL(device, pFlcn,
1011739a20eSAndy Ritger (pQueueInfo->cmdQHeadBaseAddress +
1021739a20eSAndy Ritger (pQueue->queuePhyId * pQueueInfo->cmdQHeadStride)));
1031739a20eSAndy Ritger return NV_OK;
1041739a20eSAndy Ritger }
1051739a20eSAndy Ritger
1061739a20eSAndy Ritger /*!
1071739a20eSAndy Ritger * Sets the head pointer for the given physical command queue index.
1081739a20eSAndy Ritger *
1091739a20eSAndy Ritger * @param[in] device nvswitch device pointer
1101739a20eSAndy Ritger * @param[in] pFlcn FLCN object pointer
1111739a20eSAndy Ritger * @param[in] pQueue Pointer to the queue
1121739a20eSAndy Ritger * @param[in] head The desired head value for the queue
1131739a20eSAndy Ritger *
1141739a20eSAndy Ritger * @return 'NV_OK' if the head value was successfully set.
1151739a20eSAndy Ritger */
1161739a20eSAndy Ritger static NV_STATUS
_flcnCmdQueueHeadSet_IMPL(nvswitch_device * device,PFLCN pFlcn,FLCNQUEUE * pQueue,NvU32 head)1171739a20eSAndy Ritger _flcnCmdQueueHeadSet_IMPL
1181739a20eSAndy Ritger (
1191739a20eSAndy Ritger nvswitch_device *device,
1201739a20eSAndy Ritger PFLCN pFlcn,
1211739a20eSAndy Ritger FLCNQUEUE *pQueue,
1221739a20eSAndy Ritger NvU32 head
1231739a20eSAndy Ritger )
1241739a20eSAndy Ritger {
1251739a20eSAndy Ritger PFALCON_QUEUE_INFO pQueueInfo = pFlcn->pQueueInfo;
1261739a20eSAndy Ritger
1271739a20eSAndy Ritger NVSWITCH_ASSERT(pQueueInfo != NULL);
1281739a20eSAndy Ritger NVSWITCH_ASSERT(pQueue->queuePhyId < pQueueInfo->cmdQHeadSize);
1291739a20eSAndy Ritger
1301739a20eSAndy Ritger flcnRegWrite_HAL(device, pFlcn,
1311739a20eSAndy Ritger (pQueueInfo->cmdQHeadBaseAddress +
1321739a20eSAndy Ritger (pQueue->queuePhyId * pQueueInfo->cmdQHeadStride)),
1331739a20eSAndy Ritger head);
1341739a20eSAndy Ritger return NV_OK;
1351739a20eSAndy Ritger }
1361739a20eSAndy Ritger
1371739a20eSAndy Ritger /*!
1381739a20eSAndy Ritger * Retrieves the current tail pointer for given physical command queue index.
1391739a20eSAndy Ritger *
1401739a20eSAndy Ritger * @param[in] device nvswitch device pointer
1411739a20eSAndy Ritger * @param[in] pFlcn FLCN object pointer
1421739a20eSAndy Ritger * @param[in] pQueue Pointer to the queue
1431739a20eSAndy Ritger * @param[out] pTail Pointer to write with the queue's tail value
1441739a20eSAndy Ritger *
1451739a20eSAndy Ritger * @return 'NV_OK' if the tail value was successfully retrieved.
1461739a20eSAndy Ritger */
1471739a20eSAndy Ritger static NV_STATUS
_flcnCmdQueueTailGet_IMPL(nvswitch_device * device,PFLCN pFlcn,FLCNQUEUE * pQueue,NvU32 * pTail)1481739a20eSAndy Ritger _flcnCmdQueueTailGet_IMPL
1491739a20eSAndy Ritger (
1501739a20eSAndy Ritger nvswitch_device *device,
1511739a20eSAndy Ritger PFLCN pFlcn,
1521739a20eSAndy Ritger FLCNQUEUE *pQueue,
1531739a20eSAndy Ritger NvU32 *pTail
1541739a20eSAndy Ritger )
1551739a20eSAndy Ritger {
1561739a20eSAndy Ritger PFALCON_QUEUE_INFO pQueueInfo = pFlcn->pQueueInfo;
1571739a20eSAndy Ritger
1581739a20eSAndy Ritger NVSWITCH_ASSERT(pQueueInfo != NULL);
1591739a20eSAndy Ritger NVSWITCH_ASSERT(pQueue->queuePhyId < pQueueInfo->cmdQTailSize);
1601739a20eSAndy Ritger NVSWITCH_ASSERT(pTail != NULL);
1611739a20eSAndy Ritger
1621739a20eSAndy Ritger *pTail = flcnRegRead_HAL(device, pFlcn,
1631739a20eSAndy Ritger (pQueueInfo->cmdQTailBaseAddress +
1641739a20eSAndy Ritger (pQueue->queuePhyId * pQueueInfo->cmdQTailStride)));
1651739a20eSAndy Ritger return NV_OK;
1661739a20eSAndy Ritger }
1671739a20eSAndy Ritger
1681739a20eSAndy Ritger /*!
1691739a20eSAndy Ritger * Set the Command Queue tail pointer.
1701739a20eSAndy Ritger *
1711739a20eSAndy Ritger * @param[in] device nvswitch device pointer
1721739a20eSAndy Ritger * @param[in] pFlcn FLCN object pointer
1731739a20eSAndy Ritger * @param[in] pQueue Pointer to the queue
1741739a20eSAndy Ritger * @param[in] tail The desired tail value
1751739a20eSAndy Ritger *
1761739a20eSAndy Ritger * @return 'NV_OK' if the tail value was successfully set.
1771739a20eSAndy Ritger */
1781739a20eSAndy Ritger static NV_STATUS
_flcnCmdQueueTailSet_IMPL(nvswitch_device * device,PFLCN pFlcn,FLCNQUEUE * pQueue,NvU32 tail)1791739a20eSAndy Ritger _flcnCmdQueueTailSet_IMPL
1801739a20eSAndy Ritger (
1811739a20eSAndy Ritger nvswitch_device *device,
1821739a20eSAndy Ritger PFLCN pFlcn,
1831739a20eSAndy Ritger FLCNQUEUE *pQueue,
1841739a20eSAndy Ritger NvU32 tail
1851739a20eSAndy Ritger )
1861739a20eSAndy Ritger {
1871739a20eSAndy Ritger PFALCON_QUEUE_INFO pQueueInfo = pFlcn->pQueueInfo;
1881739a20eSAndy Ritger
1891739a20eSAndy Ritger NVSWITCH_ASSERT(pQueueInfo != NULL);
1901739a20eSAndy Ritger NVSWITCH_ASSERT(pQueue->queuePhyId < pQueueInfo->cmdQTailSize);
1911739a20eSAndy Ritger
1921739a20eSAndy Ritger flcnRegWrite_HAL(device, pFlcn,
1931739a20eSAndy Ritger (pQueueInfo->cmdQTailBaseAddress +
1941739a20eSAndy Ritger (pQueue->queuePhyId * pQueueInfo->cmdQTailStride)),
1951739a20eSAndy Ritger tail);
1961739a20eSAndy Ritger return NV_OK;
1971739a20eSAndy Ritger }
1981739a20eSAndy Ritger
1991739a20eSAndy Ritger /*!
2001739a20eSAndy Ritger * Retrieve the current Message Queue Head pointer.
2011739a20eSAndy Ritger *
2021739a20eSAndy Ritger * @param[in] device nvswitch device pointer
2031739a20eSAndy Ritger * @param[in] pFlcn FLCN object pointer
2041739a20eSAndy Ritger * @param[in] pQueue Pointer to the queue
2051739a20eSAndy Ritger * @param[in] pHead Pointer to write with the queue's head value
2061739a20eSAndy Ritger *
2071739a20eSAndy Ritger * @return 'NV_OK' if the queue's head value was successfully retrieved.
2081739a20eSAndy Ritger */
2091739a20eSAndy Ritger static NV_STATUS
_flcnMsgQueueHeadGet_IMPL(nvswitch_device * device,PFLCN pFlcn,FLCNQUEUE * pQueue,NvU32 * pHead)2101739a20eSAndy Ritger _flcnMsgQueueHeadGet_IMPL
2111739a20eSAndy Ritger (
2121739a20eSAndy Ritger nvswitch_device *device,
2131739a20eSAndy Ritger PFLCN pFlcn,
2141739a20eSAndy Ritger FLCNQUEUE *pQueue,
2151739a20eSAndy Ritger NvU32 *pHead
2161739a20eSAndy Ritger )
2171739a20eSAndy Ritger {
2181739a20eSAndy Ritger PFALCON_QUEUE_INFO pQueueInfo = pFlcn->pQueueInfo;
2191739a20eSAndy Ritger
2201739a20eSAndy Ritger NVSWITCH_ASSERT(pQueueInfo != NULL);
2211739a20eSAndy Ritger NVSWITCH_ASSERT(pQueue->queuePhyId < pQueueInfo->msgQHeadSize);
2221739a20eSAndy Ritger NVSWITCH_ASSERT(pHead != NULL);
2231739a20eSAndy Ritger
2241739a20eSAndy Ritger *pHead = flcnRegRead_HAL(device, pFlcn,
2251739a20eSAndy Ritger (pQueueInfo->msgQHeadBaseAddress +
2261739a20eSAndy Ritger (pQueue->queuePhyId * pQueueInfo->msgQHeadStride)));
2271739a20eSAndy Ritger return NV_OK;
2281739a20eSAndy Ritger }
2291739a20eSAndy Ritger
2301739a20eSAndy Ritger /*!
2311739a20eSAndy Ritger * Set the Message Queue Head pointer.
2321739a20eSAndy Ritger *
2331739a20eSAndy Ritger * @param[in] device nvswitch device pointer
2341739a20eSAndy Ritger * @param[in] pFlcn FLCN object pointer
2351739a20eSAndy Ritger * @param[in] pQueue Pointer to the queue
2361739a20eSAndy Ritger * @param[in] head The desired head value
2371739a20eSAndy Ritger *
2381739a20eSAndy Ritger * @return 'NV_OK' if the head value was successfully set.
2391739a20eSAndy Ritger */
2401739a20eSAndy Ritger static NV_STATUS
_flcnMsgQueueHeadSet_IMPL(nvswitch_device * device,PFLCN pFlcn,FLCNQUEUE * pQueue,NvU32 head)2411739a20eSAndy Ritger _flcnMsgQueueHeadSet_IMPL
2421739a20eSAndy Ritger (
2431739a20eSAndy Ritger nvswitch_device *device,
2441739a20eSAndy Ritger PFLCN pFlcn,
2451739a20eSAndy Ritger FLCNQUEUE *pQueue,
2461739a20eSAndy Ritger NvU32 head
2471739a20eSAndy Ritger )
2481739a20eSAndy Ritger {
2491739a20eSAndy Ritger PFALCON_QUEUE_INFO pQueueInfo = pFlcn->pQueueInfo;
2501739a20eSAndy Ritger
2511739a20eSAndy Ritger NVSWITCH_ASSERT(pQueueInfo != NULL);
2521739a20eSAndy Ritger NVSWITCH_ASSERT(pQueue->queuePhyId < pQueueInfo->msgQHeadSize);
2531739a20eSAndy Ritger
2541739a20eSAndy Ritger flcnRegWrite_HAL(device, pFlcn,
2551739a20eSAndy Ritger (pQueueInfo->msgQHeadBaseAddress +
2561739a20eSAndy Ritger (pQueue->queuePhyId * pQueueInfo->msgQHeadStride)),
2571739a20eSAndy Ritger head);
2581739a20eSAndy Ritger return NV_OK;
2591739a20eSAndy Ritger }
2601739a20eSAndy Ritger
2611739a20eSAndy Ritger /*!
2621739a20eSAndy Ritger * Retrieve the current Message Queue Tail pointer.
2631739a20eSAndy Ritger *
2641739a20eSAndy Ritger * @param[in] device nvswitch device pointer
2651739a20eSAndy Ritger * @param[in] pFlcn FLCN object pointer
2661739a20eSAndy Ritger * @param[in] pQueue Pointer to the queue
2671739a20eSAndy Ritger * @param[out] pTail Pointer to write with the message queue's tail value
2681739a20eSAndy Ritger *
2691739a20eSAndy Ritger * @return 'NV_OK' if the tail value was successfully retrieved.
2701739a20eSAndy Ritger */
2711739a20eSAndy Ritger static NV_STATUS
_flcnMsgQueueTailGet_IMPL(nvswitch_device * device,PFLCN pFlcn,FLCNQUEUE * pQueue,NvU32 * pTail)2721739a20eSAndy Ritger _flcnMsgQueueTailGet_IMPL
2731739a20eSAndy Ritger (
2741739a20eSAndy Ritger nvswitch_device *device,
2751739a20eSAndy Ritger PFLCN pFlcn,
2761739a20eSAndy Ritger FLCNQUEUE *pQueue,
2771739a20eSAndy Ritger NvU32 *pTail
2781739a20eSAndy Ritger )
2791739a20eSAndy Ritger {
2801739a20eSAndy Ritger PFALCON_QUEUE_INFO pQueueInfo = pFlcn->pQueueInfo;
2811739a20eSAndy Ritger
2821739a20eSAndy Ritger NVSWITCH_ASSERT(pQueueInfo != NULL);
2831739a20eSAndy Ritger NVSWITCH_ASSERT(pQueue->queuePhyId < pQueueInfo->msgQTailSize);
2841739a20eSAndy Ritger NVSWITCH_ASSERT(pTail != NULL);
2851739a20eSAndy Ritger
2861739a20eSAndy Ritger *pTail = flcnRegRead_HAL(device, pFlcn,
2871739a20eSAndy Ritger (pQueueInfo->msgQTailBaseAddress +
2881739a20eSAndy Ritger (pQueue->queuePhyId * pQueueInfo->msgQTailStride)));
2891739a20eSAndy Ritger return NV_OK;
2901739a20eSAndy Ritger }
2911739a20eSAndy Ritger
2921739a20eSAndy Ritger /*!
2931739a20eSAndy Ritger * Set the Message Queue Tail pointer.
2941739a20eSAndy Ritger *
2951739a20eSAndy Ritger * @param[in] device nvswitch device pointer
2961739a20eSAndy Ritger * @param[in] pFlcn FLCN object pointer
2971739a20eSAndy Ritger * @param[in] pQueue Pointer to the queue
2981739a20eSAndy Ritger * @param[in] tail The desired tail value for the message queue
2991739a20eSAndy Ritger *
3001739a20eSAndy Ritger * @return 'NV_OK' if the tail value was successfully set.
3011739a20eSAndy Ritger */
3021739a20eSAndy Ritger static NV_STATUS
_flcnMsgQueueTailSet_IMPL(nvswitch_device * device,PFLCN pFlcn,FLCNQUEUE * pQueue,NvU32 tail)3031739a20eSAndy Ritger _flcnMsgQueueTailSet_IMPL
3041739a20eSAndy Ritger (
3051739a20eSAndy Ritger nvswitch_device *device,
3061739a20eSAndy Ritger PFLCN pFlcn,
3071739a20eSAndy Ritger FLCNQUEUE *pQueue,
3081739a20eSAndy Ritger NvU32 tail
3091739a20eSAndy Ritger )
3101739a20eSAndy Ritger {
3111739a20eSAndy Ritger PFALCON_QUEUE_INFO pQueueInfo = pFlcn->pQueueInfo;
3121739a20eSAndy Ritger
3131739a20eSAndy Ritger NVSWITCH_ASSERT(pQueueInfo != NULL);
3141739a20eSAndy Ritger NVSWITCH_ASSERT(pQueue->queuePhyId < pQueueInfo->msgQTailSize);
3151739a20eSAndy Ritger
3161739a20eSAndy Ritger flcnRegWrite_HAL(device, pFlcn,
3171739a20eSAndy Ritger (pQueueInfo->msgQTailBaseAddress +
3181739a20eSAndy Ritger (pQueue->queuePhyId * pQueueInfo->msgQTailStride)),
3191739a20eSAndy Ritger tail);
3201739a20eSAndy Ritger return NV_OK;
3211739a20eSAndy Ritger }
3221739a20eSAndy Ritger
3231739a20eSAndy Ritger /*!
3241739a20eSAndy Ritger * Copies 'sizeBytes' from DMEM offset 'src' to 'pDst' using DMEM access
3251739a20eSAndy Ritger * port 'port'.
3261739a20eSAndy Ritger *
3271739a20eSAndy Ritger * @param[in] device nvswitch device pointer
3281739a20eSAndy Ritger * @param[in] pFlcn FLCN pointer
3291739a20eSAndy Ritger * @param[in] src The DMEM offset for the source of the copy
3301739a20eSAndy Ritger * @param[out] pDst Pointer to write with copied data from DMEM
3311739a20eSAndy Ritger * @param[in] sizeBytes The number of bytes to copy from DMEM
3321739a20eSAndy Ritger * @param[in] port The DMEM port index to use when accessing the DMEM
3331739a20eSAndy Ritger */
3341739a20eSAndy Ritger static NV_STATUS
_flcnDmemCopyFrom_IMPL(nvswitch_device * device,PFLCN pFlcn,NvU32 src,NvU8 * pDst,NvU32 sizeBytes,NvU8 port)3351739a20eSAndy Ritger _flcnDmemCopyFrom_IMPL
3361739a20eSAndy Ritger (
3371739a20eSAndy Ritger nvswitch_device *device,
3381739a20eSAndy Ritger PFLCN pFlcn,
3391739a20eSAndy Ritger NvU32 src,
3401739a20eSAndy Ritger NvU8 *pDst,
3411739a20eSAndy Ritger NvU32 sizeBytes,
3421739a20eSAndy Ritger NvU8 port
3431739a20eSAndy Ritger )
3441739a20eSAndy Ritger {
3451739a20eSAndy Ritger return flcnDmemTransfer_HAL(device, pFlcn,
3461739a20eSAndy Ritger src, pDst, sizeBytes, port,
3471739a20eSAndy Ritger NV_TRUE); // bCopyFrom
3481739a20eSAndy Ritger }
3491739a20eSAndy Ritger
3501739a20eSAndy Ritger /*!
3511739a20eSAndy Ritger * Copies 'sizeBytes' from 'pDst' to DMEM offset 'dst' using DMEM access port
3521739a20eSAndy Ritger * 'port'.
3531739a20eSAndy Ritger *
3541739a20eSAndy Ritger * @param[in] device nvswitch device pointer
3551739a20eSAndy Ritger * @param[in] pFlcn FLCN pointer
3561739a20eSAndy Ritger * @param[in] dst The destination DMEM offset for the copy
3571739a20eSAndy Ritger * @param[in] pSrc The pointer to the buffer containing the data to copy
3581739a20eSAndy Ritger * @param[in] sizeBytes The number of bytes to copy into DMEM
3591739a20eSAndy Ritger * @param[in] port The DMEM port index to use when accessing the DMEM
3601739a20eSAndy Ritger */
3611739a20eSAndy Ritger static NV_STATUS
_flcnDmemCopyTo_IMPL(nvswitch_device * device,PFLCN pFlcn,NvU32 dst,NvU8 * pSrc,NvU32 sizeBytes,NvU8 port)3621739a20eSAndy Ritger _flcnDmemCopyTo_IMPL
3631739a20eSAndy Ritger (
3641739a20eSAndy Ritger nvswitch_device *device,
3651739a20eSAndy Ritger PFLCN pFlcn,
3661739a20eSAndy Ritger NvU32 dst,
3671739a20eSAndy Ritger NvU8 *pSrc,
3681739a20eSAndy Ritger NvU32 sizeBytes,
3691739a20eSAndy Ritger NvU8 port
3701739a20eSAndy Ritger )
3711739a20eSAndy Ritger {
3721739a20eSAndy Ritger return flcnDmemTransfer_HAL(device, pFlcn,
3731739a20eSAndy Ritger dst, pSrc, sizeBytes, port,
3741739a20eSAndy Ritger NV_FALSE); // bCopyFrom
3751739a20eSAndy Ritger }
3761739a20eSAndy Ritger
3771739a20eSAndy Ritger static void
_flcnPostDiscoveryInit_IMPL(nvswitch_device * device,FLCN * pFlcn)3781739a20eSAndy Ritger _flcnPostDiscoveryInit_IMPL
3791739a20eSAndy Ritger (
3801739a20eSAndy Ritger nvswitch_device *device,
3811739a20eSAndy Ritger FLCN *pFlcn
3821739a20eSAndy Ritger )
3831739a20eSAndy Ritger {
3841739a20eSAndy Ritger flcnableFetchEngines_HAL(device, pFlcn->pFlcnable, &pFlcn->engDescUc, &pFlcn->engDescBc);
3851739a20eSAndy Ritger
3861739a20eSAndy Ritger flcnSetupIpHal(device, pFlcn);
3871739a20eSAndy Ritger }
3881739a20eSAndy Ritger
3891739a20eSAndy Ritger /* -------------------- Object construction/initialization ------------------- */
3901739a20eSAndy Ritger
3911739a20eSAndy Ritger /**
3921739a20eSAndy Ritger * @brief set hal object-interface function pointers to flcn implementations
3931739a20eSAndy Ritger *
3941739a20eSAndy Ritger * this function has to be at the end of the file so that all the
3951739a20eSAndy Ritger * other functions are already defined.
3961739a20eSAndy Ritger *
3971739a20eSAndy Ritger * @param[in] pFlcn The flcn for which to set hals
3981739a20eSAndy Ritger */
3991739a20eSAndy Ritger static void
flcnSetupHal(PFLCN pFlcn,NvU32 pci_device_id)4001739a20eSAndy Ritger flcnSetupHal
4011739a20eSAndy Ritger (
4021739a20eSAndy Ritger PFLCN pFlcn,
4031739a20eSAndy Ritger NvU32 pci_device_id
4041739a20eSAndy Ritger )
4051739a20eSAndy Ritger {
4061739a20eSAndy Ritger flcn_hal *pHal = NULL;
4071739a20eSAndy Ritger if (nvswitch_is_lr10_device_id(pci_device_id))
4081739a20eSAndy Ritger {
4091739a20eSAndy Ritger flcnSetupHal_LR10(pFlcn);
4101739a20eSAndy Ritger goto _flcnSetupHal_success;
4111739a20eSAndy Ritger }
412*758b4ee8SAndy Ritger if (nvswitch_is_ls10_device_id(pci_device_id))
413*758b4ee8SAndy Ritger {
414*758b4ee8SAndy Ritger flcnSetupHal_LS10(pFlcn);
415*758b4ee8SAndy Ritger goto _flcnSetupHal_success;
416*758b4ee8SAndy Ritger }
4171739a20eSAndy Ritger
4181739a20eSAndy Ritger NVSWITCH_PRINT(NULL, ERROR,
4191739a20eSAndy Ritger "Flcn hal can't be setup due to unknown device id\n");
4201739a20eSAndy Ritger NVSWITCH_ASSERT(0);
4211739a20eSAndy Ritger
4221739a20eSAndy Ritger _flcnSetupHal_success:
4231739a20eSAndy Ritger //init hal OBJ Interfaces
4241739a20eSAndy Ritger pHal = pFlcn->pHal;
4251739a20eSAndy Ritger
4261739a20eSAndy Ritger pHal->coreRevisionGet = _flcnCoreRevisionGet_IMPL;
4271739a20eSAndy Ritger pHal->markNotReady = _flcnMarkNotReady_IMPL;
4281739a20eSAndy Ritger pHal->cmdQueueHeadGet = _flcnCmdQueueHeadGet_IMPL;
4291739a20eSAndy Ritger pHal->msgQueueHeadGet = _flcnMsgQueueHeadGet_IMPL;
4301739a20eSAndy Ritger pHal->cmdQueueTailGet = _flcnCmdQueueTailGet_IMPL;
4311739a20eSAndy Ritger pHal->msgQueueTailGet = _flcnMsgQueueTailGet_IMPL;
4321739a20eSAndy Ritger pHal->cmdQueueHeadSet = _flcnCmdQueueHeadSet_IMPL;
4331739a20eSAndy Ritger pHal->msgQueueHeadSet = _flcnMsgQueueHeadSet_IMPL;
4341739a20eSAndy Ritger pHal->cmdQueueTailSet = _flcnCmdQueueTailSet_IMPL;
4351739a20eSAndy Ritger pHal->msgQueueTailSet = _flcnMsgQueueTailSet_IMPL;
4361739a20eSAndy Ritger
4371739a20eSAndy Ritger pHal->dmemCopyFrom = _flcnDmemCopyFrom_IMPL;
4381739a20eSAndy Ritger pHal->dmemCopyTo = _flcnDmemCopyTo_IMPL;
4391739a20eSAndy Ritger pHal->postDiscoveryInit = _flcnPostDiscoveryInit_IMPL;
4401739a20eSAndy Ritger
4411739a20eSAndy Ritger flcnQueueSetupHal(pFlcn);
4421739a20eSAndy Ritger flcnRtosSetupHal(pFlcn);
4431739a20eSAndy Ritger flcnQueueRdSetupHal(pFlcn);
4441739a20eSAndy Ritger }
4451739a20eSAndy Ritger
4461739a20eSAndy Ritger static void
flcnSetupIpHal(nvswitch_device * device,PFLCN pFlcn)4471739a20eSAndy Ritger flcnSetupIpHal
4481739a20eSAndy Ritger (
4491739a20eSAndy Ritger nvswitch_device *device,
4501739a20eSAndy Ritger PFLCN pFlcn
4511739a20eSAndy Ritger )
4521739a20eSAndy Ritger {
4531739a20eSAndy Ritger NvU8 coreRev = flcnableReadCoreRev(device, pFlcn->pFlcnable);
4541739a20eSAndy Ritger
4551739a20eSAndy Ritger switch (coreRev) {
4561739a20eSAndy Ritger case NV_FLCN_CORE_REV_3_0:
4571739a20eSAndy Ritger {
4581739a20eSAndy Ritger flcnSetupHal_v03_00(pFlcn);
4591739a20eSAndy Ritger break;
4601739a20eSAndy Ritger }
4611739a20eSAndy Ritger case NV_FLCN_CORE_REV_4_0:
4621739a20eSAndy Ritger case NV_FLCN_CORE_REV_4_1:
4631739a20eSAndy Ritger {
4641739a20eSAndy Ritger flcnSetupHal_v04_00(pFlcn);
4651739a20eSAndy Ritger break;
4661739a20eSAndy Ritger }
4671739a20eSAndy Ritger case NV_FLCN_CORE_REV_5_0:
4681739a20eSAndy Ritger case NV_FLCN_CORE_REV_5_1:
4691739a20eSAndy Ritger {
4701739a20eSAndy Ritger flcnSetupHal_v05_01(pFlcn);
4711739a20eSAndy Ritger break;
4721739a20eSAndy Ritger }
4731739a20eSAndy Ritger case NV_FLCN_CORE_REV_6_0:
4741739a20eSAndy Ritger {
4751739a20eSAndy Ritger flcnSetupHal_v06_00(pFlcn);
4761739a20eSAndy Ritger break;
4771739a20eSAndy Ritger }
4781739a20eSAndy Ritger default:
4791739a20eSAndy Ritger {
4801739a20eSAndy Ritger NVSWITCH_PRINT(device, ERROR,
4811739a20eSAndy Ritger "%s: Unsupported falcon core revision: %hhu!\n",
4821739a20eSAndy Ritger __FUNCTION__, coreRev);
4831739a20eSAndy Ritger NVSWITCH_ASSERT(0);
4841739a20eSAndy Ritger break;
4851739a20eSAndy Ritger }
4861739a20eSAndy Ritger }
4871739a20eSAndy Ritger }
4881739a20eSAndy Ritger
4891739a20eSAndy Ritger FLCN *
flcnAllocNew(void)4901739a20eSAndy Ritger flcnAllocNew(void)
4911739a20eSAndy Ritger {
4921739a20eSAndy Ritger FLCN *pFlcn = nvswitch_os_malloc(sizeof(*pFlcn));
4931739a20eSAndy Ritger if (pFlcn != NULL)
4941739a20eSAndy Ritger {
4951739a20eSAndy Ritger nvswitch_os_memset(pFlcn, 0, sizeof(*pFlcn));
4961739a20eSAndy Ritger }
4971739a20eSAndy Ritger
4981739a20eSAndy Ritger return pFlcn;
4991739a20eSAndy Ritger }
5001739a20eSAndy Ritger
5011739a20eSAndy Ritger NvlStatus
flcnInit(nvswitch_device * device,FLCN * pFlcn,NvU32 pci_device_id)5021739a20eSAndy Ritger flcnInit
5031739a20eSAndy Ritger (
5041739a20eSAndy Ritger nvswitch_device *device,
5051739a20eSAndy Ritger FLCN *pFlcn,
5061739a20eSAndy Ritger NvU32 pci_device_id
5071739a20eSAndy Ritger )
5081739a20eSAndy Ritger {
5091739a20eSAndy Ritger NvlStatus retval = NVL_SUCCESS;
5101739a20eSAndy Ritger
5111739a20eSAndy Ritger // allocate hal if a child class hasn't already
5121739a20eSAndy Ritger if (pFlcn->pHal == NULL)
5131739a20eSAndy Ritger {
5141739a20eSAndy Ritger flcn_hal *pHal = pFlcn->pHal = nvswitch_os_malloc(sizeof(*pHal));
5151739a20eSAndy Ritger if (pHal == NULL)
5161739a20eSAndy Ritger {
5171739a20eSAndy Ritger NVSWITCH_PRINT(device, ERROR, "Flcn allocation failed!\n");
5181739a20eSAndy Ritger retval = -NVL_NO_MEM;
5191739a20eSAndy Ritger goto flcn_init_fail;
5201739a20eSAndy Ritger }
5211739a20eSAndy Ritger nvswitch_os_memset(pHal, 0, sizeof(*pHal));
5221739a20eSAndy Ritger }
5231739a20eSAndy Ritger
5241739a20eSAndy Ritger //don't have a parent class to init, go straight to setupHal
5251739a20eSAndy Ritger flcnSetupHal(pFlcn, pci_device_id);
5261739a20eSAndy Ritger
5271739a20eSAndy Ritger return retval;
5281739a20eSAndy Ritger
5291739a20eSAndy Ritger flcn_init_fail:
5301739a20eSAndy Ritger flcnDestroy(device, pFlcn);
5311739a20eSAndy Ritger return retval;
5321739a20eSAndy Ritger }
5331739a20eSAndy Ritger
5341739a20eSAndy Ritger // reverse of flcnInit()
5351739a20eSAndy Ritger void
flcnDestroy(nvswitch_device * device,FLCN * pFlcn)5361739a20eSAndy Ritger flcnDestroy
5371739a20eSAndy Ritger (
5381739a20eSAndy Ritger nvswitch_device *device,
5391739a20eSAndy Ritger FLCN *pFlcn
5401739a20eSAndy Ritger )
5411739a20eSAndy Ritger {
5421739a20eSAndy Ritger if (pFlcn->pHal != NULL)
5431739a20eSAndy Ritger {
5441739a20eSAndy Ritger nvswitch_os_free(pFlcn->pHal);
5451739a20eSAndy Ritger pFlcn->pHal = NULL;
5461739a20eSAndy Ritger }
5471739a20eSAndy Ritger }
548