Commit de487e43 authored by Dave Airlie's avatar Dave Airlie

Merge branch 'etnaviv/next' of https://git.pengutronix.de/git/lst/linux into drm-next

- fix for potential out-of-bounds reads in the perfmon ioctl
  implementation from Christian
- override to expose proper feature flags for the GC400 found on the
  STM32MP1 SoC, also from Christian
- Guido fixed an issue where we would spuriously fail to enter
  runtime suspend due to a new GPU engine status bit on GC7000
- tree-wide change from Gustavo to get rid of zero-length arrays
- fix for missed TS cache flush on GC7000, leading to spurious
  MMU faults from me
- request pages from DMA32 zone on systems where we can't address
  all present memory from me
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
From: Lucas Stach <l.stach@pengutronix.de>
Link: https://patchwork.freedesktop.org/patch/msgid/74d9c6d19099fdba6c6795204a6aa445b7930c79.camel@pengutronix.de
parents cb7adfd6 f232d9ec
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include "common.xml.h" #include "common.xml.h"
#include "state.xml.h" #include "state.xml.h"
#include "state_blt.xml.h"
#include "state_hi.xml.h" #include "state_hi.xml.h"
#include "state_3d.xml.h" #include "state_3d.xml.h"
#include "cmdstream.xml.h" #include "cmdstream.xml.h"
...@@ -233,6 +234,8 @@ void etnaviv_buffer_end(struct etnaviv_gpu *gpu) ...@@ -233,6 +234,8 @@ void etnaviv_buffer_end(struct etnaviv_gpu *gpu)
struct etnaviv_cmdbuf *buffer = &gpu->buffer; struct etnaviv_cmdbuf *buffer = &gpu->buffer;
unsigned int waitlink_offset = buffer->user_size - 16; unsigned int waitlink_offset = buffer->user_size - 16;
u32 link_target, flush = 0; u32 link_target, flush = 0;
bool has_blt = !!(gpu->identity.minor_features5 &
chipMinorFeatures5_BLT_ENGINE);
lockdep_assert_held(&gpu->lock); lockdep_assert_held(&gpu->lock);
...@@ -248,16 +251,38 @@ void etnaviv_buffer_end(struct etnaviv_gpu *gpu) ...@@ -248,16 +251,38 @@ void etnaviv_buffer_end(struct etnaviv_gpu *gpu)
if (flush) { if (flush) {
unsigned int dwords = 7; unsigned int dwords = 7;
if (has_blt)
dwords += 10;
link_target = etnaviv_buffer_reserve(gpu, buffer, dwords); link_target = etnaviv_buffer_reserve(gpu, buffer, dwords);
CMD_SEM(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_PE); CMD_SEM(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_PE);
CMD_STALL(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_PE); CMD_STALL(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_PE);
if (has_blt) {
CMD_LOAD_STATE(buffer, VIVS_BLT_ENABLE, 0x1);
CMD_SEM(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_BLT);
CMD_STALL(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_BLT);
CMD_LOAD_STATE(buffer, VIVS_BLT_ENABLE, 0x0);
}
CMD_LOAD_STATE(buffer, VIVS_GL_FLUSH_CACHE, flush); CMD_LOAD_STATE(buffer, VIVS_GL_FLUSH_CACHE, flush);
if (gpu->exec_state == ETNA_PIPE_3D) if (gpu->exec_state == ETNA_PIPE_3D) {
if (has_blt) {
CMD_LOAD_STATE(buffer, VIVS_BLT_ENABLE, 0x1);
CMD_LOAD_STATE(buffer, VIVS_BLT_SET_COMMAND, 0x1);
CMD_LOAD_STATE(buffer, VIVS_BLT_ENABLE, 0x0);
} else {
CMD_LOAD_STATE(buffer, VIVS_TS_FLUSH_CACHE, CMD_LOAD_STATE(buffer, VIVS_TS_FLUSH_CACHE,
VIVS_TS_FLUSH_CACHE_FLUSH); VIVS_TS_FLUSH_CACHE_FLUSH);
}
}
CMD_SEM(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_PE); CMD_SEM(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_PE);
CMD_STALL(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_PE); CMD_STALL(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_PE);
if (has_blt) {
CMD_LOAD_STATE(buffer, VIVS_BLT_ENABLE, 0x1);
CMD_SEM(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_BLT);
CMD_STALL(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_BLT);
CMD_LOAD_STATE(buffer, VIVS_BLT_ENABLE, 0x0);
}
CMD_END(buffer); CMD_END(buffer);
etnaviv_buffer_replace_wait(buffer, waitlink_offset, etnaviv_buffer_replace_wait(buffer, waitlink_offset,
...@@ -323,6 +348,8 @@ void etnaviv_buffer_queue(struct etnaviv_gpu *gpu, u32 exec_state, ...@@ -323,6 +348,8 @@ void etnaviv_buffer_queue(struct etnaviv_gpu *gpu, u32 exec_state,
bool switch_mmu_context = gpu->mmu_context != mmu_context; bool switch_mmu_context = gpu->mmu_context != mmu_context;
unsigned int new_flush_seq = READ_ONCE(gpu->mmu_context->flush_seq); unsigned int new_flush_seq = READ_ONCE(gpu->mmu_context->flush_seq);
bool need_flush = switch_mmu_context || gpu->flush_seq != new_flush_seq; bool need_flush = switch_mmu_context || gpu->flush_seq != new_flush_seq;
bool has_blt = !!(gpu->identity.minor_features5 &
chipMinorFeatures5_BLT_ENGINE);
lockdep_assert_held(&gpu->lock); lockdep_assert_held(&gpu->lock);
...@@ -433,6 +460,15 @@ void etnaviv_buffer_queue(struct etnaviv_gpu *gpu, u32 exec_state, ...@@ -433,6 +460,15 @@ void etnaviv_buffer_queue(struct etnaviv_gpu *gpu, u32 exec_state,
* 2 semaphore stall + 1 event + 1 wait + 1 link. * 2 semaphore stall + 1 event + 1 wait + 1 link.
*/ */
return_dwords = 7; return_dwords = 7;
/*
* When the BLT engine is present we need 6 more dwords in the return
* target: 3 enable/flush/disable + 4 enable/semaphore stall/disable,
* but we don't need the normal TS flush state.
*/
if (has_blt)
return_dwords += 6;
return_target = etnaviv_buffer_reserve(gpu, buffer, return_dwords); return_target = etnaviv_buffer_reserve(gpu, buffer, return_dwords);
CMD_LINK(cmdbuf, return_dwords, return_target); CMD_LINK(cmdbuf, return_dwords, return_target);
...@@ -447,11 +483,25 @@ void etnaviv_buffer_queue(struct etnaviv_gpu *gpu, u32 exec_state, ...@@ -447,11 +483,25 @@ void etnaviv_buffer_queue(struct etnaviv_gpu *gpu, u32 exec_state,
CMD_LOAD_STATE(buffer, VIVS_GL_FLUSH_CACHE, CMD_LOAD_STATE(buffer, VIVS_GL_FLUSH_CACHE,
VIVS_GL_FLUSH_CACHE_DEPTH | VIVS_GL_FLUSH_CACHE_DEPTH |
VIVS_GL_FLUSH_CACHE_COLOR); VIVS_GL_FLUSH_CACHE_COLOR);
if (has_blt) {
CMD_LOAD_STATE(buffer, VIVS_BLT_ENABLE, 0x1);
CMD_LOAD_STATE(buffer, VIVS_BLT_SET_COMMAND, 0x1);
CMD_LOAD_STATE(buffer, VIVS_BLT_ENABLE, 0x0);
} else {
CMD_LOAD_STATE(buffer, VIVS_TS_FLUSH_CACHE, CMD_LOAD_STATE(buffer, VIVS_TS_FLUSH_CACHE,
VIVS_TS_FLUSH_CACHE_FLUSH); VIVS_TS_FLUSH_CACHE_FLUSH);
} }
}
CMD_SEM(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_PE); CMD_SEM(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_PE);
CMD_STALL(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_PE); CMD_STALL(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_PE);
if (has_blt) {
CMD_LOAD_STATE(buffer, VIVS_BLT_ENABLE, 0x1);
CMD_SEM(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_BLT);
CMD_STALL(buffer, SYNC_RECIPIENT_FE, SYNC_RECIPIENT_BLT);
CMD_LOAD_STATE(buffer, VIVS_BLT_ENABLE, 0x0);
}
CMD_LOAD_STATE(buffer, VIVS_GL_EVENT, VIVS_GL_EVENT_EVENT_ID(event) | CMD_LOAD_STATE(buffer, VIVS_GL_EVENT, VIVS_GL_EVENT_EVENT_ID(event) |
VIVS_GL_EVENT_FROM_PE); VIVS_GL_EVENT_FROM_PE);
CMD_WAIT(buffer); CMD_WAIT(buffer);
......
...@@ -551,6 +551,7 @@ static int etnaviv_bind(struct device *dev) ...@@ -551,6 +551,7 @@ static int etnaviv_bind(struct device *dev)
mutex_init(&priv->gem_lock); mutex_init(&priv->gem_lock);
INIT_LIST_HEAD(&priv->gem_list); INIT_LIST_HEAD(&priv->gem_list);
priv->num_gpus = 0; priv->num_gpus = 0;
priv->shm_gfp_mask = GFP_HIGHUSER | __GFP_RETRY_MAYFAIL | __GFP_NOWARN;
priv->cmdbuf_suballoc = etnaviv_cmdbuf_suballoc_new(drm->dev); priv->cmdbuf_suballoc = etnaviv_cmdbuf_suballoc_new(drm->dev);
if (IS_ERR(priv->cmdbuf_suballoc)) { if (IS_ERR(priv->cmdbuf_suballoc)) {
......
...@@ -35,6 +35,7 @@ struct etnaviv_drm_private { ...@@ -35,6 +35,7 @@ struct etnaviv_drm_private {
int num_gpus; int num_gpus;
struct device_dma_parameters dma_parms; struct device_dma_parameters dma_parms;
struct etnaviv_gpu *gpu[ETNA_MAX_PIPES]; struct etnaviv_gpu *gpu[ETNA_MAX_PIPES];
gfp_t shm_gfp_mask;
struct etnaviv_cmdbuf_suballoc *cmdbuf_suballoc; struct etnaviv_cmdbuf_suballoc *cmdbuf_suballoc;
struct etnaviv_iommu_global *mmu_global; struct etnaviv_iommu_global *mmu_global;
......
...@@ -602,6 +602,7 @@ static int etnaviv_gem_new_impl(struct drm_device *dev, u32 size, u32 flags, ...@@ -602,6 +602,7 @@ static int etnaviv_gem_new_impl(struct drm_device *dev, u32 size, u32 flags,
int etnaviv_gem_new_handle(struct drm_device *dev, struct drm_file *file, int etnaviv_gem_new_handle(struct drm_device *dev, struct drm_file *file,
u32 size, u32 flags, u32 *handle) u32 size, u32 flags, u32 *handle)
{ {
struct etnaviv_drm_private *priv = dev->dev_private;
struct drm_gem_object *obj = NULL; struct drm_gem_object *obj = NULL;
int ret; int ret;
...@@ -624,8 +625,7 @@ int etnaviv_gem_new_handle(struct drm_device *dev, struct drm_file *file, ...@@ -624,8 +625,7 @@ int etnaviv_gem_new_handle(struct drm_device *dev, struct drm_file *file,
* above new_inode() why this is required _and_ expected if you're * above new_inode() why this is required _and_ expected if you're
* going to pin these pages. * going to pin these pages.
*/ */
mapping_set_gfp_mask(obj->filp->f_mapping, GFP_HIGHUSER | mapping_set_gfp_mask(obj->filp->f_mapping, priv->shm_gfp_mask);
__GFP_RETRY_MAYFAIL | __GFP_NOWARN);
etnaviv_gem_obj_add(dev, obj); etnaviv_gem_obj_add(dev, obj);
......
...@@ -105,7 +105,7 @@ struct etnaviv_gem_submit { ...@@ -105,7 +105,7 @@ struct etnaviv_gem_submit {
unsigned int nr_pmrs; unsigned int nr_pmrs;
struct etnaviv_perfmon_request *pmrs; struct etnaviv_perfmon_request *pmrs;
unsigned int nr_bos; unsigned int nr_bos;
struct etnaviv_gem_submit_bo bos[0]; struct etnaviv_gem_submit_bo bos[];
/* No new members here, the previous one is variable-length! */ /* No new members here, the previous one is variable-length! */
}; };
......
...@@ -333,9 +333,13 @@ static void etnaviv_hw_identify(struct etnaviv_gpu *gpu) ...@@ -333,9 +333,13 @@ static void etnaviv_hw_identify(struct etnaviv_gpu *gpu)
gpu->identity.revision = etnaviv_field(chipIdentity, gpu->identity.revision = etnaviv_field(chipIdentity,
VIVS_HI_CHIP_IDENTITY_REVISION); VIVS_HI_CHIP_IDENTITY_REVISION);
} else { } else {
u32 chipDate = gpu_read(gpu, VIVS_HI_CHIP_DATE);
gpu->identity.model = gpu_read(gpu, VIVS_HI_CHIP_MODEL); gpu->identity.model = gpu_read(gpu, VIVS_HI_CHIP_MODEL);
gpu->identity.revision = gpu_read(gpu, VIVS_HI_CHIP_REV); gpu->identity.revision = gpu_read(gpu, VIVS_HI_CHIP_REV);
gpu->identity.product_id = gpu_read(gpu, VIVS_HI_CHIP_PRODUCT_ID);
gpu->identity.customer_id = gpu_read(gpu, VIVS_HI_CHIP_CUSTOMER_ID);
gpu->identity.eco_id = gpu_read(gpu, VIVS_HI_CHIP_ECO_ID);
/* /*
* !!!! HACK ALERT !!!! * !!!! HACK ALERT !!!!
...@@ -350,7 +354,6 @@ static void etnaviv_hw_identify(struct etnaviv_gpu *gpu) ...@@ -350,7 +354,6 @@ static void etnaviv_hw_identify(struct etnaviv_gpu *gpu)
/* Another special case */ /* Another special case */
if (etnaviv_is_model_rev(gpu, GC300, 0x2201)) { if (etnaviv_is_model_rev(gpu, GC300, 0x2201)) {
u32 chipDate = gpu_read(gpu, VIVS_HI_CHIP_DATE);
u32 chipTime = gpu_read(gpu, VIVS_HI_CHIP_TIME); u32 chipTime = gpu_read(gpu, VIVS_HI_CHIP_TIME);
if (chipDate == 0x20080814 && chipTime == 0x12051100) { if (chipDate == 0x20080814 && chipTime == 0x12051100) {
...@@ -373,6 +376,12 @@ static void etnaviv_hw_identify(struct etnaviv_gpu *gpu) ...@@ -373,6 +376,12 @@ static void etnaviv_hw_identify(struct etnaviv_gpu *gpu)
gpu->identity.model = chipModel_GC3000; gpu->identity.model = chipModel_GC3000;
gpu->identity.revision &= 0xffff; gpu->identity.revision &= 0xffff;
} }
if (etnaviv_is_model_rev(gpu, GC1000, 0x5037) && (chipDate == 0x20120617))
gpu->identity.eco_id = 1;
if (etnaviv_is_model_rev(gpu, GC320, 0x5303) && (chipDate == 0x20140511))
gpu->identity.eco_id = 1;
} }
dev_info(gpu->dev, "model: GC%x, revision: %x\n", dev_info(gpu->dev, "model: GC%x, revision: %x\n",
...@@ -506,7 +515,7 @@ static int etnaviv_hw_reset(struct etnaviv_gpu *gpu) ...@@ -506,7 +515,7 @@ static int etnaviv_hw_reset(struct etnaviv_gpu *gpu)
/* read idle register. */ /* read idle register. */
idle = gpu_read(gpu, VIVS_HI_IDLE_STATE); idle = gpu_read(gpu, VIVS_HI_IDLE_STATE);
/* try reseting again if FE it not idle */ /* try resetting again if FE is not idle */
if ((idle & VIVS_HI_IDLE_STATE_FE) == 0) { if ((idle & VIVS_HI_IDLE_STATE_FE) == 0) {
dev_dbg(gpu->dev, "FE is not idle\n"); dev_dbg(gpu->dev, "FE is not idle\n");
continue; continue;
...@@ -772,6 +781,14 @@ int etnaviv_gpu_init(struct etnaviv_gpu *gpu) ...@@ -772,6 +781,14 @@ int etnaviv_gpu_init(struct etnaviv_gpu *gpu)
gpu->identity.features &= ~chipFeatures_FAST_CLEAR; gpu->identity.features &= ~chipFeatures_FAST_CLEAR;
} }
/*
* If the GPU is part of a system with DMA addressing limitations,
* request pages for our SHM backend buffers from the DMA32 zone to
* hopefully avoid performance killing SWIOTLB bounce buffering.
*/
if (dma_addressing_limited(gpu->dev))
priv->shm_gfp_mask |= GFP_DMA32;
/* Create buffer: */ /* Create buffer: */
ret = etnaviv_cmdbuf_init(priv->cmdbuf_suballoc, &gpu->buffer, ret = etnaviv_cmdbuf_init(priv->cmdbuf_suballoc, &gpu->buffer,
PAGE_SIZE); PAGE_SIZE);
...@@ -851,6 +868,13 @@ int etnaviv_gpu_debugfs(struct etnaviv_gpu *gpu, struct seq_file *m) ...@@ -851,6 +868,13 @@ int etnaviv_gpu_debugfs(struct etnaviv_gpu *gpu, struct seq_file *m)
verify_dma(gpu, &debug); verify_dma(gpu, &debug);
seq_puts(m, "\tidentity\n");
seq_printf(m, "\t model: 0x%x\n", gpu->identity.model);
seq_printf(m, "\t revision: 0x%x\n", gpu->identity.revision);
seq_printf(m, "\t product_id: 0x%x\n", gpu->identity.product_id);
seq_printf(m, "\t customer_id: 0x%x\n", gpu->identity.customer_id);
seq_printf(m, "\t eco_id: 0x%x\n", gpu->identity.eco_id);
seq_puts(m, "\tfeatures\n"); seq_puts(m, "\tfeatures\n");
seq_printf(m, "\t major_features: 0x%08x\n", seq_printf(m, "\t major_features: 0x%08x\n",
gpu->identity.features); gpu->identity.features);
...@@ -930,6 +954,20 @@ int etnaviv_gpu_debugfs(struct etnaviv_gpu *gpu, struct seq_file *m) ...@@ -930,6 +954,20 @@ int etnaviv_gpu_debugfs(struct etnaviv_gpu *gpu, struct seq_file *m)
seq_puts(m, "\t FP is not idle\n"); seq_puts(m, "\t FP is not idle\n");
if ((idle & VIVS_HI_IDLE_STATE_TS) == 0) if ((idle & VIVS_HI_IDLE_STATE_TS) == 0)
seq_puts(m, "\t TS is not idle\n"); seq_puts(m, "\t TS is not idle\n");
if ((idle & VIVS_HI_IDLE_STATE_BL) == 0)
seq_puts(m, "\t BL is not idle\n");
if ((idle & VIVS_HI_IDLE_STATE_ASYNCFE) == 0)
seq_puts(m, "\t ASYNCFE is not idle\n");
if ((idle & VIVS_HI_IDLE_STATE_MC) == 0)
seq_puts(m, "\t MC is not idle\n");
if ((idle & VIVS_HI_IDLE_STATE_PPA) == 0)
seq_puts(m, "\t PPA is not idle\n");
if ((idle & VIVS_HI_IDLE_STATE_WD) == 0)
seq_puts(m, "\t WD is not idle\n");
if ((idle & VIVS_HI_IDLE_STATE_NN) == 0)
seq_puts(m, "\t NN is not idle\n");
if ((idle & VIVS_HI_IDLE_STATE_TP) == 0)
seq_puts(m, "\t TP is not idle\n");
if (idle & VIVS_HI_IDLE_STATE_AXI_LP) if (idle & VIVS_HI_IDLE_STATE_AXI_LP)
seq_puts(m, "\t AXI low power mode\n"); seq_puts(m, "\t AXI low power mode\n");
...@@ -1805,11 +1843,15 @@ static int etnaviv_gpu_rpm_suspend(struct device *dev) ...@@ -1805,11 +1843,15 @@ static int etnaviv_gpu_rpm_suspend(struct device *dev)
if (atomic_read(&gpu->sched.hw_rq_count)) if (atomic_read(&gpu->sched.hw_rq_count))
return -EBUSY; return -EBUSY;
/* Check whether the hardware (except FE) is idle */ /* Check whether the hardware (except FE and MC) is idle */
mask = gpu->idle_mask & ~VIVS_HI_IDLE_STATE_FE; mask = gpu->idle_mask & ~(VIVS_HI_IDLE_STATE_FE |
VIVS_HI_IDLE_STATE_MC);
idle = gpu_read(gpu, VIVS_HI_IDLE_STATE) & mask; idle = gpu_read(gpu, VIVS_HI_IDLE_STATE) & mask;
if (idle != mask) if (idle != mask) {
dev_warn_ratelimited(dev, "GPU not yet idle, mask: 0x%08x\n",
idle);
return -EBUSY; return -EBUSY;
}
return etnaviv_gpu_hw_suspend(gpu); return etnaviv_gpu_hw_suspend(gpu);
} }
......
...@@ -15,11 +15,11 @@ struct etnaviv_gem_submit; ...@@ -15,11 +15,11 @@ struct etnaviv_gem_submit;
struct etnaviv_vram_mapping; struct etnaviv_vram_mapping;
struct etnaviv_chip_identity { struct etnaviv_chip_identity {
/* Chip model. */
u32 model; u32 model;
/* Revision value.*/
u32 revision; u32 revision;
u32 product_id;
u32 customer_id;
u32 eco_id;
/* Supported feature fields. */ /* Supported feature fields. */
u32 features; u32 features;
......
...@@ -6,9 +6,43 @@ ...@@ -6,9 +6,43 @@
#include "etnaviv_gpu.h" #include "etnaviv_gpu.h"
static const struct etnaviv_chip_identity etnaviv_chip_identities[] = { static const struct etnaviv_chip_identity etnaviv_chip_identities[] = {
{
.model = 0x400,
.revision = 0x4652,
.product_id = 0x70001,
.customer_id = 0x100,
.eco_id = 0,
.stream_count = 4,
.register_max = 64,
.thread_count = 128,
.shader_core_count = 1,
.vertex_cache_size = 8,
.vertex_output_buffer_size = 1024,
.pixel_pipes = 1,
.instruction_count = 256,
.num_constants = 320,
.buffer_size = 0,
.varyings_count = 8,
.features = 0xa0e9e004,
.minor_features0 = 0xe1299fff,
.minor_features1 = 0xbe13b219,
.minor_features2 = 0xce110010,
.minor_features3 = 0x8000001,
.minor_features4 = 0x20102,
.minor_features5 = 0x120000,
.minor_features6 = 0x0,
.minor_features7 = 0x0,
.minor_features8 = 0x0,
.minor_features9 = 0x0,
.minor_features10 = 0x0,
.minor_features11 = 0x0,
},
{ {
.model = 0x7000, .model = 0x7000,
.revision = 0x6214, .revision = 0x6214,
.product_id = ~0U,
.customer_id = ~0U,
.eco_id = ~0U,
.stream_count = 16, .stream_count = 16,
.register_max = 64, .register_max = 64,
.thread_count = 1024, .thread_count = 1024,
...@@ -43,7 +77,13 @@ bool etnaviv_fill_identity_from_hwdb(struct etnaviv_gpu *gpu) ...@@ -43,7 +77,13 @@ bool etnaviv_fill_identity_from_hwdb(struct etnaviv_gpu *gpu)
for (i = 0; i < ARRAY_SIZE(etnaviv_chip_identities); i++) { for (i = 0; i < ARRAY_SIZE(etnaviv_chip_identities); i++) {
if (etnaviv_chip_identities[i].model == ident->model && if (etnaviv_chip_identities[i].model == ident->model &&
etnaviv_chip_identities[i].revision == ident->revision) { etnaviv_chip_identities[i].revision == ident->revision &&
(etnaviv_chip_identities[i].product_id == ident->product_id ||
etnaviv_chip_identities[i].product_id == ~0U) &&
(etnaviv_chip_identities[i].customer_id == ident->customer_id ||
etnaviv_chip_identities[i].customer_id == ~0U) &&
(etnaviv_chip_identities[i].eco_id == ident->eco_id ||
etnaviv_chip_identities[i].eco_id == ~0U)) {
memcpy(ident, &etnaviv_chip_identities[i], memcpy(ident, &etnaviv_chip_identities[i],
sizeof(*ident)); sizeof(*ident));
return true; return true;
......
...@@ -32,6 +32,7 @@ struct etnaviv_pm_domain { ...@@ -32,6 +32,7 @@ struct etnaviv_pm_domain {
}; };
struct etnaviv_pm_domain_meta { struct etnaviv_pm_domain_meta {
unsigned int feature;
const struct etnaviv_pm_domain *domains; const struct etnaviv_pm_domain *domains;
u32 nr_domains; u32 nr_domains;
}; };
...@@ -410,36 +411,78 @@ static const struct etnaviv_pm_domain doms_vg[] = { ...@@ -410,36 +411,78 @@ static const struct etnaviv_pm_domain doms_vg[] = {
static const struct etnaviv_pm_domain_meta doms_meta[] = { static const struct etnaviv_pm_domain_meta doms_meta[] = {
{ {
.feature = chipFeatures_PIPE_3D,
.nr_domains = ARRAY_SIZE(doms_3d), .nr_domains = ARRAY_SIZE(doms_3d),
.domains = &doms_3d[0] .domains = &doms_3d[0]
}, },
{ {
.feature = chipFeatures_PIPE_2D,
.nr_domains = ARRAY_SIZE(doms_2d), .nr_domains = ARRAY_SIZE(doms_2d),
.domains = &doms_2d[0] .domains = &doms_2d[0]
}, },
{ {
.feature = chipFeatures_PIPE_VG,
.nr_domains = ARRAY_SIZE(doms_vg), .nr_domains = ARRAY_SIZE(doms_vg),
.domains = &doms_vg[0] .domains = &doms_vg[0]
} }
}; };
static unsigned int num_pm_domains(const struct etnaviv_gpu *gpu)
{
unsigned int num = 0, i;
for (i = 0; i < ARRAY_SIZE(doms_meta); i++) {
const struct etnaviv_pm_domain_meta *meta = &doms_meta[i];
if (gpu->identity.features & meta->feature)
num += meta->nr_domains;
}
return num;
}
static const struct etnaviv_pm_domain *pm_domain(const struct etnaviv_gpu *gpu,
unsigned int index)
{
const struct etnaviv_pm_domain *domain = NULL;
unsigned int offset = 0, i;
for (i = 0; i < ARRAY_SIZE(doms_meta); i++) {
const struct etnaviv_pm_domain_meta *meta = &doms_meta[i];
if (!(gpu->identity.features & meta->feature))
continue;
if (meta->nr_domains < (index - offset)) {
offset += meta->nr_domains;
continue;
}
domain = meta->domains + (index - offset);
}
return domain;
}
int etnaviv_pm_query_dom(struct etnaviv_gpu *gpu, int etnaviv_pm_query_dom(struct etnaviv_gpu *gpu,
struct drm_etnaviv_pm_domain *domain) struct drm_etnaviv_pm_domain *domain)
{ {
const struct etnaviv_pm_domain_meta *meta = &doms_meta[domain->pipe]; const unsigned int nr_domains = num_pm_domains(gpu);
const struct etnaviv_pm_domain *dom; const struct etnaviv_pm_domain *dom;
if (domain->iter >= meta->nr_domains) if (domain->iter >= nr_domains)
return -EINVAL; return -EINVAL;
dom = meta->domains + domain->iter; dom = pm_domain(gpu, domain->iter);
if (!dom)
return -EINVAL;
domain->id = domain->iter; domain->id = domain->iter;
domain->nr_signals = dom->nr_signals; domain->nr_signals = dom->nr_signals;
strncpy(domain->name, dom->name, sizeof(domain->name)); strncpy(domain->name, dom->name, sizeof(domain->name));
domain->iter++; domain->iter++;
if (domain->iter == meta->nr_domains) if (domain->iter == nr_domains)
domain->iter = 0xff; domain->iter = 0xff;
return 0; return 0;
...@@ -448,14 +491,16 @@ int etnaviv_pm_query_dom(struct etnaviv_gpu *gpu, ...@@ -448,14 +491,16 @@ int etnaviv_pm_query_dom(struct etnaviv_gpu *gpu,
int etnaviv_pm_query_sig(struct etnaviv_gpu *gpu, int etnaviv_pm_query_sig(struct etnaviv_gpu *gpu,
struct drm_etnaviv_pm_signal *signal) struct drm_etnaviv_pm_signal *signal)
{ {
const struct etnaviv_pm_domain_meta *meta = &doms_meta[signal->pipe]; const unsigned int nr_domains = num_pm_domains(gpu);
const struct etnaviv_pm_domain *dom; const struct etnaviv_pm_domain *dom;
const struct etnaviv_pm_signal *sig; const struct etnaviv_pm_signal *sig;
if (signal->domain >= meta->nr_domains) if (signal->domain >= nr_domains)
return -EINVAL; return -EINVAL;
dom = meta->domains + signal->domain; dom = pm_domain(gpu, signal->domain);
if (!dom)
return -EINVAL;
if (signal->iter >= dom->nr_signals) if (signal->iter >= dom->nr_signals)
return -EINVAL; return -EINVAL;
......
...@@ -46,6 +46,8 @@ DEALINGS IN THE SOFTWARE. ...@@ -46,6 +46,8 @@ DEALINGS IN THE SOFTWARE.
/* This is a cut-down version of the state_blt.xml.h file */ /* This is a cut-down version of the state_blt.xml.h file */
#define VIVS_BLT_SET_COMMAND 0x000140ac
#define VIVS_BLT_ENABLE 0x000140b8 #define VIVS_BLT_ENABLE 0x000140b8
#define VIVS_BLT_ENABLE_ENABLE 0x00000001 #define VIVS_BLT_ENABLE_ENABLE 0x00000001
......
...@@ -8,17 +8,17 @@ This file was generated by the rules-ng-ng headergen tool in this git repository ...@@ -8,17 +8,17 @@ This file was generated by the rules-ng-ng headergen tool in this git repository
git clone git://0x04.net/rules-ng-ng git clone git://0x04.net/rules-ng-ng
The rules-ng-ng source files this header was generated from are: The rules-ng-ng source files this header was generated from are:
- state.xml ( 26087 bytes, from 2017-12-18 16:51:59) - state.xml ( 26666 bytes, from 2019-12-20 21:20:35)
- common.xml ( 35468 bytes, from 2018-01-22 13:48:54) - common.xml ( 35468 bytes, from 2018-02-10 13:09:26)
- common_3d.xml ( 14615 bytes, from 2017-12-18 16:51:59) - common_3d.xml ( 15058 bytes, from 2019-12-28 20:02:03)
- state_hi.xml ( 30232 bytes, from 2018-02-15 15:48:01) - state_hi.xml ( 30552 bytes, from 2019-12-28 20:02:48)
- copyright.xml ( 1597 bytes, from 2016-12-08 16:37:56) - copyright.xml ( 1597 bytes, from 2018-02-10 13:09:26)
- state_2d.xml ( 51552 bytes, from 2016-12-08 16:37:56) - state_2d.xml ( 51552 bytes, from 2018-02-10 13:09:26)
- state_3d.xml ( 79992 bytes, from 2017-12-18 16:51:59) - state_3d.xml ( 83098 bytes, from 2019-12-28 20:02:03)
- state_blt.xml ( 13405 bytes, from 2017-12-18 16:51:59) - state_blt.xml ( 14252 bytes, from 2019-10-20 19:59:15)
- state_vg.xml ( 5975 bytes, from 2016-12-08 16:37:56) - state_vg.xml ( 5975 bytes, from 2018-02-10 13:09:26)
Copyright (C) 2012-2018 by the following authors: Copyright (C) 2012-2019 by the following authors:
- Wladimir J. van der Laan <laanwj@gmail.com> - Wladimir J. van der Laan <laanwj@gmail.com>
- Christian Gmeiner <christian.gmeiner@gmail.com> - Christian Gmeiner <christian.gmeiner@gmail.com>
- Lucas Stach <l.stach@pengutronix.de> - Lucas Stach <l.stach@pengutronix.de>
...@@ -48,6 +48,9 @@ DEALINGS IN THE SOFTWARE. ...@@ -48,6 +48,9 @@ DEALINGS IN THE SOFTWARE.
#define MMU_EXCEPTION_SLAVE_NOT_PRESENT 0x00000001 #define MMU_EXCEPTION_SLAVE_NOT_PRESENT 0x00000001
#define MMU_EXCEPTION_PAGE_NOT_PRESENT 0x00000002 #define MMU_EXCEPTION_PAGE_NOT_PRESENT 0x00000002
#define MMU_EXCEPTION_WRITE_VIOLATION 0x00000003 #define MMU_EXCEPTION_WRITE_VIOLATION 0x00000003
#define MMU_EXCEPTION_OUT_OF_BOUND 0x00000004
#define MMU_EXCEPTION_READ_SECURITY_VIOLATION 0x00000005
#define MMU_EXCEPTION_WRITE_SECURITY_VIOLATION 0x00000006
#define VIVS_HI 0x00000000 #define VIVS_HI 0x00000000
#define VIVS_HI_CLOCK_CONTROL 0x00000000 #define VIVS_HI_CLOCK_CONTROL 0x00000000
...@@ -81,6 +84,13 @@ DEALINGS IN THE SOFTWARE. ...@@ -81,6 +84,13 @@ DEALINGS IN THE SOFTWARE.
#define VIVS_HI_IDLE_STATE_IM 0x00000200 #define VIVS_HI_IDLE_STATE_IM 0x00000200
#define VIVS_HI_IDLE_STATE_FP 0x00000400 #define VIVS_HI_IDLE_STATE_FP 0x00000400
#define VIVS_HI_IDLE_STATE_TS 0x00000800 #define VIVS_HI_IDLE_STATE_TS 0x00000800
#define VIVS_HI_IDLE_STATE_BL 0x00001000
#define VIVS_HI_IDLE_STATE_ASYNCFE 0x00002000
#define VIVS_HI_IDLE_STATE_MC 0x00004000
#define VIVS_HI_IDLE_STATE_PPA 0x00008000
#define VIVS_HI_IDLE_STATE_WD 0x00010000
#define VIVS_HI_IDLE_STATE_NN 0x00020000
#define VIVS_HI_IDLE_STATE_TP 0x00040000
#define VIVS_HI_IDLE_STATE_AXI_LP 0x80000000 #define VIVS_HI_IDLE_STATE_AXI_LP 0x80000000
#define VIVS_HI_AXI_CONFIG 0x00000008 #define VIVS_HI_AXI_CONFIG 0x00000008
...@@ -140,6 +150,8 @@ DEALINGS IN THE SOFTWARE. ...@@ -140,6 +150,8 @@ DEALINGS IN THE SOFTWARE.
#define VIVS_HI_CHIP_TIME 0x0000002c #define VIVS_HI_CHIP_TIME 0x0000002c
#define VIVS_HI_CHIP_CUSTOMER_ID 0x00000030
#define VIVS_HI_CHIP_MINOR_FEATURE_0 0x00000034 #define VIVS_HI_CHIP_MINOR_FEATURE_0 0x00000034
#define VIVS_HI_CACHE_CONTROL 0x00000038 #define VIVS_HI_CACHE_CONTROL 0x00000038
...@@ -237,6 +249,8 @@ DEALINGS IN THE SOFTWARE. ...@@ -237,6 +249,8 @@ DEALINGS IN THE SOFTWARE.
#define VIVS_HI_BLT_INTR 0x000000d4 #define VIVS_HI_BLT_INTR 0x000000d4
#define VIVS_HI_CHIP_ECO_ID 0x000000e8
#define VIVS_HI_AUXBIT 0x000000ec #define VIVS_HI_AUXBIT 0x000000ec
#define VIVS_PM 0x00000000 #define VIVS_PM 0x00000000
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment