/*
 *
 * (C) COPYRIGHT 2014-2016 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
 * Foundation, and any use by you of this program is subject to the terms
 * of such GNU licence.
 *
 * A copy of the licence is included with the program, and can also be obtained
 * from Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA  02110-1301, USA.
 *
 */



#include "mali_kbase.h"
#include "mali_kbase_hw.h"
#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
#define MALI_COUNTERS_PER_BLOCK			64
#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;
};

static void dump_worker(struct work_struct *work);

const char * const *kbase_gator_hwcnt_init_names(uint32_t *total_counters)
{
	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;

	/* Get the first device - it doesn't matter in this case */
	kbdev = kbase_find_device(-1);
	if (!kbdev)
		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;
		}
	}

	/* 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;

	return hardware_counters;
}
KBASE_EXPORT_SYMBOL(kbase_gator_hwcnt_init_names);

void kbase_gator_hwcnt_term_names(void)
{
	/* Release the module reference. */
	module_put(THIS_MODULE);
}
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;
	uint32_t dump_size = 0, i = 0;

	if (!in_out_info)
		return NULL;

	hand = kzalloc(sizeof(*hand), GFP_KERNEL);
	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)
		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;
	in_out_info->gpu_id = hand->kbdev->gpu_props.props.core_props.product_id;

	/* If we are using a v4 device (Mali-T6xx or Mali-T72x) */
	if (kbase_hw_has_feature(hand->kbdev, BASE_HW_FEATURE_V4)) {
		uint32_t cg, j;
		uint64_t core_mask;

		/* There are 8 hardware counters blocks per core group */
		in_out_info->hwc_layout = kmalloc(sizeof(enum hwc_type) *
			MALI_MAX_NUM_BLOCKS_PER_GROUP *
			in_out_info->nr_core_groups, GFP_KERNEL);

		if (!in_out_info->hwc_layout)
			goto free_vinstr_buffer;

		dump_size = in_out_info->nr_core_groups *
			MALI_MAX_NUM_BLOCKS_PER_GROUP *
			MALI_COUNTERS_PER_BLOCK *
			MALI_BYTES_PER_COUNTER;

		for (cg = 0; cg < in_out_info->nr_core_groups; cg++) {
			core_mask = hand->kbdev->gpu_props.props.coherency_info.group[cg].core_mask;

			for (j = 0; j < MALI_MAX_CORES_PER_GROUP; j++) {
				if (core_mask & (1u << j))
					in_out_info->hwc_layout[i++] = SHADER_BLOCK;
				else
					in_out_info->hwc_layout[i++] = RESERVED_BLOCK;
			}

			in_out_info->hwc_layout[i++] = TILER_BLOCK;
			in_out_info->hwc_layout[i++] = MMU_L2_BLOCK;

			in_out_info->hwc_layout[i++] = RESERVED_BLOCK;

			if (0 == cg)
				in_out_info->hwc_layout[i++] = JM_BLOCK;
			else
				in_out_info->hwc_layout[i++] = RESERVED_BLOCK;
		}
	/* If we are using any other device */
	} else {
		uint32_t nr_l2, nr_sc_bits, 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);

		/* 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);

		if (!in_out_info->hwc_layout)
			goto free_vinstr_buffer;

		dump_size = (2 + nr_sc_bits + 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;

		for (j = 0; j < nr_l2; j++)
			in_out_info->hwc_layout[i++] = MMU_L2_BLOCK;

		while (core_mask != 0ull) {
			if ((core_mask & 1ull) != 0ull)
				in_out_info->hwc_layout[i++] = SHADER_BLOCK;
			else
				in_out_info->hwc_layout[i++] = RESERVED_BLOCK;
			core_mask >>= 1;
		}
	}

	in_out_info->nr_hwc_blocks = i;
	in_out_info->size = dump_size;

	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;
	}

	return hand;

free_layout:
	kfree(in_out_info->hwc_layout);

free_vinstr_buffer:
	kfree(hand->vinstr_buffer);

release_device:
	kbase_release_device(hand->kbdev);

free_hand:
	kfree(hand);
	return NULL;
}
KBASE_EXPORT_SYMBOL(kbase_gator_hwcnt_init);

void kbase_gator_hwcnt_term(struct kbase_gator_hwcnt_info *in_out_info, struct kbase_gator_hwcnt_handles *opaque_handles)
{
	if (in_out_info)
		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_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)
{

	if (opaque_handles && success) {
		*success = opaque_handles->dump_complete;
		opaque_handles->dump_complete = 0;
		return *success;
	}
	return 0;
}
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 0;
}
KBASE_EXPORT_SYMBOL(kbase_gator_instr_hwcnt_dump_irq);
