Unverified Commit 30f8c74c authored by Maxime Ripard's avatar Maxime Ripard
Browse files

drm/vc4: Warn if some v3d code is run on BCM2711



The BCM2711 has a separate driver for the v3d, and thus we can't call
into any of the driver entrypoints that rely on the v3d being there.

Let's add a bunch of checks and complain loudly if that ever happen.

Reviewed-by: default avatarMelissa Wen <mwen@igalia.com>
Signed-off-by: default avatarMaxime Ripard <maxime@cerno.tech>
Link: https://lore.kernel.org/r/20220610115149.964394-15-maxime@cerno.tech
parent d19e00ee
Loading
Loading
Loading
Loading
+49 −0
Original line number Diff line number Diff line
@@ -248,6 +248,9 @@ void vc4_bo_add_to_purgeable_pool(struct vc4_bo *bo)
{
	struct vc4_dev *vc4 = to_vc4_dev(bo->base.base.dev);

	if (WARN_ON_ONCE(vc4->is_vc5))
		return;

	mutex_lock(&vc4->purgeable.lock);
	list_add_tail(&bo->size_head, &vc4->purgeable.list);
	vc4->purgeable.num++;
@@ -259,6 +262,9 @@ static void vc4_bo_remove_from_purgeable_pool_locked(struct vc4_bo *bo)
{
	struct vc4_dev *vc4 = to_vc4_dev(bo->base.base.dev);

	if (WARN_ON_ONCE(vc4->is_vc5))
		return;

	/* list_del_init() is used here because the caller might release
	 * the purgeable lock in order to acquire the madv one and update the
	 * madv status.
@@ -387,6 +393,9 @@ struct drm_gem_object *vc4_create_object(struct drm_device *dev, size_t size)
	struct vc4_dev *vc4 = to_vc4_dev(dev);
	struct vc4_bo *bo;

	if (WARN_ON_ONCE(vc4->is_vc5))
		return ERR_PTR(-ENODEV);

	bo = kzalloc(sizeof(*bo), GFP_KERNEL);
	if (!bo)
		return ERR_PTR(-ENOMEM);
@@ -413,6 +422,9 @@ struct vc4_bo *vc4_bo_create(struct drm_device *dev, size_t unaligned_size,
	struct drm_gem_cma_object *cma_obj;
	struct vc4_bo *bo;

	if (WARN_ON_ONCE(vc4->is_vc5))
		return ERR_PTR(-ENODEV);

	if (size == 0)
		return ERR_PTR(-EINVAL);

@@ -475,9 +487,13 @@ int vc4_bo_dumb_create(struct drm_file *file_priv,
		       struct drm_device *dev,
		       struct drm_mode_create_dumb *args)
{
	struct vc4_dev *vc4 = to_vc4_dev(dev);
	struct vc4_bo *bo = NULL;
	int ret;

	if (WARN_ON_ONCE(vc4->is_vc5))
		return -ENODEV;

	ret = vc4_dumb_fixup_args(args);
	if (ret)
		return ret;
@@ -598,8 +614,12 @@ static void vc4_bo_cache_time_work(struct work_struct *work)

int vc4_bo_inc_usecnt(struct vc4_bo *bo)
{
	struct vc4_dev *vc4 = to_vc4_dev(bo->base.base.dev);
	int ret;

	if (WARN_ON_ONCE(vc4->is_vc5))
		return -ENODEV;

	/* Fast path: if the BO is already retained by someone, no need to
	 * check the madv status.
	 */
@@ -634,6 +654,11 @@ int vc4_bo_inc_usecnt(struct vc4_bo *bo)

void vc4_bo_dec_usecnt(struct vc4_bo *bo)
{
	struct vc4_dev *vc4 = to_vc4_dev(bo->base.base.dev);

	if (WARN_ON_ONCE(vc4->is_vc5))
		return;

	/* Fast path: if the BO is still retained by someone, no need to test
	 * the madv value.
	 */
@@ -753,6 +778,9 @@ int vc4_create_bo_ioctl(struct drm_device *dev, void *data,
	struct vc4_bo *bo = NULL;
	int ret;

	if (WARN_ON_ONCE(vc4->is_vc5))
		return -ENODEV;

	ret = vc4_grab_bin_bo(vc4, vc4file);
	if (ret)
		return ret;
@@ -776,9 +804,13 @@ int vc4_create_bo_ioctl(struct drm_device *dev, void *data,
int vc4_mmap_bo_ioctl(struct drm_device *dev, void *data,
		      struct drm_file *file_priv)
{
	struct vc4_dev *vc4 = to_vc4_dev(dev);
	struct drm_vc4_mmap_bo *args = data;
	struct drm_gem_object *gem_obj;

	if (WARN_ON_ONCE(vc4->is_vc5))
		return -ENODEV;

	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);
@@ -802,6 +834,9 @@ vc4_create_shader_bo_ioctl(struct drm_device *dev, void *data,
	struct vc4_bo *bo = NULL;
	int ret;

	if (WARN_ON_ONCE(vc4->is_vc5))
		return -ENODEV;

	if (args->size == 0)
		return -EINVAL;

@@ -872,11 +907,15 @@ vc4_create_shader_bo_ioctl(struct drm_device *dev, void *data,
int vc4_set_tiling_ioctl(struct drm_device *dev, void *data,
			 struct drm_file *file_priv)
{
	struct vc4_dev *vc4 = to_vc4_dev(dev);
	struct drm_vc4_set_tiling *args = data;
	struct drm_gem_object *gem_obj;
	struct vc4_bo *bo;
	bool t_format;

	if (WARN_ON_ONCE(vc4->is_vc5))
		return -ENODEV;

	if (args->flags != 0)
		return -EINVAL;

@@ -915,10 +954,14 @@ int vc4_set_tiling_ioctl(struct drm_device *dev, void *data,
int vc4_get_tiling_ioctl(struct drm_device *dev, void *data,
			 struct drm_file *file_priv)
{
	struct vc4_dev *vc4 = to_vc4_dev(dev);
	struct drm_vc4_get_tiling *args = data;
	struct drm_gem_object *gem_obj;
	struct vc4_bo *bo;

	if (WARN_ON_ONCE(vc4->is_vc5))
		return -ENODEV;

	if (args->flags != 0 || args->modifier != 0)
		return -EINVAL;

@@ -945,6 +988,9 @@ int vc4_bo_cache_init(struct drm_device *dev)
	struct vc4_dev *vc4 = to_vc4_dev(dev);
	int i;

	if (WARN_ON_ONCE(vc4->is_vc5))
		return -ENODEV;

	/* Create the initial set of BO labels that the kernel will
	 * use.  This lets us avoid a bunch of string reallocation in
	 * the kernel's draw and BO allocation paths.
@@ -1004,6 +1050,9 @@ int vc4_label_bo_ioctl(struct drm_device *dev, void *data,
	struct drm_gem_object *gem_obj;
	int ret = 0, label;

	if (WARN_ON_ONCE(vc4->is_vc5))
		return -ENODEV;

	if (!args->len)
		return -EINVAL;

+11 −0
Original line number Diff line number Diff line
@@ -99,6 +99,9 @@ static int vc4_get_param_ioctl(struct drm_device *dev, void *data,
	if (args->pad != 0)
		return -EINVAL;

	if (WARN_ON_ONCE(vc4->is_vc5))
		return -ENODEV;

	if (!vc4->v3d)
		return -ENODEV;

@@ -142,11 +145,16 @@ static int vc4_get_param_ioctl(struct drm_device *dev, void *data,

static int vc4_open(struct drm_device *dev, struct drm_file *file)
{
	struct vc4_dev *vc4 = to_vc4_dev(dev);
	struct vc4_file *vc4file;

	if (WARN_ON_ONCE(vc4->is_vc5))
		return -ENODEV;

	vc4file = kzalloc(sizeof(*vc4file), GFP_KERNEL);
	if (!vc4file)
		return -ENOMEM;
	vc4file->dev = vc4;

	vc4_perfmon_open_file(vc4file);
	file->driver_priv = vc4file;
@@ -158,6 +166,9 @@ static void vc4_close(struct drm_device *dev, struct drm_file *file)
	struct vc4_dev *vc4 = to_vc4_dev(dev);
	struct vc4_file *vc4file = file->driver_priv;

	if (WARN_ON_ONCE(vc4->is_vc5))
		return;

	if (vc4file->bin_bo_used)
		vc4_v3d_bin_bo_put(vc4);

+6 −0
Original line number Diff line number Diff line
@@ -48,6 +48,8 @@ enum vc4_kernel_bo_type {
 * done. This way, only events related to a specific job will be counted.
 */
struct vc4_perfmon {
	struct vc4_dev *dev;

	/* Tracks the number of users of the perfmon, when this counter reaches
	 * zero the perfmon is destroyed.
	 */
@@ -580,6 +582,8 @@ to_vc4_crtc_state(struct drm_crtc_state *crtc_state)
#define VC4_REG32(reg) { .name = #reg, .offset = reg }

struct vc4_exec_info {
	struct vc4_dev *dev;

	/* Sequence number for this bin/render job. */
	uint64_t seqno;

@@ -701,6 +705,8 @@ struct vc4_exec_info {
 * released when the DRM file is closed should be placed here.
 */
struct vc4_file {
	struct vc4_dev *dev;

	struct {
		struct idr idr;
		struct mutex lock;
+40 −0
Original line number Diff line number Diff line
@@ -76,6 +76,9 @@ vc4_get_hang_state_ioctl(struct drm_device *dev, void *data,
	u32 i;
	int ret = 0;

	if (WARN_ON_ONCE(vc4->is_vc5))
		return -ENODEV;

	if (!vc4->v3d) {
		DRM_DEBUG("VC4_GET_HANG_STATE with no VC4 V3D probed\n");
		return -ENODEV;
@@ -386,6 +389,9 @@ vc4_wait_for_seqno(struct drm_device *dev, uint64_t seqno, uint64_t timeout_ns,
	unsigned long timeout_expire;
	DEFINE_WAIT(wait);

	if (WARN_ON_ONCE(vc4->is_vc5))
		return -ENODEV;

	if (vc4->finished_seqno >= seqno)
		return 0;

@@ -468,6 +474,9 @@ vc4_submit_next_bin_job(struct drm_device *dev)
	struct vc4_dev *vc4 = to_vc4_dev(dev);
	struct vc4_exec_info *exec;

	if (WARN_ON_ONCE(vc4->is_vc5))
		return;

again:
	exec = vc4_first_bin_job(vc4);
	if (!exec)
@@ -513,6 +522,9 @@ vc4_submit_next_render_job(struct drm_device *dev)
	if (!exec)
		return;

	if (WARN_ON_ONCE(vc4->is_vc5))
		return;

	/* A previous RCL may have written to one of our textures, and
	 * our full cache flush at bin time may have occurred before
	 * that RCL completed.  Flush the texture cache now, but not
@@ -531,6 +543,9 @@ vc4_move_job_to_render(struct drm_device *dev, struct vc4_exec_info *exec)
	struct vc4_dev *vc4 = to_vc4_dev(dev);
	bool was_empty = list_empty(&vc4->render_job_list);

	if (WARN_ON_ONCE(vc4->is_vc5))
		return;

	list_move_tail(&exec->head, &vc4->render_job_list);
	if (was_empty)
		vc4_submit_next_render_job(dev);
@@ -997,6 +1012,9 @@ vc4_job_handle_completed(struct vc4_dev *vc4)
	unsigned long irqflags;
	struct vc4_seqno_cb *cb, *cb_temp;

	if (WARN_ON_ONCE(vc4->is_vc5))
		return;

	spin_lock_irqsave(&vc4->job_lock, irqflags);
	while (!list_empty(&vc4->job_done_list)) {
		struct vc4_exec_info *exec =
@@ -1033,6 +1051,9 @@ int vc4_queue_seqno_cb(struct drm_device *dev,
	struct vc4_dev *vc4 = to_vc4_dev(dev);
	unsigned long irqflags;

	if (WARN_ON_ONCE(vc4->is_vc5))
		return -ENODEV;

	cb->func = func;
	INIT_WORK(&cb->work, vc4_seqno_cb_work);

@@ -1083,8 +1104,12 @@ int
vc4_wait_seqno_ioctl(struct drm_device *dev, void *data,
		     struct drm_file *file_priv)
{
	struct vc4_dev *vc4 = to_vc4_dev(dev);
	struct drm_vc4_wait_seqno *args = data;

	if (WARN_ON_ONCE(vc4->is_vc5))
		return -ENODEV;

	return vc4_wait_for_seqno_ioctl_helper(dev, args->seqno,
					       &args->timeout_ns);
}
@@ -1093,11 +1118,15 @@ int
vc4_wait_bo_ioctl(struct drm_device *dev, void *data,
		  struct drm_file *file_priv)
{
	struct vc4_dev *vc4 = to_vc4_dev(dev);
	int ret;
	struct drm_vc4_wait_bo *args = data;
	struct drm_gem_object *gem_obj;
	struct vc4_bo *bo;

	if (WARN_ON_ONCE(vc4->is_vc5))
		return -ENODEV;

	if (args->pad != 0)
		return -EINVAL;

@@ -1144,6 +1173,9 @@ vc4_submit_cl_ioctl(struct drm_device *dev, void *data,
				  args->shader_rec_size,
				  args->bo_handle_count);

	if (WARN_ON_ONCE(vc4->is_vc5))
		return -ENODEV;

	if (!vc4->v3d) {
		DRM_DEBUG("VC4_SUBMIT_CL with no VC4 V3D probed\n");
		return -ENODEV;
@@ -1167,6 +1199,7 @@ vc4_submit_cl_ioctl(struct drm_device *dev, void *data,
		DRM_ERROR("malloc failure on exec struct\n");
		return -ENOMEM;
	}
	exec->dev = vc4;

	ret = vc4_v3d_pm_get(vc4);
	if (ret) {
@@ -1276,6 +1309,9 @@ int vc4_gem_init(struct drm_device *dev)
{
	struct vc4_dev *vc4 = to_vc4_dev(dev);

	if (WARN_ON_ONCE(vc4->is_vc5))
		return -ENODEV;

	vc4->dma_fence_context = dma_fence_context_alloc(1);

	INIT_LIST_HEAD(&vc4->bin_job_list);
@@ -1321,11 +1357,15 @@ static void vc4_gem_destroy(struct drm_device *dev, void *unused)
int vc4_gem_madvise_ioctl(struct drm_device *dev, void *data,
			  struct drm_file *file_priv)
{
	struct vc4_dev *vc4 = to_vc4_dev(dev);
	struct drm_vc4_gem_madvise *args = data;
	struct drm_gem_object *gem_obj;
	struct vc4_bo *bo;
	int ret;

	if (WARN_ON_ONCE(vc4->is_vc5))
		return -ENODEV;

	switch (args->madv) {
	case VC4_MADV_DONTNEED:
	case VC4_MADV_WILLNEED:
+16 −0
Original line number Diff line number Diff line
@@ -265,6 +265,9 @@ vc4_irq_enable(struct drm_device *dev)
{
	struct vc4_dev *vc4 = to_vc4_dev(dev);

	if (WARN_ON_ONCE(vc4->is_vc5))
		return;

	if (!vc4->v3d)
		return;

@@ -279,6 +282,9 @@ vc4_irq_disable(struct drm_device *dev)
{
	struct vc4_dev *vc4 = to_vc4_dev(dev);

	if (WARN_ON_ONCE(vc4->is_vc5))
		return;

	if (!vc4->v3d)
		return;

@@ -296,8 +302,12 @@ vc4_irq_disable(struct drm_device *dev)

int vc4_irq_install(struct drm_device *dev, int irq)
{
	struct vc4_dev *vc4 = to_vc4_dev(dev);
	int ret;

	if (WARN_ON_ONCE(vc4->is_vc5))
		return -ENODEV;

	if (irq == IRQ_NOTCONNECTED)
		return -ENOTCONN;

@@ -316,6 +326,9 @@ void vc4_irq_uninstall(struct drm_device *dev)
{
	struct vc4_dev *vc4 = to_vc4_dev(dev);

	if (WARN_ON_ONCE(vc4->is_vc5))
		return;

	vc4_irq_disable(dev);
	free_irq(vc4->irq, dev);
}
@@ -326,6 +339,9 @@ void vc4_irq_reset(struct drm_device *dev)
	struct vc4_dev *vc4 = to_vc4_dev(dev);
	unsigned long irqflags;

	if (WARN_ON_ONCE(vc4->is_vc5))
		return;

	/* Acknowledge any stale IRQs. */
	V3D_WRITE(V3D_INTCTL, V3D_DRIVER_IRQS);

Loading