2018-04-30 18:10:58 +00:00
|
|
|
// SPDX-License-Identifier: GPL-2.0+
|
|
|
|
/* Copyright (C) 2014-2018 Broadcom */
|
|
|
|
|
|
|
|
#include <drm/drmP.h>
|
|
|
|
#include <drm/drm_syncobj.h>
|
|
|
|
#include <linux/module.h>
|
|
|
|
#include <linux/platform_device.h>
|
|
|
|
#include <linux/pm_runtime.h>
|
|
|
|
#include <linux/device.h>
|
|
|
|
#include <linux/io.h>
|
|
|
|
#include <linux/sched/signal.h>
|
|
|
|
|
|
|
|
#include "uapi/drm/v3d_drm.h"
|
|
|
|
#include "v3d_drv.h"
|
|
|
|
#include "v3d_regs.h"
|
|
|
|
#include "v3d_trace.h"
|
|
|
|
|
|
|
|
static void
|
|
|
|
v3d_init_core(struct v3d_dev *v3d, int core)
|
|
|
|
{
|
|
|
|
/* Set OVRTMUOUT, which means that the texture sampler uniform
|
|
|
|
* configuration's tmu output type field is used, instead of
|
|
|
|
* using the hardware default behavior based on the texture
|
|
|
|
* type. If you want the default behavior, you can still put
|
|
|
|
* "2" in the indirect texture state's output_type field.
|
|
|
|
*/
|
|
|
|
V3D_CORE_WRITE(core, V3D_CTL_MISCCFG, V3D_MISCCFG_OVRTMUOUT);
|
|
|
|
|
|
|
|
/* Whenever we flush the L2T cache, we always want to flush
|
|
|
|
* the whole thing.
|
|
|
|
*/
|
|
|
|
V3D_CORE_WRITE(core, V3D_CTL_L2TFLSTA, 0);
|
|
|
|
V3D_CORE_WRITE(core, V3D_CTL_L2TFLEND, ~0);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Sets invariant state for the HW. */
|
|
|
|
static void
|
|
|
|
v3d_init_hw_state(struct v3d_dev *v3d)
|
|
|
|
{
|
|
|
|
v3d_init_core(v3d, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
v3d_idle_axi(struct v3d_dev *v3d, int core)
|
|
|
|
{
|
|
|
|
V3D_CORE_WRITE(core, V3D_GMP_CFG, V3D_GMP_CFG_STOP_REQ);
|
|
|
|
|
|
|
|
if (wait_for((V3D_CORE_READ(core, V3D_GMP_STATUS) &
|
|
|
|
(V3D_GMP_STATUS_RD_COUNT_MASK |
|
|
|
|
V3D_GMP_STATUS_WR_COUNT_MASK |
|
|
|
|
V3D_GMP_STATUS_CFG_BUSY)) == 0, 100)) {
|
|
|
|
DRM_ERROR("Failed to wait for safe GMP shutdown\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
v3d_idle_gca(struct v3d_dev *v3d)
|
|
|
|
{
|
|
|
|
if (v3d->ver >= 41)
|
|
|
|
return;
|
|
|
|
|
|
|
|
V3D_GCA_WRITE(V3D_GCA_SAFE_SHUTDOWN, V3D_GCA_SAFE_SHUTDOWN_EN);
|
|
|
|
|
|
|
|
if (wait_for((V3D_GCA_READ(V3D_GCA_SAFE_SHUTDOWN_ACK) &
|
|
|
|
V3D_GCA_SAFE_SHUTDOWN_ACK_ACKED) ==
|
|
|
|
V3D_GCA_SAFE_SHUTDOWN_ACK_ACKED, 100)) {
|
|
|
|
DRM_ERROR("Failed to wait for safe GCA shutdown\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
v3d_reset_v3d(struct v3d_dev *v3d)
|
|
|
|
{
|
|
|
|
int version = V3D_BRIDGE_READ(V3D_TOP_GR_BRIDGE_REVISION);
|
|
|
|
|
|
|
|
if (V3D_GET_FIELD(version, V3D_TOP_GR_BRIDGE_MAJOR) == 2) {
|
|
|
|
V3D_BRIDGE_WRITE(V3D_TOP_GR_BRIDGE_SW_INIT_0,
|
|
|
|
V3D_TOP_GR_BRIDGE_SW_INIT_0_V3D_CLK_108_SW_INIT);
|
|
|
|
V3D_BRIDGE_WRITE(V3D_TOP_GR_BRIDGE_SW_INIT_0, 0);
|
|
|
|
|
|
|
|
/* GFXH-1383: The SW_INIT may cause a stray write to address 0
|
|
|
|
* of the unit, so reset it to its power-on value here.
|
|
|
|
*/
|
|
|
|
V3D_WRITE(V3D_HUB_AXICFG, V3D_HUB_AXICFG_MAX_LEN_MASK);
|
|
|
|
} else {
|
|
|
|
WARN_ON_ONCE(V3D_GET_FIELD(version,
|
|
|
|
V3D_TOP_GR_BRIDGE_MAJOR) != 7);
|
|
|
|
V3D_BRIDGE_WRITE(V3D_TOP_GR_BRIDGE_SW_INIT_1,
|
|
|
|
V3D_TOP_GR_BRIDGE_SW_INIT_1_V3D_CLK_108_SW_INIT);
|
|
|
|
V3D_BRIDGE_WRITE(V3D_TOP_GR_BRIDGE_SW_INIT_1, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
v3d_init_hw_state(v3d);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
v3d_reset(struct v3d_dev *v3d)
|
|
|
|
{
|
|
|
|
struct drm_device *dev = &v3d->drm;
|
|
|
|
|
|
|
|
DRM_ERROR("Resetting GPU.\n");
|
|
|
|
trace_v3d_reset_begin(dev);
|
|
|
|
|
|
|
|
/* XXX: only needed for safe powerdown, not reset. */
|
|
|
|
if (false)
|
|
|
|
v3d_idle_axi(v3d, 0);
|
|
|
|
|
|
|
|
v3d_idle_gca(v3d);
|
|
|
|
v3d_reset_v3d(v3d);
|
|
|
|
|
|
|
|
v3d_mmu_set_page_table(v3d);
|
|
|
|
v3d_irq_reset(v3d);
|
|
|
|
|
|
|
|
trace_v3d_reset_end(dev);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
v3d_flush_l3(struct v3d_dev *v3d)
|
|
|
|
{
|
|
|
|
if (v3d->ver < 41) {
|
|
|
|
u32 gca_ctrl = V3D_GCA_READ(V3D_GCA_CACHE_CTRL);
|
|
|
|
|
|
|
|
V3D_GCA_WRITE(V3D_GCA_CACHE_CTRL,
|
|
|
|
gca_ctrl | V3D_GCA_CACHE_CTRL_FLUSH);
|
|
|
|
|
|
|
|
if (v3d->ver < 33) {
|
|
|
|
V3D_GCA_WRITE(V3D_GCA_CACHE_CTRL,
|
|
|
|
gca_ctrl & ~V3D_GCA_CACHE_CTRL_FLUSH);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Invalidates the (read-only) L2 cache. */
|
|
|
|
static void
|
|
|
|
v3d_invalidate_l2(struct v3d_dev *v3d, int core)
|
|
|
|
{
|
|
|
|
V3D_CORE_WRITE(core, V3D_CTL_L2CACTL,
|
|
|
|
V3D_L2CACTL_L2CCLR |
|
|
|
|
V3D_L2CACTL_L2CENA);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
v3d_invalidate_l1td(struct v3d_dev *v3d, int core)
|
|
|
|
{
|
|
|
|
V3D_CORE_WRITE(core, V3D_CTL_L2TCACTL, V3D_L2TCACTL_TMUWCF);
|
|
|
|
if (wait_for(!(V3D_CORE_READ(core, V3D_CTL_L2TCACTL) &
|
|
|
|
V3D_L2TCACTL_L2TFLS), 100)) {
|
|
|
|
DRM_ERROR("Timeout waiting for L1T write combiner flush\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Invalidates texture L2 cachelines */
|
|
|
|
static void
|
|
|
|
v3d_flush_l2t(struct v3d_dev *v3d, int core)
|
|
|
|
{
|
|
|
|
v3d_invalidate_l1td(v3d, core);
|
|
|
|
|
|
|
|
V3D_CORE_WRITE(core, V3D_CTL_L2TCACTL,
|
|
|
|
V3D_L2TCACTL_L2TFLS |
|
|
|
|
V3D_SET_FIELD(V3D_L2TCACTL_FLM_FLUSH, V3D_L2TCACTL_FLM));
|
|
|
|
if (wait_for(!(V3D_CORE_READ(core, V3D_CTL_L2TCACTL) &
|
|
|
|
V3D_L2TCACTL_L2TFLS), 100)) {
|
|
|
|
DRM_ERROR("Timeout waiting for L2T flush\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Invalidates the slice caches. These are read-only caches. */
|
|
|
|
static void
|
|
|
|
v3d_invalidate_slices(struct v3d_dev *v3d, int core)
|
|
|
|
{
|
|
|
|
V3D_CORE_WRITE(core, V3D_CTL_SLCACTL,
|
|
|
|
V3D_SET_FIELD(0xf, V3D_SLCACTL_TVCCS) |
|
|
|
|
V3D_SET_FIELD(0xf, V3D_SLCACTL_TDCCS) |
|
|
|
|
V3D_SET_FIELD(0xf, V3D_SLCACTL_UCC) |
|
|
|
|
V3D_SET_FIELD(0xf, V3D_SLCACTL_ICC));
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Invalidates texture L2 cachelines */
|
|
|
|
static void
|
|
|
|
v3d_invalidate_l2t(struct v3d_dev *v3d, int core)
|
|
|
|
{
|
|
|
|
V3D_CORE_WRITE(core,
|
|
|
|
V3D_CTL_L2TCACTL,
|
|
|
|
V3D_L2TCACTL_L2TFLS |
|
|
|
|
V3D_SET_FIELD(V3D_L2TCACTL_FLM_CLEAR, V3D_L2TCACTL_FLM));
|
|
|
|
if (wait_for(!(V3D_CORE_READ(core, V3D_CTL_L2TCACTL) &
|
|
|
|
V3D_L2TCACTL_L2TFLS), 100)) {
|
|
|
|
DRM_ERROR("Timeout waiting for L2T invalidate\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
v3d_invalidate_caches(struct v3d_dev *v3d)
|
|
|
|
{
|
|
|
|
v3d_flush_l3(v3d);
|
|
|
|
|
|
|
|
v3d_invalidate_l2(v3d, 0);
|
|
|
|
v3d_invalidate_slices(v3d, 0);
|
|
|
|
v3d_flush_l2t(v3d, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
v3d_flush_caches(struct v3d_dev *v3d)
|
|
|
|
{
|
|
|
|
v3d_invalidate_l1td(v3d, 0);
|
|
|
|
v3d_invalidate_l2t(v3d, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
drm/v3d: Add support for submitting jobs to the TFU.
The TFU can copy from raster, UIF, and SAND input images to UIF output
images, with optional mipmap generation. This will certainly be
useful for media EGL image input, but is also useful immediately for
mipmap generation without bogging the V3D core down.
For now we only run the queue 1 job deep, and don't have any hang
recovery (though I don't think we should need it, with TFU). Queuing
multiple jobs in the HW will require synchronizing the YUV coefficient
regs updates since they don't get FIFOed with the job.
v2: Change the ioctl to IOW instead of IOWR, always set COEF0, explain
why TFU is AUTH, clarify the syncing docs, drop the unused TFU
interrupt regs (you're expected to use the hub's), don't take
&bo->base for NULL bos.
v3: Fix a little whitespace alignment (noticed by checkpatch), rebase
on drm_sched_job_cleanup() changes.
Signed-off-by: Eric Anholt <eric@anholt.net>
Reviewed-by: Dave Emett <david.emett@broadcom.com> (v2)
Link: https://patchwork.freedesktop.org/patch/264607/
2018-11-28 23:09:25 +00:00
|
|
|
v3d_attach_object_fences(struct v3d_bo **bos, int bo_count,
|
|
|
|
struct dma_fence *fence)
|
2018-04-30 18:10:58 +00:00
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
drm/v3d: Add support for submitting jobs to the TFU.
The TFU can copy from raster, UIF, and SAND input images to UIF output
images, with optional mipmap generation. This will certainly be
useful for media EGL image input, but is also useful immediately for
mipmap generation without bogging the V3D core down.
For now we only run the queue 1 job deep, and don't have any hang
recovery (though I don't think we should need it, with TFU). Queuing
multiple jobs in the HW will require synchronizing the YUV coefficient
regs updates since they don't get FIFOed with the job.
v2: Change the ioctl to IOW instead of IOWR, always set COEF0, explain
why TFU is AUTH, clarify the syncing docs, drop the unused TFU
interrupt regs (you're expected to use the hub's), don't take
&bo->base for NULL bos.
v3: Fix a little whitespace alignment (noticed by checkpatch), rebase
on drm_sched_job_cleanup() changes.
Signed-off-by: Eric Anholt <eric@anholt.net>
Reviewed-by: Dave Emett <david.emett@broadcom.com> (v2)
Link: https://patchwork.freedesktop.org/patch/264607/
2018-11-28 23:09:25 +00:00
|
|
|
for (i = 0; i < bo_count; i++) {
|
2018-04-30 18:10:58 +00:00
|
|
|
/* XXX: Use shared fences for read-only objects. */
|
drm/v3d: Add support for submitting jobs to the TFU.
The TFU can copy from raster, UIF, and SAND input images to UIF output
images, with optional mipmap generation. This will certainly be
useful for media EGL image input, but is also useful immediately for
mipmap generation without bogging the V3D core down.
For now we only run the queue 1 job deep, and don't have any hang
recovery (though I don't think we should need it, with TFU). Queuing
multiple jobs in the HW will require synchronizing the YUV coefficient
regs updates since they don't get FIFOed with the job.
v2: Change the ioctl to IOW instead of IOWR, always set COEF0, explain
why TFU is AUTH, clarify the syncing docs, drop the unused TFU
interrupt regs (you're expected to use the hub's), don't take
&bo->base for NULL bos.
v3: Fix a little whitespace alignment (noticed by checkpatch), rebase
on drm_sched_job_cleanup() changes.
Signed-off-by: Eric Anholt <eric@anholt.net>
Reviewed-by: Dave Emett <david.emett@broadcom.com> (v2)
Link: https://patchwork.freedesktop.org/patch/264607/
2018-11-28 23:09:25 +00:00
|
|
|
reservation_object_add_excl_fence(bos[i]->resv, fence);
|
2018-04-30 18:10:58 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2018-11-28 23:09:26 +00:00
|
|
|
v3d_unlock_bo_reservations(struct v3d_bo **bos,
|
drm/v3d: Add support for submitting jobs to the TFU.
The TFU can copy from raster, UIF, and SAND input images to UIF output
images, with optional mipmap generation. This will certainly be
useful for media EGL image input, but is also useful immediately for
mipmap generation without bogging the V3D core down.
For now we only run the queue 1 job deep, and don't have any hang
recovery (though I don't think we should need it, with TFU). Queuing
multiple jobs in the HW will require synchronizing the YUV coefficient
regs updates since they don't get FIFOed with the job.
v2: Change the ioctl to IOW instead of IOWR, always set COEF0, explain
why TFU is AUTH, clarify the syncing docs, drop the unused TFU
interrupt regs (you're expected to use the hub's), don't take
&bo->base for NULL bos.
v3: Fix a little whitespace alignment (noticed by checkpatch), rebase
on drm_sched_job_cleanup() changes.
Signed-off-by: Eric Anholt <eric@anholt.net>
Reviewed-by: Dave Emett <david.emett@broadcom.com> (v2)
Link: https://patchwork.freedesktop.org/patch/264607/
2018-11-28 23:09:25 +00:00
|
|
|
int bo_count,
|
2018-04-30 18:10:58 +00:00
|
|
|
struct ww_acquire_ctx *acquire_ctx)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
drm/v3d: Add support for submitting jobs to the TFU.
The TFU can copy from raster, UIF, and SAND input images to UIF output
images, with optional mipmap generation. This will certainly be
useful for media EGL image input, but is also useful immediately for
mipmap generation without bogging the V3D core down.
For now we only run the queue 1 job deep, and don't have any hang
recovery (though I don't think we should need it, with TFU). Queuing
multiple jobs in the HW will require synchronizing the YUV coefficient
regs updates since they don't get FIFOed with the job.
v2: Change the ioctl to IOW instead of IOWR, always set COEF0, explain
why TFU is AUTH, clarify the syncing docs, drop the unused TFU
interrupt regs (you're expected to use the hub's), don't take
&bo->base for NULL bos.
v3: Fix a little whitespace alignment (noticed by checkpatch), rebase
on drm_sched_job_cleanup() changes.
Signed-off-by: Eric Anholt <eric@anholt.net>
Reviewed-by: Dave Emett <david.emett@broadcom.com> (v2)
Link: https://patchwork.freedesktop.org/patch/264607/
2018-11-28 23:09:25 +00:00
|
|
|
for (i = 0; i < bo_count; i++)
|
|
|
|
ww_mutex_unlock(&bos[i]->resv->lock);
|
2018-04-30 18:10:58 +00:00
|
|
|
|
|
|
|
ww_acquire_fini(acquire_ctx);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Takes the reservation lock on all the BOs being referenced, so that
|
|
|
|
* at queue submit time we can update the reservations.
|
|
|
|
*
|
|
|
|
* We don't lock the RCL the tile alloc/state BOs, or overflow memory
|
|
|
|
* (all of which are on exec->unref_list). They're entirely private
|
|
|
|
* to v3d, so we don't attach dma-buf fences to them.
|
|
|
|
*/
|
|
|
|
static int
|
2018-11-28 23:09:26 +00:00
|
|
|
v3d_lock_bo_reservations(struct v3d_bo **bos,
|
drm/v3d: Add support for submitting jobs to the TFU.
The TFU can copy from raster, UIF, and SAND input images to UIF output
images, with optional mipmap generation. This will certainly be
useful for media EGL image input, but is also useful immediately for
mipmap generation without bogging the V3D core down.
For now we only run the queue 1 job deep, and don't have any hang
recovery (though I don't think we should need it, with TFU). Queuing
multiple jobs in the HW will require synchronizing the YUV coefficient
regs updates since they don't get FIFOed with the job.
v2: Change the ioctl to IOW instead of IOWR, always set COEF0, explain
why TFU is AUTH, clarify the syncing docs, drop the unused TFU
interrupt regs (you're expected to use the hub's), don't take
&bo->base for NULL bos.
v3: Fix a little whitespace alignment (noticed by checkpatch), rebase
on drm_sched_job_cleanup() changes.
Signed-off-by: Eric Anholt <eric@anholt.net>
Reviewed-by: Dave Emett <david.emett@broadcom.com> (v2)
Link: https://patchwork.freedesktop.org/patch/264607/
2018-11-28 23:09:25 +00:00
|
|
|
int bo_count,
|
2018-04-30 18:10:58 +00:00
|
|
|
struct ww_acquire_ctx *acquire_ctx)
|
|
|
|
{
|
|
|
|
int contended_lock = -1;
|
|
|
|
int i, ret;
|
|
|
|
|
|
|
|
ww_acquire_init(acquire_ctx, &reservation_ww_class);
|
|
|
|
|
|
|
|
retry:
|
|
|
|
if (contended_lock != -1) {
|
drm/v3d: Add support for submitting jobs to the TFU.
The TFU can copy from raster, UIF, and SAND input images to UIF output
images, with optional mipmap generation. This will certainly be
useful for media EGL image input, but is also useful immediately for
mipmap generation without bogging the V3D core down.
For now we only run the queue 1 job deep, and don't have any hang
recovery (though I don't think we should need it, with TFU). Queuing
multiple jobs in the HW will require synchronizing the YUV coefficient
regs updates since they don't get FIFOed with the job.
v2: Change the ioctl to IOW instead of IOWR, always set COEF0, explain
why TFU is AUTH, clarify the syncing docs, drop the unused TFU
interrupt regs (you're expected to use the hub's), don't take
&bo->base for NULL bos.
v3: Fix a little whitespace alignment (noticed by checkpatch), rebase
on drm_sched_job_cleanup() changes.
Signed-off-by: Eric Anholt <eric@anholt.net>
Reviewed-by: Dave Emett <david.emett@broadcom.com> (v2)
Link: https://patchwork.freedesktop.org/patch/264607/
2018-11-28 23:09:25 +00:00
|
|
|
struct v3d_bo *bo = bos[contended_lock];
|
2018-11-08 16:16:53 +00:00
|
|
|
|
2018-04-30 18:10:58 +00:00
|
|
|
ret = ww_mutex_lock_slow_interruptible(&bo->resv->lock,
|
|
|
|
acquire_ctx);
|
|
|
|
if (ret) {
|
|
|
|
ww_acquire_done(acquire_ctx);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
drm/v3d: Add support for submitting jobs to the TFU.
The TFU can copy from raster, UIF, and SAND input images to UIF output
images, with optional mipmap generation. This will certainly be
useful for media EGL image input, but is also useful immediately for
mipmap generation without bogging the V3D core down.
For now we only run the queue 1 job deep, and don't have any hang
recovery (though I don't think we should need it, with TFU). Queuing
multiple jobs in the HW will require synchronizing the YUV coefficient
regs updates since they don't get FIFOed with the job.
v2: Change the ioctl to IOW instead of IOWR, always set COEF0, explain
why TFU is AUTH, clarify the syncing docs, drop the unused TFU
interrupt regs (you're expected to use the hub's), don't take
&bo->base for NULL bos.
v3: Fix a little whitespace alignment (noticed by checkpatch), rebase
on drm_sched_job_cleanup() changes.
Signed-off-by: Eric Anholt <eric@anholt.net>
Reviewed-by: Dave Emett <david.emett@broadcom.com> (v2)
Link: https://patchwork.freedesktop.org/patch/264607/
2018-11-28 23:09:25 +00:00
|
|
|
for (i = 0; i < bo_count; i++) {
|
2018-04-30 18:10:58 +00:00
|
|
|
if (i == contended_lock)
|
|
|
|
continue;
|
|
|
|
|
drm/v3d: Add support for submitting jobs to the TFU.
The TFU can copy from raster, UIF, and SAND input images to UIF output
images, with optional mipmap generation. This will certainly be
useful for media EGL image input, but is also useful immediately for
mipmap generation without bogging the V3D core down.
For now we only run the queue 1 job deep, and don't have any hang
recovery (though I don't think we should need it, with TFU). Queuing
multiple jobs in the HW will require synchronizing the YUV coefficient
regs updates since they don't get FIFOed with the job.
v2: Change the ioctl to IOW instead of IOWR, always set COEF0, explain
why TFU is AUTH, clarify the syncing docs, drop the unused TFU
interrupt regs (you're expected to use the hub's), don't take
&bo->base for NULL bos.
v3: Fix a little whitespace alignment (noticed by checkpatch), rebase
on drm_sched_job_cleanup() changes.
Signed-off-by: Eric Anholt <eric@anholt.net>
Reviewed-by: Dave Emett <david.emett@broadcom.com> (v2)
Link: https://patchwork.freedesktop.org/patch/264607/
2018-11-28 23:09:25 +00:00
|
|
|
ret = ww_mutex_lock_interruptible(&bos[i]->resv->lock,
|
2018-11-08 16:16:53 +00:00
|
|
|
acquire_ctx);
|
2018-04-30 18:10:58 +00:00
|
|
|
if (ret) {
|
|
|
|
int j;
|
|
|
|
|
2018-11-08 16:16:53 +00:00
|
|
|
for (j = 0; j < i; j++)
|
drm/v3d: Add support for submitting jobs to the TFU.
The TFU can copy from raster, UIF, and SAND input images to UIF output
images, with optional mipmap generation. This will certainly be
useful for media EGL image input, but is also useful immediately for
mipmap generation without bogging the V3D core down.
For now we only run the queue 1 job deep, and don't have any hang
recovery (though I don't think we should need it, with TFU). Queuing
multiple jobs in the HW will require synchronizing the YUV coefficient
regs updates since they don't get FIFOed with the job.
v2: Change the ioctl to IOW instead of IOWR, always set COEF0, explain
why TFU is AUTH, clarify the syncing docs, drop the unused TFU
interrupt regs (you're expected to use the hub's), don't take
&bo->base for NULL bos.
v3: Fix a little whitespace alignment (noticed by checkpatch), rebase
on drm_sched_job_cleanup() changes.
Signed-off-by: Eric Anholt <eric@anholt.net>
Reviewed-by: Dave Emett <david.emett@broadcom.com> (v2)
Link: https://patchwork.freedesktop.org/patch/264607/
2018-11-28 23:09:25 +00:00
|
|
|
ww_mutex_unlock(&bos[j]->resv->lock);
|
2018-04-30 18:10:58 +00:00
|
|
|
|
|
|
|
if (contended_lock != -1 && contended_lock >= i) {
|
drm/v3d: Add support for submitting jobs to the TFU.
The TFU can copy from raster, UIF, and SAND input images to UIF output
images, with optional mipmap generation. This will certainly be
useful for media EGL image input, but is also useful immediately for
mipmap generation without bogging the V3D core down.
For now we only run the queue 1 job deep, and don't have any hang
recovery (though I don't think we should need it, with TFU). Queuing
multiple jobs in the HW will require synchronizing the YUV coefficient
regs updates since they don't get FIFOed with the job.
v2: Change the ioctl to IOW instead of IOWR, always set COEF0, explain
why TFU is AUTH, clarify the syncing docs, drop the unused TFU
interrupt regs (you're expected to use the hub's), don't take
&bo->base for NULL bos.
v3: Fix a little whitespace alignment (noticed by checkpatch), rebase
on drm_sched_job_cleanup() changes.
Signed-off-by: Eric Anholt <eric@anholt.net>
Reviewed-by: Dave Emett <david.emett@broadcom.com> (v2)
Link: https://patchwork.freedesktop.org/patch/264607/
2018-11-28 23:09:25 +00:00
|
|
|
struct v3d_bo *bo = bos[contended_lock];
|
2018-04-30 18:10:58 +00:00
|
|
|
|
|
|
|
ww_mutex_unlock(&bo->resv->lock);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ret == -EDEADLK) {
|
|
|
|
contended_lock = i;
|
|
|
|
goto retry;
|
|
|
|
}
|
|
|
|
|
|
|
|
ww_acquire_done(acquire_ctx);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ww_acquire_done(acquire_ctx);
|
|
|
|
|
|
|
|
/* Reserve space for our shared (read-only) fence references,
|
|
|
|
* before we commit the CL to the hardware.
|
|
|
|
*/
|
drm/v3d: Add support for submitting jobs to the TFU.
The TFU can copy from raster, UIF, and SAND input images to UIF output
images, with optional mipmap generation. This will certainly be
useful for media EGL image input, but is also useful immediately for
mipmap generation without bogging the V3D core down.
For now we only run the queue 1 job deep, and don't have any hang
recovery (though I don't think we should need it, with TFU). Queuing
multiple jobs in the HW will require synchronizing the YUV coefficient
regs updates since they don't get FIFOed with the job.
v2: Change the ioctl to IOW instead of IOWR, always set COEF0, explain
why TFU is AUTH, clarify the syncing docs, drop the unused TFU
interrupt regs (you're expected to use the hub's), don't take
&bo->base for NULL bos.
v3: Fix a little whitespace alignment (noticed by checkpatch), rebase
on drm_sched_job_cleanup() changes.
Signed-off-by: Eric Anholt <eric@anholt.net>
Reviewed-by: Dave Emett <david.emett@broadcom.com> (v2)
Link: https://patchwork.freedesktop.org/patch/264607/
2018-11-28 23:09:25 +00:00
|
|
|
for (i = 0; i < bo_count; i++) {
|
|
|
|
ret = reservation_object_reserve_shared(bos[i]->resv, 1);
|
2018-04-30 18:10:58 +00:00
|
|
|
if (ret) {
|
2018-11-28 23:09:26 +00:00
|
|
|
v3d_unlock_bo_reservations(bos, bo_count,
|
drm/v3d: Add support for submitting jobs to the TFU.
The TFU can copy from raster, UIF, and SAND input images to UIF output
images, with optional mipmap generation. This will certainly be
useful for media EGL image input, but is also useful immediately for
mipmap generation without bogging the V3D core down.
For now we only run the queue 1 job deep, and don't have any hang
recovery (though I don't think we should need it, with TFU). Queuing
multiple jobs in the HW will require synchronizing the YUV coefficient
regs updates since they don't get FIFOed with the job.
v2: Change the ioctl to IOW instead of IOWR, always set COEF0, explain
why TFU is AUTH, clarify the syncing docs, drop the unused TFU
interrupt regs (you're expected to use the hub's), don't take
&bo->base for NULL bos.
v3: Fix a little whitespace alignment (noticed by checkpatch), rebase
on drm_sched_job_cleanup() changes.
Signed-off-by: Eric Anholt <eric@anholt.net>
Reviewed-by: Dave Emett <david.emett@broadcom.com> (v2)
Link: https://patchwork.freedesktop.org/patch/264607/
2018-11-28 23:09:25 +00:00
|
|
|
acquire_ctx);
|
2018-04-30 18:10:58 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* v3d_cl_lookup_bos() - Sets up exec->bo[] with the GEM objects
|
|
|
|
* referenced by the job.
|
|
|
|
* @dev: DRM device
|
|
|
|
* @file_priv: DRM file for this fd
|
|
|
|
* @exec: V3D job being set up
|
|
|
|
*
|
|
|
|
* The command validator needs to reference BOs by their index within
|
|
|
|
* the submitted job's BO list. This does the validation of the job's
|
|
|
|
* BO list and reference counting for the lifetime of the job.
|
|
|
|
*
|
|
|
|
* Note that this function doesn't need to unreference the BOs on
|
|
|
|
* failure, because that will happen at v3d_exec_cleanup() time.
|
|
|
|
*/
|
|
|
|
static int
|
|
|
|
v3d_cl_lookup_bos(struct drm_device *dev,
|
|
|
|
struct drm_file *file_priv,
|
|
|
|
struct drm_v3d_submit_cl *args,
|
|
|
|
struct v3d_exec_info *exec)
|
|
|
|
{
|
|
|
|
u32 *handles;
|
|
|
|
int ret = 0;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
exec->bo_count = args->bo_handle_count;
|
|
|
|
|
|
|
|
if (!exec->bo_count) {
|
|
|
|
/* See comment on bo_index for why we have to check
|
|
|
|
* this.
|
|
|
|
*/
|
|
|
|
DRM_DEBUG("Rendering requires BOs\n");
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
exec->bo = kvmalloc_array(exec->bo_count,
|
|
|
|
sizeof(struct drm_gem_cma_object *),
|
|
|
|
GFP_KERNEL | __GFP_ZERO);
|
|
|
|
if (!exec->bo) {
|
|
|
|
DRM_DEBUG("Failed to allocate validated BO pointers\n");
|
|
|
|
return -ENOMEM;
|
|
|
|
}
|
|
|
|
|
|
|
|
handles = kvmalloc_array(exec->bo_count, sizeof(u32), GFP_KERNEL);
|
|
|
|
if (!handles) {
|
|
|
|
ret = -ENOMEM;
|
|
|
|
DRM_DEBUG("Failed to allocate incoming GEM handles\n");
|
|
|
|
goto fail;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (copy_from_user(handles,
|
|
|
|
(void __user *)(uintptr_t)args->bo_handles,
|
|
|
|
exec->bo_count * sizeof(u32))) {
|
|
|
|
ret = -EFAULT;
|
|
|
|
DRM_DEBUG("Failed to copy in GEM handles\n");
|
|
|
|
goto fail;
|
|
|
|
}
|
|
|
|
|
|
|
|
spin_lock(&file_priv->table_lock);
|
|
|
|
for (i = 0; i < exec->bo_count; i++) {
|
|
|
|
struct drm_gem_object *bo = idr_find(&file_priv->object_idr,
|
|
|
|
handles[i]);
|
|
|
|
if (!bo) {
|
|
|
|
DRM_DEBUG("Failed to look up GEM BO %d: %d\n",
|
|
|
|
i, handles[i]);
|
|
|
|
ret = -ENOENT;
|
|
|
|
spin_unlock(&file_priv->table_lock);
|
|
|
|
goto fail;
|
|
|
|
}
|
|
|
|
drm_gem_object_get(bo);
|
|
|
|
exec->bo[i] = to_v3d_bo(bo);
|
|
|
|
}
|
|
|
|
spin_unlock(&file_priv->table_lock);
|
|
|
|
|
|
|
|
fail:
|
|
|
|
kvfree(handles);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
v3d_exec_cleanup(struct kref *ref)
|
|
|
|
{
|
|
|
|
struct v3d_exec_info *exec = container_of(ref, struct v3d_exec_info,
|
|
|
|
refcount);
|
|
|
|
struct v3d_dev *v3d = exec->v3d;
|
|
|
|
unsigned int i;
|
|
|
|
struct v3d_bo *bo, *save;
|
|
|
|
|
|
|
|
dma_fence_put(exec->bin.in_fence);
|
|
|
|
dma_fence_put(exec->render.in_fence);
|
|
|
|
|
|
|
|
dma_fence_put(exec->bin.done_fence);
|
|
|
|
dma_fence_put(exec->render.done_fence);
|
|
|
|
|
|
|
|
dma_fence_put(exec->bin_done_fence);
|
2018-09-28 23:21:23 +00:00
|
|
|
dma_fence_put(exec->render_done_fence);
|
2018-04-30 18:10:58 +00:00
|
|
|
|
|
|
|
for (i = 0; i < exec->bo_count; i++)
|
|
|
|
drm_gem_object_put_unlocked(&exec->bo[i]->base);
|
|
|
|
kvfree(exec->bo);
|
|
|
|
|
|
|
|
list_for_each_entry_safe(bo, save, &exec->unref_list, unref_head) {
|
|
|
|
drm_gem_object_put_unlocked(&bo->base);
|
|
|
|
}
|
|
|
|
|
|
|
|
pm_runtime_mark_last_busy(v3d->dev);
|
|
|
|
pm_runtime_put_autosuspend(v3d->dev);
|
|
|
|
|
|
|
|
kfree(exec);
|
|
|
|
}
|
|
|
|
|
|
|
|
void v3d_exec_put(struct v3d_exec_info *exec)
|
|
|
|
{
|
|
|
|
kref_put(&exec->refcount, v3d_exec_cleanup);
|
|
|
|
}
|
|
|
|
|
drm/v3d: Add support for submitting jobs to the TFU.
The TFU can copy from raster, UIF, and SAND input images to UIF output
images, with optional mipmap generation. This will certainly be
useful for media EGL image input, but is also useful immediately for
mipmap generation without bogging the V3D core down.
For now we only run the queue 1 job deep, and don't have any hang
recovery (though I don't think we should need it, with TFU). Queuing
multiple jobs in the HW will require synchronizing the YUV coefficient
regs updates since they don't get FIFOed with the job.
v2: Change the ioctl to IOW instead of IOWR, always set COEF0, explain
why TFU is AUTH, clarify the syncing docs, drop the unused TFU
interrupt regs (you're expected to use the hub's), don't take
&bo->base for NULL bos.
v3: Fix a little whitespace alignment (noticed by checkpatch), rebase
on drm_sched_job_cleanup() changes.
Signed-off-by: Eric Anholt <eric@anholt.net>
Reviewed-by: Dave Emett <david.emett@broadcom.com> (v2)
Link: https://patchwork.freedesktop.org/patch/264607/
2018-11-28 23:09:25 +00:00
|
|
|
static void
|
|
|
|
v3d_tfu_job_cleanup(struct kref *ref)
|
|
|
|
{
|
|
|
|
struct v3d_tfu_job *job = container_of(ref, struct v3d_tfu_job,
|
|
|
|
refcount);
|
|
|
|
struct v3d_dev *v3d = job->v3d;
|
|
|
|
unsigned int i;
|
|
|
|
|
|
|
|
dma_fence_put(job->in_fence);
|
|
|
|
dma_fence_put(job->done_fence);
|
|
|
|
|
|
|
|
for (i = 0; i < ARRAY_SIZE(job->bo); i++) {
|
|
|
|
if (job->bo[i])
|
|
|
|
drm_gem_object_put_unlocked(&job->bo[i]->base);
|
|
|
|
}
|
|
|
|
|
|
|
|
pm_runtime_mark_last_busy(v3d->dev);
|
|
|
|
pm_runtime_put_autosuspend(v3d->dev);
|
|
|
|
|
|
|
|
kfree(job);
|
|
|
|
}
|
|
|
|
|
|
|
|
void v3d_tfu_job_put(struct v3d_tfu_job *job)
|
|
|
|
{
|
|
|
|
kref_put(&job->refcount, v3d_tfu_job_cleanup);
|
|
|
|
}
|
|
|
|
|
2018-04-30 18:10:58 +00:00
|
|
|
int
|
|
|
|
v3d_wait_bo_ioctl(struct drm_device *dev, void *data,
|
|
|
|
struct drm_file *file_priv)
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
struct drm_v3d_wait_bo *args = data;
|
|
|
|
struct drm_gem_object *gem_obj;
|
|
|
|
struct v3d_bo *bo;
|
|
|
|
ktime_t start = ktime_get();
|
|
|
|
u64 delta_ns;
|
|
|
|
unsigned long timeout_jiffies =
|
|
|
|
nsecs_to_jiffies_timeout(args->timeout_ns);
|
|
|
|
|
|
|
|
if (args->pad != 0)
|
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
gem_obj = drm_gem_object_lookup(file_priv, args->handle);
|
|
|
|
if (!gem_obj) {
|
|
|
|
DRM_DEBUG("Failed to look up GEM BO %d\n", args->handle);
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
bo = to_v3d_bo(gem_obj);
|
|
|
|
|
|
|
|
ret = reservation_object_wait_timeout_rcu(bo->resv,
|
|
|
|
true, true,
|
|
|
|
timeout_jiffies);
|
|
|
|
|
|
|
|
if (ret == 0)
|
|
|
|
ret = -ETIME;
|
|
|
|
else if (ret > 0)
|
|
|
|
ret = 0;
|
|
|
|
|
|
|
|
/* Decrement the user's timeout, in case we got interrupted
|
|
|
|
* such that the ioctl will be restarted.
|
|
|
|
*/
|
|
|
|
delta_ns = ktime_to_ns(ktime_sub(ktime_get(), start));
|
|
|
|
if (delta_ns < args->timeout_ns)
|
|
|
|
args->timeout_ns -= delta_ns;
|
|
|
|
else
|
|
|
|
args->timeout_ns = 0;
|
|
|
|
|
|
|
|
/* Asked to wait beyond the jiffie/scheduler precision? */
|
|
|
|
if (ret == -ETIME && args->timeout_ns)
|
|
|
|
ret = -EAGAIN;
|
|
|
|
|
|
|
|
drm_gem_object_put_unlocked(gem_obj);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* v3d_submit_cl_ioctl() - Submits a job (frame) to the V3D.
|
|
|
|
* @dev: DRM device
|
|
|
|
* @data: ioctl argument
|
|
|
|
* @file_priv: DRM file for this fd
|
|
|
|
*
|
|
|
|
* This is the main entrypoint for userspace to submit a 3D frame to
|
|
|
|
* the GPU. Userspace provides the binner command list (if
|
|
|
|
* applicable), and the kernel sets up the render command list to draw
|
|
|
|
* to the framebuffer described in the ioctl, using the command lists
|
|
|
|
* that the 3D engine's binner will produce.
|
|
|
|
*/
|
|
|
|
int
|
|
|
|
v3d_submit_cl_ioctl(struct drm_device *dev, void *data,
|
|
|
|
struct drm_file *file_priv)
|
|
|
|
{
|
|
|
|
struct v3d_dev *v3d = to_v3d_dev(dev);
|
|
|
|
struct v3d_file_priv *v3d_priv = file_priv->driver_priv;
|
|
|
|
struct drm_v3d_submit_cl *args = data;
|
|
|
|
struct v3d_exec_info *exec;
|
|
|
|
struct ww_acquire_ctx acquire_ctx;
|
|
|
|
struct drm_syncobj *sync_out;
|
|
|
|
int ret = 0;
|
|
|
|
|
2018-12-01 00:57:58 +00:00
|
|
|
trace_v3d_submit_cl_ioctl(&v3d->drm, args->rcl_start, args->rcl_end);
|
|
|
|
|
2018-04-30 18:10:58 +00:00
|
|
|
if (args->pad != 0) {
|
|
|
|
DRM_INFO("pad must be zero: %d\n", args->pad);
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
exec = kcalloc(1, sizeof(*exec), GFP_KERNEL);
|
|
|
|
if (!exec)
|
|
|
|
return -ENOMEM;
|
|
|
|
|
|
|
|
ret = pm_runtime_get_sync(v3d->dev);
|
|
|
|
if (ret < 0) {
|
|
|
|
kfree(exec);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
kref_init(&exec->refcount);
|
|
|
|
|
|
|
|
ret = drm_syncobj_find_fence(file_priv, args->in_sync_bcl,
|
2018-10-15 08:55:47 +00:00
|
|
|
0, 0, &exec->bin.in_fence);
|
2018-04-30 18:10:58 +00:00
|
|
|
if (ret == -EINVAL)
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
ret = drm_syncobj_find_fence(file_priv, args->in_sync_rcl,
|
2018-10-15 08:55:47 +00:00
|
|
|
0, 0, &exec->render.in_fence);
|
2018-04-30 18:10:58 +00:00
|
|
|
if (ret == -EINVAL)
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
exec->qma = args->qma;
|
|
|
|
exec->qms = args->qms;
|
|
|
|
exec->qts = args->qts;
|
|
|
|
exec->bin.exec = exec;
|
|
|
|
exec->bin.start = args->bcl_start;
|
|
|
|
exec->bin.end = args->bcl_end;
|
|
|
|
exec->render.exec = exec;
|
|
|
|
exec->render.start = args->rcl_start;
|
|
|
|
exec->render.end = args->rcl_end;
|
|
|
|
exec->v3d = v3d;
|
|
|
|
INIT_LIST_HEAD(&exec->unref_list);
|
|
|
|
|
|
|
|
ret = v3d_cl_lookup_bos(dev, file_priv, args, exec);
|
|
|
|
if (ret)
|
|
|
|
goto fail;
|
|
|
|
|
2018-11-28 23:09:26 +00:00
|
|
|
ret = v3d_lock_bo_reservations(exec->bo, exec->bo_count,
|
drm/v3d: Add support for submitting jobs to the TFU.
The TFU can copy from raster, UIF, and SAND input images to UIF output
images, with optional mipmap generation. This will certainly be
useful for media EGL image input, but is also useful immediately for
mipmap generation without bogging the V3D core down.
For now we only run the queue 1 job deep, and don't have any hang
recovery (though I don't think we should need it, with TFU). Queuing
multiple jobs in the HW will require synchronizing the YUV coefficient
regs updates since they don't get FIFOed with the job.
v2: Change the ioctl to IOW instead of IOWR, always set COEF0, explain
why TFU is AUTH, clarify the syncing docs, drop the unused TFU
interrupt regs (you're expected to use the hub's), don't take
&bo->base for NULL bos.
v3: Fix a little whitespace alignment (noticed by checkpatch), rebase
on drm_sched_job_cleanup() changes.
Signed-off-by: Eric Anholt <eric@anholt.net>
Reviewed-by: Dave Emett <david.emett@broadcom.com> (v2)
Link: https://patchwork.freedesktop.org/patch/264607/
2018-11-28 23:09:25 +00:00
|
|
|
&acquire_ctx);
|
2018-04-30 18:10:58 +00:00
|
|
|
if (ret)
|
|
|
|
goto fail;
|
|
|
|
|
2018-06-06 17:48:51 +00:00
|
|
|
mutex_lock(&v3d->sched_lock);
|
2018-04-30 18:10:58 +00:00
|
|
|
if (exec->bin.start != exec->bin.end) {
|
|
|
|
ret = drm_sched_job_init(&exec->bin.base,
|
|
|
|
&v3d_priv->sched_entity[V3D_BIN],
|
|
|
|
v3d_priv);
|
|
|
|
if (ret)
|
|
|
|
goto fail_unreserve;
|
|
|
|
|
|
|
|
exec->bin_done_fence =
|
|
|
|
dma_fence_get(&exec->bin.base.s_fence->finished);
|
|
|
|
|
|
|
|
kref_get(&exec->refcount); /* put by scheduler job completion */
|
|
|
|
drm_sched_entity_push_job(&exec->bin.base,
|
|
|
|
&v3d_priv->sched_entity[V3D_BIN]);
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = drm_sched_job_init(&exec->render.base,
|
|
|
|
&v3d_priv->sched_entity[V3D_RENDER],
|
|
|
|
v3d_priv);
|
|
|
|
if (ret)
|
|
|
|
goto fail_unreserve;
|
|
|
|
|
2018-09-28 23:21:23 +00:00
|
|
|
exec->render_done_fence =
|
|
|
|
dma_fence_get(&exec->render.base.s_fence->finished);
|
|
|
|
|
2018-04-30 18:10:58 +00:00
|
|
|
kref_get(&exec->refcount); /* put by scheduler job completion */
|
|
|
|
drm_sched_entity_push_job(&exec->render.base,
|
|
|
|
&v3d_priv->sched_entity[V3D_RENDER]);
|
2018-06-06 17:48:51 +00:00
|
|
|
mutex_unlock(&v3d->sched_lock);
|
2018-04-30 18:10:58 +00:00
|
|
|
|
drm/v3d: Add support for submitting jobs to the TFU.
The TFU can copy from raster, UIF, and SAND input images to UIF output
images, with optional mipmap generation. This will certainly be
useful for media EGL image input, but is also useful immediately for
mipmap generation without bogging the V3D core down.
For now we only run the queue 1 job deep, and don't have any hang
recovery (though I don't think we should need it, with TFU). Queuing
multiple jobs in the HW will require synchronizing the YUV coefficient
regs updates since they don't get FIFOed with the job.
v2: Change the ioctl to IOW instead of IOWR, always set COEF0, explain
why TFU is AUTH, clarify the syncing docs, drop the unused TFU
interrupt regs (you're expected to use the hub's), don't take
&bo->base for NULL bos.
v3: Fix a little whitespace alignment (noticed by checkpatch), rebase
on drm_sched_job_cleanup() changes.
Signed-off-by: Eric Anholt <eric@anholt.net>
Reviewed-by: Dave Emett <david.emett@broadcom.com> (v2)
Link: https://patchwork.freedesktop.org/patch/264607/
2018-11-28 23:09:25 +00:00
|
|
|
v3d_attach_object_fences(exec->bo, exec->bo_count,
|
|
|
|
exec->render_done_fence);
|
2018-04-30 18:10:58 +00:00
|
|
|
|
2018-11-28 23:09:26 +00:00
|
|
|
v3d_unlock_bo_reservations(exec->bo, exec->bo_count, &acquire_ctx);
|
2018-04-30 18:10:58 +00:00
|
|
|
|
|
|
|
/* Update the return sync object for the */
|
|
|
|
sync_out = drm_syncobj_find(file_priv, args->out_sync);
|
|
|
|
if (sync_out) {
|
2018-11-14 13:24:27 +00:00
|
|
|
drm_syncobj_replace_fence(sync_out, exec->render_done_fence);
|
2018-04-30 18:10:58 +00:00
|
|
|
drm_syncobj_put(sync_out);
|
|
|
|
}
|
|
|
|
|
|
|
|
v3d_exec_put(exec);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
fail_unreserve:
|
2018-06-06 17:48:51 +00:00
|
|
|
mutex_unlock(&v3d->sched_lock);
|
2018-11-28 23:09:26 +00:00
|
|
|
v3d_unlock_bo_reservations(exec->bo, exec->bo_count, &acquire_ctx);
|
2018-04-30 18:10:58 +00:00
|
|
|
fail:
|
|
|
|
v3d_exec_put(exec);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
drm/v3d: Add support for submitting jobs to the TFU.
The TFU can copy from raster, UIF, and SAND input images to UIF output
images, with optional mipmap generation. This will certainly be
useful for media EGL image input, but is also useful immediately for
mipmap generation without bogging the V3D core down.
For now we only run the queue 1 job deep, and don't have any hang
recovery (though I don't think we should need it, with TFU). Queuing
multiple jobs in the HW will require synchronizing the YUV coefficient
regs updates since they don't get FIFOed with the job.
v2: Change the ioctl to IOW instead of IOWR, always set COEF0, explain
why TFU is AUTH, clarify the syncing docs, drop the unused TFU
interrupt regs (you're expected to use the hub's), don't take
&bo->base for NULL bos.
v3: Fix a little whitespace alignment (noticed by checkpatch), rebase
on drm_sched_job_cleanup() changes.
Signed-off-by: Eric Anholt <eric@anholt.net>
Reviewed-by: Dave Emett <david.emett@broadcom.com> (v2)
Link: https://patchwork.freedesktop.org/patch/264607/
2018-11-28 23:09:25 +00:00
|
|
|
/**
|
|
|
|
* v3d_submit_tfu_ioctl() - Submits a TFU (texture formatting) job to the V3D.
|
|
|
|
* @dev: DRM device
|
|
|
|
* @data: ioctl argument
|
|
|
|
* @file_priv: DRM file for this fd
|
|
|
|
*
|
|
|
|
* Userspace provides the register setup for the TFU, which we don't
|
|
|
|
* need to validate since the TFU is behind the MMU.
|
|
|
|
*/
|
|
|
|
int
|
|
|
|
v3d_submit_tfu_ioctl(struct drm_device *dev, void *data,
|
|
|
|
struct drm_file *file_priv)
|
|
|
|
{
|
|
|
|
struct v3d_dev *v3d = to_v3d_dev(dev);
|
|
|
|
struct v3d_file_priv *v3d_priv = file_priv->driver_priv;
|
|
|
|
struct drm_v3d_submit_tfu *args = data;
|
|
|
|
struct v3d_tfu_job *job;
|
|
|
|
struct ww_acquire_ctx acquire_ctx;
|
|
|
|
struct drm_syncobj *sync_out;
|
|
|
|
struct dma_fence *sched_done_fence;
|
|
|
|
int ret = 0;
|
|
|
|
int bo_count;
|
|
|
|
|
2018-12-01 00:57:58 +00:00
|
|
|
trace_v3d_submit_tfu_ioctl(&v3d->drm, args->iia);
|
|
|
|
|
drm/v3d: Add support for submitting jobs to the TFU.
The TFU can copy from raster, UIF, and SAND input images to UIF output
images, with optional mipmap generation. This will certainly be
useful for media EGL image input, but is also useful immediately for
mipmap generation without bogging the V3D core down.
For now we only run the queue 1 job deep, and don't have any hang
recovery (though I don't think we should need it, with TFU). Queuing
multiple jobs in the HW will require synchronizing the YUV coefficient
regs updates since they don't get FIFOed with the job.
v2: Change the ioctl to IOW instead of IOWR, always set COEF0, explain
why TFU is AUTH, clarify the syncing docs, drop the unused TFU
interrupt regs (you're expected to use the hub's), don't take
&bo->base for NULL bos.
v3: Fix a little whitespace alignment (noticed by checkpatch), rebase
on drm_sched_job_cleanup() changes.
Signed-off-by: Eric Anholt <eric@anholt.net>
Reviewed-by: Dave Emett <david.emett@broadcom.com> (v2)
Link: https://patchwork.freedesktop.org/patch/264607/
2018-11-28 23:09:25 +00:00
|
|
|
job = kcalloc(1, sizeof(*job), GFP_KERNEL);
|
|
|
|
if (!job)
|
|
|
|
return -ENOMEM;
|
|
|
|
|
|
|
|
ret = pm_runtime_get_sync(v3d->dev);
|
|
|
|
if (ret < 0) {
|
|
|
|
kfree(job);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
kref_init(&job->refcount);
|
|
|
|
|
|
|
|
ret = drm_syncobj_find_fence(file_priv, args->in_sync,
|
|
|
|
0, 0, &job->in_fence);
|
|
|
|
if (ret == -EINVAL)
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
job->args = *args;
|
|
|
|
job->v3d = v3d;
|
|
|
|
|
|
|
|
spin_lock(&file_priv->table_lock);
|
|
|
|
for (bo_count = 0; bo_count < ARRAY_SIZE(job->bo); bo_count++) {
|
|
|
|
struct drm_gem_object *bo;
|
|
|
|
|
|
|
|
if (!args->bo_handles[bo_count])
|
|
|
|
break;
|
|
|
|
|
|
|
|
bo = idr_find(&file_priv->object_idr,
|
|
|
|
args->bo_handles[bo_count]);
|
|
|
|
if (!bo) {
|
|
|
|
DRM_DEBUG("Failed to look up GEM BO %d: %d\n",
|
|
|
|
bo_count, args->bo_handles[bo_count]);
|
|
|
|
ret = -ENOENT;
|
|
|
|
spin_unlock(&file_priv->table_lock);
|
|
|
|
goto fail;
|
|
|
|
}
|
|
|
|
drm_gem_object_get(bo);
|
|
|
|
job->bo[bo_count] = to_v3d_bo(bo);
|
|
|
|
}
|
|
|
|
spin_unlock(&file_priv->table_lock);
|
|
|
|
|
2018-11-28 23:09:26 +00:00
|
|
|
ret = v3d_lock_bo_reservations(job->bo, bo_count, &acquire_ctx);
|
drm/v3d: Add support for submitting jobs to the TFU.
The TFU can copy from raster, UIF, and SAND input images to UIF output
images, with optional mipmap generation. This will certainly be
useful for media EGL image input, but is also useful immediately for
mipmap generation without bogging the V3D core down.
For now we only run the queue 1 job deep, and don't have any hang
recovery (though I don't think we should need it, with TFU). Queuing
multiple jobs in the HW will require synchronizing the YUV coefficient
regs updates since they don't get FIFOed with the job.
v2: Change the ioctl to IOW instead of IOWR, always set COEF0, explain
why TFU is AUTH, clarify the syncing docs, drop the unused TFU
interrupt regs (you're expected to use the hub's), don't take
&bo->base for NULL bos.
v3: Fix a little whitespace alignment (noticed by checkpatch), rebase
on drm_sched_job_cleanup() changes.
Signed-off-by: Eric Anholt <eric@anholt.net>
Reviewed-by: Dave Emett <david.emett@broadcom.com> (v2)
Link: https://patchwork.freedesktop.org/patch/264607/
2018-11-28 23:09:25 +00:00
|
|
|
if (ret)
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
mutex_lock(&v3d->sched_lock);
|
|
|
|
ret = drm_sched_job_init(&job->base,
|
|
|
|
&v3d_priv->sched_entity[V3D_TFU],
|
|
|
|
v3d_priv);
|
|
|
|
if (ret)
|
|
|
|
goto fail_unreserve;
|
|
|
|
|
|
|
|
sched_done_fence = dma_fence_get(&job->base.s_fence->finished);
|
|
|
|
|
|
|
|
kref_get(&job->refcount); /* put by scheduler job completion */
|
|
|
|
drm_sched_entity_push_job(&job->base, &v3d_priv->sched_entity[V3D_TFU]);
|
|
|
|
mutex_unlock(&v3d->sched_lock);
|
|
|
|
|
|
|
|
v3d_attach_object_fences(job->bo, bo_count, sched_done_fence);
|
|
|
|
|
2018-11-28 23:09:26 +00:00
|
|
|
v3d_unlock_bo_reservations(job->bo, bo_count, &acquire_ctx);
|
drm/v3d: Add support for submitting jobs to the TFU.
The TFU can copy from raster, UIF, and SAND input images to UIF output
images, with optional mipmap generation. This will certainly be
useful for media EGL image input, but is also useful immediately for
mipmap generation without bogging the V3D core down.
For now we only run the queue 1 job deep, and don't have any hang
recovery (though I don't think we should need it, with TFU). Queuing
multiple jobs in the HW will require synchronizing the YUV coefficient
regs updates since they don't get FIFOed with the job.
v2: Change the ioctl to IOW instead of IOWR, always set COEF0, explain
why TFU is AUTH, clarify the syncing docs, drop the unused TFU
interrupt regs (you're expected to use the hub's), don't take
&bo->base for NULL bos.
v3: Fix a little whitespace alignment (noticed by checkpatch), rebase
on drm_sched_job_cleanup() changes.
Signed-off-by: Eric Anholt <eric@anholt.net>
Reviewed-by: Dave Emett <david.emett@broadcom.com> (v2)
Link: https://patchwork.freedesktop.org/patch/264607/
2018-11-28 23:09:25 +00:00
|
|
|
|
|
|
|
/* Update the return sync object */
|
|
|
|
sync_out = drm_syncobj_find(file_priv, args->out_sync);
|
|
|
|
if (sync_out) {
|
Final changes to drm-misc-next for v4.21:
UAPI Changes:
Core Changes:
- Add dma_fence_get_stub to dma-buf, and use it in drm/syncobj.
- Add and use DRM_MODESET_LOCK_BEGIN/END helpers.
- Small fixes to drm_atomic_helper_resume(), drm_mode_setcrtc() and
drm_atomic_helper_commit_duplicated_state()
- Fix drm_atomic_state_helper.[c] extraction.
Driver Changes:
- Small fixes to tinydrm, vkms, meson, rcar-du, virtio, vkms,
v3d, and pl111.
- vc4: Allow scaling and YUV formats on cursor planes.
- v3d: Enable use of the Texture Formatting Unit, and fix
prime imports of buffers from other drivers.
- Add support for the AUO G101EVN010 panel.
- sun4i: Enable support for the H6 display engine.
-----BEGIN PGP SIGNATURE-----
iQIzBAABCgAdFiEEuXvWqAysSYEJGuVH/lWMcqZwE8MFAlwI7wUACgkQ/lWMcqZw
E8O/3g/9GQvNpNthglt4kSXUn9bj2D/MzQsL4sEsKYcp9eM3XTMy6raybfBpMdtf
U9y7G9EwQ8F01wd1m3d3HfBkKoy0WDTIsAjh06QUuSyyEivuQEoSxCKiI7t+Tatc
gJaj2TKHF1RaDikcV+x2pqqv8ptH+IzF0A65v5SAn8U5PVYz17pD0jctYR8F434X
o1xkjL5KS+vmfzu2keUCrWWtfAsPoyqcbEu5A3W+hhpKyQmS/8kVwr5J5LylvWqa
xalXHRUgaUrOGOFuYrqWhIKjydqpr8QhIuJqacmHfmV/qvASUTeqTTnzartb+FuU
d5E4p3bFaAjbAOHUEdlaLRA4oUK8/VA+WWaGKhPGreUE3TWn/thJJElAqoJhkbql
bGelBBkNNzDbJhtwjR4hmFN7fQz0Y1LxuBXtjw7wfomJAd/xJ5fgxqT58OovZgZt
f+hxxBTsdov5MOZ3XsB457b2MNmM+4kHM7urP3Z7mluEJ0ojmiokYMGJx0RDtLzP
YoukpqEwCaMlS4rdvil1nUfYw61/PFRxoBwlmarV2A3m1DUDQ2YyUNHOgVLrlzXv
RGdiTBvuvUZm6aSuzCVUiiiuQ0zwaFfBKdwXEA016irb34rdOoZ2b6w70GWi7QEl
0tQy5ULBwuhy1Kk8QXsJxRZPnnHznGoREryNDDOC0RAr/WEhwGY=
=t02J
-----END PGP SIGNATURE-----
Merge tag 'drm-misc-next-2018-12-06' of git://anongit.freedesktop.org/drm/drm-misc into drm-next
Final changes to drm-misc-next for v4.21:
UAPI Changes:
Core Changes:
- Add dma_fence_get_stub to dma-buf, and use it in drm/syncobj.
- Add and use DRM_MODESET_LOCK_BEGIN/END helpers.
- Small fixes to drm_atomic_helper_resume(), drm_mode_setcrtc() and
drm_atomic_helper_commit_duplicated_state()
- Fix drm_atomic_state_helper.[c] extraction.
Driver Changes:
- Small fixes to tinydrm, vkms, meson, rcar-du, virtio, vkms,
v3d, and pl111.
- vc4: Allow scaling and YUV formats on cursor planes.
- v3d: Enable use of the Texture Formatting Unit, and fix
prime imports of buffers from other drivers.
- Add support for the AUO G101EVN010 panel.
- sun4i: Enable support for the H6 display engine.
Signed-off-by: Dave Airlie <airlied@redhat.com>
[airlied: added drm/v3d: fix broken build to the merge commit]
From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/321be9d3-ab75-5f92-8193-e5113662edef@linux.intel.com
2018-12-07 00:46:29 +00:00
|
|
|
drm_syncobj_replace_fence(sync_out, sched_done_fence);
|
drm/v3d: Add support for submitting jobs to the TFU.
The TFU can copy from raster, UIF, and SAND input images to UIF output
images, with optional mipmap generation. This will certainly be
useful for media EGL image input, but is also useful immediately for
mipmap generation without bogging the V3D core down.
For now we only run the queue 1 job deep, and don't have any hang
recovery (though I don't think we should need it, with TFU). Queuing
multiple jobs in the HW will require synchronizing the YUV coefficient
regs updates since they don't get FIFOed with the job.
v2: Change the ioctl to IOW instead of IOWR, always set COEF0, explain
why TFU is AUTH, clarify the syncing docs, drop the unused TFU
interrupt regs (you're expected to use the hub's), don't take
&bo->base for NULL bos.
v3: Fix a little whitespace alignment (noticed by checkpatch), rebase
on drm_sched_job_cleanup() changes.
Signed-off-by: Eric Anholt <eric@anholt.net>
Reviewed-by: Dave Emett <david.emett@broadcom.com> (v2)
Link: https://patchwork.freedesktop.org/patch/264607/
2018-11-28 23:09:25 +00:00
|
|
|
drm_syncobj_put(sync_out);
|
|
|
|
}
|
|
|
|
dma_fence_put(sched_done_fence);
|
|
|
|
|
|
|
|
v3d_tfu_job_put(job);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
fail_unreserve:
|
|
|
|
mutex_unlock(&v3d->sched_lock);
|
2018-11-28 23:09:26 +00:00
|
|
|
v3d_unlock_bo_reservations(job->bo, bo_count, &acquire_ctx);
|
drm/v3d: Add support for submitting jobs to the TFU.
The TFU can copy from raster, UIF, and SAND input images to UIF output
images, with optional mipmap generation. This will certainly be
useful for media EGL image input, but is also useful immediately for
mipmap generation without bogging the V3D core down.
For now we only run the queue 1 job deep, and don't have any hang
recovery (though I don't think we should need it, with TFU). Queuing
multiple jobs in the HW will require synchronizing the YUV coefficient
regs updates since they don't get FIFOed with the job.
v2: Change the ioctl to IOW instead of IOWR, always set COEF0, explain
why TFU is AUTH, clarify the syncing docs, drop the unused TFU
interrupt regs (you're expected to use the hub's), don't take
&bo->base for NULL bos.
v3: Fix a little whitespace alignment (noticed by checkpatch), rebase
on drm_sched_job_cleanup() changes.
Signed-off-by: Eric Anholt <eric@anholt.net>
Reviewed-by: Dave Emett <david.emett@broadcom.com> (v2)
Link: https://patchwork.freedesktop.org/patch/264607/
2018-11-28 23:09:25 +00:00
|
|
|
fail:
|
|
|
|
v3d_tfu_job_put(job);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2018-04-30 18:10:58 +00:00
|
|
|
int
|
|
|
|
v3d_gem_init(struct drm_device *dev)
|
|
|
|
{
|
|
|
|
struct v3d_dev *v3d = to_v3d_dev(dev);
|
|
|
|
u32 pt_size = 4096 * 1024;
|
|
|
|
int ret, i;
|
|
|
|
|
|
|
|
for (i = 0; i < V3D_MAX_QUEUES; i++)
|
|
|
|
v3d->queue[i].fence_context = dma_fence_context_alloc(1);
|
|
|
|
|
|
|
|
spin_lock_init(&v3d->mm_lock);
|
|
|
|
spin_lock_init(&v3d->job_lock);
|
|
|
|
mutex_init(&v3d->bo_lock);
|
|
|
|
mutex_init(&v3d->reset_lock);
|
2018-06-06 17:48:51 +00:00
|
|
|
mutex_init(&v3d->sched_lock);
|
2018-04-30 18:10:58 +00:00
|
|
|
|
|
|
|
/* Note: We don't allocate address 0. Various bits of HW
|
|
|
|
* treat 0 as special, such as the occlusion query counters
|
|
|
|
* where 0 means "disabled".
|
|
|
|
*/
|
|
|
|
drm_mm_init(&v3d->mm, 1, pt_size / sizeof(u32) - 1);
|
|
|
|
|
|
|
|
v3d->pt = dma_alloc_wc(v3d->dev, pt_size,
|
|
|
|
&v3d->pt_paddr,
|
|
|
|
GFP_KERNEL | __GFP_NOWARN | __GFP_ZERO);
|
|
|
|
if (!v3d->pt) {
|
|
|
|
drm_mm_takedown(&v3d->mm);
|
|
|
|
dev_err(v3d->dev,
|
|
|
|
"Failed to allocate page tables. "
|
|
|
|
"Please ensure you have CMA enabled.\n");
|
|
|
|
return -ENOMEM;
|
|
|
|
}
|
|
|
|
|
|
|
|
v3d_init_hw_state(v3d);
|
|
|
|
v3d_mmu_set_page_table(v3d);
|
|
|
|
|
|
|
|
ret = v3d_sched_init(v3d);
|
|
|
|
if (ret) {
|
|
|
|
drm_mm_takedown(&v3d->mm);
|
|
|
|
dma_free_coherent(v3d->dev, 4096 * 1024, (void *)v3d->pt,
|
|
|
|
v3d->pt_paddr);
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
v3d_gem_destroy(struct drm_device *dev)
|
|
|
|
{
|
|
|
|
struct v3d_dev *v3d = to_v3d_dev(dev);
|
|
|
|
|
|
|
|
v3d_sched_fini(v3d);
|
|
|
|
|
|
|
|
/* Waiting for exec to finish would need to be done before
|
|
|
|
* unregistering V3D.
|
|
|
|
*/
|
2018-06-05 19:03:01 +00:00
|
|
|
WARN_ON(v3d->bin_job);
|
|
|
|
WARN_ON(v3d->render_job);
|
2018-04-30 18:10:58 +00:00
|
|
|
|
|
|
|
drm_mm_takedown(&v3d->mm);
|
|
|
|
|
|
|
|
dma_free_coherent(v3d->dev, 4096 * 1024, (void *)v3d->pt, v3d->pt_paddr);
|
|
|
|
}
|