drm/tegra NVIDIA Tegra GPU and display driver¶
NVIDIA Tegra SoCs support a set of display, graphics and video functions viathe host1x controller. host1x supplies command streams, gathered from a pushbuffer provided directly by the CPU, to its clients via channels. Software,or blocks amongst themselves, can use syncpoints for synchronization.
Up until, but not including, Tegra124 (aka Tegra K1) the drm/tegra driversupports the built-in GPU, comprised of the gr2d and gr3d engines. Startingwith Tegra124 the GPU is based on the NVIDIA desktop GPU architecture andsupported by the drm/nouveau driver.
The drm/tegra driver supports NVIDIA Tegra SoC generations since Tegra20. Ithas three parts:
A host1x driver that provides infrastructure and access to the host1xservices.
A KMS driver that supports the display controllers as well as a number ofoutputs, such as RGB, HDMI, DSI, and DisplayPort.
A set of custom userspace IOCTLs that can be used to submit jobs to theGPU and video engines via host1x.
Driver Infrastructure¶
The various host1x clients need to be bound together into a logical device inorder to expose their functionality to users. The infrastructure that supportsthis is implemented in the host1x driver. When a driver is registered with theinfrastructure it provides a list of compatible strings specifying the devicesthat it needs. The infrastructure creates a logical device and scan the devicetree for matching device nodes, adding the required clients to a list. Driversfor individual clients register with the infrastructure as well and are addedto the logical host1x device.
Once all clients are available, the infrastructure will initialize the logicaldevice using a driver-provided function which will set up the bits specific tothe subsystem and in turn initialize each of its clients.
Similarly, when one of the clients is unregistered, the infrastructure willdestroy the logical device by calling back into the driver, which ensures thatthe subsystem specific bits are torn down and the clients destroyed in turn.
Host1x Infrastructure Reference¶
- structhost1x_bo_cache¶
host1x buffer object cache
Definition:
struct host1x_bo_cache { struct list_head mappings; struct mutex lock;};Members
mappingslist of mappings
locksynchronizes accesses to the list of mappings
Description
Note that entries are not periodically evicted from this cache and instead need to beexplicitly released. This is used primarily for DRM/KMS where the cache’s reference isreleased when the last reference to a buffer object represented by a mapping in thiscache is dropped.
- structhost1x_client_ops¶
host1x client operations
Definition:
struct host1x_client_ops { int (*early_init)(struct host1x_client *client); int (*init)(struct host1x_client *client); int (*exit)(struct host1x_client *client); int (*late_exit)(struct host1x_client *client); int (*suspend)(struct host1x_client *client); int (*resume)(struct host1x_client *client);};Members
early_inithost1x client early initialization code
inithost1x client initialization code
exithost1x client tear down code
late_exithost1x client late tear down code
suspendhost1x client suspend code
resumehost1x client resume code
- structhost1x_client¶
host1x client structure
Definition:
struct host1x_client { struct list_head list; struct device *host; struct device *dev; struct iommu_group *group; const struct host1x_client_ops *ops; enum host1x_class class; struct host1x_channel *channel; struct host1x_syncpt **syncpts; unsigned int num_syncpts; struct host1x_client *parent; unsigned int usecount; struct mutex lock; struct host1x_bo_cache cache;};Members
listlist node for the host1x client
hostpointer to
structdevicerepresenting the host1x controllerdevpointer to
structdevicebacking this host1x clientgroupIOMMU group that this client is a member of
opshost1x client operations
classhost1x class represented by this client
channelhost1x channel associated with this client
syncptsarray of syncpoints requested for this client
num_syncptsnumber of syncpoints requested for this client
parentpointer to parent structure
usecountreference count for this structure
lockmutex for mutually exclusive concurrency
cachehost1x buffer object cache
- structhost1x_driver¶
host1x logical device driver
Definition:
struct host1x_driver { struct device_driver driver; const struct of_device_id *subdevs; struct list_head list; int (*probe)(struct host1x_device *device); void (*remove)(struct host1x_device *device); void (*shutdown)(struct host1x_device *device);};Members
drivercore driver
subdevstable of OF device IDs matching subdevices for this driver
listlist node for the driver
probecalled when the host1x logical device is probed
removecalled when the host1x logical device is removed
shutdowncalled when the host1x logical device is shut down
- inthost1x_device_init(structhost1x_device*device)¶
initialize a host1x logical device
Parameters
structhost1x_device*devicehost1x logical device
Description
The driver for the host1x logical device can call this during execution ofitshost1x_driver.probe implementation to initialize each of its clients.The client drivers access the subsystem specific driver data using thehost1x_client.parent field and driver data associated with it (usually bycallingdev_get_drvdata()).
- inthost1x_device_exit(structhost1x_device*device)¶
uninitialize host1x logical device
Parameters
structhost1x_device*devicehost1x logical device
Description
When the driver for a host1x logical device is unloaded, it can call thisfunction to tear down each of its clients. Typically this is done after asubsystem-specific data structure is removed and the functionality can nolonger be used.
- inthost1x_driver_register_full(structhost1x_driver*driver,structmodule*owner)¶
register a host1x driver
Parameters
structhost1x_driver*driverhost1x driver
structmodule*ownerowner module
Description
Drivers for host1x logical devices call this function to register a driverwith the infrastructure. Note that since these drive logical devices, theregistration of the driver actually triggers tho logical device creation.A logical device will be created for each host1x instance.
- voidhost1x_driver_unregister(structhost1x_driver*driver)¶
unregister a host1x driver
Parameters
structhost1x_driver*driverhost1x driver
Description
Unbinds the driver from each of the host1x logical devices that it isbound to, effectively removing the subsystem devices that they represent.
- void__host1x_client_init(structhost1x_client*client,structlock_class_key*key)¶
initialize a host1x client
Parameters
structhost1x_client*clienthost1x client
structlock_class_key*keylock class key for the client-specific mutex
- voidhost1x_client_exit(structhost1x_client*client)¶
uninitialize a host1x client
Parameters
structhost1x_client*clienthost1x client
- int__host1x_client_register(structhost1x_client*client)¶
register a host1x client
Parameters
structhost1x_client*clienthost1x client
Description
Registers a host1x client with each host1x controller instance. Note thateach client will only match their parent host1x controller and will only beassociated with that instance. Once all clients have been registered withtheir parent host1x controller, the infrastructure will set up the logicaldevice and callhost1x_device_init(), which will in turn call each client’shost1x_client_ops.init implementation.
- voidhost1x_client_unregister(structhost1x_client*client)¶
unregister a host1x client
Parameters
structhost1x_client*clienthost1x client
Description
Removes a host1x client from its host1x controller instance. If a logicaldevice has already been initialized, it will be torn down.
Host1x Syncpoint Reference¶
- structhost1x_syncpt*host1x_syncpt_alloc(structhost1x*host,unsignedlongflags,constchar*name)¶
allocate a syncpoint
Parameters
structhost1x*hosthost1x device data
unsignedlongflagsbitfield of HOST1X_SYNCPT_* flags
constchar*namename for the syncpoint for use in debug prints
Description
Allocates a hardware syncpoint for the caller’s use. The caller then hasthe sole authority to mutate the syncpoint’s value until it is freed again.
If no free syncpoints are available, or a NULL name was specified, returnsNULL.
- u32host1x_syncpt_id(structhost1x_syncpt*sp)¶
retrieve syncpoint ID
Parameters
structhost1x_syncpt*sphost1x syncpoint
Description
Given a pointer to astructhost1x_syncpt, retrieves its ID. This ID isoften used as a value to program into registers that control how hardwareblocks interact with syncpoints.
- u32host1x_syncpt_incr_max(structhost1x_syncpt*sp,u32incrs)¶
update the value sent to hardware
Parameters
structhost1x_syncpt*sphost1x syncpoint
u32incrsnumber of increments
- inthost1x_syncpt_incr(structhost1x_syncpt*sp)¶
increment syncpoint value from CPU, updating cache
Parameters
structhost1x_syncpt*sphost1x syncpoint
- inthost1x_syncpt_wait(structhost1x_syncpt*sp,u32thresh,longtimeout,u32*value)¶
wait for a syncpoint to reach a given value
Parameters
structhost1x_syncpt*sphost1x syncpoint
u32threshthreshold
longtimeoutmaximum time to wait for the syncpoint to reach the given value
u32*valuereturn location for the syncpoint value
- structhost1x_syncpt*host1x_syncpt_request(structhost1x_client*client,unsignedlongflags)¶
request a syncpoint
Parameters
structhost1x_client*clientclient requesting the syncpoint
unsignedlongflagsflags
Description
host1x client drivers can use this function to allocate a syncpoint forsubsequent use. A syncpoint returned by this function will be reserved foruse by the client exclusively. When no longer using a syncpoint, a host1xclient driver needs to release it usinghost1x_syncpt_put().
- voidhost1x_syncpt_put(structhost1x_syncpt*sp)¶
free a requested syncpoint
Parameters
structhost1x_syncpt*sphost1x syncpoint
Description
Release a syncpoint previously allocated usinghost1x_syncpt_request(). Ahost1x client driver should call this when the syncpoint is no longer inuse.
- u32host1x_syncpt_read_max(structhost1x_syncpt*sp)¶
read maximum syncpoint value
Parameters
structhost1x_syncpt*sphost1x syncpoint
Description
The maximum syncpoint value indicates how many operations there are inqueue, either in channel or in a software thread.
- u32host1x_syncpt_read_min(structhost1x_syncpt*sp)¶
read minimum syncpoint value
Parameters
structhost1x_syncpt*sphost1x syncpoint
Description
The minimum syncpoint value is a shadow of the current sync point value inhardware.
- u32host1x_syncpt_read(structhost1x_syncpt*sp)¶
read the current syncpoint value
Parameters
structhost1x_syncpt*sphost1x syncpoint
- structhost1x_syncpt*host1x_syncpt_get_by_id(structhost1x*host,unsignedintid)¶
obtain a syncpoint by ID
Parameters
structhost1x*hosthost1x controller
unsignedintidsyncpoint ID
- structhost1x_syncpt*host1x_syncpt_get_by_id_noref(structhost1x*host,unsignedintid)¶
obtain a syncpoint by ID but don’t increase the refcount.
Parameters
structhost1x*hosthost1x controller
unsignedintidsyncpoint ID
- structhost1x_syncpt*host1x_syncpt_get(structhost1x_syncpt*sp)¶
increment syncpoint refcount
Parameters
structhost1x_syncpt*spsyncpoint
- structhost1x_syncpt_base*host1x_syncpt_get_base(structhost1x_syncpt*sp)¶
obtain the wait base associated with a syncpoint
Parameters
structhost1x_syncpt*sphost1x syncpoint
- u32host1x_syncpt_base_id(structhost1x_syncpt_base*base)¶
retrieve the ID of a syncpoint wait base
Parameters
structhost1x_syncpt_base*basehost1x syncpoint wait base
- voidhost1x_syncpt_release_vblank_reservation(structhost1x_client*client,u32syncpt_id)¶
Make VBLANK syncpoint available for allocation
Parameters
structhost1x_client*clienthost1x bus client
u32syncpt_idsyncpoint ID to make available
Description
Makes VBLANK<i> syncpoint available for allocatation if it wasreserved at initialization time. This should be called by the displaydriver after it has ensured that any VBLANK increment programming configuredby the boot chain has been disabled.
KMS driver¶
The display hardware has remained mostly backwards compatible over the variousTegra SoC generations, up until Tegra186 which introduces several changes thatmake it difficult to support with a parameterized driver.
Display Controllers¶
Tegra SoCs have two display controllers, each of which can be associated withzero or more outputs. Outputs can also share a single display controller, butonly if they run with compatible display timings. Two display controllers canalso share a single framebuffer, allowing cloned configurations even if modeson two outputs don’t match. A display controller is modelled as a CRTC in KMSterms.
On Tegra186, the number of display controllers has been increased to three. Adisplay controller can no longer drive all of the outputs. While two of thesecontrollers can drive both DSI outputs and both SOR outputs, the third cannotdrive any DSI.
Windows¶
A display controller controls a set of windows that can be used to compositemultiple buffers onto the screen. While it is possible to assign arbitrary Zordering to individual windows (by programming the corresponding blendingregisters), this is currently not supported by the driver. Instead, it willassume a fixed Z ordering of the windows (window A is the root window, thatis, the lowest, while windows B and C are overlaid on top of window A). Theoverlay windows support multiple pixel formats and can automatically convertfrom YUV to RGB at scanout time. This makes them useful for displaying videocontent. In KMS, each window is modelled as a plane. Each display controllerhas a hardware cursor that is exposed as a cursor plane.
Outputs¶
The type and number of supported outputs varies between Tegra SoC generations.All generations support at least HDMI. While earlier generations supported thevery simple RGB interfaces (one per display controller), recent generations nolonger do and instead provide standard interfaces such as DSI and eDP/DP.
Outputs are modelled as a composite encoder/connector pair.
RGB/LVDS¶
This interface is no longer available since Tegra124. It has been replaced bythe more standard DSI and eDP interfaces.
HDMI¶
HDMI is supported on all Tegra SoCs. Starting with Tegra210, HDMI is providedby the versatile SOR output, which supports eDP, DP and HDMI. The SOR is ableto support HDMI 2.0, though support for this is currently not merged.
DSI¶
Although Tegra has supported DSI since Tegra30, the controller has changed inseveral ways in Tegra114. Since none of the publicly available developmentboards prior to Dalmore (Tegra114) have made use of DSI, only Tegra114 andlater are supported by the drm/tegra driver.
eDP/DP¶
eDP was first introduced in Tegra124 where it was used to drive the displaypanel for notebook form factors. Tegra210 added support for full DisplayPortsupport, though this is currently not implemented in the drm/tegra driver.
Userspace Interface¶
The userspace interface provided by drm/tegra allows applications to createGEM buffers, access and control syncpoints as well as submit command streamsto host1x.
GEM Buffers¶
TheDRM_IOCTL_TEGRA_GEM_CREATE IOCTL is used to create a GEM buffer objectwith Tegra-specific flags. This is useful for buffers that should be tiled, orthat are to be scanned out upside down (useful for 3D content).
After a GEM buffer object has been created, its memory can be mapped by anapplication using the mmap offset returned by theDRM_IOCTL_TEGRA_GEM_MMAPIOCTL.
Syncpoints¶
The current value of a syncpoint can be obtained by executing theDRM_IOCTL_TEGRA_SYNCPT_READ IOCTL. Incrementing the syncpoint is achievedusing theDRM_IOCTL_TEGRA_SYNCPT_INCR IOCTL.
Userspace can also request blocking on a syncpoint. To do so, it needs toexecute theDRM_IOCTL_TEGRA_SYNCPT_WAIT IOCTL, specifying the value ofthe syncpoint to wait for. The kernel will release the application when thesyncpoint reaches that value or after a specified timeout.
Command Stream Submission¶
Before an application can submit command streams to host1x it needs to open achannel to an engine using theDRM_IOCTL_TEGRA_OPEN_CHANNEL IOCTL. ClientIDs are used to identify the target of the channel. When a channel is nolonger needed, it can be closed using theDRM_IOCTL_TEGRA_CLOSE_CHANNELIOCTL. To retrieve the syncpoint associated with a channel, an applicationcan use theDRM_IOCTL_TEGRA_GET_SYNCPT.
After opening a channel, submitting command streams is easy. The applicationwrites commands into the memory backing a GEM buffer object and passes theseto theDRM_IOCTL_TEGRA_SUBMIT IOCTL along with various other parameters,such as the syncpoints or relocations used in the job submission.