/*
 * SPDX-FileCopyrightText: Copyright (c) 2022-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
 * SPDX-License-Identifier: MIT
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 */

#ifndef NV_FIRMWARE_H
#define NV_FIRMWARE_H



#include <nvtypes.h>
#include <nvmisc.h>

typedef enum
{
    NV_FIRMWARE_TYPE_GSP,
    NV_FIRMWARE_TYPE_GSP_LOG,
#if defined(NV_VMWARE)
    // GR-3428: Merge _BINDATA and _UCODES
    NV_FIRMWARE_TYPE_BINDATA,
#endif
    NV_FIRMWARE_TYPE_UCODES
} nv_firmware_type_t;

typedef enum
{
    NV_FIRMWARE_CHIP_FAMILY_NULL = 0,
    NV_FIRMWARE_CHIP_FAMILY_TU10X = 1,
    NV_FIRMWARE_CHIP_FAMILY_TU11X = 2,
    NV_FIRMWARE_CHIP_FAMILY_GA100 = 3,
    NV_FIRMWARE_CHIP_FAMILY_GA10X = 4,
    NV_FIRMWARE_CHIP_FAMILY_AD10X = 5,
    NV_FIRMWARE_CHIP_FAMILY_GH100 = 6,
    NV_FIRMWARE_CHIP_FAMILY_GB10X = 8,
    NV_FIRMWARE_CHIP_FAMILY_GB20X = 9,
    NV_FIRMWARE_CHIP_FAMILY_GR10X = 10,
    NV_FIRMWARE_CHIP_FAMILY_GB10Y = 11,
    NV_FIRMWARE_CHIP_FAMILY_GB20Y = 12,
    NV_FIRMWARE_CHIP_FAMILY_END,
} nv_firmware_chip_family_t;

static inline const char *nv_firmware_chip_family_to_string(
    nv_firmware_chip_family_t fw_chip_family
)
{
    switch (fw_chip_family) {
        case NV_FIRMWARE_CHIP_FAMILY_GR10X: return "gr10x";
        case NV_FIRMWARE_CHIP_FAMILY_GB10X: return "gb10x";
        case NV_FIRMWARE_CHIP_FAMILY_GB10Y: return "gb10y";
        case NV_FIRMWARE_CHIP_FAMILY_GB20Y: return "gb20y";
        case NV_FIRMWARE_CHIP_FAMILY_GB20X: return "gb20x";
        case NV_FIRMWARE_CHIP_FAMILY_GH100: return "gh100";
        case NV_FIRMWARE_CHIP_FAMILY_AD10X: return "ad10x";
        case NV_FIRMWARE_CHIP_FAMILY_GA10X: return "ga10x";
        case NV_FIRMWARE_CHIP_FAMILY_GA100: return "ga100";
        case NV_FIRMWARE_CHIP_FAMILY_TU11X: return "tu11x";
        case NV_FIRMWARE_CHIP_FAMILY_TU10X: return "tu10x";

        case NV_FIRMWARE_CHIP_FAMILY_END:  // fall through
        case NV_FIRMWARE_CHIP_FAMILY_NULL:
            return "";
    }
    return "";
}

// The includer may optionally define
// NV_FIRMWARE_FOR_NAME(name)
// to return a platform-defined string for a given a firmware base name.
//
// The function nv_firmware_for_chip_family will then be available.
#if defined(NV_FIRMWARE_FOR_NAME)
static inline const char *nv_firmware_for_chip_family(
    nv_firmware_type_t fw_type,
    nv_firmware_chip_family_t fw_chip_family
)
{
    switch (fw_chip_family)
    {
        case NV_FIRMWARE_CHIP_FAMILY_GR10X:  // fall through
        case NV_FIRMWARE_CHIP_FAMILY_GB10X:  // fall through
        case NV_FIRMWARE_CHIP_FAMILY_GB10Y:  // fall through
        case NV_FIRMWARE_CHIP_FAMILY_GB20Y:  // fall through
        case NV_FIRMWARE_CHIP_FAMILY_GB20X:  // fall through
        case NV_FIRMWARE_CHIP_FAMILY_GH100:  // fall through
        case NV_FIRMWARE_CHIP_FAMILY_AD10X:  // fall through
        case NV_FIRMWARE_CHIP_FAMILY_GA10X:
        {
            switch (fw_type)
            {
                case NV_FIRMWARE_TYPE_GSP:     return NV_FIRMWARE_FOR_NAME("gsp_ga10x");
                case NV_FIRMWARE_TYPE_GSP_LOG: return NV_FIRMWARE_FOR_NAME("gsp_log_ga10x");
#if defined(NV_VMWARE)
                case NV_FIRMWARE_TYPE_BINDATA: return NV_FIRMWARE_FOR_NAME("bindata_image");
#endif
                case NV_FIRMWARE_TYPE_UCODES:  return NV_FIRMWARE_FOR_NAME("ucodes_ga10x");
            }
            return "";
        }

        case NV_FIRMWARE_CHIP_FAMILY_GA100:  // fall through
        case NV_FIRMWARE_CHIP_FAMILY_TU11X:  // fall through
        case NV_FIRMWARE_CHIP_FAMILY_TU10X:
        {
            switch (fw_type)
            {
                case NV_FIRMWARE_TYPE_GSP:     return NV_FIRMWARE_FOR_NAME("gsp_tu10x");
                case NV_FIRMWARE_TYPE_GSP_LOG: return NV_FIRMWARE_FOR_NAME("gsp_log_tu10x");
#if defined(NV_VMWARE)
                case NV_FIRMWARE_TYPE_BINDATA: return NV_FIRMWARE_FOR_NAME("bindata_image");
#endif
                case NV_FIRMWARE_TYPE_UCODES:  return NV_FIRMWARE_FOR_NAME("ucodes_tu10x");
            }
            return "";
        }

        case NV_FIRMWARE_CHIP_FAMILY_END:  // fall through
        case NV_FIRMWARE_CHIP_FAMILY_NULL:
            return "";
    }

    return "";
}
#endif  // defined(NV_FIRMWARE_FOR_NAME)

// The includer may optionally define
// NV_FIRMWARE_DECLARE_GSP(name)
// which will then be invoked (at the top-level) for each
// gsp_* and ucodes_* (but not gsp_log_*)
#if defined(NV_FIRMWARE_DECLARE_GSP)
NV_FIRMWARE_DECLARE_GSP("gsp_ga10x")
NV_FIRMWARE_DECLARE_GSP("gsp_tu10x")
NV_FIRMWARE_DECLARE_GSP("ucodes_ga10x")
NV_FIRMWARE_DECLARE_GSP("ucodes_tu10x")
#endif  // defined(NV_FIRMWARE_DECLARE_GSP)

#endif  // NV_FIRMWARE_DECLARE_GSP

