summaryrefslogtreecommitdiff
path: root/drivers/gpu/arm/midgard/mali_kbase_gator_api.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/arm/midgard/mali_kbase_gator_api.c')
-rw-r--r--drivers/gpu/arm/midgard/mali_kbase_gator_api.c239
1 files changed, 116 insertions, 123 deletions
diff --git a/drivers/gpu/arm/midgard/mali_kbase_gator_api.c b/drivers/gpu/arm/midgard/mali_kbase_gator_api.c
index 4af3e4815e95..a2174b24ac3c 100644
--- a/drivers/gpu/arm/midgard/mali_kbase_gator_api.c
+++ b/drivers/gpu/arm/midgard/mali_kbase_gator_api.c
@@ -1,6 +1,6 @@
/*
*
- * (C) COPYRIGHT 2014-2016 ARM Limited. All rights reserved.
+ * (C) COPYRIGHT 2014-2015 ARM Limited. All rights reserved.
*
* This program is free software and is provided to you under the terms of the
* GNU General Public License version 2 as published by the Free Software
@@ -20,6 +20,7 @@
#include "mali_kbase_mem_linux.h"
#include "mali_kbase_gator_api.h"
#include "mali_kbase_gator_hwcnt_names.h"
+#include "mali_kbase_instr.h"
#define MALI_MAX_CORES_PER_GROUP 4
#define MALI_MAX_NUM_BLOCKS_PER_GROUP 8
@@ -27,23 +28,18 @@
#define MALI_BYTES_PER_COUNTER 4
struct kbase_gator_hwcnt_handles {
- struct kbase_device *kbdev;
- struct kbase_vinstr_client *vinstr_cli;
- void *vinstr_buffer;
- struct work_struct dump_work;
- int dump_complete;
- spinlock_t dump_lock;
+ struct kbase_device *kbdev;
+ struct kbase_context *kctx;
+ u64 hwcnt_gpu_va;
+ void *hwcnt_cpu_va;
+ struct kbase_vmap_struct hwcnt_map;
};
-static void dump_worker(struct work_struct *work);
-
const char * const *kbase_gator_hwcnt_init_names(uint32_t *total_counters)
{
+ uint32_t gpu_id;
const char * const *hardware_counters;
struct kbase_device *kbdev;
- uint32_t gpu_id;
- uint32_t product_id;
- uint32_t count;
if (!total_counters)
return NULL;
@@ -54,78 +50,58 @@ const char * const *kbase_gator_hwcnt_init_names(uint32_t *total_counters)
return NULL;
gpu_id = kbdev->gpu_props.props.core_props.product_id;
- product_id = gpu_id & GPU_ID_VERSION_PRODUCT_ID;
- product_id >>= GPU_ID_VERSION_PRODUCT_ID_SHIFT;
-
- if (GPU_ID_IS_NEW_FORMAT(product_id)) {
- switch (gpu_id & GPU_ID2_PRODUCT_MODEL) {
- case GPU_ID2_PRODUCT_TMIX:
- hardware_counters = hardware_counters_mali_tMIx;
- count = ARRAY_SIZE(hardware_counters_mali_tMIx);
- break;
- default:
- hardware_counters = NULL;
- count = 0;
- dev_err(kbdev->dev, "Unrecognized gpu ID: %u\n",
- gpu_id);
- break;
- }
- } else {
- switch (gpu_id) {
- /* If we are using a Mali-T60x device */
- case GPU_ID_PI_T60X:
- hardware_counters = hardware_counters_mali_t60x;
- count = ARRAY_SIZE(hardware_counters_mali_t60x);
- break;
- /* If we are using a Mali-T62x device */
- case GPU_ID_PI_T62X:
- hardware_counters = hardware_counters_mali_t62x;
- count = ARRAY_SIZE(hardware_counters_mali_t62x);
- break;
- /* If we are using a Mali-T72x device */
- case GPU_ID_PI_T72X:
- hardware_counters = hardware_counters_mali_t72x;
- count = ARRAY_SIZE(hardware_counters_mali_t72x);
- break;
- /* If we are using a Mali-T76x device */
- case GPU_ID_PI_T76X:
- hardware_counters = hardware_counters_mali_t76x;
- count = ARRAY_SIZE(hardware_counters_mali_t76x);
- break;
- /* If we are using a Mali-T82x device */
- case GPU_ID_PI_T82X:
- hardware_counters = hardware_counters_mali_t82x;
- count = ARRAY_SIZE(hardware_counters_mali_t82x);
- break;
- /* If we are using a Mali-T83x device */
- case GPU_ID_PI_T83X:
- hardware_counters = hardware_counters_mali_t83x;
- count = ARRAY_SIZE(hardware_counters_mali_t83x);
- break;
- /* If we are using a Mali-T86x device */
- case GPU_ID_PI_T86X:
- hardware_counters = hardware_counters_mali_t86x;
- count = ARRAY_SIZE(hardware_counters_mali_t86x);
- break;
- /* If we are using a Mali-T88x device */
- case GPU_ID_PI_TFRX:
- hardware_counters = hardware_counters_mali_t88x;
- count = ARRAY_SIZE(hardware_counters_mali_t88x);
- break;
- default:
- hardware_counters = NULL;
- count = 0;
- dev_err(kbdev->dev, "Unrecognized gpu ID: %u\n",
- gpu_id);
- break;
- }
+
+ switch (gpu_id) {
+ /* If we are using a Mali-T60x device */
+ case GPU_ID_PI_T60X:
+ hardware_counters = hardware_counters_mali_t60x;
+ *total_counters = ARRAY_SIZE(hardware_counters_mali_t60x);
+ break;
+ /* If we are using a Mali-T62x device */
+ case GPU_ID_PI_T62X:
+ hardware_counters = hardware_counters_mali_t62x;
+ *total_counters = ARRAY_SIZE(hardware_counters_mali_t62x);
+ break;
+ /* If we are using a Mali-T72x device */
+ case GPU_ID_PI_T72X:
+ hardware_counters = hardware_counters_mali_t72x;
+ *total_counters = ARRAY_SIZE(hardware_counters_mali_t72x);
+ break;
+ /* If we are using a Mali-T76x device */
+ case GPU_ID_PI_T76X:
+ hardware_counters = hardware_counters_mali_t76x;
+ *total_counters = ARRAY_SIZE(hardware_counters_mali_t76x);
+ break;
+ /* If we are using a Mali-T82x device */
+ case GPU_ID_PI_T82X:
+ hardware_counters = hardware_counters_mali_t82x;
+ *total_counters = ARRAY_SIZE(hardware_counters_mali_t82x);
+ break;
+ /* If we are using a Mali-T83x device */
+ case GPU_ID_PI_T83X:
+ hardware_counters = hardware_counters_mali_t83x;
+ *total_counters = ARRAY_SIZE(hardware_counters_mali_t83x);
+ break;
+ /* If we are using a Mali-T86x device */
+ case GPU_ID_PI_T86X:
+ hardware_counters = hardware_counters_mali_t86x;
+ *total_counters = ARRAY_SIZE(hardware_counters_mali_t86x);
+ break;
+ /* If we are using a Mali-T88x device */
+ case GPU_ID_PI_TFRX:
+ hardware_counters = hardware_counters_mali_t88x;
+ *total_counters = ARRAY_SIZE(hardware_counters_mali_t88x);
+ break;
+ default:
+ hardware_counters = NULL;
+ *total_counters = 0;
+ dev_err(kbdev->dev, "Unrecognized gpu ID: %u\n", gpu_id);
+ break;
}
/* Release the kbdev reference. */
kbase_release_device(kbdev);
- *total_counters = count;
-
/* If we return a string array take a reference on the module (or fail). */
if (hardware_counters && !try_module_get(THIS_MODULE))
return NULL;
@@ -144,8 +120,13 @@ KBASE_EXPORT_SYMBOL(kbase_gator_hwcnt_term_names);
struct kbase_gator_hwcnt_handles *kbase_gator_hwcnt_init(struct kbase_gator_hwcnt_info *in_out_info)
{
struct kbase_gator_hwcnt_handles *hand;
- struct kbase_uk_hwcnt_reader_setup setup;
+ struct kbase_uk_hwcnt_setup setup;
+ int err;
uint32_t dump_size = 0, i = 0;
+ struct kbase_va_region *reg;
+ u64 flags;
+ u64 nr_pages;
+ u16 va_alignment = 0;
if (!in_out_info)
return NULL;
@@ -154,19 +135,15 @@ struct kbase_gator_hwcnt_handles *kbase_gator_hwcnt_init(struct kbase_gator_hwcn
if (!hand)
return NULL;
- INIT_WORK(&hand->dump_work, dump_worker);
- spin_lock_init(&hand->dump_lock);
-
/* Get the first device */
hand->kbdev = kbase_find_device(-1);
if (!hand->kbdev)
goto free_hand;
- dump_size = kbase_vinstr_dump_size(hand->kbdev);
- hand->vinstr_buffer = kzalloc(dump_size, GFP_KERNEL);
- if (!hand->vinstr_buffer)
+ /* Create a kbase_context */
+ hand->kctx = kbase_create_context(hand->kbdev, true);
+ if (!hand->kctx)
goto release_device;
- in_out_info->kernel_dump_buffer = hand->vinstr_buffer;
in_out_info->nr_cores = hand->kbdev->gpu_props.num_cores;
in_out_info->nr_core_groups = hand->kbdev->gpu_props.num_core_groups;
@@ -183,7 +160,7 @@ struct kbase_gator_hwcnt_handles *kbase_gator_hwcnt_init(struct kbase_gator_hwcn
in_out_info->nr_core_groups, GFP_KERNEL);
if (!in_out_info->hwc_layout)
- goto free_vinstr_buffer;
+ goto destroy_context;
dump_size = in_out_info->nr_core_groups *
MALI_MAX_NUM_BLOCKS_PER_GROUP *
@@ -212,23 +189,23 @@ struct kbase_gator_hwcnt_handles *kbase_gator_hwcnt_init(struct kbase_gator_hwcn
}
/* If we are using any other device */
} else {
- uint32_t nr_l2, nr_sc_bits, j;
+ uint32_t nr_l2, nr_sc, j;
uint64_t core_mask;
nr_l2 = hand->kbdev->gpu_props.props.l2_props.num_l2_slices;
core_mask = hand->kbdev->gpu_props.props.coherency_info.group[0].core_mask;
- nr_sc_bits = fls64(core_mask);
+ nr_sc = hand->kbdev->gpu_props.props.coherency_info.group[0].num_cores;
/* The job manager and tiler sets of counters
* are always present */
- in_out_info->hwc_layout = kmalloc(sizeof(enum hwc_type) * (2 + nr_sc_bits + nr_l2), GFP_KERNEL);
+ in_out_info->hwc_layout = kmalloc(sizeof(enum hwc_type) * (2 + nr_sc + nr_l2), GFP_KERNEL);
if (!in_out_info->hwc_layout)
- goto free_vinstr_buffer;
+ goto destroy_context;
- dump_size = (2 + nr_sc_bits + nr_l2) * MALI_COUNTERS_PER_BLOCK * MALI_BYTES_PER_COUNTER;
+ dump_size = (2 + nr_sc + nr_l2) * MALI_COUNTERS_PER_BLOCK * MALI_BYTES_PER_COUNTER;
in_out_info->hwc_layout[i++] = JM_BLOCK;
in_out_info->hwc_layout[i++] = TILER_BLOCK;
@@ -246,32 +223,58 @@ struct kbase_gator_hwcnt_handles *kbase_gator_hwcnt_init(struct kbase_gator_hwcn
}
in_out_info->nr_hwc_blocks = i;
+
in_out_info->size = dump_size;
+ flags = BASE_MEM_PROT_CPU_RD | BASE_MEM_PROT_CPU_WR | BASE_MEM_PROT_GPU_WR;
+ nr_pages = PFN_UP(dump_size);
+ reg = kbase_mem_alloc(hand->kctx, nr_pages, nr_pages, 0,
+ &flags, &hand->hwcnt_gpu_va, &va_alignment);
+ if (!reg)
+ goto free_layout;
+
+ hand->hwcnt_cpu_va = kbase_vmap(hand->kctx, hand->hwcnt_gpu_va,
+ dump_size, &hand->hwcnt_map);
+
+ if (!hand->hwcnt_cpu_va)
+ goto free_buffer;
+
+ in_out_info->kernel_dump_buffer = hand->hwcnt_cpu_va;
+ memset(in_out_info->kernel_dump_buffer, 0, nr_pages * PAGE_SIZE);
+
+ /*setup.dump_buffer = (uintptr_t)in_out_info->kernel_dump_buffer;*/
+ setup.dump_buffer = hand->hwcnt_gpu_va;
setup.jm_bm = in_out_info->bitmask[0];
setup.tiler_bm = in_out_info->bitmask[1];
setup.shader_bm = in_out_info->bitmask[2];
setup.mmu_l2_bm = in_out_info->bitmask[3];
- hand->vinstr_cli = kbase_vinstr_hwcnt_kernel_setup(hand->kbdev->vinstr_ctx,
- &setup, hand->vinstr_buffer);
- if (!hand->vinstr_cli) {
- dev_err(hand->kbdev->dev, "Failed to register gator with vinstr core");
- goto free_layout;
- }
+
+ err = kbase_instr_hwcnt_enable(hand->kctx, &setup);
+ if (err)
+ goto free_unmap;
+
+ kbase_instr_hwcnt_clear(hand->kctx);
return hand;
+free_unmap:
+ kbase_vunmap(hand->kctx, &hand->hwcnt_map);
+
+free_buffer:
+ kbase_mem_free(hand->kctx, hand->hwcnt_gpu_va);
+
free_layout:
kfree(in_out_info->hwc_layout);
-free_vinstr_buffer:
- kfree(hand->vinstr_buffer);
+destroy_context:
+ kbase_destroy_context(hand->kctx);
release_device:
kbase_release_device(hand->kbdev);
free_hand:
kfree(hand);
+
return NULL;
}
KBASE_EXPORT_SYMBOL(kbase_gator_hwcnt_init);
@@ -282,39 +285,27 @@ void kbase_gator_hwcnt_term(struct kbase_gator_hwcnt_info *in_out_info, struct k
kfree(in_out_info->hwc_layout);
if (opaque_handles) {
- cancel_work_sync(&opaque_handles->dump_work);
- kbase_vinstr_detach_client(opaque_handles->vinstr_cli);
- kfree(opaque_handles->vinstr_buffer);
+ kbase_instr_hwcnt_disable(opaque_handles->kctx);
+ kbase_vunmap(opaque_handles->kctx, &opaque_handles->hwcnt_map);
+ kbase_mem_free(opaque_handles->kctx, opaque_handles->hwcnt_gpu_va);
+ kbase_destroy_context(opaque_handles->kctx);
kbase_release_device(opaque_handles->kbdev);
kfree(opaque_handles);
}
}
KBASE_EXPORT_SYMBOL(kbase_gator_hwcnt_term);
-static void dump_worker(struct work_struct *work)
-{
- struct kbase_gator_hwcnt_handles *hand;
-
- hand = container_of(work, struct kbase_gator_hwcnt_handles, dump_work);
- if (!kbase_vinstr_hwc_dump(hand->vinstr_cli,
- BASE_HWCNT_READER_EVENT_MANUAL)) {
- spin_lock_bh(&hand->dump_lock);
- hand->dump_complete = 1;
- spin_unlock_bh(&hand->dump_lock);
- } else {
- schedule_work(&hand->dump_work);
- }
-}
-
uint32_t kbase_gator_instr_hwcnt_dump_complete(
struct kbase_gator_hwcnt_handles *opaque_handles,
uint32_t * const success)
{
+ bool ret_res, success_res;
if (opaque_handles && success) {
- *success = opaque_handles->dump_complete;
- opaque_handles->dump_complete = 0;
- return *success;
+ ret_res = kbase_instr_hwcnt_dump_complete(opaque_handles->kctx,
+ &success_res);
+ *success = (uint32_t)success_res;
+ return (uint32_t)(ret_res != 0);
}
return 0;
}
@@ -323,7 +314,9 @@ KBASE_EXPORT_SYMBOL(kbase_gator_instr_hwcnt_dump_complete);
uint32_t kbase_gator_instr_hwcnt_dump_irq(struct kbase_gator_hwcnt_handles *opaque_handles)
{
if (opaque_handles)
- schedule_work(&opaque_handles->dump_work);
+ return (kbase_instr_hwcnt_request_dump(
+ opaque_handles->kctx) == 0);
+
return 0;
}
KBASE_EXPORT_SYMBOL(kbase_gator_instr_hwcnt_dump_irq);