// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
//
// This file is provided under a dual BSD/GPLv2 license. When using or
// redistributing this file, you may do so under either license.
//
// Copyright(c) 2021 Advanced Micro Devices, Inc.
//
// Authors: Ajit Kumar Pandey <AjitKumar.Pandey@amd.com>

/*
 * Hardware interface for generic AMD audio DSP ACP IP
 */

#include "../ops.h"
#include "acp-dsp-offset.h"
#include "acp.h"

#define PTE_GRP1_OFFSET		0x00000000
#define PTE_GRP2_OFFSET		0x00800000
#define PTE_GRP3_OFFSET		0x01000000
#define PTE_GRP4_OFFSET		0x01800000
#define PTE_GRP5_OFFSET		0x02000000
#define PTE_GRP6_OFFSET		0x02800000
#define PTE_GRP7_OFFSET		0x03000000
#define PTE_GRP8_OFFSET		0x03800000

int acp_dsp_stream_config(struct snd_sof_dev *sdev, struct acp_dsp_stream *stream)
{
	unsigned int pte_reg, pte_size, phy_addr_offset, index;
	int stream_tag = stream->stream_tag;
	u32 low, high, offset, reg_val;
	dma_addr_t addr;
	int page_idx;

	switch (stream_tag) {
	case 1:
		pte_reg = ACPAXI2AXI_ATU_BASE_ADDR_GRP_1;
		pte_size = ACPAXI2AXI_ATU_PAGE_SIZE_GRP_1;
		offset = offsetof(struct scratch_reg_conf, grp1_pte);
		stream->reg_offset = PTE_GRP1_OFFSET;
		break;
	case 2:
		pte_reg = ACPAXI2AXI_ATU_BASE_ADDR_GRP_2;
		pte_size = ACPAXI2AXI_ATU_PAGE_SIZE_GRP_2;
		offset = offsetof(struct scratch_reg_conf, grp2_pte);
		stream->reg_offset = PTE_GRP2_OFFSET;
		break;
	case 3:
		pte_reg = ACPAXI2AXI_ATU_BASE_ADDR_GRP_3;
		pte_size = ACPAXI2AXI_ATU_PAGE_SIZE_GRP_3;
		offset = offsetof(struct scratch_reg_conf, grp3_pte);
		stream->reg_offset = PTE_GRP3_OFFSET;
		break;
	case 4:
		pte_reg = ACPAXI2AXI_ATU_BASE_ADDR_GRP_4;
		pte_size = ACPAXI2AXI_ATU_PAGE_SIZE_GRP_4;
		offset = offsetof(struct scratch_reg_conf, grp4_pte);
		stream->reg_offset = PTE_GRP4_OFFSET;
		break;
	case 5:
		pte_reg = ACPAXI2AXI_ATU_BASE_ADDR_GRP_5;
		pte_size = ACPAXI2AXI_ATU_PAGE_SIZE_GRP_5;
		offset = offsetof(struct scratch_reg_conf, grp5_pte);
		stream->reg_offset = PTE_GRP5_OFFSET;
		break;
	case 6:
		pte_reg = ACPAXI2AXI_ATU_BASE_ADDR_GRP_6;
		pte_size = ACPAXI2AXI_ATU_PAGE_SIZE_GRP_6;
		offset = offsetof(struct scratch_reg_conf, grp6_pte);
		stream->reg_offset = PTE_GRP6_OFFSET;
		break;
	case 7:
		pte_reg = ACPAXI2AXI_ATU_BASE_ADDR_GRP_7;
		pte_size = ACPAXI2AXI_ATU_PAGE_SIZE_GRP_7;
		offset = offsetof(struct scratch_reg_conf, grp7_pte);
		stream->reg_offset = PTE_GRP7_OFFSET;
		break;
	case 8:
		pte_reg = ACPAXI2AXI_ATU_BASE_ADDR_GRP_8;
		pte_size = ACPAXI2AXI_ATU_PAGE_SIZE_GRP_8;
		offset = offsetof(struct scratch_reg_conf, grp8_pte);
		stream->reg_offset = PTE_GRP8_OFFSET;
		break;
	default:
		dev_err(sdev->dev, "Invalid stream tag %d\n", stream_tag);
		return -EINVAL;
	}

	/* write phy_addr in scratch memory */

	phy_addr_offset = offsetof(struct scratch_reg_conf, reg_offset);
	index = stream_tag - 1;
	phy_addr_offset = phy_addr_offset + index * 4;

	snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_SCRATCH_REG_0 +
			  phy_addr_offset, stream->reg_offset);

	/* Group Enable */
	reg_val = ACP_SRAM_PTE_OFFSET + offset;
	snd_sof_dsp_write(sdev, ACP_DSP_BAR, pte_reg, reg_val | BIT(31));
	snd_sof_dsp_write(sdev, ACP_DSP_BAR, pte_size, PAGE_SIZE_4K_ENABLE);

	for (page_idx = 0; page_idx < stream->num_pages; page_idx++) {
		addr = snd_sgbuf_get_addr(stream->dmab, page_idx * PAGE_SIZE);

		/* Load the low address of page int ACP SRAM through SRBM */
		low = lower_32_bits(addr);
		high = upper_32_bits(addr);

		snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_SCRATCH_REG_0 + offset, low);

		high |= BIT(31);
		snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_SCRATCH_REG_0 + offset + 4, high);
		/* Move to next physically contiguous page */
		offset += 8;
	}

	/* Flush ATU Cache after PTE Update */
	snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACPAXI2AXI_ATU_CTRL, ACP_ATU_CACHE_INVALID);

	return 0;
}

struct acp_dsp_stream *acp_dsp_stream_get(struct snd_sof_dev *sdev, int tag)
{
	struct acp_dev_data *adata = sdev->pdata->hw_pdata;
	struct acp_dsp_stream *stream = adata->stream_buf;
	int i;

	for (i = 0; i < ACP_MAX_STREAM; i++, stream++) {
		if (stream->active)
			continue;

		/* return stream if tag not specified*/
		if (!tag) {
			stream->active = 1;
			return stream;
		}

		/* check if this is the requested stream tag */
		if (stream->stream_tag == tag) {
			stream->active = 1;
			return stream;
		}
	}

	dev_err(sdev->dev, "stream %d active or no inactive stream\n", tag);
	return NULL;
}
EXPORT_SYMBOL_NS(acp_dsp_stream_get, SND_SOC_SOF_AMD_COMMON);

int acp_dsp_stream_put(struct snd_sof_dev *sdev,
		       struct acp_dsp_stream *acp_stream)
{
	struct acp_dev_data *adata = sdev->pdata->hw_pdata;
	struct acp_dsp_stream *stream = adata->stream_buf;
	int i;

	/* Free an active stream */
	for (i = 0; i < ACP_MAX_STREAM; i++, stream++) {
		if (stream == acp_stream) {
			stream->active = 0;
			return 0;
		}
	}

	dev_err(sdev->dev, "Cannot find active stream tag %d\n", acp_stream->stream_tag);
	return -EINVAL;
}
EXPORT_SYMBOL_NS(acp_dsp_stream_put, SND_SOC_SOF_AMD_COMMON);

int acp_dsp_stream_init(struct snd_sof_dev *sdev)
{
	struct acp_dev_data *adata = sdev->pdata->hw_pdata;
	int i;

	for (i = 0; i < ACP_MAX_STREAM; i++) {
		adata->stream_buf[i].sdev = sdev;
		adata->stream_buf[i].active = 0;
		adata->stream_buf[i].stream_tag = i + 1;
	}
	return 0;
}
EXPORT_SYMBOL_NS(acp_dsp_stream_init, SND_SOC_SOF_AMD_COMMON);
