brintos

brintos / linux-shallow public Read only

0
0
Text · 45.2 KiB · 5c2825b Raw
1571 lines · c
1/*2 * Copyright 2012-15 Advanced Micro Devices, Inc.3 *4 * Permission is hereby granted, free of charge, to any person obtaining a5 * copy of this software and associated documentation files (the "Software"),6 * to deal in the Software without restriction, including without limitation7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,8 *  and/or sell copies of the Software, and to permit persons to whom the9 * Software is furnished to do so, subject to the following conditions:10 *11 * The above copyright notice and this permission notice shall be included in12 * all copies or substantial portions of the Software.13 *14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR20 * OTHER DEALINGS IN THE SOFTWARE.21 *22 * Authors: AMD23 *24 */25 26#include "dc_bios_types.h"27#include "dce_stream_encoder.h"28#include "reg_helper.h"29#include "hw_shared.h"30 31#define DC_LOGGER \32		enc110->base.ctx->logger33 34#define REG(reg)\35	(enc110->regs->reg)36 37#undef FN38#define FN(reg_name, field_name) \39	enc110->se_shift->field_name, enc110->se_mask->field_name40 41#define VBI_LINE_0 042#define DP_BLANK_MAX_RETRY 2043#define HDMI_CLOCK_CHANNEL_RATE_MORE_340M 34000044 45#ifndef TMDS_CNTL__TMDS_PIXEL_ENCODING_MASK46	#define TMDS_CNTL__TMDS_PIXEL_ENCODING_MASK       0x00000010L47	#define TMDS_CNTL__TMDS_COLOR_FORMAT_MASK         0x00000300L48	#define	TMDS_CNTL__TMDS_PIXEL_ENCODING__SHIFT     0x0000000449	#define	TMDS_CNTL__TMDS_COLOR_FORMAT__SHIFT       0x0000000850#endif51 52enum {53	DP_MST_UPDATE_MAX_RETRY = 5054};55 56#define DCE110_SE(audio)\57	container_of(audio, struct dce110_stream_encoder, base)58 59#define CTX \60	enc110->base.ctx61 62static void dce110_update_generic_info_packet(63	struct dce110_stream_encoder *enc110,64	uint32_t packet_index,65	const struct dc_info_packet *info_packet)66{67	/* TODOFPGA Figure out a proper number for max_retries polling for lock68	 * use 50 for now.69	 */70	uint32_t max_retries = 50;71 72	/*we need turn on clock before programming AFMT block*/73	if (REG(AFMT_CNTL))74		REG_UPDATE(AFMT_CNTL, AFMT_AUDIO_CLOCK_EN, 1);75 76	if (REG(AFMT_VBI_PACKET_CONTROL1)) {77		if (packet_index >= 8)78			ASSERT(0);79 80		/* poll dig_update_lock is not locked -> asic internal signal81		 * assume otg master lock will unlock it82		 */83/*		REG_WAIT(AFMT_VBI_PACKET_CONTROL, AFMT_GENERIC_LOCK_STATUS,84				0, 10, max_retries);*/85 86		/* check if HW reading GSP memory */87		REG_WAIT(AFMT_VBI_PACKET_CONTROL, AFMT_GENERIC_CONFLICT,88				0, 10, max_retries);89 90		/* HW does is not reading GSP memory not reading too long ->91		 * something wrong. clear GPS memory access and notify?92		 * hw SW is writing to GSP memory93		 */94		REG_UPDATE(AFMT_VBI_PACKET_CONTROL, AFMT_GENERIC_CONFLICT_CLR, 1);95	}96	/* choose which generic packet to use */97	{98		REG_READ(AFMT_VBI_PACKET_CONTROL);99		REG_UPDATE(AFMT_VBI_PACKET_CONTROL,100				AFMT_GENERIC_INDEX, packet_index);101	}102 103	/* write generic packet header104	 * (4th byte is for GENERIC0 only) */105	{106		REG_SET_4(AFMT_GENERIC_HDR, 0,107				AFMT_GENERIC_HB0, info_packet->hb0,108				AFMT_GENERIC_HB1, info_packet->hb1,109				AFMT_GENERIC_HB2, info_packet->hb2,110				AFMT_GENERIC_HB3, info_packet->hb3);111	}112 113	/* write generic packet contents114	 * (we never use last 4 bytes)115	 * there are 8 (0-7) mmDIG0_AFMT_GENERIC0_x registers */116	{117		const uint32_t *content =118			(const uint32_t *) &info_packet->sb[0];119 120		REG_WRITE(AFMT_GENERIC_0, *content++);121		REG_WRITE(AFMT_GENERIC_1, *content++);122		REG_WRITE(AFMT_GENERIC_2, *content++);123		REG_WRITE(AFMT_GENERIC_3, *content++);124		REG_WRITE(AFMT_GENERIC_4, *content++);125		REG_WRITE(AFMT_GENERIC_5, *content++);126		REG_WRITE(AFMT_GENERIC_6, *content++);127		REG_WRITE(AFMT_GENERIC_7, *content);128	}129 130	if (!REG(AFMT_VBI_PACKET_CONTROL1)) {131		/* force double-buffered packet update */132		REG_UPDATE_2(AFMT_VBI_PACKET_CONTROL,133			AFMT_GENERIC0_UPDATE, (packet_index == 0),134			AFMT_GENERIC2_UPDATE, (packet_index == 2));135	}136 137	if (REG(AFMT_VBI_PACKET_CONTROL1)) {138		switch (packet_index) {139		case 0:140			REG_UPDATE(AFMT_VBI_PACKET_CONTROL1,141					AFMT_GENERIC0_FRAME_UPDATE, 1);142			break;143		case 1:144			REG_UPDATE(AFMT_VBI_PACKET_CONTROL1,145					AFMT_GENERIC1_FRAME_UPDATE, 1);146			break;147		case 2:148			REG_UPDATE(AFMT_VBI_PACKET_CONTROL1,149					AFMT_GENERIC2_FRAME_UPDATE, 1);150			break;151		case 3:152			REG_UPDATE(AFMT_VBI_PACKET_CONTROL1,153					AFMT_GENERIC3_FRAME_UPDATE, 1);154			break;155		case 4:156			REG_UPDATE(AFMT_VBI_PACKET_CONTROL1,157					AFMT_GENERIC4_FRAME_UPDATE, 1);158			break;159		case 5:160			REG_UPDATE(AFMT_VBI_PACKET_CONTROL1,161					AFMT_GENERIC5_FRAME_UPDATE, 1);162			break;163		case 6:164			REG_UPDATE(AFMT_VBI_PACKET_CONTROL1,165					AFMT_GENERIC6_FRAME_UPDATE, 1);166			break;167		case 7:168			REG_UPDATE(AFMT_VBI_PACKET_CONTROL1,169					AFMT_GENERIC7_FRAME_UPDATE, 1);170			break;171		default:172			break;173		}174	}175}176 177static void dce110_update_hdmi_info_packet(178	struct dce110_stream_encoder *enc110,179	uint32_t packet_index,180	const struct dc_info_packet *info_packet)181{182	uint32_t cont, send, line;183 184	if (info_packet->valid) {185		dce110_update_generic_info_packet(186			enc110,187			packet_index,188			info_packet);189 190		/* enable transmission of packet(s) -191		 * packet transmission begins on the next frame */192		cont = 1;193		/* send packet(s) every frame */194		send = 1;195		/* select line number to send packets on */196		line = 2;197	} else {198		cont = 0;199		send = 0;200		line = 0;201	}202 203	/* choose which generic packet control to use */204	switch (packet_index) {205	case 0:206		REG_UPDATE_3(HDMI_GENERIC_PACKET_CONTROL0,207				HDMI_GENERIC0_CONT, cont,208				HDMI_GENERIC0_SEND, send,209				HDMI_GENERIC0_LINE, line);210		break;211	case 1:212		REG_UPDATE_3(HDMI_GENERIC_PACKET_CONTROL0,213				HDMI_GENERIC1_CONT, cont,214				HDMI_GENERIC1_SEND, send,215				HDMI_GENERIC1_LINE, line);216		break;217	case 2:218		REG_UPDATE_3(HDMI_GENERIC_PACKET_CONTROL1,219				HDMI_GENERIC0_CONT, cont,220				HDMI_GENERIC0_SEND, send,221				HDMI_GENERIC0_LINE, line);222		break;223	case 3:224		REG_UPDATE_3(HDMI_GENERIC_PACKET_CONTROL1,225				HDMI_GENERIC1_CONT, cont,226				HDMI_GENERIC1_SEND, send,227				HDMI_GENERIC1_LINE, line);228		break;229	case 4:230		if (REG(HDMI_GENERIC_PACKET_CONTROL2))231			REG_UPDATE_3(HDMI_GENERIC_PACKET_CONTROL2,232					HDMI_GENERIC0_CONT, cont,233					HDMI_GENERIC0_SEND, send,234					HDMI_GENERIC0_LINE, line);235		break;236	case 5:237		if (REG(HDMI_GENERIC_PACKET_CONTROL2))238			REG_UPDATE_3(HDMI_GENERIC_PACKET_CONTROL2,239					HDMI_GENERIC1_CONT, cont,240					HDMI_GENERIC1_SEND, send,241					HDMI_GENERIC1_LINE, line);242		break;243	case 6:244		if (REG(HDMI_GENERIC_PACKET_CONTROL3))245			REG_UPDATE_3(HDMI_GENERIC_PACKET_CONTROL3,246					HDMI_GENERIC0_CONT, cont,247					HDMI_GENERIC0_SEND, send,248					HDMI_GENERIC0_LINE, line);249		break;250	case 7:251		if (REG(HDMI_GENERIC_PACKET_CONTROL3))252			REG_UPDATE_3(HDMI_GENERIC_PACKET_CONTROL3,253					HDMI_GENERIC1_CONT, cont,254					HDMI_GENERIC1_SEND, send,255					HDMI_GENERIC1_LINE, line);256		break;257	default:258		/* invalid HW packet index */259		DC_LOG_WARNING(260			"Invalid HW packet index: %s()\n",261			__func__);262		return;263	}264}265 266/* setup stream encoder in dp mode */267static void dce110_stream_encoder_dp_set_stream_attribute(268	struct stream_encoder *enc,269	struct dc_crtc_timing *crtc_timing,270	enum dc_color_space output_color_space,271	bool use_vsc_sdp_for_colorimetry,272	uint32_t enable_sdp_splitting)273{274	uint32_t h_active_start;275	uint32_t v_active_start;276	uint32_t misc0 = 0;277	uint32_t misc1 = 0;278	uint32_t h_blank;279	uint32_t h_back_porch;280	uint8_t synchronous_clock = 0; /* asynchronous mode */281	uint8_t colorimetry_bpc;282	uint8_t dynamic_range_rgb = 0; /*full range*/283	uint8_t dynamic_range_ycbcr = 1; /*bt709*/284 285	struct dce110_stream_encoder *enc110 = DCE110STRENC_FROM_STRENC(enc);286	struct dc_crtc_timing hw_crtc_timing = *crtc_timing;287	if (hw_crtc_timing.flags.INTERLACE) {288		/*the input timing is in VESA spec format with Interlace flag =1*/289		hw_crtc_timing.v_total /= 2;290		hw_crtc_timing.v_border_top /= 2;291		hw_crtc_timing.v_addressable /= 2;292		hw_crtc_timing.v_border_bottom /= 2;293		hw_crtc_timing.v_front_porch /= 2;294		hw_crtc_timing.v_sync_width /= 2;295	}296	/* set pixel encoding */297	switch (hw_crtc_timing.pixel_encoding) {298	case PIXEL_ENCODING_YCBCR422:299		REG_UPDATE(DP_PIXEL_FORMAT, DP_PIXEL_ENCODING,300				DP_PIXEL_ENCODING_TYPE_YCBCR422);301		break;302	case PIXEL_ENCODING_YCBCR444:303		REG_UPDATE(DP_PIXEL_FORMAT, DP_PIXEL_ENCODING,304				DP_PIXEL_ENCODING_TYPE_YCBCR444);305 306		if (hw_crtc_timing.flags.Y_ONLY)307			if (hw_crtc_timing.display_color_depth != COLOR_DEPTH_666)308				/* HW testing only, no use case yet.309				 * Color depth of Y-only could be310				 * 8, 10, 12, 16 bits */311				REG_UPDATE(DP_PIXEL_FORMAT, DP_PIXEL_ENCODING,312						DP_PIXEL_ENCODING_TYPE_Y_ONLY);313		/* Note: DP_MSA_MISC1 bit 7 is the indicator314		 * of Y-only mode.315		 * This bit is set in HW if register316		 * DP_PIXEL_ENCODING is programmed to 0x4 */317		break;318	case PIXEL_ENCODING_YCBCR420:319		REG_UPDATE(DP_PIXEL_FORMAT, DP_PIXEL_ENCODING,320				DP_PIXEL_ENCODING_TYPE_YCBCR420);321		if (enc110->se_mask->DP_VID_M_DOUBLE_VALUE_EN)322			REG_UPDATE(DP_VID_TIMING, DP_VID_M_DOUBLE_VALUE_EN, 1);323 324		if (enc110->se_mask->DP_VID_N_MUL)325			REG_UPDATE(DP_VID_TIMING, DP_VID_N_MUL, 1);326		break;327	default:328		REG_UPDATE(DP_PIXEL_FORMAT, DP_PIXEL_ENCODING,329				DP_PIXEL_ENCODING_TYPE_RGB444);330		break;331	}332 333	if (REG(DP_MSA_MISC))334		misc1 = REG_READ(DP_MSA_MISC);335 336	/* set color depth */337 338	switch (hw_crtc_timing.display_color_depth) {339	case COLOR_DEPTH_666:340		REG_UPDATE(DP_PIXEL_FORMAT, DP_COMPONENT_DEPTH,341				0);342		break;343	case COLOR_DEPTH_888:344		REG_UPDATE(DP_PIXEL_FORMAT, DP_COMPONENT_DEPTH,345				DP_COMPONENT_PIXEL_DEPTH_8BPC);346		break;347	case COLOR_DEPTH_101010:348		REG_UPDATE(DP_PIXEL_FORMAT, DP_COMPONENT_DEPTH,349				DP_COMPONENT_PIXEL_DEPTH_10BPC);350 351		break;352	case COLOR_DEPTH_121212:353		REG_UPDATE(DP_PIXEL_FORMAT, DP_COMPONENT_DEPTH,354				DP_COMPONENT_PIXEL_DEPTH_12BPC);355		break;356	default:357		REG_UPDATE(DP_PIXEL_FORMAT, DP_COMPONENT_DEPTH,358				DP_COMPONENT_PIXEL_DEPTH_6BPC);359		break;360	}361 362	/* set dynamic range and YCbCr range */363 364 365	switch (hw_crtc_timing.display_color_depth) {366	case COLOR_DEPTH_666:367		colorimetry_bpc = 0;368		break;369	case COLOR_DEPTH_888:370		colorimetry_bpc = 1;371		break;372	case COLOR_DEPTH_101010:373		colorimetry_bpc = 2;374		break;375	case COLOR_DEPTH_121212:376		colorimetry_bpc = 3;377		break;378	default:379		colorimetry_bpc = 0;380		break;381	}382 383	misc0 = misc0 | synchronous_clock;384	misc0 = colorimetry_bpc << 5;385 386	if (REG(DP_MSA_TIMING_PARAM1)) {387		switch (output_color_space) {388		case COLOR_SPACE_SRGB:389			misc0 = misc0 | 0x0;390			misc1 = misc1 & ~0x80; /* bit7 = 0*/391			dynamic_range_rgb = 0; /*full range*/392			break;393		case COLOR_SPACE_SRGB_LIMITED:394			misc0 = misc0 | 0x8; /* bit3=1 */395			misc1 = misc1 & ~0x80; /* bit7 = 0*/396			dynamic_range_rgb = 1; /*limited range*/397			break;398		case COLOR_SPACE_YCBCR601:399		case COLOR_SPACE_YCBCR601_LIMITED:400			misc0 = misc0 | 0x8; /* bit3=1, bit4=0 */401			misc1 = misc1 & ~0x80; /* bit7 = 0*/402			dynamic_range_ycbcr = 0; /*bt601*/403			if (hw_crtc_timing.pixel_encoding == PIXEL_ENCODING_YCBCR422)404				misc0 = misc0 | 0x2; /* bit2=0, bit1=1 */405			else if (hw_crtc_timing.pixel_encoding == PIXEL_ENCODING_YCBCR444)406				misc0 = misc0 | 0x4; /* bit2=1, bit1=0 */407			break;408		case COLOR_SPACE_YCBCR709:409		case COLOR_SPACE_YCBCR709_LIMITED:410		case COLOR_SPACE_YCBCR709_BLACK:411			misc0 = misc0 | 0x18; /* bit3=1, bit4=1 */412			misc1 = misc1 & ~0x80; /* bit7 = 0*/413			dynamic_range_ycbcr = 1; /*bt709*/414			if (hw_crtc_timing.pixel_encoding == PIXEL_ENCODING_YCBCR422)415				misc0 = misc0 | 0x2; /* bit2=0, bit1=1 */416			else if (hw_crtc_timing.pixel_encoding == PIXEL_ENCODING_YCBCR444)417				misc0 = misc0 | 0x4; /* bit2=1, bit1=0 */418			break;419		case COLOR_SPACE_2020_RGB_LIMITEDRANGE:420			dynamic_range_rgb = 1; /*limited range*/421			break;422		case COLOR_SPACE_2020_RGB_FULLRANGE:423		case COLOR_SPACE_2020_YCBCR:424		case COLOR_SPACE_XR_RGB:425		case COLOR_SPACE_MSREF_SCRGB:426		case COLOR_SPACE_ADOBERGB:427		case COLOR_SPACE_DCIP3:428		case COLOR_SPACE_XV_YCC_709:429		case COLOR_SPACE_XV_YCC_601:430		case COLOR_SPACE_DISPLAYNATIVE:431		case COLOR_SPACE_DOLBYVISION:432		case COLOR_SPACE_APPCTRL:433		case COLOR_SPACE_CUSTOMPOINTS:434		case COLOR_SPACE_UNKNOWN:435			/* do nothing */436			break;437		}438		if (enc110->se_mask->DP_DYN_RANGE && enc110->se_mask->DP_YCBCR_RANGE)439			REG_UPDATE_2(440				DP_PIXEL_FORMAT,441				DP_DYN_RANGE, dynamic_range_rgb,442				DP_YCBCR_RANGE, dynamic_range_ycbcr);443 444		if (REG(DP_MSA_COLORIMETRY))445			REG_SET(DP_MSA_COLORIMETRY, 0, DP_MSA_MISC0, misc0);446 447		if (REG(DP_MSA_MISC))448			REG_WRITE(DP_MSA_MISC, misc1);   /* MSA_MISC1 */449 450	/* dcn new register451	 * dc_crtc_timing is vesa dmt struct. data from edid452	 */453		if (REG(DP_MSA_TIMING_PARAM1))454			REG_SET_2(DP_MSA_TIMING_PARAM1, 0,455					DP_MSA_HTOTAL, hw_crtc_timing.h_total,456					DP_MSA_VTOTAL, hw_crtc_timing.v_total);457 458		/* calcuate from vesa timing parameters459		 * h_active_start related to leading edge of sync460		 */461 462		h_blank = hw_crtc_timing.h_total - hw_crtc_timing.h_border_left -463				hw_crtc_timing.h_addressable - hw_crtc_timing.h_border_right;464 465		h_back_porch = h_blank - hw_crtc_timing.h_front_porch -466				hw_crtc_timing.h_sync_width;467 468		/* start at begining of left border */469		h_active_start = hw_crtc_timing.h_sync_width + h_back_porch;470 471 472		v_active_start = hw_crtc_timing.v_total - hw_crtc_timing.v_border_top -473				hw_crtc_timing.v_addressable - hw_crtc_timing.v_border_bottom -474				hw_crtc_timing.v_front_porch;475 476 477		/* start at begining of left border */478		if (REG(DP_MSA_TIMING_PARAM2))479			REG_SET_2(DP_MSA_TIMING_PARAM2, 0,480				DP_MSA_HSTART, h_active_start,481				DP_MSA_VSTART, v_active_start);482 483		if (REG(DP_MSA_TIMING_PARAM3))484			REG_SET_4(DP_MSA_TIMING_PARAM3, 0,485					DP_MSA_HSYNCWIDTH,486					hw_crtc_timing.h_sync_width,487					DP_MSA_HSYNCPOLARITY,488					!hw_crtc_timing.flags.HSYNC_POSITIVE_POLARITY,489					DP_MSA_VSYNCWIDTH,490					hw_crtc_timing.v_sync_width,491					DP_MSA_VSYNCPOLARITY,492					!hw_crtc_timing.flags.VSYNC_POSITIVE_POLARITY);493 494		/* HWDITH include border or overscan */495		if (REG(DP_MSA_TIMING_PARAM4))496			REG_SET_2(DP_MSA_TIMING_PARAM4, 0,497				DP_MSA_HWIDTH, hw_crtc_timing.h_border_left +498				hw_crtc_timing.h_addressable + hw_crtc_timing.h_border_right,499				DP_MSA_VHEIGHT, hw_crtc_timing.v_border_top +500				hw_crtc_timing.v_addressable + hw_crtc_timing.v_border_bottom);501	}502}503 504static void dce110_stream_encoder_set_stream_attribute_helper(505		struct dce110_stream_encoder *enc110,506		struct dc_crtc_timing *crtc_timing)507{508	if (enc110->regs->TMDS_CNTL) {509		switch (crtc_timing->pixel_encoding) {510		case PIXEL_ENCODING_YCBCR422:511			REG_UPDATE(TMDS_CNTL, TMDS_PIXEL_ENCODING, 1);512			break;513		default:514			REG_UPDATE(TMDS_CNTL, TMDS_PIXEL_ENCODING, 0);515			break;516		}517		REG_UPDATE(TMDS_CNTL, TMDS_COLOR_FORMAT, 0);518	} else if (enc110->regs->DIG_FE_CNTL) {519		switch (crtc_timing->pixel_encoding) {520		case PIXEL_ENCODING_YCBCR422:521			REG_UPDATE(DIG_FE_CNTL, TMDS_PIXEL_ENCODING, 1);522			break;523		default:524			REG_UPDATE(DIG_FE_CNTL, TMDS_PIXEL_ENCODING, 0);525			break;526		}527		REG_UPDATE(DIG_FE_CNTL, TMDS_COLOR_FORMAT, 0);528	}529 530}531 532/* setup stream encoder in hdmi mode */533static void dce110_stream_encoder_hdmi_set_stream_attribute(534	struct stream_encoder *enc,535	struct dc_crtc_timing *crtc_timing,536	int actual_pix_clk_khz,537	bool enable_audio)538{539	struct dce110_stream_encoder *enc110 = DCE110STRENC_FROM_STRENC(enc);540	struct bp_encoder_control cntl = {0};541 542	cntl.action = ENCODER_CONTROL_SETUP;543	cntl.engine_id = enc110->base.id;544	cntl.signal = SIGNAL_TYPE_HDMI_TYPE_A;545	cntl.enable_dp_audio = enable_audio;546	cntl.pixel_clock = actual_pix_clk_khz;547	cntl.lanes_number = LANE_COUNT_FOUR;548	cntl.color_depth = crtc_timing->display_color_depth;549 550	if (enc110->base.bp->funcs->encoder_control(551			enc110->base.bp, &cntl) != BP_RESULT_OK)552		return;553 554	dce110_stream_encoder_set_stream_attribute_helper(enc110, crtc_timing);555 556	/* setup HDMI engine */557	if (!enc110->se_mask->HDMI_DATA_SCRAMBLE_EN) {558		REG_UPDATE_3(HDMI_CONTROL,559			HDMI_PACKET_GEN_VERSION, 1,560			HDMI_KEEPOUT_MODE, 1,561			HDMI_DEEP_COLOR_ENABLE, 0);562	} else if (enc110->regs->DIG_FE_CNTL) {563		REG_UPDATE_5(HDMI_CONTROL,564			HDMI_PACKET_GEN_VERSION, 1,565			HDMI_KEEPOUT_MODE, 1,566			HDMI_DEEP_COLOR_ENABLE, 0,567			HDMI_DATA_SCRAMBLE_EN, 0,568			HDMI_CLOCK_CHANNEL_RATE, 0);569	}570 571	switch (crtc_timing->display_color_depth) {572	case COLOR_DEPTH_888:573		REG_UPDATE(HDMI_CONTROL, HDMI_DEEP_COLOR_DEPTH, 0);574		break;575	case COLOR_DEPTH_101010:576		if (crtc_timing->pixel_encoding == PIXEL_ENCODING_YCBCR422) {577			REG_UPDATE_2(HDMI_CONTROL,578					HDMI_DEEP_COLOR_DEPTH, 1,579					HDMI_DEEP_COLOR_ENABLE, 0);580		} else {581			REG_UPDATE_2(HDMI_CONTROL,582					HDMI_DEEP_COLOR_DEPTH, 1,583					HDMI_DEEP_COLOR_ENABLE, 1);584			}585		break;586	case COLOR_DEPTH_121212:587		if (crtc_timing->pixel_encoding == PIXEL_ENCODING_YCBCR422) {588			REG_UPDATE_2(HDMI_CONTROL,589					HDMI_DEEP_COLOR_DEPTH, 2,590					HDMI_DEEP_COLOR_ENABLE, 0);591		} else {592			REG_UPDATE_2(HDMI_CONTROL,593					HDMI_DEEP_COLOR_DEPTH, 2,594					HDMI_DEEP_COLOR_ENABLE, 1);595			}596		break;597	case COLOR_DEPTH_161616:598		REG_UPDATE_2(HDMI_CONTROL,599				HDMI_DEEP_COLOR_DEPTH, 3,600				HDMI_DEEP_COLOR_ENABLE, 1);601		break;602	default:603		break;604	}605 606	if (enc110->se_mask->HDMI_DATA_SCRAMBLE_EN) {607		if (actual_pix_clk_khz >= HDMI_CLOCK_CHANNEL_RATE_MORE_340M) {608			/* enable HDMI data scrambler609			 * HDMI_CLOCK_CHANNEL_RATE_MORE_340M610			 * Clock channel frequency is 1/4 of character rate.611			 */612			REG_UPDATE_2(HDMI_CONTROL,613				HDMI_DATA_SCRAMBLE_EN, 1,614				HDMI_CLOCK_CHANNEL_RATE, 1);615		} else if (crtc_timing->flags.LTE_340MCSC_SCRAMBLE) {616 617			/* TODO: New feature for DCE11, still need to implement */618 619			/* enable HDMI data scrambler620			 * HDMI_CLOCK_CHANNEL_FREQ_EQUAL_TO_CHAR_RATE621			 * Clock channel frequency is the same622			 * as character rate623			 */624			REG_UPDATE_2(HDMI_CONTROL,625				HDMI_DATA_SCRAMBLE_EN, 1,626				HDMI_CLOCK_CHANNEL_RATE, 0);627		}628	}629 630	REG_UPDATE_3(HDMI_VBI_PACKET_CONTROL,631		HDMI_GC_CONT, 1,632		HDMI_GC_SEND, 1,633		HDMI_NULL_SEND, 1);634 635	REG_UPDATE(HDMI_VBI_PACKET_CONTROL, HDMI_ACP_SEND, 0);636 637	/* following belongs to audio */638	REG_UPDATE(HDMI_INFOFRAME_CONTROL0, HDMI_AUDIO_INFO_SEND, 1);639 640	REG_UPDATE(AFMT_INFOFRAME_CONTROL0, AFMT_AUDIO_INFO_UPDATE, 1);641 642	REG_UPDATE(HDMI_INFOFRAME_CONTROL1, HDMI_AUDIO_INFO_LINE,643				VBI_LINE_0 + 2);644 645	REG_UPDATE(HDMI_GC, HDMI_GC_AVMUTE, 0);646 647}648 649/* setup stream encoder in dvi mode */650static void dce110_stream_encoder_dvi_set_stream_attribute(651	struct stream_encoder *enc,652	struct dc_crtc_timing *crtc_timing,653	bool is_dual_link)654{655	struct dce110_stream_encoder *enc110 = DCE110STRENC_FROM_STRENC(enc);656	struct bp_encoder_control cntl = {0};657 658	cntl.action = ENCODER_CONTROL_SETUP;659	cntl.engine_id = enc110->base.id;660	cntl.signal = is_dual_link ?661			SIGNAL_TYPE_DVI_DUAL_LINK : SIGNAL_TYPE_DVI_SINGLE_LINK;662	cntl.enable_dp_audio = false;663	cntl.pixel_clock = crtc_timing->pix_clk_100hz / 10;664	cntl.lanes_number = (is_dual_link) ? LANE_COUNT_EIGHT : LANE_COUNT_FOUR;665 666	if (enc110->base.bp->funcs->encoder_control(667			enc110->base.bp, &cntl) != BP_RESULT_OK)668		return;669 670	ASSERT(crtc_timing->pixel_encoding == PIXEL_ENCODING_RGB);671	ASSERT(crtc_timing->display_color_depth == COLOR_DEPTH_888);672	dce110_stream_encoder_set_stream_attribute_helper(enc110, crtc_timing);673}674 675/* setup stream encoder in LVDS mode */676static void dce110_stream_encoder_lvds_set_stream_attribute(677	struct stream_encoder *enc,678	struct dc_crtc_timing *crtc_timing)679{680	struct dce110_stream_encoder *enc110 = DCE110STRENC_FROM_STRENC(enc);681	struct bp_encoder_control cntl = {0};682 683	cntl.action = ENCODER_CONTROL_SETUP;684	cntl.engine_id = enc110->base.id;685	cntl.signal = SIGNAL_TYPE_LVDS;686	cntl.enable_dp_audio = false;687	cntl.pixel_clock = crtc_timing->pix_clk_100hz / 10;688	cntl.lanes_number = LANE_COUNT_FOUR;689 690	if (enc110->base.bp->funcs->encoder_control(691			enc110->base.bp, &cntl) != BP_RESULT_OK)692		return;693 694	ASSERT(crtc_timing->pixel_encoding == PIXEL_ENCODING_RGB);695}696 697static void dce110_stream_encoder_set_throttled_vcp_size(698	struct stream_encoder *enc,699	struct fixed31_32 avg_time_slots_per_mtp)700{701	struct dce110_stream_encoder *enc110 = DCE110STRENC_FROM_STRENC(enc);702	uint32_t x = dc_fixpt_floor(703		avg_time_slots_per_mtp);704	uint32_t y = dc_fixpt_ceil(705		dc_fixpt_shl(706			dc_fixpt_sub_int(707				avg_time_slots_per_mtp,708				x),709			26));710 711	{712		REG_SET_2(DP_MSE_RATE_CNTL, 0,713			DP_MSE_RATE_X, x,714			DP_MSE_RATE_Y, y);715	}716 717	/* wait for update to be completed on the link */718	/* i.e. DP_MSE_RATE_UPDATE_PENDING field (read only) */719	/* is reset to 0 (not pending) */720	REG_WAIT(DP_MSE_RATE_UPDATE, DP_MSE_RATE_UPDATE_PENDING,721			0,722			10, DP_MST_UPDATE_MAX_RETRY);723}724 725static void dce110_stream_encoder_update_hdmi_info_packets(726	struct stream_encoder *enc,727	const struct encoder_info_frame *info_frame)728{729	struct dce110_stream_encoder *enc110 = DCE110STRENC_FROM_STRENC(enc);730 731	if (enc110->se_mask->HDMI_AVI_INFO_CONT &&732			enc110->se_mask->HDMI_AVI_INFO_SEND) {733 734		if (info_frame->avi.valid) {735			const uint32_t *content =736				(const uint32_t *) &info_frame->avi.sb[0];737			/*we need turn on clock before programming AFMT block*/738			if (REG(AFMT_CNTL))739				REG_UPDATE(AFMT_CNTL, AFMT_AUDIO_CLOCK_EN, 1);740 741			REG_WRITE(AFMT_AVI_INFO0, content[0]);742 743			REG_WRITE(AFMT_AVI_INFO1, content[1]);744 745			REG_WRITE(AFMT_AVI_INFO2, content[2]);746 747			REG_WRITE(AFMT_AVI_INFO3, content[3]);748 749			REG_UPDATE(AFMT_AVI_INFO3, AFMT_AVI_INFO_VERSION,750						info_frame->avi.hb1);751 752			REG_UPDATE_2(HDMI_INFOFRAME_CONTROL0,753					HDMI_AVI_INFO_SEND, 1,754					HDMI_AVI_INFO_CONT, 1);755 756			REG_UPDATE(HDMI_INFOFRAME_CONTROL1, HDMI_AVI_INFO_LINE,757							VBI_LINE_0 + 2);758 759		} else {760			REG_UPDATE_2(HDMI_INFOFRAME_CONTROL0,761				HDMI_AVI_INFO_SEND, 0,762				HDMI_AVI_INFO_CONT, 0);763		}764	}765 766	if (enc110->se_mask->HDMI_AVI_INFO_CONT &&767			enc110->se_mask->HDMI_AVI_INFO_SEND) {768		dce110_update_hdmi_info_packet(enc110, 0, &info_frame->vendor);769		dce110_update_hdmi_info_packet(enc110, 1, &info_frame->gamut);770		dce110_update_hdmi_info_packet(enc110, 2, &info_frame->spd);771		dce110_update_hdmi_info_packet(enc110, 3, &info_frame->hdrsmd);772	}773 774	if (enc110->se_mask->HDMI_DB_DISABLE) {775		/* for bring up, disable dp double  TODO */776		if (REG(HDMI_DB_CONTROL))777			REG_UPDATE(HDMI_DB_CONTROL, HDMI_DB_DISABLE, 1);778 779		dce110_update_hdmi_info_packet(enc110, 0, &info_frame->avi);780		dce110_update_hdmi_info_packet(enc110, 1, &info_frame->vendor);781		dce110_update_hdmi_info_packet(enc110, 2, &info_frame->gamut);782		dce110_update_hdmi_info_packet(enc110, 3, &info_frame->spd);783		dce110_update_hdmi_info_packet(enc110, 4, &info_frame->hdrsmd);784	}785}786 787static void dce110_stream_encoder_stop_hdmi_info_packets(788	struct stream_encoder *enc)789{790	struct dce110_stream_encoder *enc110 = DCE110STRENC_FROM_STRENC(enc);791 792	/* stop generic packets 0 & 1 on HDMI */793	REG_SET_6(HDMI_GENERIC_PACKET_CONTROL0, 0,794		HDMI_GENERIC1_CONT, 0,795		HDMI_GENERIC1_LINE, 0,796		HDMI_GENERIC1_SEND, 0,797		HDMI_GENERIC0_CONT, 0,798		HDMI_GENERIC0_LINE, 0,799		HDMI_GENERIC0_SEND, 0);800 801	/* stop generic packets 2 & 3 on HDMI */802	REG_SET_6(HDMI_GENERIC_PACKET_CONTROL1, 0,803		HDMI_GENERIC0_CONT, 0,804		HDMI_GENERIC0_LINE, 0,805		HDMI_GENERIC0_SEND, 0,806		HDMI_GENERIC1_CONT, 0,807		HDMI_GENERIC1_LINE, 0,808		HDMI_GENERIC1_SEND, 0);809 810	/* stop generic packets 2 & 3 on HDMI */811	if (REG(HDMI_GENERIC_PACKET_CONTROL2))812		REG_SET_6(HDMI_GENERIC_PACKET_CONTROL2, 0,813			HDMI_GENERIC0_CONT, 0,814			HDMI_GENERIC0_LINE, 0,815			HDMI_GENERIC0_SEND, 0,816			HDMI_GENERIC1_CONT, 0,817			HDMI_GENERIC1_LINE, 0,818			HDMI_GENERIC1_SEND, 0);819 820	if (REG(HDMI_GENERIC_PACKET_CONTROL3))821		REG_SET_6(HDMI_GENERIC_PACKET_CONTROL3, 0,822			HDMI_GENERIC0_CONT, 0,823			HDMI_GENERIC0_LINE, 0,824			HDMI_GENERIC0_SEND, 0,825			HDMI_GENERIC1_CONT, 0,826			HDMI_GENERIC1_LINE, 0,827			HDMI_GENERIC1_SEND, 0);828}829 830static void dce110_stream_encoder_update_dp_info_packets(831	struct stream_encoder *enc,832	const struct encoder_info_frame *info_frame)833{834	struct dce110_stream_encoder *enc110 = DCE110STRENC_FROM_STRENC(enc);835	uint32_t value = 0;836 837	if (info_frame->vsc.valid)838		dce110_update_generic_info_packet(839					enc110,840					0,  /* packetIndex */841					&info_frame->vsc);842 843	if (info_frame->spd.valid)844		dce110_update_generic_info_packet(845				enc110,846				2,  /* packetIndex */847				&info_frame->spd);848 849	if (info_frame->hdrsmd.valid)850		dce110_update_generic_info_packet(851				enc110,852				3,  /* packetIndex */853				&info_frame->hdrsmd);854 855	/* enable/disable transmission of packet(s).856	*  If enabled, packet transmission begins on the next frame857	*/858	REG_UPDATE(DP_SEC_CNTL, DP_SEC_GSP0_ENABLE, info_frame->vsc.valid);859	REG_UPDATE(DP_SEC_CNTL, DP_SEC_GSP2_ENABLE, info_frame->spd.valid);860	REG_UPDATE(DP_SEC_CNTL, DP_SEC_GSP3_ENABLE, info_frame->hdrsmd.valid);861 862	/* This bit is the master enable bit.863	* When enabling secondary stream engine,864	* this master bit must also be set.865	* This register shared with audio info frame.866	* Therefore we need to enable master bit867	* if at least on of the fields is not 0868	*/869	value = REG_READ(DP_SEC_CNTL);870	if (value)871		REG_UPDATE(DP_SEC_CNTL, DP_SEC_STREAM_ENABLE, 1);872}873 874static void dce110_stream_encoder_stop_dp_info_packets(875	struct stream_encoder *enc)876{877	/* stop generic packets on DP */878	struct dce110_stream_encoder *enc110 = DCE110STRENC_FROM_STRENC(enc);879	uint32_t value = 0;880 881	if (enc110->se_mask->DP_SEC_AVI_ENABLE) {882		REG_SET_7(DP_SEC_CNTL, 0,883			DP_SEC_GSP0_ENABLE, 0,884			DP_SEC_GSP1_ENABLE, 0,885			DP_SEC_GSP2_ENABLE, 0,886			DP_SEC_GSP3_ENABLE, 0,887			DP_SEC_AVI_ENABLE, 0,888			DP_SEC_MPG_ENABLE, 0,889			DP_SEC_STREAM_ENABLE, 0);890	}891 892	/* this register shared with audio info frame.893	 * therefore we need to keep master enabled894	 * if at least one of the fields is not 0 */895	value = REG_READ(DP_SEC_CNTL);896	if (value)897		REG_UPDATE(DP_SEC_CNTL, DP_SEC_STREAM_ENABLE, 1);898 899}900 901static void dce110_stream_encoder_dp_blank(902	struct dc_link *link,903	struct stream_encoder *enc)904{905	struct dce110_stream_encoder *enc110 = DCE110STRENC_FROM_STRENC(enc);906	uint32_t  reg1 = 0;907	uint32_t max_retries = DP_BLANK_MAX_RETRY * 10;908 909	/* Note: For CZ, we are changing driver default to disable910	 * stream deferred to next VBLANK. If results are positive, we911	 * will make the same change to all DCE versions. There are a912	 * handful of panels that cannot handle disable stream at913	 * HBLANK and will result in a white line flash across the914	 * screen on stream disable. */915	REG_GET(DP_VID_STREAM_CNTL, DP_VID_STREAM_ENABLE, &reg1);916	if ((reg1 & 0x1) == 0)917		/*stream not enabled*/918		return;919	/* Specify the video stream disable point920	 * (2 = start of the next vertical blank) */921	REG_UPDATE(DP_VID_STREAM_CNTL, DP_VID_STREAM_DIS_DEFER, 2);922	/* Larger delay to wait until VBLANK - use max retry of923	 * 10us*3000=30ms. This covers 16.6ms of typical 60 Hz mode +924	 * a little more because we may not trust delay accuracy.925	 */926	max_retries = DP_BLANK_MAX_RETRY * 150;927 928	/* disable DP stream */929	REG_UPDATE(DP_VID_STREAM_CNTL, DP_VID_STREAM_ENABLE, 0);930 931	/* the encoder stops sending the video stream932	 * at the start of the vertical blanking.933	 * Poll for DP_VID_STREAM_STATUS == 0934	 */935 936	REG_WAIT(DP_VID_STREAM_CNTL, DP_VID_STREAM_STATUS,937			0,938			10, max_retries);939 940	/* Tell the DP encoder to ignore timing from CRTC, must be done after941	 * the polling. If we set DP_STEER_FIFO_RESET before DP stream blank is942	 * complete, stream status will be stuck in video stream enabled state,943	 * i.e. DP_VID_STREAM_STATUS stuck at 1.944	 */945 946	REG_UPDATE(DP_STEER_FIFO, DP_STEER_FIFO_RESET, true);947}948 949/* output video stream to link encoder */950static void dce110_stream_encoder_dp_unblank(951	struct dc_link *link,952	struct stream_encoder *enc,953	const struct encoder_unblank_param *param)954{955	struct dce110_stream_encoder *enc110 = DCE110STRENC_FROM_STRENC(enc);956 957	if (param->link_settings.link_rate != LINK_RATE_UNKNOWN) {958		uint32_t n_vid = 0x8000;959		uint32_t m_vid;960 961		/* M / N = Fstream / Flink962		* m_vid / n_vid = pixel rate / link rate963		*/964 965		uint64_t m_vid_l = n_vid;966 967		m_vid_l *= param->timing.pix_clk_100hz / 10;968		m_vid_l = div_u64(m_vid_l,969			param->link_settings.link_rate970				* LINK_RATE_REF_FREQ_IN_KHZ);971 972		m_vid = (uint32_t) m_vid_l;973 974		/* enable auto measurement */975 976		REG_UPDATE(DP_VID_TIMING, DP_VID_M_N_GEN_EN, 0);977 978		/* auto measurement need 1 full 0x8000 symbol cycle to kick in,979		 * therefore program initial value for Mvid and Nvid980		 */981 982		REG_UPDATE(DP_VID_N, DP_VID_N, n_vid);983 984		REG_UPDATE(DP_VID_M, DP_VID_M, m_vid);985 986		REG_UPDATE(DP_VID_TIMING, DP_VID_M_N_GEN_EN, 1);987	}988 989	/* set DIG_START to 0x1 to resync FIFO */990 991	REG_UPDATE(DIG_FE_CNTL, DIG_START, 1);992 993	/* switch DP encoder to CRTC data */994 995	REG_UPDATE(DP_STEER_FIFO, DP_STEER_FIFO_RESET, 0);996 997	/* wait 100us for DIG/DP logic to prime998	* (i.e. a few video lines)999	*/1000	udelay(100);1001 1002	/* the hardware would start sending video at the start of the next DP1003	* frame (i.e. rising edge of the vblank).1004	* NOTE: We used to program DP_VID_STREAM_DIS_DEFER = 2 here, but this1005	* register has no effect on enable transition! HW always guarantees1006	* VID_STREAM enable at start of next frame, and this is not1007	* programmable1008	*/1009 1010	REG_UPDATE(DP_VID_STREAM_CNTL, DP_VID_STREAM_ENABLE, true);1011}1012 1013static void dce110_stream_encoder_set_avmute(1014	struct stream_encoder *enc,1015	bool enable)1016{1017	struct dce110_stream_encoder *enc110 = DCE110STRENC_FROM_STRENC(enc);1018	unsigned int value = enable ? 1 : 0;1019 1020	REG_UPDATE(HDMI_GC, HDMI_GC_AVMUTE, value);1021}1022 1023 1024static void dce110_reset_hdmi_stream_attribute(1025	struct stream_encoder *enc)1026{1027	struct dce110_stream_encoder *enc110 = DCE110STRENC_FROM_STRENC(enc);1028 1029	if (enc110->se_mask->HDMI_DATA_SCRAMBLE_EN)1030		REG_UPDATE_5(HDMI_CONTROL,1031			HDMI_PACKET_GEN_VERSION, 1,1032			HDMI_KEEPOUT_MODE, 1,1033			HDMI_DEEP_COLOR_ENABLE, 0,1034			HDMI_DATA_SCRAMBLE_EN, 0,1035			HDMI_CLOCK_CHANNEL_RATE, 0);1036	else1037		REG_UPDATE_3(HDMI_CONTROL,1038			HDMI_PACKET_GEN_VERSION, 1,1039			HDMI_KEEPOUT_MODE, 1,1040			HDMI_DEEP_COLOR_ENABLE, 0);1041}1042 1043#define DP_SEC_AUD_N__DP_SEC_AUD_N__DEFAULT 0x80001044#define DP_SEC_TIMESTAMP__DP_SEC_TIMESTAMP_MODE__AUTO_CALC 11045 1046#include "include/audio_types.h"1047 1048 1049/* 25.2MHz/1.001*/1050/* 25.2MHz/1.001*/1051/* 25.2MHz*/1052/* 27MHz */1053/* 27MHz*1.001*/1054/* 27MHz*1.001*/1055/* 54MHz*/1056/* 54MHz*1.001*/1057/* 74.25MHz/1.001*/1058/* 74.25MHz*/1059/* 148.5MHz/1.001*/1060/* 148.5MHz*/1061 1062static const struct audio_clock_info audio_clock_info_table[16] = {1063	{2517, 4576, 28125, 7007, 31250, 6864, 28125},1064	{2518, 4576, 28125, 7007, 31250, 6864, 28125},1065	{2520, 4096, 25200, 6272, 28000, 6144, 25200},1066	{2700, 4096, 27000, 6272, 30000, 6144, 27000},1067	{2702, 4096, 27027, 6272, 30030, 6144, 27027},1068	{2703, 4096, 27027, 6272, 30030, 6144, 27027},1069	{5400, 4096, 54000, 6272, 60000, 6144, 54000},1070	{5405, 4096, 54054, 6272, 60060, 6144, 54054},1071	{7417, 11648, 210937, 17836, 234375, 11648, 140625},1072	{7425, 4096, 74250, 6272, 82500, 6144, 74250},1073	{14835, 11648, 421875, 8918, 234375, 5824, 140625},1074	{14850, 4096, 148500, 6272, 165000, 6144, 148500},1075	{29670, 5824, 421875, 4459, 234375, 5824, 281250},1076	{29700, 3072, 222750, 4704, 247500, 5120, 247500},1077	{59340, 5824, 843750, 8918, 937500, 5824, 562500},1078	{59400, 3072, 445500, 9408, 990000, 6144, 594000}1079};1080 1081static const struct audio_clock_info audio_clock_info_table_36bpc[14] = {1082	{2517,  9152,  84375,  7007,  48875,  9152,  56250},1083	{2518,  9152,  84375,  7007,  48875,  9152,  56250},1084	{2520,  4096,  37800,  6272,  42000,  6144,  37800},1085	{2700,  4096,  40500,  6272,  45000,  6144,  40500},1086	{2702,  8192,  81081,  6272,  45045,  8192,  54054},1087	{2703,  8192,  81081,  6272,  45045,  8192,  54054},1088	{5400,  4096,  81000,  6272,  90000,  6144,  81000},1089	{5405,  4096,  81081,  6272,  90090,  6144,  81081},1090	{7417, 11648, 316406, 17836, 351562, 11648, 210937},1091	{7425, 4096, 111375,  6272, 123750,  6144, 111375},1092	{14835, 11648, 632812, 17836, 703125, 11648, 421875},1093	{14850, 4096, 222750,  6272, 247500,  6144, 222750},1094	{29670, 5824, 632812,  8918, 703125,  5824, 421875},1095	{29700, 4096, 445500,  4704, 371250,  5120, 371250}1096};1097 1098static const struct audio_clock_info audio_clock_info_table_48bpc[14] = {1099	{2517,  4576,  56250,  7007,  62500,  6864,  56250},1100	{2518,  4576,  56250,  7007,  62500,  6864,  56250},1101	{2520,  4096,  50400,  6272,  56000,  6144,  50400},1102	{2700,  4096,  54000,  6272,  60000,  6144,  54000},1103	{2702,  4096,  54054,  6267,  60060,  8192,  54054},1104	{2703,  4096,  54054,  6272,  60060,  8192,  54054},1105	{5400,  4096, 108000,  6272, 120000,  6144, 108000},1106	{5405,  4096, 108108,  6272, 120120,  6144, 108108},1107	{7417, 11648, 421875, 17836, 468750, 11648, 281250},1108	{7425,  4096, 148500,  6272, 165000,  6144, 148500},1109	{14835, 11648, 843750,  8918, 468750, 11648, 281250},1110	{14850, 4096, 297000,  6272, 330000,  6144, 297000},1111	{29670, 5824, 843750,  4459, 468750,  5824, 562500},1112	{29700, 3072, 445500,  4704, 495000,  5120, 495000}1113 1114 1115};1116 1117static union audio_cea_channels speakers_to_channels(1118	struct audio_speaker_flags speaker_flags)1119{1120	union audio_cea_channels cea_channels = {0};1121 1122	/* these are one to one */1123	cea_channels.channels.FL = speaker_flags.FL_FR;1124	cea_channels.channels.FR = speaker_flags.FL_FR;1125	cea_channels.channels.LFE = speaker_flags.LFE;1126	cea_channels.channels.FC = speaker_flags.FC;1127 1128	/* if Rear Left and Right exist move RC speaker to channel 71129	 * otherwise to channel 51130	 */1131	if (speaker_flags.RL_RR) {1132		cea_channels.channels.RL_RC = speaker_flags.RL_RR;1133		cea_channels.channels.RR = speaker_flags.RL_RR;1134		cea_channels.channels.RC_RLC_FLC = speaker_flags.RC;1135	} else {1136		cea_channels.channels.RL_RC = speaker_flags.RC;1137	}1138 1139	/* FRONT Left Right Center and REAR Left Right Center are exclusive */1140	if (speaker_flags.FLC_FRC) {1141		cea_channels.channels.RC_RLC_FLC = speaker_flags.FLC_FRC;1142		cea_channels.channels.RRC_FRC = speaker_flags.FLC_FRC;1143	} else {1144		cea_channels.channels.RC_RLC_FLC = speaker_flags.RLC_RRC;1145		cea_channels.channels.RRC_FRC = speaker_flags.RLC_RRC;1146	}1147 1148	return cea_channels;1149}1150 1151static uint32_t calc_max_audio_packets_per_line(1152	const struct audio_crtc_info *crtc_info)1153{1154	uint32_t max_packets_per_line;1155 1156	max_packets_per_line =1157		crtc_info->h_total - crtc_info->h_active;1158 1159	if (crtc_info->pixel_repetition)1160		max_packets_per_line *= crtc_info->pixel_repetition;1161 1162	/* for other hdmi features */1163	max_packets_per_line -= 58;1164	/* for Control Period */1165	max_packets_per_line -= 16;1166	/* Number of Audio Packets per Line */1167	max_packets_per_line /= 32;1168 1169	return max_packets_per_line;1170}1171 1172static void get_audio_clock_info(1173	enum dc_color_depth color_depth,1174	uint32_t crtc_pixel_clock_100Hz,1175	uint32_t actual_pixel_clock_100Hz,1176	struct audio_clock_info *audio_clock_info)1177{1178	const struct audio_clock_info *clock_info;1179	uint32_t index;1180	uint32_t crtc_pixel_clock_in_10khz = crtc_pixel_clock_100Hz / 100;1181	uint32_t audio_array_size;1182 1183	switch (color_depth) {1184	case COLOR_DEPTH_161616:1185		clock_info = audio_clock_info_table_48bpc;1186		audio_array_size = ARRAY_SIZE(1187				audio_clock_info_table_48bpc);1188		break;1189	case COLOR_DEPTH_121212:1190		clock_info = audio_clock_info_table_36bpc;1191		audio_array_size = ARRAY_SIZE(1192				audio_clock_info_table_36bpc);1193		break;1194	default:1195		clock_info = audio_clock_info_table;1196		audio_array_size = ARRAY_SIZE(1197				audio_clock_info_table);1198		break;1199	}1200 1201	if (clock_info != NULL) {1202		/* search for exact pixel clock in table */1203		for (index = 0; index < audio_array_size; index++) {1204			if (clock_info[index].pixel_clock_in_10khz >1205				crtc_pixel_clock_in_10khz)1206				break;  /* not match */1207			else if (clock_info[index].pixel_clock_in_10khz ==1208					crtc_pixel_clock_in_10khz) {1209				/* match found */1210				*audio_clock_info = clock_info[index];1211				return;1212			}1213		}1214	}1215 1216	/* not found */1217	if (actual_pixel_clock_100Hz == 0)1218		actual_pixel_clock_100Hz = crtc_pixel_clock_100Hz;1219 1220	/* See HDMI spec  the table entry under1221	 *  pixel clock of "Other". */1222	audio_clock_info->pixel_clock_in_10khz =1223			actual_pixel_clock_100Hz / 100;1224	audio_clock_info->cts_32khz = actual_pixel_clock_100Hz / 10;1225	audio_clock_info->cts_44khz = actual_pixel_clock_100Hz / 10;1226	audio_clock_info->cts_48khz = actual_pixel_clock_100Hz / 10;1227 1228	audio_clock_info->n_32khz = 4096;1229	audio_clock_info->n_44khz = 6272;1230	audio_clock_info->n_48khz = 6144;1231}1232 1233static void dce110_se_audio_setup(1234	struct stream_encoder *enc,1235	unsigned int az_inst,1236	struct audio_info *audio_info)1237{1238	struct dce110_stream_encoder *enc110 = DCE110STRENC_FROM_STRENC(enc);1239 1240	uint32_t channels = 0;1241 1242	ASSERT(audio_info);1243	if (audio_info == NULL)1244		/* This should not happen.it does so we don't get BSOD*/1245		return;1246 1247	channels = speakers_to_channels(audio_info->flags.speaker_flags).all;1248 1249	/* setup the audio stream source select (audio -> dig mapping) */1250	REG_SET(AFMT_AUDIO_SRC_CONTROL, 0, AFMT_AUDIO_SRC_SELECT, az_inst);1251 1252	/* Channel allocation */1253	REG_UPDATE(AFMT_AUDIO_PACKET_CONTROL2, AFMT_AUDIO_CHANNEL_ENABLE, channels);1254}1255 1256static void dce110_se_setup_hdmi_audio(1257	struct stream_encoder *enc,1258	const struct audio_crtc_info *crtc_info)1259{1260	struct dce110_stream_encoder *enc110 = DCE110STRENC_FROM_STRENC(enc);1261 1262	struct audio_clock_info audio_clock_info = {0};1263	uint32_t max_packets_per_line;1264 1265	/* For now still do calculation, although this field is ignored when1266	above HDMI_PACKET_GEN_VERSION set to 1 */1267	max_packets_per_line = calc_max_audio_packets_per_line(crtc_info);1268 1269	/* HDMI_AUDIO_PACKET_CONTROL */1270	REG_UPDATE_2(HDMI_AUDIO_PACKET_CONTROL,1271			HDMI_AUDIO_PACKETS_PER_LINE, max_packets_per_line,1272			HDMI_AUDIO_DELAY_EN, 1);1273 1274	/* AFMT_AUDIO_PACKET_CONTROL */1275	REG_UPDATE(AFMT_AUDIO_PACKET_CONTROL, AFMT_60958_CS_UPDATE, 1);1276 1277	/* AFMT_AUDIO_PACKET_CONTROL2 */1278	REG_UPDATE_2(AFMT_AUDIO_PACKET_CONTROL2,1279			AFMT_AUDIO_LAYOUT_OVRD, 0,1280			AFMT_60958_OSF_OVRD, 0);1281 1282	/* HDMI_ACR_PACKET_CONTROL */1283	REG_UPDATE_3(HDMI_ACR_PACKET_CONTROL,1284			HDMI_ACR_AUTO_SEND, 1,1285			HDMI_ACR_SOURCE, 0,1286			HDMI_ACR_AUDIO_PRIORITY, 0);1287 1288	/* Program audio clock sample/regeneration parameters */1289	get_audio_clock_info(crtc_info->color_depth,1290			     crtc_info->requested_pixel_clock_100Hz,1291			     crtc_info->calculated_pixel_clock_100Hz,1292			     &audio_clock_info);1293	DC_LOG_HW_AUDIO(1294			"\n%s:Input::requested_pixel_clock_100Hz = %d"	\1295			"calculated_pixel_clock_100Hz = %d \n", __func__,	\1296			crtc_info->requested_pixel_clock_100Hz,		\1297			crtc_info->calculated_pixel_clock_100Hz);1298 1299	/* HDMI_ACR_32_0__HDMI_ACR_CTS_32_MASK */1300	REG_UPDATE(HDMI_ACR_32_0, HDMI_ACR_CTS_32, audio_clock_info.cts_32khz);1301 1302	/* HDMI_ACR_32_1__HDMI_ACR_N_32_MASK */1303	REG_UPDATE(HDMI_ACR_32_1, HDMI_ACR_N_32, audio_clock_info.n_32khz);1304 1305	/* HDMI_ACR_44_0__HDMI_ACR_CTS_44_MASK */1306	REG_UPDATE(HDMI_ACR_44_0, HDMI_ACR_CTS_44, audio_clock_info.cts_44khz);1307 1308	/* HDMI_ACR_44_1__HDMI_ACR_N_44_MASK */1309	REG_UPDATE(HDMI_ACR_44_1, HDMI_ACR_N_44, audio_clock_info.n_44khz);1310 1311	/* HDMI_ACR_48_0__HDMI_ACR_CTS_48_MASK */1312	REG_UPDATE(HDMI_ACR_48_0, HDMI_ACR_CTS_48, audio_clock_info.cts_48khz);1313 1314	/* HDMI_ACR_48_1__HDMI_ACR_N_48_MASK */1315	REG_UPDATE(HDMI_ACR_48_1, HDMI_ACR_N_48, audio_clock_info.n_48khz);1316 1317	/* Video driver cannot know in advance which sample rate will1318	   be used by HD Audio driver1319	   HDMI_ACR_PACKET_CONTROL__HDMI_ACR_N_MULTIPLE field is1320	   programmed below in interruppt callback */1321 1322	/* AFMT_60958_0__AFMT_60958_CS_CHANNEL_NUMBER_L_MASK &1323	AFMT_60958_0__AFMT_60958_CS_CLOCK_ACCURACY_MASK */1324	REG_UPDATE_2(AFMT_60958_0,1325			AFMT_60958_CS_CHANNEL_NUMBER_L, 1,1326			AFMT_60958_CS_CLOCK_ACCURACY, 0);1327 1328	/* AFMT_60958_1 AFMT_60958_CS_CHALNNEL_NUMBER_R */1329	REG_UPDATE(AFMT_60958_1, AFMT_60958_CS_CHANNEL_NUMBER_R, 2);1330 1331	/*AFMT_60958_2 now keep this settings until1332	 *  Programming guide comes out*/1333	REG_UPDATE_6(AFMT_60958_2,1334			AFMT_60958_CS_CHANNEL_NUMBER_2, 3,1335			AFMT_60958_CS_CHANNEL_NUMBER_3, 4,1336			AFMT_60958_CS_CHANNEL_NUMBER_4, 5,1337			AFMT_60958_CS_CHANNEL_NUMBER_5, 6,1338			AFMT_60958_CS_CHANNEL_NUMBER_6, 7,1339			AFMT_60958_CS_CHANNEL_NUMBER_7, 8);1340}1341 1342static void dce110_se_setup_dp_audio(1343	struct stream_encoder *enc)1344{1345	struct dce110_stream_encoder *enc110 = DCE110STRENC_FROM_STRENC(enc);1346 1347	/* --- DP Audio packet configurations --- */1348 1349	/* ATP Configuration */1350	REG_SET(DP_SEC_AUD_N, 0,1351			DP_SEC_AUD_N, DP_SEC_AUD_N__DP_SEC_AUD_N__DEFAULT);1352 1353	/* Async/auto-calc timestamp mode */1354	REG_SET(DP_SEC_TIMESTAMP, 0, DP_SEC_TIMESTAMP_MODE,1355			DP_SEC_TIMESTAMP__DP_SEC_TIMESTAMP_MODE__AUTO_CALC);1356 1357	/* --- The following are the registers1358	 *  copied from the SetupHDMI --- */1359 1360	/* AFMT_AUDIO_PACKET_CONTROL */1361	REG_UPDATE(AFMT_AUDIO_PACKET_CONTROL, AFMT_60958_CS_UPDATE, 1);1362 1363	/* AFMT_AUDIO_PACKET_CONTROL2 */1364	/* Program the ATP and AIP next */1365	REG_UPDATE_2(AFMT_AUDIO_PACKET_CONTROL2,1366			AFMT_AUDIO_LAYOUT_OVRD, 0,1367			AFMT_60958_OSF_OVRD, 0);1368 1369	/* AFMT_INFOFRAME_CONTROL0 */1370	REG_UPDATE(AFMT_INFOFRAME_CONTROL0, AFMT_AUDIO_INFO_UPDATE, 1);1371 1372	/* AFMT_60958_0__AFMT_60958_CS_CLOCK_ACCURACY_MASK */1373	REG_UPDATE(AFMT_60958_0, AFMT_60958_CS_CLOCK_ACCURACY, 0);1374}1375 1376static void dce110_se_enable_audio_clock(1377	struct stream_encoder *enc,1378	bool enable)1379{1380	struct dce110_stream_encoder *enc110 = DCE110STRENC_FROM_STRENC(enc);1381 1382	if (REG(AFMT_CNTL) == 0)1383		return;   /* DCE8/10 does not have this register */1384 1385	REG_UPDATE(AFMT_CNTL, AFMT_AUDIO_CLOCK_EN, !!enable);1386 1387	/* wait for AFMT clock to turn on,1388	 * expectation: this should complete in 1-2 reads1389	 *1390	 * REG_WAIT(AFMT_CNTL, AFMT_AUDIO_CLOCK_ON, !!enable, 1, 10);1391	 *1392	 * TODO: wait for clock_on does not work well. May need HW1393	 * program sequence. But audio seems work normally even without wait1394	 * for clock_on status change1395	 */1396}1397 1398static void dce110_se_enable_dp_audio(1399	struct stream_encoder *enc)1400{1401	struct dce110_stream_encoder *enc110 = DCE110STRENC_FROM_STRENC(enc);1402 1403	/* Enable Audio packets */1404	REG_UPDATE(DP_SEC_CNTL, DP_SEC_ASP_ENABLE, 1);1405 1406	/* Program the ATP and AIP next */1407	REG_UPDATE_2(DP_SEC_CNTL,1408			DP_SEC_ATP_ENABLE, 1,1409			DP_SEC_AIP_ENABLE, 1);1410 1411	/* Program STREAM_ENABLE after all the other enables. */1412	REG_UPDATE(DP_SEC_CNTL, DP_SEC_STREAM_ENABLE, 1);1413}1414 1415static void dce110_se_disable_dp_audio(1416	struct stream_encoder *enc)1417{1418	struct dce110_stream_encoder *enc110 = DCE110STRENC_FROM_STRENC(enc);1419	uint32_t value = 0;1420 1421	/* Disable Audio packets */1422	REG_UPDATE_5(DP_SEC_CNTL,1423			DP_SEC_ASP_ENABLE, 0,1424			DP_SEC_ATP_ENABLE, 0,1425			DP_SEC_AIP_ENABLE, 0,1426			DP_SEC_ACM_ENABLE, 0,1427			DP_SEC_STREAM_ENABLE, 0);1428 1429	/* This register shared with encoder info frame. Therefore we need to1430	keep master enabled if at least on of the fields is not 0 */1431	value = REG_READ(DP_SEC_CNTL);1432	if (value != 0)1433		REG_UPDATE(DP_SEC_CNTL, DP_SEC_STREAM_ENABLE, 1);1434 1435}1436 1437void dce110_se_audio_mute_control(1438	struct stream_encoder *enc,1439	bool mute)1440{1441	struct dce110_stream_encoder *enc110 = DCE110STRENC_FROM_STRENC(enc);1442 1443	REG_UPDATE(AFMT_AUDIO_PACKET_CONTROL, AFMT_AUDIO_SAMPLE_SEND, !mute);1444}1445 1446void dce110_se_dp_audio_setup(1447	struct stream_encoder *enc,1448	unsigned int az_inst,1449	struct audio_info *info)1450{1451	dce110_se_audio_setup(enc, az_inst, info);1452}1453 1454void dce110_se_dp_audio_enable(1455	struct stream_encoder *enc)1456{1457	dce110_se_enable_audio_clock(enc, true);1458	dce110_se_setup_dp_audio(enc);1459	dce110_se_enable_dp_audio(enc);1460}1461 1462void dce110_se_dp_audio_disable(1463	struct stream_encoder *enc)1464{1465	dce110_se_disable_dp_audio(enc);1466	dce110_se_enable_audio_clock(enc, false);1467}1468 1469void dce110_se_hdmi_audio_setup(1470	struct stream_encoder *enc,1471	unsigned int az_inst,1472	struct audio_info *info,1473	struct audio_crtc_info *audio_crtc_info)1474{1475	dce110_se_enable_audio_clock(enc, true);1476	dce110_se_setup_hdmi_audio(enc, audio_crtc_info);1477	dce110_se_audio_setup(enc, az_inst, info);1478}1479 1480void dce110_se_hdmi_audio_disable(1481	struct stream_encoder *enc)1482{1483	dce110_se_enable_audio_clock(enc, false);1484}1485 1486 1487static void setup_stereo_sync(1488	struct stream_encoder *enc,1489	int tg_inst, bool enable)1490{1491	struct dce110_stream_encoder *enc110 = DCE110STRENC_FROM_STRENC(enc);1492	REG_UPDATE(DIG_FE_CNTL, DIG_STEREOSYNC_SELECT, tg_inst);1493	REG_UPDATE(DIG_FE_CNTL, DIG_STEREOSYNC_GATE_EN, !enable);1494}1495 1496static void dig_connect_to_otg(1497	struct stream_encoder *enc,1498	int tg_inst)1499{1500	struct dce110_stream_encoder *enc110 = DCE110STRENC_FROM_STRENC(enc);1501 1502	REG_UPDATE(DIG_FE_CNTL, DIG_SOURCE_SELECT, tg_inst);1503}1504 1505static unsigned int dig_source_otg(1506	struct stream_encoder *enc)1507{1508	uint32_t tg_inst = 0;1509	struct dce110_stream_encoder *enc110 = DCE110STRENC_FROM_STRENC(enc);1510 1511	REG_GET(DIG_FE_CNTL, DIG_SOURCE_SELECT, &tg_inst);1512 1513	return tg_inst;1514}1515 1516static const struct stream_encoder_funcs dce110_str_enc_funcs = {1517	.dp_set_stream_attribute =1518		dce110_stream_encoder_dp_set_stream_attribute,1519	.hdmi_set_stream_attribute =1520		dce110_stream_encoder_hdmi_set_stream_attribute,1521	.dvi_set_stream_attribute =1522		dce110_stream_encoder_dvi_set_stream_attribute,1523	.lvds_set_stream_attribute =1524		dce110_stream_encoder_lvds_set_stream_attribute,1525	.set_throttled_vcp_size =1526		dce110_stream_encoder_set_throttled_vcp_size,1527	.update_hdmi_info_packets =1528		dce110_stream_encoder_update_hdmi_info_packets,1529	.stop_hdmi_info_packets =1530		dce110_stream_encoder_stop_hdmi_info_packets,1531	.update_dp_info_packets =1532		dce110_stream_encoder_update_dp_info_packets,1533	.stop_dp_info_packets =1534		dce110_stream_encoder_stop_dp_info_packets,1535	.dp_blank =1536		dce110_stream_encoder_dp_blank,1537	.dp_unblank =1538		dce110_stream_encoder_dp_unblank,1539	.audio_mute_control = dce110_se_audio_mute_control,1540 1541	.dp_audio_setup = dce110_se_dp_audio_setup,1542	.dp_audio_enable = dce110_se_dp_audio_enable,1543	.dp_audio_disable = dce110_se_dp_audio_disable,1544 1545	.hdmi_audio_setup = dce110_se_hdmi_audio_setup,1546	.hdmi_audio_disable = dce110_se_hdmi_audio_disable,1547	.setup_stereo_sync  = setup_stereo_sync,1548	.set_avmute = dce110_stream_encoder_set_avmute,1549	.dig_connect_to_otg  = dig_connect_to_otg,1550	.hdmi_reset_stream_attribute = dce110_reset_hdmi_stream_attribute,1551	.dig_source_otg = dig_source_otg,1552};1553 1554void dce110_stream_encoder_construct(1555	struct dce110_stream_encoder *enc110,1556	struct dc_context *ctx,1557	struct dc_bios *bp,1558	enum engine_id eng_id,1559	const struct dce110_stream_enc_registers *regs,1560	const struct dce_stream_encoder_shift *se_shift,1561	const struct dce_stream_encoder_mask *se_mask)1562{1563	enc110->base.funcs = &dce110_str_enc_funcs;1564	enc110->base.ctx = ctx;1565	enc110->base.id = eng_id;1566	enc110->base.bp = bp;1567	enc110->regs = regs;1568	enc110->se_shift = se_shift;1569	enc110->se_mask = se_mask;1570}1571