#define SRBM_STATUS2 0x0e4c
#define SDMA_BUSY(x) (((x) >> 5) & 0x1)
+#define CP_STAT 0x8680
+#define PFP_BUSY(x) (((x) >> 15) & 0x1)
+#define MEQ_BUSY(x) (((x) >> 16) & 0x1)
+#define ME_BUSY(x) (((x) >> 17) & 0x1)
+#define SURFACE_SYNC_BUSY(x) (((x) >> 21) & 0x1)
+#define DMA_BUSY(x) (((x) >> 22) & 0x1)
+#define SCRATCH_RAM_BUSY(x) (((x) >> 24) & 0x1)
+#define CE_BUSY(x) (((x) >> 26) & 0x1)
+
+#define IDENTITY(x) x
+
#define UPDATE_COUNTER(field, mask) \
do { \
if (mask(value)) \
union r600_mmio_counters *counters)
{
uint32_t value = 0;
+ bool gui_busy, sdma_busy = false;
/* GRBM_STATUS */
rscreen->ws->read_registers(rscreen->ws, GRBM_STATUS, 1, &value);
UPDATE_COUNTER(cp, CP_BUSY);
UPDATE_COUNTER(cb, CB_BUSY);
UPDATE_COUNTER(gui, GUI_ACTIVE);
+ gui_busy = GUI_ACTIVE(value);
- if (rscreen->chip_class >= EVERGREEN) {
+ if (rscreen->chip_class >= CIK) {
/* SRBM_STATUS2 */
rscreen->ws->read_registers(rscreen->ws, SRBM_STATUS2, 1, &value);
UPDATE_COUNTER(sdma, SDMA_BUSY);
+ sdma_busy = SDMA_BUSY(value);
+ }
+
+ if (rscreen->chip_class >= VI) {
+ /* CP_STAT */
+ rscreen->ws->read_registers(rscreen->ws, CP_STAT, 1, &value);
+
+ UPDATE_COUNTER(pfp, PFP_BUSY);
+ UPDATE_COUNTER(meq, MEQ_BUSY);
+ UPDATE_COUNTER(me, ME_BUSY);
+ UPDATE_COUNTER(surf_sync, SURFACE_SYNC_BUSY);
+ UPDATE_COUNTER(dma, DMA_BUSY);
+ UPDATE_COUNTER(scratch_ram, SCRATCH_RAM_BUSY);
+ UPDATE_COUNTER(ce, CE_BUSY);
}
+
+ value = gui_busy || sdma_busy;
+ UPDATE_COUNTER(gpu, IDENTITY);
}
#undef UPDATE_COUNTER
-static PIPE_THREAD_ROUTINE(r600_gpu_load_thread, param)
+static int
+r600_gpu_load_thread(void *param)
{
struct r600_common_screen *rscreen = (struct r600_common_screen*)param;
const int period_us = 1000000 / SAMPLES_PER_SEC;
return;
p_atomic_inc(&rscreen->gpu_load_stop_thread);
- pipe_thread_wait(rscreen->gpu_load_thread);
+ thrd_join(rscreen->gpu_load_thread, NULL);
rscreen->gpu_load_thread = 0;
}
{
/* Start the thread if needed. */
if (!rscreen->gpu_load_thread) {
- pipe_mutex_lock(rscreen->gpu_load_mutex);
+ mtx_lock(&rscreen->gpu_load_mutex);
/* Check again inside the mutex. */
if (!rscreen->gpu_load_thread)
rscreen->gpu_load_thread =
- pipe_thread_create(r600_gpu_load_thread, rscreen);
- pipe_mutex_unlock(rscreen->gpu_load_mutex);
+ u_thread_create(r600_gpu_load_thread, rscreen);
+ mtx_unlock(&rscreen->gpu_load_mutex);
}
unsigned busy = p_atomic_read(&rscreen->mmio_counters.array[busy_index]);
{
switch (type) {
case R600_QUERY_GPU_LOAD:
- return BUSY_INDEX(rscreen, gui);
+ return BUSY_INDEX(rscreen, gpu);
case R600_QUERY_GPU_SHADERS_BUSY:
return BUSY_INDEX(rscreen, spi);
case R600_QUERY_GPU_TA_BUSY:
return BUSY_INDEX(rscreen, cb);
case R600_QUERY_GPU_SDMA_BUSY:
return BUSY_INDEX(rscreen, sdma);
+ case R600_QUERY_GPU_PFP_BUSY:
+ return BUSY_INDEX(rscreen, pfp);
+ case R600_QUERY_GPU_MEQ_BUSY:
+ return BUSY_INDEX(rscreen, meq);
+ case R600_QUERY_GPU_ME_BUSY:
+ return BUSY_INDEX(rscreen, me);
+ case R600_QUERY_GPU_SURF_SYNC_BUSY:
+ return BUSY_INDEX(rscreen, surf_sync);
+ case R600_QUERY_GPU_DMA_BUSY:
+ return BUSY_INDEX(rscreen, dma);
+ case R600_QUERY_GPU_SCRATCH_RAM_BUSY:
+ return BUSY_INDEX(rscreen, scratch_ram);
+ case R600_QUERY_GPU_CE_BUSY:
+ return BUSY_INDEX(rscreen, ce);
default:
unreachable("invalid query type");
}