/*
 * Copyright 2012-15 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: AMD
 *
 */

#include "reg_helper.h"
#include "dce_audio.h"
#include "dce/dce_11_0_d.h"
#include "dce/dce_11_0_sh_mask.h"

#define DCE_AUD(audio)\
	container_of(audio, struct dce_audio, base)

#define CTX \
	aud->base.ctx

#define DC_LOGGER_INIT()

#define REG(reg)\
	(aud->regs->reg)

#undef FN
#define FN(reg_name, field_name) \
	aud->shifts->field_name, aud->masks->field_name

#define IX_REG(reg)\
	ix ## reg

#define AZ_REG_READ(reg_name) \
		read_indirect_azalia_reg(audio, IX_REG(reg_name))

#define AZ_REG_WRITE(reg_name, value) \
		write_indirect_azalia_reg(audio, IX_REG(reg_name), value)

static void write_indirect_azalia_reg(struct audio *audio,
	uint32_t reg_index,
	uint32_t reg_data)
{
	struct dce_audio *aud = DCE_AUD(audio);

	/* AZALIA_F0_CODEC_ENDPOINT_INDEX  endpoint index  */
	REG_SET(AZALIA_F0_CODEC_ENDPOINT_INDEX, 0,
			AZALIA_ENDPOINT_REG_INDEX, reg_index);

	/* AZALIA_F0_CODEC_ENDPOINT_DATA  endpoint data  */
	REG_SET(AZALIA_F0_CODEC_ENDPOINT_DATA, 0,
			AZALIA_ENDPOINT_REG_DATA, reg_data);

	DC_LOG_HW_AUDIO("AUDIO:write_indirect_azalia_reg: index: %u  data: %u\n",
		reg_index, reg_data);
}

static uint32_t read_indirect_azalia_reg(struct audio *audio, uint32_t reg_index)
{
	struct dce_audio *aud = DCE_AUD(audio);

	uint32_t value = 0;

	/* AZALIA_F0_CODEC_ENDPOINT_INDEX  endpoint index  */
	REG_SET(AZALIA_F0_CODEC_ENDPOINT_INDEX, 0,
			AZALIA_ENDPOINT_REG_INDEX, reg_index);

	/* AZALIA_F0_CODEC_ENDPOINT_DATA  endpoint data  */
	value = REG_READ(AZALIA_F0_CODEC_ENDPOINT_DATA);

	DC_LOG_HW_AUDIO("AUDIO:read_indirect_azalia_reg: index: %u  data: %u\n",
		reg_index, value);

	return value;
}

static bool is_audio_format_supported(
	const struct audio_info *audio_info,
	enum audio_format_code audio_format_code,
	uint32_t *format_index)
{
	uint32_t index;
	uint32_t max_channe_index = 0;
	bool found = false;

	if (audio_info == NULL)
		return found;

	/* pass through whole array */
	for (index = 0; index < audio_info->mode_count; index++) {
		if (audio_info->modes[index].format_code == audio_format_code) {
			if (found) {
				/* format has multiply entries, choose one with
				 *  highst number of channels */
				if (audio_info->modes[index].channel_count >
		audio_info->modes[max_channe_index].channel_count) {
					max_channe_index = index;
				}
			} else {
				/* format found, save it's index */
				found = true;
				max_channe_index = index;
			}
		}
	}

	/* return index */
	if (found && format_index != NULL)
		*format_index = max_channe_index;

	return found;
}

/*For HDMI, calculate if specified sample rates can fit into a given timing */
static void check_audio_bandwidth_hdmi(
	const struct audio_crtc_info *crtc_info,
	uint32_t channel_count,
	union audio_sample_rates *sample_rates)
{
	uint32_t samples;
	uint32_t  h_blank;
	bool limit_freq_to_48_khz = false;
	bool limit_freq_to_88_2_khz = false;
	bool limit_freq_to_96_khz = false;
	bool limit_freq_to_174_4_khz = false;

	/* For two channels supported return whatever sink support,unmodified*/
	if (channel_count > 2) {

		/* Based on HDMI spec 1.3 Table 7.5 */
		if ((crtc_info->requested_pixel_clock <= 27000) &&
		(crtc_info->v_active <= 576) &&
		!(crtc_info->interlaced) &&
		!(crtc_info->pixel_repetition == 2 ||
		crtc_info->pixel_repetition == 4)) {
			limit_freq_to_48_khz = true;

		} else if ((crtc_info->requested_pixel_clock <= 27000) &&
				(crtc_info->v_active <= 576) &&
				(crtc_info->interlaced) &&
				(crtc_info->pixel_repetition == 2)) {
			limit_freq_to_88_2_khz = true;

		} else if ((crtc_info->requested_pixel_clock <= 54000) &&
				(crtc_info->v_active <= 576) &&
				!(crtc_info->interlaced)) {
			limit_freq_to_174_4_khz = true;
		}
	}

	/* Also do some calculation for the available Audio Bandwidth for the
	 * 8 ch (i.e. for the Layout 1 => ch > 2)
	 */
	h_blank = crtc_info->h_total - crtc_info->h_active;

	if (crtc_info->pixel_repetition)
		h_blank *= crtc_info->pixel_repetition;

	/*based on HDMI spec 1.3 Table 7.5 */
	h_blank -= 58;
	/*for Control Period */
	h_blank -= 16;

	samples = h_blank * 10;
	/* Number of Audio Packets (multiplied by 10) per Line (for 8 ch number
	 * of Audio samples per line multiplied by 10 - Layout 1)
	 */
	samples /= 32;
	samples *= crtc_info->v_active;
	/*Number of samples multiplied by 10, per second */
	samples *= crtc_info->refresh_rate;
	/*Number of Audio samples per second */
	samples /= 10;

	/* @todo do it after deep color is implemented
	 * 8xx - deep color bandwidth scaling
	 * Extra bandwidth is avaliable in deep color b/c link runs faster than
	 * pixel rate. This has the effect of allowing more tmds characters to
	 * be transmitted during blank
	 */

	switch (crtc_info->color_depth) {
	case COLOR_DEPTH_888:
		samples *= 4;
		break;
	case COLOR_DEPTH_101010:
		samples *= 5;
		break;
	case COLOR_DEPTH_121212:
		samples *= 6;
		break;
	default:
		samples *= 4;
		break;
	}

	samples /= 4;

	/*check limitation*/
	if (samples < 88200)
		limit_freq_to_48_khz = true;
	else if (samples < 96000)
		limit_freq_to_88_2_khz = true;
	else if (samples < 176400)
		limit_freq_to_96_khz = true;
	else if (samples < 192000)
		limit_freq_to_174_4_khz = true;

	if (sample_rates != NULL) {
		/* limit frequencies */
		if (limit_freq_to_174_4_khz)
			sample_rates->rate.RATE_192 = 0;

		if (limit_freq_to_96_khz) {
			sample_rates->rate.RATE_192 = 0;
			sample_rates->rate.RATE_176_4 = 0;
		}
		if (limit_freq_to_88_2_khz) {
			sample_rates->rate.RATE_192 = 0;
			sample_rates->rate.RATE_176_4 = 0;
			sample_rates->rate.RATE_96 = 0;
		}
		if (limit_freq_to_48_khz) {
			sample_rates->rate.RATE_192 = 0;
			sample_rates->rate.RATE_176_4 = 0;
			sample_rates->rate.RATE_96 = 0;
			sample_rates->rate.RATE_88_2 = 0;
		}
	}
}

/*For DP SST, calculate if specified sample rates can fit into a given timing */
static void check_audio_bandwidth_dpsst(
	const struct audio_crtc_info *crtc_info,
	uint32_t channel_count,
	union audio_sample_rates *sample_rates)
{
	/* do nothing */
}

/*For DP MST, calculate if specified sample rates can fit into a given timing */
static void check_audio_bandwidth_dpmst(
	const struct audio_crtc_info *crtc_info,
	uint32_t channel_count,
	union audio_sample_rates *sample_rates)
{
	/* do nothing  */
}

static void check_audio_bandwidth(
	const struct audio_crtc_info *crtc_info,
	uint32_t channel_count,
	enum signal_type signal,
	union audio_sample_rates *sample_rates)
{
	switch (signal) {
	case SIGNAL_TYPE_HDMI_TYPE_A:
		check_audio_bandwidth_hdmi(
			crtc_info, channel_count, sample_rates);
		break;
	case SIGNAL_TYPE_EDP:
	case SIGNAL_TYPE_DISPLAY_PORT:
		check_audio_bandwidth_dpsst(
			crtc_info, channel_count, sample_rates);
		break;
	case SIGNAL_TYPE_DISPLAY_PORT_MST:
		check_audio_bandwidth_dpmst(
			crtc_info, channel_count, sample_rates);
		break;
	default:
		break;
	}
}

/* expose/not expose HBR capability to Audio driver */
static void set_high_bit_rate_capable(
	struct audio *audio,
	bool capable)
{
	uint32_t value = 0;

	/* set high bit rate audio capable*/
	value = AZ_REG_READ(AZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_HBR);

	set_reg_field_value(value, capable,
		AZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_HBR,
		HBR_CAPABLE);

	AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_HBR, value);
}

/* set video latency in in ms/2+1 */
static void set_video_latency(
	struct audio *audio,
	int latency_in_ms)
{
	uint32_t value = 0;

	if ((latency_in_ms < 0) || (latency_in_ms > 255))
		return;

	value = AZ_REG_READ(AZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_LIPSYNC);

	set_reg_field_value(value, latency_in_ms,
		AZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_LIPSYNC,
		VIDEO_LIPSYNC);

	AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_LIPSYNC,
		value);
}

/* set audio latency in in ms/2+1 */
static void set_audio_latency(
	struct audio *audio,
	int latency_in_ms)
{
	uint32_t value = 0;

	if (latency_in_ms < 0)
		latency_in_ms = 0;

	if (latency_in_ms > 255)
		latency_in_ms = 255;

	value = AZ_REG_READ(AZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_LIPSYNC);

	set_reg_field_value(value, latency_in_ms,
		AZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_LIPSYNC,
		AUDIO_LIPSYNC);

	AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_LIPSYNC,
		value);
}

void dce_aud_az_enable(struct audio *audio)
{
	uint32_t value = AZ_REG_READ(AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL);
	DC_LOGGER_INIT();

	set_reg_field_value(value, 1,
			    AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL,
			    CLOCK_GATING_DISABLE);
	set_reg_field_value(value, 1,
			    AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL,
			    AUDIO_ENABLED);

	AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL, value);
	set_reg_field_value(value, 0,
			AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL,
			CLOCK_GATING_DISABLE);
	AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL, value);

	DC_LOG_HW_AUDIO("\n\t========= AUDIO:dce_aud_az_enable: index: %u  data: 0x%x\n",
			audio->inst, value);
}

void dce_aud_az_disable(struct audio *audio)
{
	uint32_t value;
	DC_LOGGER_INIT();

	value = AZ_REG_READ(AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL);
	set_reg_field_value(value, 1,
			AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL,
			CLOCK_GATING_DISABLE);
	AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL, value);

	set_reg_field_value(value, 0,
		AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL,
		AUDIO_ENABLED);
	AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL, value);

	set_reg_field_value(value, 0,
			AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL,
			CLOCK_GATING_DISABLE);
	AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL, value);
	value = AZ_REG_READ(AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL);
	DC_LOG_HW_AUDIO("\n\t========= AUDIO:dce_aud_az_disable: index: %u  data: 0x%x\n",
			audio->inst, value);
}

void dce_aud_az_configure(
	struct audio *audio,
	enum signal_type signal,
	const struct audio_crtc_info *crtc_info,
	const struct audio_info *audio_info)
{
	struct dce_audio *aud = DCE_AUD(audio);

	uint32_t speakers = audio_info->flags.info.ALLSPEAKERS;
	uint32_t value;
	uint32_t field = 0;
	enum audio_format_code audio_format_code;
	uint32_t format_index;
	uint32_t index;
	bool is_ac3_supported = false;
	union audio_sample_rates sample_rate;
	uint32_t strlen = 0;
	value = AZ_REG_READ(AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL);
	set_reg_field_value(value, 1,
			AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL,
			CLOCK_GATING_DISABLE);
	AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL, value);

	/* Speaker Allocation */
	/*
	uint32_t value;
	uint32_t field = 0;*/
	value = AZ_REG_READ(AZALIA_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER);

	set_reg_field_value(value,
		speakers,
		AZALIA_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER,
		SPEAKER_ALLOCATION);

	/* LFE_PLAYBACK_LEVEL = LFEPBL
	 * LFEPBL = 0 : Unknown or refer to other information
	 * LFEPBL = 1 : 0dB playback
	 * LFEPBL = 2 : +10dB playback
	 * LFE_BL = 3 : Reserved
	 */
	set_reg_field_value(value,
		0,
		AZALIA_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER,
		LFE_PLAYBACK_LEVEL);
	/* todo: according to reg spec LFE_PLAYBACK_LEVEL is read only.
	 *  why are we writing to it?  DCE8 does not write this */


	set_reg_field_value(value,
		0,
		AZALIA_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER,
		HDMI_CONNECTION);

	set_reg_field_value(value,
		0,
		AZALIA_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER,
		DP_CONNECTION);

	field = get_reg_field_value(value,
			AZALIA_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER,
			EXTRA_CONNECTION_INFO);

	field &= ~0x1;

	set_reg_field_value(value,
		field,
		AZALIA_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER,
		EXTRA_CONNECTION_INFO);

	/* set audio for output signal */
	switch (signal) {
	case SIGNAL_TYPE_HDMI_TYPE_A:
		set_reg_field_value(value,
			1,
			AZALIA_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER,
			HDMI_CONNECTION);

		break;

	case SIGNAL_TYPE_EDP:
	case SIGNAL_TYPE_DISPLAY_PORT:
	case SIGNAL_TYPE_DISPLAY_PORT_MST:
		set_reg_field_value(value,
			1,
			AZALIA_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER,
			DP_CONNECTION);
		break;
	default:
		BREAK_TO_DEBUGGER();
		break;
	}

	AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_CHANNEL_SPEAKER, value);

	/*  Audio Descriptors   */
	/* pass through all formats */
	for (format_index = 0; format_index < AUDIO_FORMAT_CODE_COUNT;
			format_index++) {
		audio_format_code =
			(AUDIO_FORMAT_CODE_FIRST + format_index);

		/* those are unsupported, skip programming */
		if (audio_format_code == AUDIO_FORMAT_CODE_1BITAUDIO ||
			audio_format_code == AUDIO_FORMAT_CODE_DST)
			continue;

		value = 0;

		/* check if supported */
		if (is_audio_format_supported(
				audio_info, audio_format_code, &index)) {
			const struct audio_mode *audio_mode =
					&audio_info->modes[index];
			union audio_sample_rates sample_rates =
					audio_mode->sample_rates;
			uint8_t byte2 = audio_mode->max_bit_rate;

			/* adjust specific properties */
			switch (audio_format_code) {
			case AUDIO_FORMAT_CODE_LINEARPCM: {
				check_audio_bandwidth(
					crtc_info,
					audio_mode->channel_count,
					signal,
					&sample_rates);

				byte2 = audio_mode->sample_size;

				set_reg_field_value(value,
						sample_rates.all,
						AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR0,
						SUPPORTED_FREQUENCIES_STEREO);
				}
				break;
			case AUDIO_FORMAT_CODE_AC3:
				is_ac3_supported = true;
				break;
			case AUDIO_FORMAT_CODE_DOLBYDIGITALPLUS:
			case AUDIO_FORMAT_CODE_DTS_HD:
			case AUDIO_FORMAT_CODE_MAT_MLP:
			case AUDIO_FORMAT_CODE_DST:
			case AUDIO_FORMAT_CODE_WMAPRO:
				byte2 = audio_mode->vendor_specific;
				break;
			default:
				break;
			}

			/* fill audio format data */
			set_reg_field_value(value,
					audio_mode->channel_count - 1,
					AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR0,
					MAX_CHANNELS);

			set_reg_field_value(value,
					sample_rates.all,
					AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR0,
					SUPPORTED_FREQUENCIES);

			set_reg_field_value(value,
					byte2,
					AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR0,
					DESCRIPTOR_BYTE_2);
		} /* if */

		AZ_REG_WRITE(
				AZALIA_F0_CODEC_PIN_CONTROL_AUDIO_DESCRIPTOR0 + format_index,
				value);
	} /* for */

	if (is_ac3_supported)
		/* todo: this reg global.  why program global register? */
		REG_WRITE(AZALIA_F0_CODEC_FUNCTION_PARAMETER_STREAM_FORMATS,
				0x05);

	/* check for 192khz/8-Ch support for HBR requirements */
	sample_rate.all = 0;
	sample_rate.rate.RATE_192 = 1;

	check_audio_bandwidth(
		crtc_info,
		8,
		signal,
		&sample_rate);

	set_high_bit_rate_capable(audio, sample_rate.rate.RATE_192);

	/* Audio and Video Lipsync */
	set_video_latency(audio, audio_info->video_latency);
	set_audio_latency(audio, audio_info->audio_latency);

	value = 0;
	set_reg_field_value(value, audio_info->manufacture_id,
		AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO0,
		MANUFACTURER_ID);

	set_reg_field_value(value, audio_info->product_id,
		AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO0,
		PRODUCT_ID);

	AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO0,
		value);

	value = 0;

	/*get display name string length */
	while (audio_info->display_name[strlen++] != '\0') {
		if (strlen >=
		MAX_HW_AUDIO_INFO_DISPLAY_NAME_SIZE_IN_CHARS)
			break;
		}
	set_reg_field_value(value, strlen,
		AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO1,
		SINK_DESCRIPTION_LEN);

	AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO1,
		value);

	/*
	*write the port ID:
	*PORT_ID0 = display index
	*PORT_ID1 = 16bit BDF
	*(format MSB->LSB: 8bit Bus, 5bit Device, 3bit Function)
	*/

	value = 0;

	set_reg_field_value(value, audio_info->port_id[0],
		AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO2,
		PORT_ID0);

	AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO2, value);

	value = 0;
	set_reg_field_value(value, audio_info->port_id[1],
		AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO3,
		PORT_ID1);

	AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO3, value);

	/*write the 18 char monitor string */

	value = 0;
	set_reg_field_value(value, audio_info->display_name[0],
		AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO4,
		DESCRIPTION0);

	set_reg_field_value(value, audio_info->display_name[1],
		AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO4,
		DESCRIPTION1);

	set_reg_field_value(value, audio_info->display_name[2],
		AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO4,
		DESCRIPTION2);

	set_reg_field_value(value, audio_info->display_name[3],
		AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO4,
		DESCRIPTION3);

	AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO4, value);

	value = 0;
	set_reg_field_value(value, audio_info->display_name[4],
		AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO5,
		DESCRIPTION4);

	set_reg_field_value(value, audio_info->display_name[5],
		AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO5,
		DESCRIPTION5);

	set_reg_field_value(value, audio_info->display_name[6],
		AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO5,
		DESCRIPTION6);

	set_reg_field_value(value, audio_info->display_name[7],
		AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO5,
		DESCRIPTION7);

	AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO5, value);

	value = 0;
	set_reg_field_value(value, audio_info->display_name[8],
		AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO6,
		DESCRIPTION8);

	set_reg_field_value(value, audio_info->display_name[9],
		AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO6,
		DESCRIPTION9);

	set_reg_field_value(value, audio_info->display_name[10],
		AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO6,
		DESCRIPTION10);

	set_reg_field_value(value, audio_info->display_name[11],
		AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO6,
		DESCRIPTION11);

	AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO6, value);

	value = 0;
	set_reg_field_value(value, audio_info->display_name[12],
		AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO7,
		DESCRIPTION12);

	set_reg_field_value(value, audio_info->display_name[13],
		AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO7,
		DESCRIPTION13);

	set_reg_field_value(value, audio_info->display_name[14],
		AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO7,
		DESCRIPTION14);

	set_reg_field_value(value, audio_info->display_name[15],
		AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO7,
		DESCRIPTION15);

	AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO7, value);

	value = 0;
	set_reg_field_value(value, audio_info->display_name[16],
		AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO8,
		DESCRIPTION16);

	set_reg_field_value(value, audio_info->display_name[17],
		AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO8,
		DESCRIPTION17);

	AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_SINK_INFO8, value);
	value = AZ_REG_READ(AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL);
	set_reg_field_value(value, 0,
			AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL,
			CLOCK_GATING_DISABLE);
	AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL, value);
}

/*
* todo: wall clk related functionality probably belong to clock_src.
*/

/* search pixel clock value for Azalia HDMI Audio */
static void get_azalia_clock_info_hdmi(
	uint32_t crtc_pixel_clock_in_khz,
	uint32_t actual_pixel_clock_in_khz,
	struct azalia_clock_info *azalia_clock_info)
{
	/* audio_dto_phase= 24 * 10,000;
	 *   24MHz in [100Hz] units */
	azalia_clock_info->audio_dto_phase =
			24 * 10000;

	/* audio_dto_module = PCLKFrequency * 10,000;
	 *  [khz] -> [100Hz] */
	azalia_clock_info->audio_dto_module =
			actual_pixel_clock_in_khz * 10;
}

static void get_azalia_clock_info_dp(
	uint32_t requested_pixel_clock_in_khz,
	const struct audio_pll_info *pll_info,
	struct azalia_clock_info *azalia_clock_info)
{
	/* Reported dpDtoSourceClockInkhz value for
	 * DCE8 already adjusted for SS, do not need any
	 * adjustment here anymore
	 */

	/*audio_dto_phase = 24 * 10,000;
	 * 24MHz in [100Hz] units */
	azalia_clock_info->audio_dto_phase = 24 * 10000;

	/*audio_dto_module = dpDtoSourceClockInkhz * 10,000;
	 *  [khz] ->[100Hz] */
	azalia_clock_info->audio_dto_module =
		pll_info->dp_dto_source_clock_in_khz * 10;
}

void dce_aud_wall_dto_setup(
	struct audio *audio,
	enum signal_type signal,
	const struct audio_crtc_info *crtc_info,
	const struct audio_pll_info *pll_info)
{
	struct dce_audio *aud = DCE_AUD(audio);

	struct azalia_clock_info clock_info = { 0 };

	if (dc_is_hdmi_signal(signal)) {
		uint32_t src_sel;

		/*DTO0 Programming goal:
		-generate 24MHz, 128*Fs from 24MHz
		-use DTO0 when an active HDMI port is connected
		(optionally a DP is connected) */

		/* calculate DTO settings */
		get_azalia_clock_info_hdmi(
			crtc_info->requested_pixel_clock,
			crtc_info->calculated_pixel_clock,
			&clock_info);

		DC_LOG_HW_AUDIO("\n%s:Input::requested_pixel_clock = %d"\
				"calculated_pixel_clock =%d\n"\
				"audio_dto_module = %d audio_dto_phase =%d \n\n", __func__,\
				crtc_info->requested_pixel_clock,\
				crtc_info->calculated_pixel_clock,\
				clock_info.audio_dto_module,\
				clock_info.audio_dto_phase);

		/* On TN/SI, Program DTO source select and DTO select before
		programming DTO modulo and DTO phase. These bits must be
		programmed first, otherwise there will be no HDMI audio at boot
		up. This is a HW sequence change (different from old ASICs).
		Caution when changing this programming sequence.

		HDMI enabled, using DTO0
		program master CRTC for DTO0 */
		src_sel = pll_info->dto_source - DTO_SOURCE_ID0;
		REG_UPDATE_2(DCCG_AUDIO_DTO_SOURCE,
			DCCG_AUDIO_DTO0_SOURCE_SEL, src_sel,
			DCCG_AUDIO_DTO_SEL, 0);

		/* module */
		REG_UPDATE(DCCG_AUDIO_DTO0_MODULE,
			DCCG_AUDIO_DTO0_MODULE, clock_info.audio_dto_module);

		/* phase */
		REG_UPDATE(DCCG_AUDIO_DTO0_PHASE,
			DCCG_AUDIO_DTO0_PHASE, clock_info.audio_dto_phase);
	} else {
		/*DTO1 Programming goal:
		-generate 24MHz, 512*Fs, 128*Fs from 24MHz
		-default is to used DTO1, and switch to DTO0 when an audio
		master HDMI port is connected
		-use as default for DP

		calculate DTO settings */
		get_azalia_clock_info_dp(
			crtc_info->requested_pixel_clock,
			pll_info,
			&clock_info);

		/* Program DTO select before programming DTO modulo and DTO
		phase. default to use DTO1 */

		REG_UPDATE(DCCG_AUDIO_DTO_SOURCE,
				DCCG_AUDIO_DTO_SEL, 1);

		REG_UPDATE(DCCG_AUDIO_DTO_SOURCE,
			DCCG_AUDIO_DTO_SEL, 1);
			/* DCCG_AUDIO_DTO2_USE_512FBR_DTO, 1)
			 * Select 512fs for DP TODO: web register definition
			 * does not match register header file
			 * DCE11 version it's commented out while DCE8 it's set to 1
			*/

		/* module */
		REG_UPDATE(DCCG_AUDIO_DTO1_MODULE,
				DCCG_AUDIO_DTO1_MODULE, clock_info.audio_dto_module);

		/* phase */
		REG_UPDATE(DCCG_AUDIO_DTO1_PHASE,
				DCCG_AUDIO_DTO1_PHASE, clock_info.audio_dto_phase);

		REG_UPDATE(DCCG_AUDIO_DTO_SOURCE,
				DCCG_AUDIO_DTO2_USE_512FBR_DTO, 1);

	}
}

static bool dce_aud_endpoint_valid(struct audio *audio)
{
	uint32_t value;
	uint32_t port_connectivity;

	value = AZ_REG_READ(
			AZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_CONFIGURATION_DEFAULT);

	port_connectivity = get_reg_field_value(value,
			AZALIA_F0_CODEC_PIN_CONTROL_RESPONSE_CONFIGURATION_DEFAULT,
			PORT_CONNECTIVITY);

	return !(port_connectivity == 1);
}

/* initialize HW state */
void dce_aud_hw_init(
		struct audio *audio)
{
	uint32_t value;
	struct dce_audio *aud = DCE_AUD(audio);

	/* we only need to program the following registers once, so we only do
	it for the inst 0*/
	if (audio->inst != 0)
		return;

	/* Suport R5 - 32khz
	 * Suport R6 - 44.1khz
	 * Suport R7 - 48khz
	 */
	/*disable clock gating before write to endpoint register*/
	value = AZ_REG_READ(AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL);
	set_reg_field_value(value, 1,
			AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL,
			CLOCK_GATING_DISABLE);
	AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL, value);
	REG_UPDATE(AZALIA_F0_CODEC_FUNCTION_PARAMETER_SUPPORTED_SIZE_RATES,
			AUDIO_RATE_CAPABILITIES, 0x70);

	/*Keep alive bit to verify HW block in BU. */
	REG_UPDATE_2(AZALIA_F0_CODEC_FUNCTION_PARAMETER_POWER_STATES,
			CLKSTOP, 1,
			EPSS, 1);
	set_reg_field_value(value, 0,
			AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL,
			CLOCK_GATING_DISABLE);
	AZ_REG_WRITE(AZALIA_F0_CODEC_PIN_CONTROL_HOT_PLUG_CONTROL, value);
}

static const struct audio_funcs funcs = {
	.endpoint_valid = dce_aud_endpoint_valid,
	.hw_init = dce_aud_hw_init,
	.wall_dto_setup = dce_aud_wall_dto_setup,
	.az_enable = dce_aud_az_enable,
	.az_disable = dce_aud_az_disable,
	.az_configure = dce_aud_az_configure,
	.destroy = dce_aud_destroy,
};

void dce_aud_destroy(struct audio **audio)
{
	struct dce_audio *aud = DCE_AUD(*audio);

	kfree(aud);
	*audio = NULL;
}

struct audio *dce_audio_create(
		struct dc_context *ctx,
		unsigned int inst,
		const struct dce_audio_registers *reg,
		const struct dce_audio_shift *shifts,
		const struct dce_aduio_mask *masks
		)
{
	struct dce_audio *audio = kzalloc(sizeof(*audio), GFP_KERNEL);

	if (audio == NULL) {
		ASSERT_CRITICAL(audio);
		return NULL;
	}

	audio->base.ctx = ctx;
	audio->base.inst = inst;
	audio->base.funcs = &funcs;

	audio->regs = reg;
	audio->shifts = shifts;
	audio->masks = masks;

	return &audio->base;
}

