/*
 * Copyright 2022 Advanced Micro Devices, Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */

#include <linux/firmware.h>
#include <drm/drm_drv.h>

#include "amdgpu.h"
#include "amdgpu_ucode.h"
#include "amdgpu_vpe.h"
#include "vpe_v6_1.h"
#include "soc15_common.h"
#include "ivsrcid/vpe/irqsrcs_vpe_6_1.h"
#include "vpe/vpe_6_1_0_offset.h"
#include "vpe/vpe_6_1_0_sh_mask.h"

MODULE_FIRMWARE("amdgpu/vpe_6_1_0.bin");
MODULE_FIRMWARE("amdgpu/vpe_6_1_1.bin");

#define VPE_THREAD1_UCODE_OFFSET	0x8000

#define regVPEC_COLLABORATE_CNTL                                                0x0013
#define regVPEC_COLLABORATE_CNTL_BASE_IDX                                       0
#define VPEC_COLLABORATE_CNTL__COLLABORATE_MODE_EN__SHIFT                       0x0
#define VPEC_COLLABORATE_CNTL__COLLABORATE_MODE_EN_MASK                         0x00000001L

#define regVPEC_COLLABORATE_CFG                                                 0x0014
#define regVPEC_COLLABORATE_CFG_BASE_IDX                                        0
#define VPEC_COLLABORATE_CFG__MASTER_ID__SHIFT                                  0x0
#define VPEC_COLLABORATE_CFG__MASTER_EN__SHIFT                                  0x3
#define VPEC_COLLABORATE_CFG__SLAVE0_ID__SHIFT                                  0x4
#define VPEC_COLLABORATE_CFG__SLAVE0_EN__SHIFT                                  0x7
#define VPEC_COLLABORATE_CFG__MASTER_ID_MASK                                    0x00000007L
#define VPEC_COLLABORATE_CFG__MASTER_EN_MASK                                    0x00000008L
#define VPEC_COLLABORATE_CFG__SLAVE0_ID_MASK                                    0x00000070L
#define VPEC_COLLABORATE_CFG__SLAVE0_EN_MASK                                    0x00000080L

#define regVPEC_CNTL_6_1_1                                                      0x0016
#define regVPEC_CNTL_6_1_1_BASE_IDX                                             0
#define regVPEC_QUEUE_RESET_REQ_6_1_1                                           0x002c
#define regVPEC_QUEUE_RESET_REQ_6_1_1_BASE_IDX                                  0
#define regVPEC_PUB_DUMMY2_6_1_1                                                0x004c
#define regVPEC_PUB_DUMMY2_6_1_1_BASE_IDX                                       0

static uint32_t vpe_v6_1_get_reg_offset(struct amdgpu_vpe *vpe, uint32_t inst, uint32_t offset)
{
	uint32_t base;

	base = vpe->ring.adev->reg_offset[VPE_HWIP][inst][0];

	return base + offset;
}

static void vpe_v6_1_halt(struct amdgpu_vpe *vpe, bool halt)
{
	struct amdgpu_device *adev = vpe->ring.adev;
	uint32_t i, f32_cntl;

	for (i = 0; i < vpe->num_instances; i++) {
		f32_cntl = RREG32(vpe_get_reg_offset(vpe, i, regVPEC_F32_CNTL));
		f32_cntl = REG_SET_FIELD(f32_cntl, VPEC_F32_CNTL, HALT, halt ? 1 : 0);
		f32_cntl = REG_SET_FIELD(f32_cntl, VPEC_F32_CNTL, TH1_RESET, halt ? 1 : 0);
		WREG32(vpe_get_reg_offset(vpe, i, regVPEC_F32_CNTL), f32_cntl);
	}
}

static int vpe_v6_1_irq_init(struct amdgpu_vpe *vpe)
{
	struct amdgpu_device *adev = container_of(vpe, struct amdgpu_device, vpe);
	int ret;

	ret = amdgpu_irq_add_id(adev, SOC21_IH_CLIENTID_VPE,
				VPE_6_1_SRCID__VPE_TRAP,
				&adev->vpe.trap_irq);
	if (ret)
		return ret;

	return 0;
}

static void vpe_v6_1_set_collaborate_mode(struct amdgpu_vpe *vpe, bool enable)
{
	struct amdgpu_device *adev = vpe->ring.adev;
	uint32_t vpe_colla_cntl, vpe_colla_cfg, i;

	if (!vpe->collaborate_mode)
		return;

	for (i = 0; i < vpe->num_instances; i++) {
		vpe_colla_cntl = RREG32(vpe_get_reg_offset(vpe, i, regVPEC_COLLABORATE_CNTL));
		vpe_colla_cntl = REG_SET_FIELD(vpe_colla_cntl, VPEC_COLLABORATE_CNTL,
					       COLLABORATE_MODE_EN, enable ? 1 : 0);
		WREG32(vpe_get_reg_offset(vpe, i, regVPEC_COLLABORATE_CNTL), vpe_colla_cntl);

		vpe_colla_cfg = RREG32(vpe_get_reg_offset(vpe, i, regVPEC_COLLABORATE_CFG));
		vpe_colla_cfg = REG_SET_FIELD(vpe_colla_cfg, VPEC_COLLABORATE_CFG, MASTER_ID, 0);
		vpe_colla_cfg = REG_SET_FIELD(vpe_colla_cfg, VPEC_COLLABORATE_CFG, MASTER_EN, enable ? 1 : 0);
		vpe_colla_cfg = REG_SET_FIELD(vpe_colla_cfg, VPEC_COLLABORATE_CFG, SLAVE0_ID, 1);
		vpe_colla_cfg = REG_SET_FIELD(vpe_colla_cfg, VPEC_COLLABORATE_CFG, SLAVE0_EN, enable ? 1 : 0);
		WREG32(vpe_get_reg_offset(vpe, i, regVPEC_COLLABORATE_CFG), vpe_colla_cfg);
	}
}

static int vpe_v6_1_load_microcode(struct amdgpu_vpe *vpe)
{
	struct amdgpu_device *adev = vpe->ring.adev;
	const struct vpe_firmware_header_v1_0 *vpe_hdr;
	const __le32 *data;
	uint32_t ucode_offset[2], ucode_size[2];
	uint32_t i, j, size_dw;
	uint32_t ret;

	/* disable UMSCH_INT_ENABLE */
	for (j = 0; j < vpe->num_instances; j++) {

		if (amdgpu_ip_version(adev, VPE_HWIP, 0) == IP_VERSION(6, 1, 1))
			ret = RREG32(vpe_get_reg_offset(vpe, j, regVPEC_CNTL_6_1_1));
		else
			ret = RREG32(vpe_get_reg_offset(vpe, j, regVPEC_CNTL));

		ret = REG_SET_FIELD(ret, VPEC_CNTL, UMSCH_INT_ENABLE, 0);

		if (amdgpu_ip_version(adev, VPE_HWIP, 0) == IP_VERSION(6, 1, 1))
			WREG32(vpe_get_reg_offset(vpe, j, regVPEC_CNTL_6_1_1), ret);
		else
			WREG32(vpe_get_reg_offset(vpe, j, regVPEC_CNTL), ret);
	}

	/*
	 * For VPE 6.1.1, still only need to add master's offset, and psp will apply it to slave as well.
	 * Here use instance 0 as master.
	 */
	if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
		uint32_t f32_offset, f32_cntl;

		f32_offset = vpe_get_reg_offset(vpe, 0, regVPEC_F32_CNTL);
		f32_cntl = RREG32(f32_offset);
		f32_cntl = REG_SET_FIELD(f32_cntl, VPEC_F32_CNTL, HALT, 0);
		f32_cntl = REG_SET_FIELD(f32_cntl, VPEC_F32_CNTL, TH1_RESET, 0);

		adev->vpe.cmdbuf_cpu_addr[0] = f32_offset;
		adev->vpe.cmdbuf_cpu_addr[1] = f32_cntl;

		amdgpu_vpe_psp_update_sram(adev);
		vpe_v6_1_set_collaborate_mode(vpe, true);
		amdgpu_vpe_configure_dpm(vpe);

		return 0;
	}

	vpe_hdr = (const struct vpe_firmware_header_v1_0 *)adev->vpe.fw->data;

	/* Thread 0(command thread) ucode offset/size */
	ucode_offset[0] = le32_to_cpu(vpe_hdr->header.ucode_array_offset_bytes);
	ucode_size[0] = le32_to_cpu(vpe_hdr->ctx_ucode_size_bytes);
	/* Thread 1(control thread) ucode offset/size */
	ucode_offset[1] = le32_to_cpu(vpe_hdr->ctl_ucode_offset);
	ucode_size[1] = le32_to_cpu(vpe_hdr->ctl_ucode_size_bytes);

	vpe_v6_1_halt(vpe, true);

	for (j = 0; j < vpe->num_instances; j++) {
		for (i = 0; i < 2; i++) {
			if (i > 0)
				WREG32(vpe_get_reg_offset(vpe, j, regVPEC_UCODE_ADDR), VPE_THREAD1_UCODE_OFFSET);
			else
				WREG32(vpe_get_reg_offset(vpe, j, regVPEC_UCODE_ADDR), 0);

			data = (const __le32 *)(adev->vpe.fw->data + ucode_offset[i]);
			size_dw = ucode_size[i] / sizeof(__le32);

			while (size_dw--) {
				if (amdgpu_emu_mode && size_dw % 500 == 0)
					msleep(1);
				WREG32(vpe_get_reg_offset(vpe, j, regVPEC_UCODE_DATA), le32_to_cpup(data++));
			}
		}
	}

	vpe_v6_1_halt(vpe, false);
	vpe_v6_1_set_collaborate_mode(vpe, true);
	amdgpu_vpe_configure_dpm(vpe);

	return 0;
}

static int vpe_v6_1_ring_start(struct amdgpu_vpe *vpe)
{
	struct amdgpu_ring *ring = &vpe->ring;
	struct amdgpu_device *adev = ring->adev;
	uint32_t doorbell, doorbell_offset;
	uint32_t rb_bufsz, rb_cntl;
	uint32_t ib_cntl, i;
	int ret;

	for (i = 0; i < vpe->num_instances; i++) {
		/* Set ring buffer size in dwords */
		rb_bufsz = order_base_2(ring->ring_size / 4);
		rb_cntl = RREG32(vpe_get_reg_offset(vpe, i, regVPEC_QUEUE0_RB_CNTL));
		rb_cntl = REG_SET_FIELD(rb_cntl, VPEC_QUEUE0_RB_CNTL, RB_SIZE, rb_bufsz);
		rb_cntl = REG_SET_FIELD(rb_cntl, VPEC_QUEUE0_RB_CNTL, RB_PRIV, 1);
		rb_cntl = REG_SET_FIELD(rb_cntl, VPEC_QUEUE0_RB_CNTL, RB_VMID, 0);
		WREG32(vpe_get_reg_offset(vpe, i, regVPEC_QUEUE0_RB_CNTL), rb_cntl);

		/* Initialize the ring buffer's read and write pointers */
		WREG32(vpe_get_reg_offset(vpe, i, regVPEC_QUEUE0_RB_RPTR), 0);
		WREG32(vpe_get_reg_offset(vpe, i, regVPEC_QUEUE0_RB_RPTR_HI), 0);
		WREG32(vpe_get_reg_offset(vpe, i, regVPEC_QUEUE0_RB_WPTR), 0);
		WREG32(vpe_get_reg_offset(vpe, i, regVPEC_QUEUE0_RB_WPTR_HI), 0);

		/* set the wb address whether it's enabled or not */
		WREG32(vpe_get_reg_offset(vpe, i, regVPEC_QUEUE0_RB_RPTR_ADDR_LO),
			lower_32_bits(ring->rptr_gpu_addr) & 0xFFFFFFFC);
		WREG32(vpe_get_reg_offset(vpe, i, regVPEC_QUEUE0_RB_RPTR_ADDR_HI),
			upper_32_bits(ring->rptr_gpu_addr) & 0xFFFFFFFF);

		rb_cntl = REG_SET_FIELD(rb_cntl, VPEC_QUEUE0_RB_CNTL, RPTR_WRITEBACK_ENABLE, 1);

		WREG32(vpe_get_reg_offset(vpe, i, regVPEC_QUEUE0_RB_BASE), ring->gpu_addr >> 8);
		WREG32(vpe_get_reg_offset(vpe, i, regVPEC_QUEUE0_RB_BASE_HI), ring->gpu_addr >> 40);

		ring->wptr = 0;

		/* before programing wptr to a less value, need set minor_ptr_update first */
		WREG32(vpe_get_reg_offset(vpe, i, regVPEC_QUEUE0_MINOR_PTR_UPDATE), 1);
		WREG32(vpe_get_reg_offset(vpe, i, regVPEC_QUEUE0_RB_WPTR), lower_32_bits(ring->wptr) << 2);
		WREG32(vpe_get_reg_offset(vpe, i, regVPEC_QUEUE0_RB_WPTR_HI), upper_32_bits(ring->wptr) << 2);
		/* set minor_ptr_update to 0 after wptr programed */
		WREG32(vpe_get_reg_offset(vpe, i, regVPEC_QUEUE0_MINOR_PTR_UPDATE), 0);

		doorbell_offset = RREG32(vpe_get_reg_offset(vpe, i, regVPEC_QUEUE0_DOORBELL_OFFSET));
		doorbell_offset = REG_SET_FIELD(doorbell_offset, VPEC_QUEUE0_DOORBELL_OFFSET, OFFSET, ring->doorbell_index + i*4);
		WREG32(vpe_get_reg_offset(vpe, i, regVPEC_QUEUE0_DOORBELL_OFFSET), doorbell_offset);

		doorbell = RREG32(vpe_get_reg_offset(vpe, i, regVPEC_QUEUE0_DOORBELL));
		doorbell = REG_SET_FIELD(doorbell, VPEC_QUEUE0_DOORBELL, ENABLE, ring->use_doorbell ? 1 : 0);
		WREG32(vpe_get_reg_offset(vpe, i, regVPEC_QUEUE0_DOORBELL), doorbell);

		adev->nbio.funcs->vpe_doorbell_range(adev, i, ring->use_doorbell, ring->doorbell_index + i*4, 4);

		rb_cntl = REG_SET_FIELD(rb_cntl, VPEC_QUEUE0_RB_CNTL, RPTR_WRITEBACK_ENABLE, 1);
		rb_cntl = REG_SET_FIELD(rb_cntl, VPEC_QUEUE0_RB_CNTL, RB_ENABLE, 1);
		WREG32(vpe_get_reg_offset(vpe, i, regVPEC_QUEUE0_RB_CNTL), rb_cntl);

		ib_cntl = RREG32(vpe_get_reg_offset(vpe, i, regVPEC_QUEUE0_IB_CNTL));
		ib_cntl = REG_SET_FIELD(ib_cntl, VPEC_QUEUE0_IB_CNTL, IB_ENABLE, 1);
		WREG32(vpe_get_reg_offset(vpe, i, regVPEC_QUEUE0_IB_CNTL), ib_cntl);
	}

	ret = amdgpu_ring_test_helper(ring);
	if (ret)
		return ret;

	return 0;
}

static int vpe_v_6_1_ring_stop(struct amdgpu_vpe *vpe)
{
	struct amdgpu_device *adev = vpe->ring.adev;
	uint32_t queue_reset, i;
	int ret;

	for (i = 0; i < vpe->num_instances; i++) {
		if (amdgpu_ip_version(adev, VPE_HWIP, 0) == IP_VERSION(6, 1, 1))
			queue_reset = RREG32(vpe_get_reg_offset(vpe, i, regVPEC_QUEUE_RESET_REQ_6_1_1));
		else
			queue_reset = RREG32(vpe_get_reg_offset(vpe, i, regVPEC_QUEUE_RESET_REQ));

		queue_reset = REG_SET_FIELD(queue_reset, VPEC_QUEUE_RESET_REQ, QUEUE0_RESET, 1);

		if (amdgpu_ip_version(adev, VPE_HWIP, 0) == IP_VERSION(6, 1, 1)) {
			WREG32(vpe_get_reg_offset(vpe, i, regVPEC_QUEUE_RESET_REQ_6_1_1), queue_reset);
			ret = SOC15_WAIT_ON_RREG(VPE, i, regVPEC_QUEUE_RESET_REQ_6_1_1, 0,
						 VPEC_QUEUE_RESET_REQ__QUEUE0_RESET_MASK);
		} else {
			WREG32(vpe_get_reg_offset(vpe, i, regVPEC_QUEUE_RESET_REQ), queue_reset);
			ret = SOC15_WAIT_ON_RREG(VPE, i, regVPEC_QUEUE_RESET_REQ, 0,
						 VPEC_QUEUE_RESET_REQ__QUEUE0_RESET_MASK);
		}

		if (ret)
			dev_err(adev->dev, "VPE queue reset failed\n");
	}

	vpe->ring.sched.ready = false;

	return ret;
}

static int vpe_v6_1_set_trap_irq_state(struct amdgpu_device *adev,
				       struct amdgpu_irq_src *source,
				       unsigned int type,
				       enum amdgpu_interrupt_state state)
{
	struct amdgpu_vpe *vpe = &adev->vpe;
	uint32_t vpe_cntl;

	if (amdgpu_ip_version(adev, VPE_HWIP, 0) == IP_VERSION(6, 1, 1))
		vpe_cntl = RREG32(vpe_get_reg_offset(vpe, 0, regVPEC_CNTL_6_1_1));
	else
		vpe_cntl = RREG32(vpe_get_reg_offset(vpe, 0, regVPEC_CNTL));

	vpe_cntl = REG_SET_FIELD(vpe_cntl, VPEC_CNTL, TRAP_ENABLE,
				 state == AMDGPU_IRQ_STATE_ENABLE ? 1 : 0);

	if (amdgpu_ip_version(adev, VPE_HWIP, 0) == IP_VERSION(6, 1, 1))
		WREG32(vpe_get_reg_offset(vpe, 0, regVPEC_CNTL_6_1_1), vpe_cntl);
	else
		WREG32(vpe_get_reg_offset(vpe, 0, regVPEC_CNTL), vpe_cntl);

	return 0;
}

static int vpe_v6_1_process_trap_irq(struct amdgpu_device *adev,
				     struct amdgpu_irq_src *source,
				     struct amdgpu_iv_entry *entry)
{

	dev_dbg(adev->dev, "IH: VPE trap\n");

	switch (entry->client_id) {
	case SOC21_IH_CLIENTID_VPE:
		amdgpu_fence_process(&adev->vpe.ring);
		break;
	default:
		break;
	}

	return 0;
}

static int vpe_v6_1_set_regs(struct amdgpu_vpe *vpe)
{
	struct amdgpu_device *adev = container_of(vpe, struct amdgpu_device, vpe);

	vpe->regs.queue0_rb_rptr_lo = regVPEC_QUEUE0_RB_RPTR;
	vpe->regs.queue0_rb_rptr_hi = regVPEC_QUEUE0_RB_RPTR_HI;
	vpe->regs.queue0_rb_wptr_lo = regVPEC_QUEUE0_RB_WPTR;
	vpe->regs.queue0_rb_wptr_hi = regVPEC_QUEUE0_RB_WPTR_HI;
	vpe->regs.queue0_preempt = regVPEC_QUEUE0_PREEMPT;

	if (amdgpu_ip_version(adev, VPE_HWIP, 0) == IP_VERSION(6, 1, 1))
		vpe->regs.dpm_enable = regVPEC_PUB_DUMMY2_6_1_1;
	else
		vpe->regs.dpm_enable = regVPEC_PUB_DUMMY2;

	vpe->regs.dpm_pratio = regVPEC_QUEUE6_DUMMY4;
	vpe->regs.dpm_request_interval = regVPEC_QUEUE5_DUMMY3;
	vpe->regs.dpm_decision_threshold = regVPEC_QUEUE5_DUMMY4;
	vpe->regs.dpm_busy_clamp_threshold = regVPEC_QUEUE7_DUMMY2;
	vpe->regs.dpm_idle_clamp_threshold = regVPEC_QUEUE7_DUMMY3;
	vpe->regs.dpm_request_lv = regVPEC_QUEUE7_DUMMY1;
	vpe->regs.context_indicator = regVPEC_QUEUE6_DUMMY3;

	return 0;
}

static const struct vpe_funcs vpe_v6_1_funcs = {
	.get_reg_offset = vpe_v6_1_get_reg_offset,
	.set_regs = vpe_v6_1_set_regs,
	.irq_init = vpe_v6_1_irq_init,
	.init_microcode = amdgpu_vpe_init_microcode,
	.load_microcode = vpe_v6_1_load_microcode,
	.ring_init = amdgpu_vpe_ring_init,
	.ring_start = vpe_v6_1_ring_start,
	.ring_stop = vpe_v_6_1_ring_stop,
	.ring_fini = amdgpu_vpe_ring_fini,
};

static const struct amdgpu_irq_src_funcs vpe_v6_1_trap_irq_funcs = {
	.set = vpe_v6_1_set_trap_irq_state,
	.process = vpe_v6_1_process_trap_irq,
};

void vpe_v6_1_set_funcs(struct amdgpu_vpe *vpe)
{
	vpe->funcs = &vpe_v6_1_funcs;
	vpe->trap_irq.funcs = &vpe_v6_1_trap_irq_funcs;
}
