// SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
/*
 *
 * (C) COPYRIGHT 2012-2015, 2018-2021 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 license.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, you can access it online at
 * http://www.gnu.org/licenses/gpl-2.0.html.
 *
 */

#include <mali_kbase.h>
#include <device/mali_kbase_device.h>
#include "mali_kbase_debug_job_fault.h"

#if IS_ENABLED(CONFIG_DEBUG_FS)

/*GPU_CONTROL_REG(r)*/
static int gpu_control_reg_snapshot[] = {
	GPU_ID,
	SHADER_READY_LO,
	SHADER_READY_HI,
	TILER_READY_LO,
	TILER_READY_HI,
	L2_READY_LO,
	L2_READY_HI
};

/* JOB_CONTROL_REG(r) */
static int job_control_reg_snapshot[] = {
	JOB_IRQ_MASK,
	JOB_IRQ_STATUS
};

/* JOB_SLOT_REG(n,r) */
static int job_slot_reg_snapshot[] = {
	JS_HEAD_LO,
	JS_HEAD_HI,
	JS_TAIL_LO,
	JS_TAIL_HI,
	JS_AFFINITY_LO,
	JS_AFFINITY_HI,
	JS_CONFIG,
	JS_STATUS,
	JS_HEAD_NEXT_LO,
	JS_HEAD_NEXT_HI,
	JS_AFFINITY_NEXT_LO,
	JS_AFFINITY_NEXT_HI,
	JS_CONFIG_NEXT
};

/*MMU_REG(r)*/
static int mmu_reg_snapshot[] = {
	MMU_IRQ_MASK,
	MMU_IRQ_STATUS
};

/* MMU_AS_REG(n,r) */
static int as_reg_snapshot[] = {
	AS_TRANSTAB_LO,
	AS_TRANSTAB_HI,
	AS_TRANSCFG_LO,
	AS_TRANSCFG_HI,
	AS_MEMATTR_LO,
	AS_MEMATTR_HI,
	AS_FAULTSTATUS,
	AS_FAULTADDRESS_LO,
	AS_FAULTADDRESS_HI,
	AS_STATUS
};

bool kbase_debug_job_fault_reg_snapshot_init(struct kbase_context *kctx,
		int reg_range)
{
	int i, j;
	int offset = 0;
	int slot_number;
	int as_number;

	if (kctx->reg_dump == NULL)
		return false;

	slot_number = kctx->kbdev->gpu_props.num_job_slots;
	as_number = kctx->kbdev->gpu_props.num_address_spaces;

	/* get the GPU control registers*/
	for (i = 0; i < sizeof(gpu_control_reg_snapshot)/4; i++) {
		kctx->reg_dump[offset] =
				GPU_CONTROL_REG(gpu_control_reg_snapshot[i]);
		offset += 2;
	}

	/* get the Job control registers*/
	for (i = 0; i < sizeof(job_control_reg_snapshot)/4; i++) {
		kctx->reg_dump[offset] =
				JOB_CONTROL_REG(job_control_reg_snapshot[i]);
		offset += 2;
	}

	/* get the Job Slot registers*/
	for (j = 0; j < slot_number; j++)	{
		for (i = 0; i < sizeof(job_slot_reg_snapshot)/4; i++) {
			kctx->reg_dump[offset] =
			JOB_SLOT_REG(j, job_slot_reg_snapshot[i]);
			offset += 2;
		}
	}

	/* get the MMU registers*/
	for (i = 0; i < sizeof(mmu_reg_snapshot)/4; i++) {
		kctx->reg_dump[offset] = MMU_REG(mmu_reg_snapshot[i]);
		offset += 2;
	}

	/* get the Address space registers*/
	for (j = 0; j < as_number; j++) {
		for (i = 0; i < sizeof(as_reg_snapshot)/4; i++) {
			kctx->reg_dump[offset] =
					MMU_AS_REG(j, as_reg_snapshot[i]);
			offset += 2;
		}
	}

	WARN_ON(offset >= (reg_range*2/4));

	/* set the termination flag*/
	kctx->reg_dump[offset] = REGISTER_DUMP_TERMINATION_FLAG;
	kctx->reg_dump[offset + 1] = REGISTER_DUMP_TERMINATION_FLAG;

	dev_dbg(kctx->kbdev->dev, "kbase_job_fault_reg_snapshot_init:%d\n",
			offset);

	return true;
}

bool kbase_job_fault_get_reg_snapshot(struct kbase_context *kctx)
{
	int offset = 0;

	if (kctx->reg_dump == NULL)
		return false;

	while (kctx->reg_dump[offset] != REGISTER_DUMP_TERMINATION_FLAG) {
		kctx->reg_dump[offset+1] =
				kbase_reg_read(kctx->kbdev,
						kctx->reg_dump[offset]);
		offset += 2;
	}
	return true;
}


#endif
