Files
linux-nvgpu/drivers/gpu/nvgpu/include/nvgpu/device.h
Alex Waterman 2b48aa5b0c gpu: nvgpu: Add device for_each macro
Add a macro to iterate over a device list; it is just a wrapper to
the nvgpu_list_for_each() macro. It lets code iterate over the
list of detected devices without being aware of the underlying
instance IDs.

This also removes the need to do a separate nvgpu_device_get()
and subsequent NULL checking. This will reduce overhead for
unit testing!

Change-Id: If41dbee30a743d29ab62ce930a819160265b9351
Signed-off-by: Alex Waterman <alexw@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvgpu/+/2404914
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
2020-12-15 14:13:28 -06:00

321 lines
8.7 KiB
C

/*
* Copyright (c) 2018-2020, NVIDIA CORPORATION. All rights reserved.
*
* 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 NVGPU_DEVICE_H
#define NVGPU_DEVICE_H
/**
* @file
*
* Declare device info specific struct and defines.
*/
#include <nvgpu/types.h>
#include <nvgpu/list.h>
#if defined(CONFIG_NVGPU_NON_FUSA) && defined(CONFIG_NVGPU_NEXT)
#include "include/nvgpu/nvgpu_next_device.h"
#endif
struct gk20a;
/**
* @defgroup NVGPU_DEVTYPE_DEFINES
*
* List of engine enumeration values supported for device_info parsing.
*/
/**
* @ingroup NVGPU_TOP_DEVICE_INFO_DEFINES
*
* Device type for all graphics engine instances.
*/
#define NVGPU_DEVTYPE_GRAPHICS 0U
/**
* @ingroup NVGPU_TOP_DEVICE_INFO_DEFINES
*
* Copy Engine 0; obsolete on pascal+. For Pascal+ use the LCE type and relevant
* instance ID.
*
* This describes the 0th copy engine.
*/
#define NVGPU_DEVTYPE_COPY0 1U
/**
* @ingroup NVGPU_TOP_DEVICE_INFO_DEFINES
*
* See #NVGPU_DEVTYPE_COPY0.
*/
#define NVGPU_DEVTYPE_COPY1 2U
/**
* @ingroup NVGPU_TOP_DEVICE_INFO_DEFINES
*
* See #NVGPU_DEVTYPE_COPY0.
*/
#define NVGPU_DEVTYPE_COPY2 3U
/**
* @ingroup NVGPU_TOP_DEVICE_INFO_DEFINES
*
* NVLINK IOCTRL device - used by NVLINK on dGPUs.
*/
#define NVGPU_DEVTYPE_IOCTRL 18U
/**
* @ingroup NVGPU_TOP_DEVICE_INFO_DEFINES
*
* Logical Copy Engine devices.
*/
#define NVGPU_DEVTYPE_LCE 19U
#define NVGPU_MAX_DEVTYPE 24U
#define NVGPU_DEVICE_TOKEN_INIT 0U
/**
* Structure definition for storing information for the devices and the engines
* available on the chip.
*/
struct nvgpu_device {
struct nvgpu_list_node dev_list_node;
/**
* Engine type for this device.
*/
u32 type;
/**
* Specifies instance of a device, allowing SW to distinguish between
* multiple copies of a device present on the chip.
*/
u32 inst_id;
/**
* PRI base register offset for the 0th device instance of this type.
*/
u32 pri_base;
/**
* MMU fault ID for this device or the invalid fault ID: U32_MAX.
*/
u32 fault_id;
/**
* The unique per-device ID that host uses to identify any given engine.
*/
u32 engine_id;
/**
* The ID of the runlist that serves this engine.
*/
u32 runlist_id;
/**
* Interrupt ID for determining if this device has a pending interrupt.
*/
u32 intr_id;
/**
* Reset ID for resetting the device in MC.
*/
u32 reset_id;
/**
* PBDMA ID for this device. Technically not part of the dev_top array,
* but it's computable from various registers when the other device info
* is read.
*
* This also makes the vGPU support a little easier as this field gets
* passed to the vGPU client in the same data structure as the rest of the
* device info.
*/
u32 pbdma_id;
/** @cond DOXYGEN_SHOULD_SKIP_THIS */
#if defined(CONFIG_NVGPU_NON_FUSA) && defined(CONFIG_NVGPU_NEXT)
/* nvgpu next device info additions */
struct nvgpu_device_next next;
#endif
/** @endcond DOXYGEN_SHOULD_SKIP_THIS */
};
struct nvgpu_device_list {
/**
* Array of lists of devices; each list corresponds to one type of
* device. By having this as an array it's trivial to go from device
* enum type in the HW to the relevant devlist.
*/
struct nvgpu_list_node devlist_heads[NVGPU_MAX_DEVTYPE];
/**
* Keep track of how many devices of each type exist.
*/
u32 dev_counts[NVGPU_MAX_DEVTYPE];
};
/*
* Internal function: this shouldn't be necessary to directly call.
* But in any event it converts a list_node pointer to the parent
* nvgpu_device pointer.
*/
static inline struct nvgpu_device *
nvgpu_device_from_dev_list_node(struct nvgpu_list_node *node)
{
return (struct nvgpu_device *)
((uintptr_t)node - offsetof(struct nvgpu_device,
dev_list_node));
};
/**
* @brief Iterate over each device of the specified type.
*
* @param g [in] The GPU.
* @param dev [in] Device pointer to visit each device with.
* @param dev_type [in] Device type to iterate over.
*
* Visit each device of the specified type; _do_not_ modify this device
* list. It is immutable. Although it's' not type checked the dev pointer
* should be a const struct device *.
*/
#define nvgpu_device_for_each(g, dev, dev_type) \
nvgpu_list_for_each_entry(dev, \
&g->devs->devlist_heads[dev_type], \
nvgpu_device, \
dev_list_node)
/**
* @brief Initialize the SW device list from the HW device list.
*
* @param g [in] The GPU.
*
* @return 0 on success; a negative error code otherwise.
*/
int nvgpu_device_init(struct gk20a *g);
/**
* @brief Cleanup the device list on power down.
*
* @param g [in] The GPU.
*/
void nvgpu_device_cleanup(struct gk20a *g);
/**
* @brief Read device info from SW device table.
*
* @param g [in] GPU device struct pointer
* @param dev_info [out] Pointer to device information struct
* which gets populated with all the
* engine related information.
* @param engine_type [in] Engine enumeration value
* @param inst_id [in] Engine's instance identification number
*
* This will copy the contents of the requested device into the passed
* device pointer. The device copied is chosen based on the \a type and
* \a inst_id fields provided.
*/
const struct nvgpu_device *nvgpu_device_get(struct gk20a *g,
u32 type, u32 inst_id);
/**
* @brief Return number of devices of type \a type.
*
* @param g [in] The GPU.
* @param type [i] The type of device.
*/
u32 nvgpu_device_count(struct gk20a *g, u32 type);
/**
* @brief Return true if dev is a copy engine device.
*
* @param g [in] The GPU.
* @param dev [in] A device.
*
* @return true if \a dev matches a copy engine device type. For pre-Pascal
* chips this is COPY[0, 1, 2], for Pascal and onward this is LCE.
*/
bool nvgpu_device_is_ce(struct gk20a *g, const struct nvgpu_device *dev);
/**
* @brief Return true if dev is a graphics device.
*
* @param g [in] The GPU.
* @param dev [in] A device.
*
* @return true if \a dev matches the graphics device type.
*/
bool nvgpu_device_is_graphics(struct gk20a *g, const struct nvgpu_device *dev);
/**
* @brief Get all the copy engine pointers for this chip.
*
* @param g [in] The GPU.
* @param ces [out] List to store CE pointers.
* @param max [in] Length of the ces list.
*
* Due to the change from Maxwell to Pascal - the adddition of logical copy
* engines - the copy engine type changed from Maxwell to Pascal. For code that
* aims to be chip agnostic, often it's useful obtain the set of copy engines,
* regardless of type. This function does that by returning any COPY[0-2]
* egnines detected and then any LCEs detected. No chip has both LCEs and
* COPY[0-2], but by combining them, it's possible to avoid any chip specific
* checks.
*
* @return The number of copy engine pointers written to the \a ces array.
*/
u32 nvgpu_device_get_copies(struct gk20a *g,
const struct nvgpu_device **ces,
u32 max);
/**
* @brief Query list of async copy engines in the chip.
*
* @param g [in] The GPU.
* @param ces [out] List to store CE pointers.
* @param max [in] Length of the ces list.
*
* Like nvgpu_device_get_copies() only this returns only asynchronous copy
* engines. Async copy engines are engines that do not share a runlist with
* a GR engine.
*
* @return The number of copy engine pointers written to the \a ces array.
*/
u32 nvgpu_device_get_async_copies(struct gk20a *g,
const struct nvgpu_device **ces,
u32 max);
/**
* @brief Dubug dump for a device. Prints under the gpu_dbg_device log
* level.
*
* @param g [in] The GPU.
* @param dev [in] A device.
*
* Use the nvgpu_info() framework for printing a given given device's
* state information. This uses the gpu_dbg_device log level to condition
* the prints.
*/
void nvgpu_device_dump_dev(struct gk20a *g, const struct nvgpu_device *dev);
#endif /* NVGPU_DEVICE_H */