1615 lines · 46.6 KB · C
RawDownload
/* * 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 "dc_bios_types.h"#include "dce_stream_encoder.h"#include "reg_helper.h"#include "hw_shared.h" #define DC_LOGGER \		enc110->base.ctx->logger #define REG(reg)\	(enc110->regs->reg) #undef FN#define FN(reg_name, field_name) \	enc110->se_shift->field_name, enc110->se_mask->field_name #define VBI_LINE_0 0#define DP_BLANK_MAX_RETRY 20#define HDMI_CLOCK_CHANNEL_RATE_MORE_340M 340000 #ifndef TMDS_CNTL__TMDS_PIXEL_ENCODING_MASK	#define TMDS_CNTL__TMDS_PIXEL_ENCODING_MASK       0x00000010L	#define TMDS_CNTL__TMDS_COLOR_FORMAT_MASK         0x00000300L	#define	TMDS_CNTL__TMDS_PIXEL_ENCODING__SHIFT     0x00000004	#define	TMDS_CNTL__TMDS_COLOR_FORMAT__SHIFT       0x00000008#endif enum {	DP_MST_UPDATE_MAX_RETRY = 50}; #define DCE110_SE(audio)\	container_of(audio, struct dce110_stream_encoder, base) #define CTX \	enc110->base.ctx static void dce110_update_generic_info_packet(	struct dce110_stream_encoder *enc110,	uint32_t packet_index,	const struct dc_info_packet *info_packet){	/* TODOFPGA Figure out a proper number for max_retries polling for lock	 * use 50 for now.	 */	uint32_t max_retries = 50; 	/*we need turn on clock before programming AFMT block*/	if (REG(AFMT_CNTL))		REG_UPDATE(AFMT_CNTL, AFMT_AUDIO_CLOCK_EN, 1); 	if (REG(AFMT_VBI_PACKET_CONTROL1)) {		if (packet_index >= 8)			ASSERT(0); 		/* poll dig_update_lock is not locked -> asic internal signal		 * assume otg master lock will unlock it		 *//*		REG_WAIT(AFMT_VBI_PACKET_CONTROL, AFMT_GENERIC_LOCK_STATUS,				0, 10, max_retries);*/ 		/* check if HW reading GSP memory */		REG_WAIT(AFMT_VBI_PACKET_CONTROL, AFMT_GENERIC_CONFLICT,				0, 10, max_retries); 		/* HW does is not reading GSP memory not reading too long ->		 * something wrong. clear GPS memory access and notify?		 * hw SW is writing to GSP memory		 */		REG_UPDATE(AFMT_VBI_PACKET_CONTROL, AFMT_GENERIC_CONFLICT_CLR, 1);	}	/* choose which generic packet to use */	{		REG_READ(AFMT_VBI_PACKET_CONTROL);		REG_UPDATE(AFMT_VBI_PACKET_CONTROL,				AFMT_GENERIC_INDEX, packet_index);	} 	/* write generic packet header	 * (4th byte is for GENERIC0 only) */	{		REG_SET_4(AFMT_GENERIC_HDR, 0,				AFMT_GENERIC_HB0, info_packet->hb0,				AFMT_GENERIC_HB1, info_packet->hb1,				AFMT_GENERIC_HB2, info_packet->hb2,				AFMT_GENERIC_HB3, info_packet->hb3);	} 	/* write generic packet contents	 * (we never use last 4 bytes)	 * there are 8 (0-7) mmDIG0_AFMT_GENERIC0_x registers */	{		const uint32_t *content =			(const uint32_t *) &info_packet->sb[0]; 		REG_WRITE(AFMT_GENERIC_0, *content++);		REG_WRITE(AFMT_GENERIC_1, *content++);		REG_WRITE(AFMT_GENERIC_2, *content++);		REG_WRITE(AFMT_GENERIC_3, *content++);		REG_WRITE(AFMT_GENERIC_4, *content++);		REG_WRITE(AFMT_GENERIC_5, *content++);		REG_WRITE(AFMT_GENERIC_6, *content++);		REG_WRITE(AFMT_GENERIC_7, *content);	} 	if (!REG(AFMT_VBI_PACKET_CONTROL1)) {		/* force double-buffered packet update */		REG_UPDATE_2(AFMT_VBI_PACKET_CONTROL,			AFMT_GENERIC0_UPDATE, (packet_index == 0),			AFMT_GENERIC2_UPDATE, (packet_index == 2));	} 	if (REG(AFMT_VBI_PACKET_CONTROL1)) {		switch (packet_index) {		case 0:			REG_UPDATE(AFMT_VBI_PACKET_CONTROL1,					AFMT_GENERIC0_FRAME_UPDATE, 1);			break;		case 1:			REG_UPDATE(AFMT_VBI_PACKET_CONTROL1,					AFMT_GENERIC1_FRAME_UPDATE, 1);			break;		case 2:			REG_UPDATE(AFMT_VBI_PACKET_CONTROL1,					AFMT_GENERIC2_FRAME_UPDATE, 1);			break;		case 3:			REG_UPDATE(AFMT_VBI_PACKET_CONTROL1,					AFMT_GENERIC3_FRAME_UPDATE, 1);			break;		case 4:			REG_UPDATE(AFMT_VBI_PACKET_CONTROL1,					AFMT_GENERIC4_FRAME_UPDATE, 1);			break;		case 5:			REG_UPDATE(AFMT_VBI_PACKET_CONTROL1,					AFMT_GENERIC5_FRAME_UPDATE, 1);			break;		case 6:			REG_UPDATE(AFMT_VBI_PACKET_CONTROL1,					AFMT_GENERIC6_FRAME_UPDATE, 1);			break;		case 7:			REG_UPDATE(AFMT_VBI_PACKET_CONTROL1,					AFMT_GENERIC7_FRAME_UPDATE, 1);			break;		default:			break;		}	}} static void dce110_update_hdmi_info_packet(	struct dce110_stream_encoder *enc110,	uint32_t packet_index,	const struct dc_info_packet *info_packet){	uint32_t cont, send, line; 	if (info_packet->valid) {		dce110_update_generic_info_packet(			enc110,			packet_index,			info_packet); 		/* enable transmission of packet(s) -		 * packet transmission begins on the next frame */		cont = 1;		/* send packet(s) every frame */		send = 1;		/* select line number to send packets on */		line = 2;	} else {		cont = 0;		send = 0;		line = 0;	} 	/* choose which generic packet control to use */	switch (packet_index) {	case 0:		REG_UPDATE_3(HDMI_GENERIC_PACKET_CONTROL0,				HDMI_GENERIC0_CONT, cont,				HDMI_GENERIC0_SEND, send,				HDMI_GENERIC0_LINE, line);		break;	case 1:		REG_UPDATE_3(HDMI_GENERIC_PACKET_CONTROL0,				HDMI_GENERIC1_CONT, cont,				HDMI_GENERIC1_SEND, send,				HDMI_GENERIC1_LINE, line);		break;	case 2:		REG_UPDATE_3(HDMI_GENERIC_PACKET_CONTROL1,				HDMI_GENERIC0_CONT, cont,				HDMI_GENERIC0_SEND, send,				HDMI_GENERIC0_LINE, line);		break;	case 3:		REG_UPDATE_3(HDMI_GENERIC_PACKET_CONTROL1,				HDMI_GENERIC1_CONT, cont,				HDMI_GENERIC1_SEND, send,				HDMI_GENERIC1_LINE, line);		break;	case 4:		if (REG(HDMI_GENERIC_PACKET_CONTROL2))			REG_UPDATE_3(HDMI_GENERIC_PACKET_CONTROL2,					HDMI_GENERIC0_CONT, cont,					HDMI_GENERIC0_SEND, send,					HDMI_GENERIC0_LINE, line);		break;	case 5:		if (REG(HDMI_GENERIC_PACKET_CONTROL2))			REG_UPDATE_3(HDMI_GENERIC_PACKET_CONTROL2,					HDMI_GENERIC1_CONT, cont,					HDMI_GENERIC1_SEND, send,					HDMI_GENERIC1_LINE, line);		break;	case 6:		if (REG(HDMI_GENERIC_PACKET_CONTROL3))			REG_UPDATE_3(HDMI_GENERIC_PACKET_CONTROL3,					HDMI_GENERIC0_CONT, cont,					HDMI_GENERIC0_SEND, send,					HDMI_GENERIC0_LINE, line);		break;	case 7:		if (REG(HDMI_GENERIC_PACKET_CONTROL3))			REG_UPDATE_3(HDMI_GENERIC_PACKET_CONTROL3,					HDMI_GENERIC1_CONT, cont,					HDMI_GENERIC1_SEND, send,					HDMI_GENERIC1_LINE, line);		break;	default:		/* invalid HW packet index */		DC_LOG_WARNING(			"Invalid HW packet index: %s()\n",			__func__);		return;	}} /* setup stream encoder in dp mode */static void dce110_stream_encoder_dp_set_stream_attribute(	struct stream_encoder *enc,	struct dc_crtc_timing *crtc_timing,	enum dc_color_space output_color_space,	bool use_vsc_sdp_for_colorimetry,	uint32_t enable_sdp_splitting){	(void)enable_sdp_splitting;	uint32_t h_active_start;	uint32_t v_active_start;	uint32_t misc0 = 0;	uint32_t misc1 = 0;	uint32_t h_blank;	uint32_t h_back_porch;	uint8_t colorimetry_bpc;	uint8_t dynamic_range_rgb = 0; /*full range*/	uint8_t dynamic_range_ycbcr = 1; /*bt709*/ 	struct dce110_stream_encoder *enc110 = DCE110STRENC_FROM_STRENC(enc);	struct dc_crtc_timing hw_crtc_timing = *crtc_timing;	if (hw_crtc_timing.flags.INTERLACE) {		/*the input timing is in VESA spec format with Interlace flag =1*/		hw_crtc_timing.v_total /= 2;		hw_crtc_timing.v_border_top /= 2;		hw_crtc_timing.v_addressable /= 2;		hw_crtc_timing.v_border_bottom /= 2;		hw_crtc_timing.v_front_porch /= 2;		hw_crtc_timing.v_sync_width /= 2;	}	/* set pixel encoding */	switch (hw_crtc_timing.pixel_encoding) {	case PIXEL_ENCODING_YCBCR422:		REG_UPDATE(DP_PIXEL_FORMAT, DP_PIXEL_ENCODING,				DP_PIXEL_ENCODING_TYPE_YCBCR422);		break;	case PIXEL_ENCODING_YCBCR444:		REG_UPDATE(DP_PIXEL_FORMAT, DP_PIXEL_ENCODING,				DP_PIXEL_ENCODING_TYPE_YCBCR444); 		if (hw_crtc_timing.flags.Y_ONLY)			if (hw_crtc_timing.display_color_depth != COLOR_DEPTH_666)				/* HW testing only, no use case yet.				 * Color depth of Y-only could be				 * 8, 10, 12, 16 bits */				REG_UPDATE(DP_PIXEL_FORMAT, DP_PIXEL_ENCODING,						DP_PIXEL_ENCODING_TYPE_Y_ONLY);		/* Note: DP_MSA_MISC1 bit 7 is the indicator		 * of Y-only mode.		 * This bit is set in HW if register		 * DP_PIXEL_ENCODING is programmed to 0x4 */		break;	case PIXEL_ENCODING_YCBCR420:		REG_UPDATE(DP_PIXEL_FORMAT, DP_PIXEL_ENCODING,				DP_PIXEL_ENCODING_TYPE_YCBCR420);		if (enc110->se_mask->DP_VID_M_DOUBLE_VALUE_EN)			REG_UPDATE(DP_VID_TIMING, DP_VID_M_DOUBLE_VALUE_EN, 1); 		if (enc110->se_mask->DP_VID_N_MUL)			REG_UPDATE(DP_VID_TIMING, DP_VID_N_MUL, 1);		break;	default:		REG_UPDATE(DP_PIXEL_FORMAT, DP_PIXEL_ENCODING,				DP_PIXEL_ENCODING_TYPE_RGB444);		break;	} 	if (REG(DP_MSA_MISC))		misc1 = REG_READ(DP_MSA_MISC); 	/* For YCbCr420 and BT2020 Colorimetry Formats, VSC SDP shall be used.	 * When MISC1, bit 6, is Set to 1, a Source device uses a VSC SDP to indicate the	 * Pixel Encoding/Colorimetry Format and that a Sink device shall ignore MISC1, bit 7,	 * and MISC0, bits 7:1 (MISC1, bit 7, and MISC0, bits 7:1, become "don't care").	 */	if (use_vsc_sdp_for_colorimetry)		misc1 = misc1 | 0x40;	else		misc1 = misc1 & ~0x40; 	/* set color depth */ 	switch (hw_crtc_timing.display_color_depth) {	case COLOR_DEPTH_666:		REG_UPDATE(DP_PIXEL_FORMAT, DP_COMPONENT_DEPTH,				0);		break;	case COLOR_DEPTH_888:		REG_UPDATE(DP_PIXEL_FORMAT, DP_COMPONENT_DEPTH,				DP_COMPONENT_PIXEL_DEPTH_8BPC);		break;	case COLOR_DEPTH_101010:		REG_UPDATE(DP_PIXEL_FORMAT, DP_COMPONENT_DEPTH,				DP_COMPONENT_PIXEL_DEPTH_10BPC); 		break;	case COLOR_DEPTH_121212:		REG_UPDATE(DP_PIXEL_FORMAT, DP_COMPONENT_DEPTH,				DP_COMPONENT_PIXEL_DEPTH_12BPC);		break;	default:		REG_UPDATE(DP_PIXEL_FORMAT, DP_COMPONENT_DEPTH,				DP_COMPONENT_PIXEL_DEPTH_6BPC);		break;	} 	/* set dynamic range and YCbCr range */  	switch (hw_crtc_timing.display_color_depth) {	case COLOR_DEPTH_666:		colorimetry_bpc = 0;		break;	case COLOR_DEPTH_888:		colorimetry_bpc = 1;		break;	case COLOR_DEPTH_101010:		colorimetry_bpc = 2;		break;	case COLOR_DEPTH_121212:		colorimetry_bpc = 3;		break;	default:		colorimetry_bpc = 0;		break;	} 	misc0 = colorimetry_bpc << 5; 	if (REG(DP_MSA_TIMING_PARAM1)) {		switch (output_color_space) {		case COLOR_SPACE_SRGB:			misc0 = misc0 | 0x0;			misc1 = misc1 & ~0x80; /* bit7 = 0*/			dynamic_range_rgb = 0; /*full range*/			break;		case COLOR_SPACE_SRGB_LIMITED:			misc0 = misc0 | 0x8; /* bit3=1 */			misc1 = misc1 & ~0x80; /* bit7 = 0*/			dynamic_range_rgb = 1; /*limited range*/			break;		case COLOR_SPACE_YCBCR601:		case COLOR_SPACE_YCBCR601_LIMITED:			misc0 = misc0 | 0x8; /* bit3=1, bit4=0 */			misc1 = misc1 & ~0x80; /* bit7 = 0*/			dynamic_range_ycbcr = 0; /*bt601*/			if (hw_crtc_timing.pixel_encoding == PIXEL_ENCODING_YCBCR422)				misc0 = misc0 | 0x2; /* bit2=0, bit1=1 */			else if (hw_crtc_timing.pixel_encoding == PIXEL_ENCODING_YCBCR444)				misc0 = misc0 | 0x4; /* bit2=1, bit1=0 */			break;		case COLOR_SPACE_YCBCR709:		case COLOR_SPACE_YCBCR709_LIMITED:		case COLOR_SPACE_YCBCR709_BLACK:			misc0 = misc0 | 0x18; /* bit3=1, bit4=1 */			misc1 = misc1 & ~0x80; /* bit7 = 0*/			dynamic_range_ycbcr = 1; /*bt709*/			if (hw_crtc_timing.pixel_encoding == PIXEL_ENCODING_YCBCR422)				misc0 = misc0 | 0x2; /* bit2=0, bit1=1 */			else if (hw_crtc_timing.pixel_encoding == PIXEL_ENCODING_YCBCR444)				misc0 = misc0 | 0x4; /* bit2=1, bit1=0 */			break;		case COLOR_SPACE_2020_RGB_LIMITEDRANGE:			dynamic_range_rgb = 1; /*limited range*/			break;		case COLOR_SPACE_2020_RGB_FULLRANGE:		case COLOR_SPACE_2020_YCBCR_LIMITED:		case COLOR_SPACE_XR_RGB:		case COLOR_SPACE_MSREF_SCRGB:		case COLOR_SPACE_ADOBERGB:		case COLOR_SPACE_DCIP3:		case COLOR_SPACE_XV_YCC_709:		case COLOR_SPACE_XV_YCC_601:		case COLOR_SPACE_DISPLAYNATIVE:		case COLOR_SPACE_DOLBYVISION:		case COLOR_SPACE_APPCTRL:		case COLOR_SPACE_CUSTOMPOINTS:		case COLOR_SPACE_UNKNOWN:		default:			/* do nothing */			break;		}		if (enc110->se_mask->DP_DYN_RANGE && enc110->se_mask->DP_YCBCR_RANGE)			REG_UPDATE_2(				DP_PIXEL_FORMAT,				DP_DYN_RANGE, dynamic_range_rgb,				DP_YCBCR_RANGE, dynamic_range_ycbcr); 		if (REG(DP_MSA_COLORIMETRY))			REG_SET(DP_MSA_COLORIMETRY, 0, DP_MSA_MISC0, misc0); 		if (REG(DP_MSA_MISC))			REG_WRITE(DP_MSA_MISC, misc1);   /* MSA_MISC1 */ 	/* dcn new register	 * dc_crtc_timing is vesa dmt struct. data from edid	 */		if (REG(DP_MSA_TIMING_PARAM1))			REG_SET_2(DP_MSA_TIMING_PARAM1, 0,					DP_MSA_HTOTAL, hw_crtc_timing.h_total,					DP_MSA_VTOTAL, hw_crtc_timing.v_total); 		/* calcuate from vesa timing parameters		 * h_active_start related to leading edge of sync		 */ 		h_blank = hw_crtc_timing.h_total - hw_crtc_timing.h_border_left -				hw_crtc_timing.h_addressable - hw_crtc_timing.h_border_right; 		h_back_porch = h_blank - hw_crtc_timing.h_front_porch -				hw_crtc_timing.h_sync_width; 		/* start at begining of left border */		h_active_start = hw_crtc_timing.h_sync_width + h_back_porch;  		v_active_start = hw_crtc_timing.v_total - hw_crtc_timing.v_border_top -				hw_crtc_timing.v_addressable - hw_crtc_timing.v_border_bottom -				hw_crtc_timing.v_front_porch;  		/* start at begining of left border */		if (REG(DP_MSA_TIMING_PARAM2))			REG_SET_2(DP_MSA_TIMING_PARAM2, 0,				DP_MSA_HSTART, h_active_start,				DP_MSA_VSTART, v_active_start); 		if (REG(DP_MSA_TIMING_PARAM3))			REG_SET_4(DP_MSA_TIMING_PARAM3, 0,					DP_MSA_HSYNCWIDTH,					hw_crtc_timing.h_sync_width,					DP_MSA_HSYNCPOLARITY,					!hw_crtc_timing.flags.HSYNC_POSITIVE_POLARITY,					DP_MSA_VSYNCWIDTH,					hw_crtc_timing.v_sync_width,

Lines 1–500 of 1615.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t