/*
 * Copyright 2013 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.
 *
 * Authors: Christian König <christian.koenig@amd.com>
 */

#include <linux/firmware.h>

#include "radeon.h"
#include "radeon_asic.h"
#include "r600d.h"

/**
 * uvd_v1_0_get_rptr - get read pointer
 *
 * @rdev: radeon_device pointer
 * @ring: radeon_ring pointer
 *
 * Returns the current hardware read pointer
 */
uint32_t uvd_v1_0_get_rptr(struct radeon_device *rdev,
			   struct radeon_ring *ring)
{
	return RREG32(UVD_RBC_RB_RPTR);
}

/**
 * uvd_v1_0_get_wptr - get write pointer
 *
 * @rdev: radeon_device pointer
 * @ring: radeon_ring pointer
 *
 * Returns the current hardware write pointer
 */
uint32_t uvd_v1_0_get_wptr(struct radeon_device *rdev,
			   struct radeon_ring *ring)
{
	return RREG32(UVD_RBC_RB_WPTR);
}

/**
 * uvd_v1_0_set_wptr - set write pointer
 *
 * @rdev: radeon_device pointer
 * @ring: radeon_ring pointer
 *
 * Commits the write pointer to the hardware
 */
void uvd_v1_0_set_wptr(struct radeon_device *rdev,
		       struct radeon_ring *ring)
{
	WREG32(UVD_RBC_RB_WPTR, ring->wptr);
}

/**
 * uvd_v1_0_fence_emit - emit an fence & trap command
 *
 * @rdev: radeon_device pointer
 * @fence: fence to emit
 *
 * Write a fence and a trap command to the ring.
 */
void uvd_v1_0_fence_emit(struct radeon_device *rdev,
			 struct radeon_fence *fence)
{
	struct radeon_ring *ring = &rdev->ring[fence->ring];
	uint64_t addr = rdev->fence_drv[fence->ring].gpu_addr;

	radeon_ring_write(ring, PACKET0(UVD_GPCOM_VCPU_DATA0, 0));
	radeon_ring_write(ring, addr & 0xffffffff);
	radeon_ring_write(ring, PACKET0(UVD_GPCOM_VCPU_DATA1, 0));
	radeon_ring_write(ring, fence->seq);
	radeon_ring_write(ring, PACKET0(UVD_GPCOM_VCPU_CMD, 0));
	radeon_ring_write(ring, 0);

	radeon_ring_write(ring, PACKET0(UVD_GPCOM_VCPU_DATA0, 0));
	radeon_ring_write(ring, 0);
	radeon_ring_write(ring, PACKET0(UVD_GPCOM_VCPU_DATA1, 0));
	radeon_ring_write(ring, 0);
	radeon_ring_write(ring, PACKET0(UVD_GPCOM_VCPU_CMD, 0));
	radeon_ring_write(ring, 2);
	return;
}

/**
 * uvd_v1_0_resume - memory controller programming
 *
 * @rdev: radeon_device pointer
 *
 * Let the UVD memory controller know it's offsets
 */
int uvd_v1_0_resume(struct radeon_device *rdev)
{
	uint64_t addr;
	uint32_t size;
	int r;

	r = radeon_uvd_resume(rdev);
	if (r)
		return r;

	/* program the VCPU memory controller bits 0-27 */
	addr = (rdev->uvd.gpu_addr >> 3) + 16;
	size = RADEON_GPU_PAGE_ALIGN(rdev->uvd_fw->size) >> 3;
	WREG32(UVD_VCPU_CACHE_OFFSET0, addr);
	WREG32(UVD_VCPU_CACHE_SIZE0, size);

	addr += size;
	size = RADEON_UVD_HEAP_SIZE >> 3;
	WREG32(UVD_VCPU_CACHE_OFFSET1, addr);
	WREG32(UVD_VCPU_CACHE_SIZE1, size);

	addr += size;
	size = (RADEON_UVD_STACK_SIZE +
	       (RADEON_UVD_SESSION_SIZE * rdev->uvd.max_handles)) >> 3;
	WREG32(UVD_VCPU_CACHE_OFFSET2, addr);
	WREG32(UVD_VCPU_CACHE_SIZE2, size);

	/* bits 28-31 */
	addr = (rdev->uvd.gpu_addr >> 28) & 0xF;
	WREG32(UVD_LMI_ADDR_EXT, (addr << 12) | (addr << 0));

	/* bits 32-39 */
	addr = (rdev->uvd.gpu_addr >> 32) & 0xFF;
	WREG32(UVD_LMI_EXT40_ADDR, addr | (0x9 << 16) | (0x1 << 31));

	WREG32(UVD_FW_START, *((uint32_t *)rdev->uvd.cpu_addr));

	return 0;
}

/**
 * uvd_v1_0_init - start and test UVD block
 *
 * @rdev: radeon_device pointer
 *
 * Initialize the hardware, boot up the VCPU and do some testing
 */
int uvd_v1_0_init(struct radeon_device *rdev)
{
	struct radeon_ring *ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
	uint32_t tmp;
	int r;

	/* raise clocks while booting up the VCPU */
	if (rdev->family < CHIP_RV740)
		radeon_set_uvd_clocks(rdev, 10000, 10000);
	else
		radeon_set_uvd_clocks(rdev, 53300, 40000);

	r = uvd_v1_0_start(rdev);
	if (r)
		goto done;

	ring->ready = true;
	r = radeon_ring_test(rdev, R600_RING_TYPE_UVD_INDEX, ring);
	if (r) {
		ring->ready = false;
		goto done;
	}

	r = radeon_ring_lock(rdev, ring, 10);
	if (r) {
		DRM_ERROR("radeon: ring failed to lock UVD ring (%d).\n", r);
		goto done;
	}

	tmp = PACKET0(UVD_SEMA_WAIT_FAULT_TIMEOUT_CNTL, 0);
	radeon_ring_write(ring, tmp);
	radeon_ring_write(ring, 0xFFFFF);

	tmp = PACKET0(UVD_SEMA_WAIT_INCOMPLETE_TIMEOUT_CNTL, 0);
	radeon_ring_write(ring, tmp);
	radeon_ring_write(ring, 0xFFFFF);

	tmp = PACKET0(UVD_SEMA_SIGNAL_INCOMPLETE_TIMEOUT_CNTL, 0);
	radeon_ring_write(ring, tmp);
	radeon_ring_write(ring, 0xFFFFF);

	/* Clear timeout status bits */
	radeon_ring_write(ring, PACKET0(UVD_SEMA_TIMEOUT_STATUS, 0));
	radeon_ring_write(ring, 0x8);

	radeon_ring_write(ring, PACKET0(UVD_SEMA_CNTL, 0));
	radeon_ring_write(ring, 3);

	radeon_ring_unlock_commit(rdev, ring, false);

done:
	/* lower clocks again */
	radeon_set_uvd_clocks(rdev, 0, 0);

	if (!r) {
		switch (rdev->family) {
		case CHIP_RV610:
		case CHIP_RV630:
		case CHIP_RV620:
			/* 64byte granularity workaround */
			WREG32(MC_CONFIG, 0);
			WREG32(MC_CONFIG, 1 << 4);
			WREG32(RS_DQ_RD_RET_CONF, 0x3f);
			WREG32(MC_CONFIG, 0x1f);

			fallthrough;
		case CHIP_RV670:
		case CHIP_RV635:

			/* write clean workaround */
			WREG32_P(UVD_VCPU_CNTL, 0x10, ~0x10);
			break;

		default:
			/* TODO: Do we need more? */
			break;
		}

		DRM_INFO("UVD initialized successfully.\n");
	}

	return r;
}

/**
 * uvd_v1_0_fini - stop the hardware block
 *
 * @rdev: radeon_device pointer
 *
 * Stop the UVD block, mark ring as not ready any more
 */
void uvd_v1_0_fini(struct radeon_device *rdev)
{
	struct radeon_ring *ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];

	uvd_v1_0_stop(rdev);
	ring->ready = false;
}

/**
 * uvd_v1_0_start - start UVD block
 *
 * @rdev: radeon_device pointer
 *
 * Setup and start the UVD block
 */
int uvd_v1_0_start(struct radeon_device *rdev)
{
	struct radeon_ring *ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
	uint32_t rb_bufsz;
	int i, j, r;

	/* disable byte swapping */
	u32 lmi_swap_cntl = 0;
	u32 mp_swap_cntl = 0;

	/* disable clock gating */
	WREG32(UVD_CGC_GATE, 0);

	/* disable interupt */
	WREG32_P(UVD_MASTINT_EN, 0, ~(1 << 1));

	/* Stall UMC and register bus before resetting VCPU */
	WREG32_P(UVD_LMI_CTRL2, 1 << 8, ~(1 << 8));
	WREG32_P(UVD_RB_ARB_CTRL, 1 << 3, ~(1 << 3));
	mdelay(1);

	/* put LMI, VCPU, RBC etc... into reset */
	WREG32(UVD_SOFT_RESET, LMI_SOFT_RESET | VCPU_SOFT_RESET |
	       LBSI_SOFT_RESET | RBC_SOFT_RESET | CSM_SOFT_RESET |
	       CXW_SOFT_RESET | TAP_SOFT_RESET | LMI_UMC_SOFT_RESET);
	mdelay(5);

	/* take UVD block out of reset */
	WREG32_P(SRBM_SOFT_RESET, 0, ~SOFT_RESET_UVD);
	mdelay(5);

	/* initialize UVD memory controller */
	WREG32(UVD_LMI_CTRL, 0x40 | (1 << 8) | (1 << 13) |
			     (1 << 21) | (1 << 9) | (1 << 20));

#ifdef __BIG_ENDIAN
	/* swap (8 in 32) RB and IB */
	lmi_swap_cntl = 0xa;
	mp_swap_cntl = 0;
#endif
	WREG32(UVD_LMI_SWAP_CNTL, lmi_swap_cntl);
	WREG32(UVD_MP_SWAP_CNTL, mp_swap_cntl);

	WREG32(UVD_MPC_SET_MUXA0, 0x40c2040);
	WREG32(UVD_MPC_SET_MUXA1, 0x0);
	WREG32(UVD_MPC_SET_MUXB0, 0x40c2040);
	WREG32(UVD_MPC_SET_MUXB1, 0x0);
	WREG32(UVD_MPC_SET_ALU, 0);
	WREG32(UVD_MPC_SET_MUX, 0x88);

	/* take all subblocks out of reset, except VCPU */
	WREG32(UVD_SOFT_RESET, VCPU_SOFT_RESET);
	mdelay(5);

	/* enable VCPU clock */
	WREG32(UVD_VCPU_CNTL,  1 << 9);

	/* enable UMC */
	WREG32_P(UVD_LMI_CTRL2, 0, ~(1 << 8));

	WREG32_P(UVD_RB_ARB_CTRL, 0, ~(1 << 3));

	/* boot up the VCPU */
	WREG32(UVD_SOFT_RESET, 0);
	mdelay(10);

	for (i = 0; i < 10; ++i) {
		uint32_t status;
		for (j = 0; j < 100; ++j) {
			status = RREG32(UVD_STATUS);
			if (status & 2)
				break;
			mdelay(10);
		}
		r = 0;
		if (status & 2)
			break;

		DRM_ERROR("UVD not responding, trying to reset the VCPU!!!\n");
		WREG32_P(UVD_SOFT_RESET, VCPU_SOFT_RESET, ~VCPU_SOFT_RESET);
		mdelay(10);
		WREG32_P(UVD_SOFT_RESET, 0, ~VCPU_SOFT_RESET);
		mdelay(10);
		r = -1;
	}

	if (r) {
		DRM_ERROR("UVD not responding, giving up!!!\n");
		return r;
	}

	/* enable interupt */
	WREG32_P(UVD_MASTINT_EN, 3<<1, ~(3 << 1));

	/* force RBC into idle state */
	WREG32(UVD_RBC_RB_CNTL, 0x11010101);

	/* Set the write pointer delay */
	WREG32(UVD_RBC_RB_WPTR_CNTL, 0);

	/* program the 4GB memory segment for rptr and ring buffer */
	WREG32(UVD_LMI_EXT40_ADDR, upper_32_bits(ring->gpu_addr) |
				   (0x7 << 16) | (0x1 << 31));

	/* Initialize the ring buffer's read and write pointers */
	WREG32(UVD_RBC_RB_RPTR, 0x0);

	ring->wptr = RREG32(UVD_RBC_RB_RPTR);
	WREG32(UVD_RBC_RB_WPTR, ring->wptr);

	/* set the ring address */
	WREG32(UVD_RBC_RB_BASE, ring->gpu_addr);

	/* Set ring buffer size */
	rb_bufsz = order_base_2(ring->ring_size);
	rb_bufsz = (0x1 << 8) | rb_bufsz;
	WREG32_P(UVD_RBC_RB_CNTL, rb_bufsz, ~0x11f1f);

	return 0;
}

/**
 * uvd_v1_0_stop - stop UVD block
 *
 * @rdev: radeon_device pointer
 *
 * stop the UVD block
 */
void uvd_v1_0_stop(struct radeon_device *rdev)
{
	/* force RBC into idle state */
	WREG32(UVD_RBC_RB_CNTL, 0x11010101);

	/* Stall UMC and register bus before resetting VCPU */
	WREG32_P(UVD_LMI_CTRL2, 1 << 8, ~(1 << 8));
	WREG32_P(UVD_RB_ARB_CTRL, 1 << 3, ~(1 << 3));
	mdelay(1);

	/* put VCPU into reset */
	WREG32(UVD_SOFT_RESET, VCPU_SOFT_RESET);
	mdelay(5);

	/* disable VCPU clock */
	WREG32(UVD_VCPU_CNTL, 0x0);

	/* Unstall UMC and register bus */
	WREG32_P(UVD_LMI_CTRL2, 0, ~(1 << 8));
	WREG32_P(UVD_RB_ARB_CTRL, 0, ~(1 << 3));
}

/**
 * uvd_v1_0_ring_test - register write test
 *
 * @rdev: radeon_device pointer
 * @ring: radeon_ring pointer
 *
 * Test if we can successfully write to the context register
 */
int uvd_v1_0_ring_test(struct radeon_device *rdev, struct radeon_ring *ring)
{
	uint32_t tmp = 0;
	unsigned i;
	int r;

	WREG32(UVD_CONTEXT_ID, 0xCAFEDEAD);
	r = radeon_ring_lock(rdev, ring, 3);
	if (r) {
		DRM_ERROR("radeon: cp failed to lock ring %d (%d).\n",
			  ring->idx, r);
		return r;
	}
	radeon_ring_write(ring, PACKET0(UVD_CONTEXT_ID, 0));
	radeon_ring_write(ring, 0xDEADBEEF);
	radeon_ring_unlock_commit(rdev, ring, false);
	for (i = 0; i < rdev->usec_timeout; i++) {
		tmp = RREG32(UVD_CONTEXT_ID);
		if (tmp == 0xDEADBEEF)
			break;
		udelay(1);
	}

	if (i < rdev->usec_timeout) {
		DRM_INFO("ring test on %d succeeded in %d usecs\n",
			 ring->idx, i);
	} else {
		DRM_ERROR("radeon: ring %d test failed (0x%08X)\n",
			  ring->idx, tmp);
		r = -EINVAL;
	}
	return r;
}

/**
 * uvd_v1_0_semaphore_emit - emit semaphore command
 *
 * @rdev: radeon_device pointer
 * @ring: radeon_ring pointer
 * @semaphore: semaphore to emit commands for
 * @emit_wait: true if we should emit a wait command
 *
 * Emit a semaphore command (either wait or signal) to the UVD ring.
 */
bool uvd_v1_0_semaphore_emit(struct radeon_device *rdev,
			     struct radeon_ring *ring,
			     struct radeon_semaphore *semaphore,
			     bool emit_wait)
{
	/* disable semaphores for UVD V1 hardware */
	return false;
}

/**
 * uvd_v1_0_ib_execute - execute indirect buffer
 *
 * @rdev: radeon_device pointer
 * @ib: indirect buffer to execute
 *
 * Write ring commands to execute the indirect buffer
 */
void uvd_v1_0_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib)
{
	struct radeon_ring *ring = &rdev->ring[ib->ring];

	radeon_ring_write(ring, PACKET0(UVD_RBC_IB_BASE, 0));
	radeon_ring_write(ring, ib->gpu_addr);
	radeon_ring_write(ring, PACKET0(UVD_RBC_IB_SIZE, 0));
	radeon_ring_write(ring, ib->length_dw);
}

/**
 * uvd_v1_0_ib_test - test ib execution
 *
 * @rdev: radeon_device pointer
 * @ring: radeon_ring pointer
 *
 * Test if we can successfully execute an IB
 */
int uvd_v1_0_ib_test(struct radeon_device *rdev, struct radeon_ring *ring)
{
	struct radeon_fence *fence = NULL;
	int r;

	if (rdev->family < CHIP_RV740)
		r = radeon_set_uvd_clocks(rdev, 10000, 10000);
	else
		r = radeon_set_uvd_clocks(rdev, 53300, 40000);
	if (r) {
		DRM_ERROR("radeon: failed to raise UVD clocks (%d).\n", r);
		return r;
	}

	r = radeon_uvd_get_create_msg(rdev, ring->idx, 1, NULL);
	if (r) {
		DRM_ERROR("radeon: failed to get create msg (%d).\n", r);
		goto error;
	}

	r = radeon_uvd_get_destroy_msg(rdev, ring->idx, 1, &fence);
	if (r) {
		DRM_ERROR("radeon: failed to get destroy ib (%d).\n", r);
		goto error;
	}

	r = radeon_fence_wait_timeout(fence, false, usecs_to_jiffies(
		RADEON_USEC_IB_TEST_TIMEOUT));
	if (r < 0) {
		DRM_ERROR("radeon: fence wait failed (%d).\n", r);
		goto error;
	} else if (r == 0) {
		DRM_ERROR("radeon: fence wait timed out.\n");
		r = -ETIMEDOUT;
		goto error;
	}
	r = 0;
	DRM_INFO("ib test on ring %d succeeded\n",  ring->idx);
error:
	radeon_fence_unref(&fence);
	radeon_set_uvd_clocks(rdev, 0, 0);
	return r;
}
