Commit 6ec692d6 authored by Dave Airlie's avatar Dave Airlie
Browse files

Merge tag 'drm-etnaviv-next-2025-01-08' of https://git.pengutronix.de/git/lst/linux into drm-next



- cleanups
- add fdinfo memory support
- add explicit reset handling

Signed-off-by: default avatarDave Airlie <airlied@redhat.com>

From: Lucas Stach <l.stach@pengutronix.de>
Link: https://patchwork.freedesktop.org/patch/msgid/41c1e476c6014010247d164ac8d21bd6f922cce1.camel@pengutronix.de
parents 4695a9cc 6bde14ba
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
@@ -9,7 +9,6 @@
#include "etnaviv_gem.h"
#include "etnaviv_gpu.h"
#include "etnaviv_mmu.h"
#include "etnaviv_perfmon.h"

#define SUBALLOC_SIZE		SZ_512K
#define SUBALLOC_GRANULE	SZ_4K
@@ -100,7 +99,7 @@ int etnaviv_cmdbuf_init(struct etnaviv_cmdbuf_suballoc *suballoc,
		mutex_unlock(&suballoc->lock);
		ret = wait_event_interruptible_timeout(suballoc->free_event,
						       suballoc->free_space,
						       msecs_to_jiffies(10 * 1000));
						       secs_to_jiffies(10));
		if (!ret) {
			dev_err(suballoc->dev,
				"Timeout waiting for cmdbuf space\n");
+11 −1
Original line number Diff line number Diff line
@@ -488,7 +488,16 @@ static const struct drm_ioctl_desc etnaviv_ioctls[] = {
	ETNA_IOCTL(PM_QUERY_SIG, pm_query_sig, DRM_RENDER_ALLOW),
};

DEFINE_DRM_GEM_FOPS(fops);
static void etnaviv_show_fdinfo(struct drm_printer *p, struct drm_file *file)
{
	drm_show_memory_stats(p, file);
}

static const struct file_operations fops = {
	.owner = THIS_MODULE,
	DRM_GEM_FOPS,
	.show_fdinfo = drm_show_fdinfo,
};

static const struct drm_driver etnaviv_drm_driver = {
	.driver_features    = DRIVER_GEM | DRIVER_RENDER,
@@ -498,6 +507,7 @@ static const struct drm_driver etnaviv_drm_driver = {
#ifdef CONFIG_DEBUG_FS
	.debugfs_init       = etnaviv_debugfs_init,
#endif
	.show_fdinfo        = etnaviv_show_fdinfo,
	.ioctls             = etnaviv_ioctls,
	.num_ioctls         = DRM_ETNAVIV_NUM_IOCTLS,
	.fops               = &fops,
+26 −2
Original line number Diff line number Diff line
@@ -342,6 +342,7 @@ void *etnaviv_gem_vmap(struct drm_gem_object *obj)
static void *etnaviv_gem_vmap_impl(struct etnaviv_gem_object *obj)
{
	struct page **pages;
	pgprot_t prot;

	lockdep_assert_held(&obj->lock);

@@ -349,8 +350,19 @@ static void *etnaviv_gem_vmap_impl(struct etnaviv_gem_object *obj)
	if (IS_ERR(pages))
		return NULL;

	return vmap(pages, obj->base.size >> PAGE_SHIFT,
			VM_MAP, pgprot_writecombine(PAGE_KERNEL));
	switch (obj->flags & ETNA_BO_CACHE_MASK) {
	case ETNA_BO_CACHED:
		prot = PAGE_KERNEL;
		break;
	case ETNA_BO_UNCACHED:
		prot = pgprot_noncached(PAGE_KERNEL);
		break;
	case ETNA_BO_WC:
	default:
		prot = pgprot_writecombine(PAGE_KERNEL);
	}

	return vmap(pages, obj->base.size >> PAGE_SHIFT, VM_MAP, prot);
}

static inline enum dma_data_direction etnaviv_op_to_dma_dir(u32 op)
@@ -528,6 +540,17 @@ void etnaviv_gem_obj_add(struct drm_device *dev, struct drm_gem_object *obj)
	mutex_unlock(&priv->gem_lock);
}

static enum drm_gem_object_status etnaviv_gem_status(struct drm_gem_object *obj)
{
	struct etnaviv_gem_object *etnaviv_obj = to_etnaviv_bo(obj);
	enum drm_gem_object_status status = 0;

	if (etnaviv_obj->pages)
		status |= DRM_GEM_OBJECT_RESIDENT;

	return status;
}

static const struct vm_operations_struct vm_ops = {
	.fault = etnaviv_gem_fault,
	.open = drm_gem_vm_open,
@@ -541,6 +564,7 @@ static const struct drm_gem_object_funcs etnaviv_gem_object_funcs = {
	.get_sg_table = etnaviv_gem_prime_get_sg_table,
	.vmap = etnaviv_gem_prime_vmap,
	.mmap = etnaviv_gem_mmap,
	.status = etnaviv_gem_status,
	.vm_ops = &vm_ops,
};

+0 −2
Original line number Diff line number Diff line
@@ -44,9 +44,7 @@ struct etnaviv_gem_object {
	u32 flags;

	struct list_head gem_node;
	struct etnaviv_gpu *gpu;     /* non-null if active */
	atomic_t gpu_active;
	u32 access;

	struct page **pages;
	struct sg_table *sgt;
+41 −0
Original line number Diff line number Diff line
@@ -13,6 +13,7 @@
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/regulator/consumer.h>
#include <linux/reset.h>
#include <linux/thermal.h>

#include "etnaviv_cmdbuf.h"
@@ -172,6 +173,29 @@ int etnaviv_gpu_get_param(struct etnaviv_gpu *gpu, u32 param, u64 *value)
	return 0;
}

static int etnaviv_gpu_reset_deassert(struct etnaviv_gpu *gpu)
{
	int ret;

	/*
	 * 32 core clock cycles (slowest clock) required before deassertion
	 * 1 microsecond might match all implementations without computation
	 */
	usleep_range(1, 2);

	ret = reset_control_deassert(gpu->rst);
	if (ret)
		return ret;

	/*
	 * 128 core clock cycles (slowest clock) required before any activity on AHB
	 * 1 microsecond might match all implementations without computation
	 */
	usleep_range(1, 2);

	return 0;
}

static inline bool etnaviv_is_model_rev(struct etnaviv_gpu *gpu, u32 model, u32 revision)
{
	return gpu->identity.model == model &&
@@ -799,6 +823,12 @@ int etnaviv_gpu_init(struct etnaviv_gpu *gpu)
		goto pm_put;
	}

	ret = etnaviv_gpu_reset_deassert(gpu);
	if (ret) {
		dev_err(gpu->dev, "GPU reset deassert failed\n");
		goto fail;
	}

	etnaviv_hw_identify(gpu);

	if (gpu->identity.model == 0) {
@@ -1860,6 +1890,17 @@ static int etnaviv_gpu_platform_probe(struct platform_device *pdev)
	if (IS_ERR(gpu->mmio))
		return PTR_ERR(gpu->mmio);


	/* Get Reset: */
	gpu->rst = devm_reset_control_get_optional_exclusive(&pdev->dev, NULL);
	if (IS_ERR(gpu->rst))
		return dev_err_probe(dev, PTR_ERR(gpu->rst),
				     "failed to get reset\n");

	err = reset_control_assert(gpu->rst);
	if (err)
		return dev_err_probe(dev, err, "failed to assert reset\n");

	/* Get Interrupt: */
	gpu->irq = platform_get_irq(pdev, 0);
	if (gpu->irq < 0)
Loading