Skip to content

Commit

Permalink
Merge branch 'etnaviv/next' of https://git.pengutronix.de/git/lst/linux
Browse files Browse the repository at this point in the history
… into drm-next

Changes this time mostly come down to:
- hook up the DRM GPU scheduler
- prep work for GC7000L support, to be completed in the next cycle

* 'etnaviv/next' of https://git.pengutronix.de/git/lst/linux: (22 commits)
  drm/etnaviv: bump HW job limit to 4
  drm/etnaviv: etnaviv_sched: Staticize functions when possible
  drm/etnaviv: add PTA handling to MMUv2
  drm/etnaviv: add function to load the initial PTA state
  drm/etnaviv: handle security states
  drm/etnaviv: add security handling mode enum
  drm/etnaviv: add hardware database
  drm/etnaviv: add more minor features fields
  drm/etnaviv: update hardware headers from rnndb
  drm/etnaviv: add support for slave interface clock
  drm/etnaviv: split out and optimize MMU fault dumping
  drm/etnaviv: remove the need for a gpu-subsystem DT node
  dt-bindings: etnaviv: add slave interface clock
  drm/etnaviv: use correct format specifier for size_t
  drm/etnaviv: replace hangcheck with scheduler timeout
  drm/etnaviv: lock BOs after all other submit work is done
  drm/etnaviv: move dependency handling to scheduler
  drm/etnaviv: hook up DRM GPU scheduler
  drm/etnaviv: track fences by IDR instead of seqno
  drm/etnaviv: add missing major features field to debugfs
  ...
  • Loading branch information
Dave Airlie committed Mar 22, 2018
2 parents 0c5286a + 4ed75c3 commit f3924ae
Show file tree
Hide file tree
Showing 23 changed files with 1,310 additions and 455 deletions.
24 changes: 3 additions & 21 deletions Documentation/devicetree/bindings/display/etnaviv/etnaviv-drm.txt
Original file line number Diff line number Diff line change
@@ -1,23 +1,3 @@
Etnaviv DRM master device
=========================

The Etnaviv DRM master device is a virtual device needed to list all
Vivante GPU cores that comprise the GPU subsystem.

Required properties:
- compatible: Should be one of
"fsl,imx-gpu-subsystem"
"marvell,dove-gpu-subsystem"
- cores: Should contain a list of phandles pointing to Vivante GPU devices

example:

gpu-subsystem {
compatible = "fsl,imx-gpu-subsystem";
cores = <&gpu_2d>, <&gpu_3d>;
};


Vivante GPU core devices
========================

Expand All @@ -32,7 +12,9 @@ Required properties:
- clocks: should contain one clock for entry in clock-names
see Documentation/devicetree/bindings/clock/clock-bindings.txt
- clock-names:
- "bus": AXI/register clock
- "bus": AXI/master interface clock
- "reg": AHB/slave interface clock
(only required if GPU can gate slave interface independently)
- "core": GPU core clock
- "shader": Shader clock (only required if GPU has feature PIPE_3D)

Expand Down
1 change: 1 addition & 0 deletions drivers/gpu/drm/etnaviv/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ config DRM_ETNAVIV
select WANT_DEV_COREDUMP
select CMA if HAVE_DMA_CONTIGUOUS
select DMA_CMA if HAVE_DMA_CONTIGUOUS
select DRM_SCHED
help
DRM driver for Vivante GPUs.

Expand Down
4 changes: 3 additions & 1 deletion drivers/gpu/drm/etnaviv/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@ etnaviv-y := \
etnaviv_gem_submit.o \
etnaviv_gem.o \
etnaviv_gpu.o \
etnaviv_hwdb.o \
etnaviv_iommu_v2.o \
etnaviv_iommu.o \
etnaviv_mmu.o \
etnaviv_perfmon.o
etnaviv_perfmon.o \
etnaviv_sched.o

obj-$(CONFIG_DRM_ETNAVIV) += etnaviv.o
281 changes: 223 additions & 58 deletions drivers/gpu/drm/etnaviv/common.xml.h

Large diffs are not rendered by default.

18 changes: 18 additions & 0 deletions drivers/gpu/drm/etnaviv/etnaviv_buffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,24 @@ u16 etnaviv_buffer_config_mmuv2(struct etnaviv_gpu *gpu, u32 mtlb_addr, u32 safe
return buffer->user_size / 8;
}

u16 etnaviv_buffer_config_pta(struct etnaviv_gpu *gpu)
{
struct etnaviv_cmdbuf *buffer = &gpu->buffer;

lockdep_assert_held(&gpu->lock);

buffer->user_size = 0;

CMD_LOAD_STATE(buffer, VIVS_MMUv2_PTA_CONFIG,
VIVS_MMUv2_PTA_CONFIG_INDEX(0));

CMD_END(buffer);

buffer->user_size = ALIGN(buffer->user_size, 8);

return buffer->user_size / 8;
}

void etnaviv_buffer_end(struct etnaviv_gpu *gpu)
{
struct etnaviv_cmdbuf *buffer = &gpu->buffer;
Expand Down
52 changes: 35 additions & 17 deletions drivers/gpu/drm/etnaviv/etnaviv_drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -101,12 +101,25 @@ static void load_gpu(struct drm_device *dev)

static int etnaviv_open(struct drm_device *dev, struct drm_file *file)
{
struct etnaviv_drm_private *priv = dev->dev_private;
struct etnaviv_file_private *ctx;
int i;

ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
if (!ctx)
return -ENOMEM;

for (i = 0; i < ETNA_MAX_PIPES; i++) {
struct etnaviv_gpu *gpu = priv->gpu[i];

if (gpu) {
drm_sched_entity_init(&gpu->sched,
&ctx->sched_entity[i],
&gpu->sched.sched_rq[DRM_SCHED_PRIORITY_NORMAL],
32, NULL);
}
}

file->driver_priv = ctx;

return 0;
Expand All @@ -126,6 +139,9 @@ static void etnaviv_postclose(struct drm_device *dev, struct drm_file *file)
if (gpu->lastctx == ctx)
gpu->lastctx = NULL;
mutex_unlock(&gpu->lock);

drm_sched_entity_fini(&gpu->sched,
&ctx->sched_entity[i]);
}
}

Expand Down Expand Up @@ -637,25 +653,21 @@ static int compare_str(struct device *dev, void *data)
static int etnaviv_pdev_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct device_node *node = dev->of_node;
struct component_match *match = NULL;

dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));

if (node) {
if (!dev->platform_data) {
struct device_node *core_node;
int i;

for (i = 0; ; i++) {
core_node = of_parse_phandle(node, "cores", i);
if (!core_node)
break;
for_each_compatible_node(core_node, NULL, "vivante,gc") {
if (!of_device_is_available(core_node))
continue;

drm_of_component_match_add(&pdev->dev, &match,
compare_of, core_node);
of_node_put(core_node);
}
} else if (dev->platform_data) {
} else {
char **names = dev->platform_data;
unsigned i;

Expand All @@ -673,25 +685,18 @@ static int etnaviv_pdev_remove(struct platform_device *pdev)
return 0;
}

static const struct of_device_id dt_match[] = {
{ .compatible = "fsl,imx-gpu-subsystem" },
{ .compatible = "marvell,dove-gpu-subsystem" },
{}
};
MODULE_DEVICE_TABLE(of, dt_match);

static struct platform_driver etnaviv_platform_driver = {
.probe = etnaviv_pdev_probe,
.remove = etnaviv_pdev_remove,
.driver = {
.name = "etnaviv",
.of_match_table = dt_match,
},
};

static int __init etnaviv_init(void)
{
int ret;
struct device_node *np;

etnaviv_validate_init();

Expand All @@ -703,6 +708,19 @@ static int __init etnaviv_init(void)
if (ret != 0)
platform_driver_unregister(&etnaviv_gpu_driver);

/*
* If the DT contains at least one available GPU device, instantiate
* the DRM platform device.
*/
for_each_compatible_node(np, NULL, "vivante,gc") {
if (!of_device_is_available(np))
continue;

platform_device_register_simple("etnaviv", -1, NULL, 0);
of_node_put(np);
break;
}

return ret;
}
module_init(etnaviv_init);
Expand Down
8 changes: 5 additions & 3 deletions drivers/gpu/drm/etnaviv/etnaviv_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#include <drm/drm_fb_helper.h>
#include <drm/drm_gem.h>
#include <drm/etnaviv_drm.h>
#include <drm/gpu_scheduler.h>

struct etnaviv_cmdbuf;
struct etnaviv_gpu;
Expand All @@ -42,11 +43,11 @@ struct etnaviv_gem_object;
struct etnaviv_gem_submit;

struct etnaviv_file_private {
/* currently we don't do anything useful with this.. but when
* per-context address spaces are supported we'd keep track of
/*
* When per-context address spaces are supported we'd keep track of
* the context's page-tables here.
*/
int dummy;
struct drm_sched_entity sched_entity[ETNA_MAX_PIPES];
};

struct etnaviv_drm_private {
Expand Down Expand Up @@ -85,6 +86,7 @@ int etnaviv_gem_new_userptr(struct drm_device *dev, struct drm_file *file,
uintptr_t ptr, u32 size, u32 flags, u32 *handle);
u16 etnaviv_buffer_init(struct etnaviv_gpu *gpu);
u16 etnaviv_buffer_config_mmuv2(struct etnaviv_gpu *gpu, u32 mtlb_addr, u32 safe_addr);
u16 etnaviv_buffer_config_pta(struct etnaviv_gpu *gpu);
void etnaviv_buffer_end(struct etnaviv_gpu *gpu);
void etnaviv_sync_point_queue(struct etnaviv_gpu *gpu, unsigned int event);
void etnaviv_buffer_queue(struct etnaviv_gpu *gpu, u32 exec_state,
Expand Down
21 changes: 19 additions & 2 deletions drivers/gpu/drm/etnaviv/etnaviv_dump.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,13 @@
#include "etnaviv_gem.h"
#include "etnaviv_gpu.h"
#include "etnaviv_mmu.h"
#include "etnaviv_sched.h"
#include "state.xml.h"
#include "state_hi.xml.h"

static bool etnaviv_dump_core = true;
module_param_named(dump_core, etnaviv_dump_core, bool, 0600);

struct core_dump_iterator {
void *start;
struct etnaviv_dump_object_header *hdr;
Expand Down Expand Up @@ -121,10 +125,16 @@ void etnaviv_core_dump(struct etnaviv_gpu *gpu)
struct etnaviv_vram_mapping *vram;
struct etnaviv_gem_object *obj;
struct etnaviv_gem_submit *submit;
struct drm_sched_job *s_job;
unsigned int n_obj, n_bomap_pages;
size_t file_size, mmu_size;
__le64 *bomap, *bomap_start;

/* Only catch the first event, or when manually re-armed */
if (!etnaviv_dump_core)
return;
etnaviv_dump_core = false;

mmu_size = etnaviv_iommu_dump_size(gpu->mmu);

/* We always dump registers, mmu, ring and end marker */
Expand All @@ -135,10 +145,13 @@ void etnaviv_core_dump(struct etnaviv_gpu *gpu)
mmu_size + gpu->buffer.size;

/* Add in the active command buffers */
list_for_each_entry(submit, &gpu->active_submit_list, node) {
spin_lock(&gpu->sched.job_list_lock);
list_for_each_entry(s_job, &gpu->sched.ring_mirror_list, node) {
submit = to_etnaviv_submit(s_job);
file_size += submit->cmdbuf.size;
n_obj++;
}
spin_unlock(&gpu->sched.job_list_lock);

/* Add in the active buffer objects */
list_for_each_entry(vram, &gpu->mmu->mappings, mmu_node) {
Expand Down Expand Up @@ -180,10 +193,14 @@ void etnaviv_core_dump(struct etnaviv_gpu *gpu)
gpu->buffer.size,
etnaviv_cmdbuf_get_va(&gpu->buffer));

list_for_each_entry(submit, &gpu->active_submit_list, node)
spin_lock(&gpu->sched.job_list_lock);
list_for_each_entry(s_job, &gpu->sched.ring_mirror_list, node) {
submit = to_etnaviv_submit(s_job);
etnaviv_core_dump_mem(&iter, ETDUMP_BUF_CMD,
submit->cmdbuf.vaddr, submit->cmdbuf.size,
etnaviv_cmdbuf_get_va(&submit->cmdbuf));
}
spin_unlock(&gpu->sched.job_list_lock);

/* Reserve space for the bomap */
if (n_bomap_pages) {
Expand Down
5 changes: 5 additions & 0 deletions drivers/gpu/drm/etnaviv/etnaviv_gem.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,16 +94,21 @@ struct etnaviv_gem_submit_bo {
u32 flags;
struct etnaviv_gem_object *obj;
struct etnaviv_vram_mapping *mapping;
struct dma_fence *excl;
unsigned int nr_shared;
struct dma_fence **shared;
};

/* Created per submit-ioctl, to track bo's and cmdstream bufs, etc,
* associated with the cmdstream submission for synchronization (and
* make it easier to unwind when things go wrong, etc).
*/
struct etnaviv_gem_submit {
struct drm_sched_job sched_job;
struct kref refcount;
struct etnaviv_gpu *gpu;
struct dma_fence *out_fence, *in_fence;
int out_fence_id;
struct list_head node; /* GPU active submit list */
struct etnaviv_cmdbuf cmdbuf;
bool runtime_resumed;
Expand Down
Loading

0 comments on commit f3924ae

Please sign in to comment.