// SPDX-License-Identifier: GPL-2.0-only /* * Tegra host1x Command DMA * * Copyright (c) 2010-2013, NVIDIA Corporation. */ #include <asm/cacheflush.h> #include <linux/device.h> #include <linux/dma-mapping.h> #include <linux/host1x.h> #include <linux/interrupt.h> #include <linux/kernel.h> #include <linux/kfifo.h> #include <linux/slab.h> #include <trace/events/host1x.h> #include "cdma.h" #include "channel.h" #include "dev.h" #include "debug.h" #include "job.h" /* * push_buffer * * The push buffer is a circular array of words to be fetched by command DMA. * Note that it works slightly differently to the sync queue; fence == pos * means that the push buffer is full, not empty. */ /* * Typically the commands written into the push buffer are a pair of words. We * use slots to represent each of these pairs and to simplify things. Note the * strange number of slots allocated here. 512 slots will fit exactly within a * single memory page. We also need one additional word at the end of the push * buffer for the RESTART opcode that will instruct the CDMA to jump back to * the beginning of the push buffer. With 512 slots, this means that we'll use * 2 memory pages and waste 4092 bytes of the second page that will never be * used. */ #define HOST1X_PUSHBUFFER_SLOTS … /* * Clean up push buffer resources */ static void host1x_pushbuffer_destroy(struct push_buffer *pb) { … } /* * Init push buffer resources */ static int host1x_pushbuffer_init(struct push_buffer *pb) { … } /* * Push two words to the push buffer * Caller must ensure push buffer is not full */ static void host1x_pushbuffer_push(struct push_buffer *pb, u32 op1, u32 op2) { … } /* * Pop a number of two word slots from the push buffer * Caller must ensure push buffer is not empty */ static void host1x_pushbuffer_pop(struct push_buffer *pb, unsigned int slots) { … } /* * Return the number of two word slots free in the push buffer */ static u32 host1x_pushbuffer_space(struct push_buffer *pb) { … } /* * Sleep (if necessary) until the requested event happens * - CDMA_EVENT_SYNC_QUEUE_EMPTY : sync queue is completely empty. * - Returns 1 * - CDMA_EVENT_PUSH_BUFFER_SPACE : there is space in the push buffer * - Return the amount of space (> 0) * Must be called with the cdma lock held. */ unsigned int host1x_cdma_wait_locked(struct host1x_cdma *cdma, enum cdma_event event) { … } /* * Sleep (if necessary) until the push buffer has enough free space. * * Must be called with the cdma lock held. */ static int host1x_cdma_wait_pushbuffer_space(struct host1x *host1x, struct host1x_cdma *cdma, unsigned int needed) { … } /* * Start timer that tracks the time spent by the job. * Must be called with the cdma lock held. */ static void cdma_start_timer_locked(struct host1x_cdma *cdma, struct host1x_job *job) { … } /* * Stop timer when a buffer submission completes. * Must be called with the cdma lock held. */ static void stop_cdma_timer_locked(struct host1x_cdma *cdma) { … } /* * For all sync queue entries that have already finished according to the * current sync point registers: * - unpin & unref their mems * - pop their push buffer slots * - remove them from the sync queue * This is normally called from the host code's worker thread, but can be * called manually if necessary. * Must be called with the cdma lock held. */ static void update_cdma_locked(struct host1x_cdma *cdma) { … } void host1x_cdma_update_sync_queue(struct host1x_cdma *cdma, struct device *dev) { … } static void cdma_update_work(struct work_struct *work) { … } /* * Create a cdma */ int host1x_cdma_init(struct host1x_cdma *cdma) { … } /* * Destroy a cdma */ int host1x_cdma_deinit(struct host1x_cdma *cdma) { … } /* * Begin a cdma submit */ int host1x_cdma_begin(struct host1x_cdma *cdma, struct host1x_job *job) { … } /* * Push two words into a push buffer slot * Blocks as necessary if the push buffer is full. */ void host1x_cdma_push(struct host1x_cdma *cdma, u32 op1, u32 op2) { … } /* * Push four words into two consecutive push buffer slots. Note that extra * care needs to be taken not to split the two slots across the end of the * push buffer. Otherwise the RESTART opcode at the end of the push buffer * that ensures processing will restart at the beginning will break up the * four words. * * Blocks as necessary if the push buffer is full. */ void host1x_cdma_push_wide(struct host1x_cdma *cdma, u32 op1, u32 op2, u32 op3, u32 op4) { … } /* * End a cdma submit * Kick off DMA, add job to the sync queue, and a number of slots to be freed * from the pushbuffer. The handles for a submit must all be pinned at the same * time, but they can be unpinned in smaller chunks. */ void host1x_cdma_end(struct host1x_cdma *cdma, struct host1x_job *job) { … } /* * Update cdma state according to current sync point values */ void host1x_cdma_update(struct host1x_cdma *cdma) { … }