/*
 * arch/arm/cpu/armv8/gx12b/sound.c
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the named License,
 * or any later version.
 *
 * 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.
 *
 */
#include <asm/arch/io.h>
#include <asm/arch/secure_apb.h>
#include <common.h>
#include <amlogic/auge_sound.h>


struct aiu_958_channel_status {
	unsigned short chstat0_l;
	unsigned short chstat1_l;
	unsigned short chstat0_r;
	unsigned short chstat1_r;
};

static int audiobus_read(unsigned long reg, unsigned int *val)
{
	*val = readl(reg);

	return 0;
}

static void audiobus_write(unsigned long reg, unsigned int val)
{
	writel(val, reg);
}

static int audiobus_update_bits(unsigned int reg, unsigned int mask, unsigned int value)
{
	bool change;
	unsigned int old, new;

	audiobus_read(reg, &old);

	new = (old & ~mask) | (value & mask);
	change = old != new;
	if (change)
		audiobus_write(reg, new);

	return change;
}

static void aml_set_audio_spdif_clk(void)
{
	/*mpll0: 25m*/
	audiobus_write(HHI_MPLL_CNTL0, 0x543);
	audiobus_write(HHI_MPLL_CNTL1, 0xC5101856);
	audiobus_write(HHI_MPLL_CNTL2, 0x40000033);

	/* audio clk gate */
	audiobus_write(EE_AUDIO_CLK_GATE_EN,
		       1 << 17 /* spdifout */
		       | 1 << 9 /* frddra */
		       | 1 << 0 /* ddr_arb */);

	/*SPDIFOUT_CTRL clk:6m*/
	audiobus_write(EE_AUDIO_CLK_SPDIFOUT_CTRL,
		       1 << 31    /* enable */
		       | 0 << 24 /* mpll0 */
		       | 3 << 0  /* dividor */);
}

static void aml_spdif_fifo_ctrl(void)
{
	/* reg mute val */
	audiobus_write(EE_AUDIO_SPDIFOUT_MUTE_VAL, 0x0);

	/* mask lane0 L/R, lsb first,  insert data from 31bits */
	audiobus_update_bits(EE_AUDIO_SPDIFOUT_CTRL0,
			     0x1<<22 | 0x1<<21 | 0x1<<20 | 0x1<<19 | 0xff << 4,
			     0x1<<22 | 0x1<<21 | 0x0<<20 | 0x0<<19 | 0x3 << 4);

	/* split 64bits ddr data to 2 sample */
	/* msb position of data */
	/* frddr_A */
	audiobus_update_bits(EE_AUDIO_SPDIFOUT_CTRL1,
			     0x3 << 24 | 0x1f << 8 | 0x7 << 4,
			     0 << 24 | (32 - 1) << 8 | 3<<4);

	audiobus_write(EE_AUDIO_SPDIFOUT_SWAP, 0x1 << 4);
}

static void spdifout_set_pcm_chsts(struct aiu_958_channel_status *set)
{
	if (!set) {
		printf("spdifout_set_pcm_chsts, error set NULL point\n");
		return;
	}

	audiobus_write(EE_AUDIO_SPDIFOUT_CHSTS0, set->chstat1_l << 16 | set->chstat0_l);
	audiobus_write(EE_AUDIO_SPDIFOUT_CHSTS6, set->chstat1_r << 16 | set->chstat0_r);
}

void frddr_init_without_mngr(void)
{
	unsigned int start_addr, end_addr, int_addr;
	static int buf[256];

	memset(buf, 0x0, sizeof(buf));
	start_addr = virt_to_phys(buf);
	end_addr = start_addr + sizeof(buf) - 1;
	int_addr = sizeof(buf) / 64;

	audiobus_write(EE_AUDIO_ARB_CTRL, 0x800000ff);

	audiobus_write(EE_AUDIO_FRDDR_A_START_ADDR, start_addr);

	audiobus_write(EE_AUDIO_FRDDR_A_INIT_ADDR, start_addr);

	audiobus_write(EE_AUDIO_FRDDR_A_FINISH_ADDR, end_addr);

	audiobus_write(EE_AUDIO_FRDDR_A_INT_ADDR, int_addr);

	audiobus_write(EE_AUDIO_FRDDR_A_CTRL1,
		       (0x40 - 1) << 24 | (0x20 - 1) << 16 | 2 << 8 | 0 << 0);

	audiobus_write(EE_AUDIO_FRDDR_A_CTRL0,
		       1 << 31
		       | 0 << 24
		       | 4 << 16
		       | 1 << 3 /* src0 enable */
		       | 3 << 0 /* src0 select spdifout*/
	);
}

static void aml_spdif_enable(void)
{
	/* reset */
	audiobus_update_bits(EE_AUDIO_SPDIFOUT_CTRL0, 3<<28, 0);
	audiobus_update_bits(EE_AUDIO_SPDIFOUT_CTRL0, 1<<29, 1<<29);
	audiobus_update_bits(EE_AUDIO_SPDIFOUT_CTRL0, 1<<28, 1<<28);
	/* enable */
	audiobus_update_bits(EE_AUDIO_SPDIFOUT_CTRL0, 1 << 31, 1 << 31);

	/* tohdmitx enable */
	audiobus_write(EE_AUDIO_TOHDMITX_CTRL0,
		       1 << 31
		       | 1 << 3 /* spdif_clk_cap_inv */
		       | 0 << 2 /* spdif_clk_inv */
		       | 0 << 1 /* spdif_out */
		       | 0 << 0 /* spdif_clk */
	);
}

static void aml_spdif_play(void)
{
	struct aiu_958_channel_status chstat;

	chstat.chstat0_l = 0x0100;
	chstat.chstat0_r = 0x0100;
	chstat.chstat1_l = 0X200;
	chstat.chstat1_r = 0X200;

	aml_spdif_fifo_ctrl();
	spdifout_set_pcm_chsts(&chstat);
	frddr_init_without_mngr();
	aml_spdif_enable();
}

int aml_audio_init(void)
{
	printf("aml_audio_init\n");

	aml_set_audio_spdif_clk();
	aml_spdif_play();

	return 0;
}
