staticvoid
v3d_init_core(struct v3d_dev *v3d, int core)
{ /* Set OVRTMUOUT, which means that the texture sampler uniform *configuration'stmuoutputtypefieldisused,insteadof *usingthehardwaredefaultbehaviorbasedonthetexture *type.Ifyouwantthedefaultbehavior,youcanstillput *"2"intheindirecttexturestate'soutput_typefield.
*/ if (v3d->ver < V3D_GEN_41)
V3D_CORE_WRITE(core, V3D_CTL_MISCCFG, V3D_MISCCFG_OVRTMUOUT);
/* Whenever we flush the L2T cache, we always want to flush *thewholething.
*/
V3D_CORE_WRITE(core, V3D_CTL_L2TFLSTA, 0);
V3D_CORE_WRITE(core, V3D_CTL_L2TFLEND, ~0);
}
/* Sets invariant state for the HW. */ staticvoid
v3d_init_hw_state(struct v3d_dev *v3d)
{
v3d_init_core(v3d, 0);
}
staticvoid
v3d_idle_axi(struct v3d_dev *v3d, int core)
{
V3D_CORE_WRITE(core, V3D_GMP_CFG(v3d->ver), V3D_GMP_CFG_STOP_REQ);
if (wait_for((V3D_CORE_READ(core, V3D_GMP_STATUS(v3d->ver)) &
(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");
}
}
staticvoid
v3d_idle_gca(struct v3d_dev *v3d)
{ if (v3d->ver >= V3D_GEN_41) return;
/* Invalidates the (read-only) L2C cache. This was the L2 cache for *uniformsandinstructionsonV3D3.2.
*/ staticvoid
v3d_invalidate_l2c(struct v3d_dev *v3d, int core)
{ if (v3d->ver >= V3D_GEN_33) return;
if (wait_for(!(V3D_CORE_READ(core, V3D_CTL_L2TCACTL) &
V3D_L2TCACTL_L2TFLS), 100)) {
DRM_ERROR("Timeout waiting for L2T clean\n");
}
mutex_unlock(&v3d->cache_clean_lock);
trace_v3d_cache_clean_end(dev);
}
/* Invalidates the slice caches. These are read-only caches. */ staticvoid
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));
}
void
v3d_invalidate_caches(struct v3d_dev *v3d)
{ /* Invalidate the caches from the outside in. That way if *anotherCL'sconcurrentuseofnearbymemoryweretopull *aninvalidatedcachelinebackin,wewouldn'tleavestale *dataintheinnercache.
*/
v3d_flush_l3(v3d);
v3d_invalidate_l2c(v3d, 0);
v3d_flush_l2t(v3d, 0);
v3d_invalidate_slices(v3d, 0);
}
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++) { struct v3d_queue_state *queue = &v3d->queue[i];
spin_lock_init(&v3d->mm_lock);
spin_lock_init(&v3d->job_lock);
ret = drmm_mutex_init(dev, &v3d->bo_lock); if (ret) return ret;
ret = drmm_mutex_init(dev, &v3d->reset_lock); if (ret) return ret;
ret = drmm_mutex_init(dev, &v3d->sched_lock); if (ret) return ret;
ret = drmm_mutex_init(dev, &v3d->cache_clean_lock); if (ret) return ret;
/* Note: We don't allocate address 0. Various bits of HW *treat0asspecial,suchastheocclusionquerycounters *where0means"disabled".
*/
drm_mm_init(&v3d->mm, 1, pt_size / sizeof(u32) - 1);
v3d->pt = dma_alloc_wc(v3d->drm.dev, pt_size,
&v3d->pt_paddr,
GFP_KERNEL | __GFP_NOWARN | __GFP_ZERO); if (!v3d->pt) {
drm_mm_takedown(&v3d->mm);
dev_err(v3d->drm.dev, "Failed to allocate page tables. Please ensure you have DMA enabled.\n"); return -ENOMEM;
}
/* Waiting for jobs to finish would need to be done before *unregisteringV3D.
*/
WARN_ON(v3d->bin_job);
WARN_ON(v3d->render_job);
WARN_ON(v3d->tfu_job);
WARN_ON(v3d->csd_job);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.