brintos

brintos / linux-shallow public Read only

0
0
Text · 15.4 KiB · 661f374 Raw
537 lines · c
1/*2 * Copyright 2008 Advanced Micro Devices, Inc.3 * Copyright 2008 Red Hat Inc.4 * Copyright 2009 Christian König.5 *6 * Permission is hereby granted, free of charge, to any person obtaining a7 * copy of this software and associated documentation files (the "Software"),8 * to deal in the Software without restriction, including without limitation9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,10 * and/or sell copies of the Software, and to permit persons to whom the11 * Software is furnished to do so, subject to the following conditions:12 *13 * The above copyright notice and this permission notice shall be included in14 * all copies or substantial portions of the Software.15 *16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL19 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR22 * OTHER DEALINGS IN THE SOFTWARE.23 *24 * Authors: Christian König25 */26#include <linux/hdmi.h>27#include <linux/gcd.h>28 29#include <drm/radeon_drm.h>30#include "radeon.h"31#include "radeon_asic.h"32#include "radeon_audio.h"33#include "r600.h"34#include "r600d.h"35#include "atom.h"36 37/*38 * HDMI color format39 */40enum r600_hdmi_color_format {41	RGB = 0,42	YCC_422 = 1,43	YCC_444 = 244};45 46/*47 * IEC60958 status bits48 */49enum r600_hdmi_iec_status_bits {50	AUDIO_STATUS_DIG_ENABLE   = 0x01,51	AUDIO_STATUS_V            = 0x02,52	AUDIO_STATUS_VCFG         = 0x04,53	AUDIO_STATUS_EMPHASIS     = 0x08,54	AUDIO_STATUS_COPYRIGHT    = 0x10,55	AUDIO_STATUS_NONAUDIO     = 0x20,56	AUDIO_STATUS_PROFESSIONAL = 0x40,57	AUDIO_STATUS_LEVEL        = 0x8058};59 60static struct r600_audio_pin r600_audio_status(struct radeon_device *rdev)61{62	struct r600_audio_pin status = {};63	uint32_t value;64 65	value = RREG32(R600_AUDIO_RATE_BPS_CHANNEL);66 67	/* number of channels */68	status.channels = (value & 0x7) + 1;69 70	/* bits per sample */71	switch ((value & 0xF0) >> 4) {72	case 0x0:73		status.bits_per_sample = 8;74		break;75	case 0x1:76		status.bits_per_sample = 16;77		break;78	case 0x2:79		status.bits_per_sample = 20;80		break;81	case 0x3:82		status.bits_per_sample = 24;83		break;84	case 0x4:85		status.bits_per_sample = 32;86		break;87	default:88		dev_err(rdev->dev, "Unknown bits per sample 0x%x, using 16\n",89			(int)value);90		status.bits_per_sample = 16;91	}92 93	/* current sampling rate in HZ */94	if (value & 0x4000)95		status.rate = 44100;96	else97		status.rate = 48000;98	status.rate *= ((value >> 11) & 0x7) + 1;99	status.rate /= ((value >> 8) & 0x7) + 1;100 101	value = RREG32(R600_AUDIO_STATUS_BITS);102 103	/* iec 60958 status bits */104	status.status_bits = value & 0xff;105 106	/* iec 60958 category code */107	status.category_code = (value >> 8) & 0xff;108 109	return status;110}111 112/*113 * update all hdmi interfaces with current audio parameters114 */115void r600_audio_update_hdmi(struct work_struct *work)116{117	struct radeon_device *rdev = container_of(work, struct radeon_device,118						  audio_work);119	struct drm_device *dev = rdev_to_drm(rdev);120	struct r600_audio_pin audio_status = r600_audio_status(rdev);121	struct drm_encoder *encoder;122	bool changed = false;123 124	if (rdev->audio.pin[0].channels != audio_status.channels ||125	    rdev->audio.pin[0].rate != audio_status.rate ||126	    rdev->audio.pin[0].bits_per_sample != audio_status.bits_per_sample ||127	    rdev->audio.pin[0].status_bits != audio_status.status_bits ||128	    rdev->audio.pin[0].category_code != audio_status.category_code) {129		rdev->audio.pin[0] = audio_status;130		changed = true;131	}132 133	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {134		if (!radeon_encoder_is_digital(encoder))135			continue;136		if (changed || r600_hdmi_buffer_status_changed(encoder))137			r600_hdmi_update_audio_settings(encoder);138	}139}140 141/* enable the audio stream */142void r600_audio_enable(struct radeon_device *rdev,143		       struct r600_audio_pin *pin,144		       u8 enable_mask)145{146	u32 tmp = RREG32(AZ_HOT_PLUG_CONTROL);147 148	if (!pin)149		return;150 151	if (enable_mask) {152		tmp |= AUDIO_ENABLED;153		if (enable_mask & 1)154			tmp |= PIN0_AUDIO_ENABLED;155		if (enable_mask & 2)156			tmp |= PIN1_AUDIO_ENABLED;157		if (enable_mask & 4)158			tmp |= PIN2_AUDIO_ENABLED;159		if (enable_mask & 8)160			tmp |= PIN3_AUDIO_ENABLED;161	} else {162		tmp &= ~(AUDIO_ENABLED |163			 PIN0_AUDIO_ENABLED |164			 PIN1_AUDIO_ENABLED |165			 PIN2_AUDIO_ENABLED |166			 PIN3_AUDIO_ENABLED);167	}168 169	WREG32(AZ_HOT_PLUG_CONTROL, tmp);170}171 172struct r600_audio_pin *r600_audio_get_pin(struct radeon_device *rdev)173{174	/* only one pin on 6xx-NI */175	return &rdev->audio.pin[0];176}177 178void r600_hdmi_update_acr(struct drm_encoder *encoder, long offset,179	const struct radeon_hdmi_acr *acr)180{181	struct drm_device *dev = encoder->dev;182	struct radeon_device *rdev = dev->dev_private;183 184	/* DCE 3.0 uses register that's normally for CRC_CONTROL */185	uint32_t acr_ctl = ASIC_IS_DCE3(rdev) ? DCE3_HDMI0_ACR_PACKET_CONTROL :186				       HDMI0_ACR_PACKET_CONTROL;187	WREG32_P(acr_ctl + offset,188		HDMI0_ACR_SOURCE |		/* select SW CTS value */189		HDMI0_ACR_AUTO_SEND,	/* allow hw to sent ACR packets when required */190		~(HDMI0_ACR_SOURCE |191		HDMI0_ACR_AUTO_SEND));192 193	WREG32_P(HDMI0_ACR_32_0 + offset,194		HDMI0_ACR_CTS_32(acr->cts_32khz),195		~HDMI0_ACR_CTS_32_MASK);196	WREG32_P(HDMI0_ACR_32_1 + offset,197		HDMI0_ACR_N_32(acr->n_32khz),198		~HDMI0_ACR_N_32_MASK);199 200	WREG32_P(HDMI0_ACR_44_0 + offset,201		HDMI0_ACR_CTS_44(acr->cts_44_1khz),202		~HDMI0_ACR_CTS_44_MASK);203	WREG32_P(HDMI0_ACR_44_1 + offset,204		HDMI0_ACR_N_44(acr->n_44_1khz),205		~HDMI0_ACR_N_44_MASK);206 207	WREG32_P(HDMI0_ACR_48_0 + offset,208		HDMI0_ACR_CTS_48(acr->cts_48khz),209		~HDMI0_ACR_CTS_48_MASK);210	WREG32_P(HDMI0_ACR_48_1 + offset,211		HDMI0_ACR_N_48(acr->n_48khz),212		~HDMI0_ACR_N_48_MASK);213}214 215/*216 * build a HDMI Video Info Frame217 */218void r600_set_avi_packet(struct radeon_device *rdev, u32 offset,219			 unsigned char *buffer, size_t size)220{221	uint8_t *frame = buffer + 3;222 223	WREG32(HDMI0_AVI_INFO0 + offset,224		frame[0x0] | (frame[0x1] << 8) | (frame[0x2] << 16) | (frame[0x3] << 24));225	WREG32(HDMI0_AVI_INFO1 + offset,226		frame[0x4] | (frame[0x5] << 8) | (frame[0x6] << 16) | (frame[0x7] << 24));227	WREG32(HDMI0_AVI_INFO2 + offset,228		frame[0x8] | (frame[0x9] << 8) | (frame[0xA] << 16) | (frame[0xB] << 24));229	WREG32(HDMI0_AVI_INFO3 + offset,230		frame[0xC] | (frame[0xD] << 8) | (buffer[1] << 24));231 232	WREG32_OR(HDMI0_INFOFRAME_CONTROL1 + offset,233		  HDMI0_AVI_INFO_LINE(2));	/* anything other than 0 */234 235	WREG32_OR(HDMI0_INFOFRAME_CONTROL0 + offset,236		  HDMI0_AVI_INFO_SEND |	/* enable AVI info frames */237		  HDMI0_AVI_INFO_CONT);	/* send AVI info frames every frame/field */238 239}240 241/*242 * build a Audio Info Frame243 */244static void r600_hdmi_update_audio_infoframe(struct drm_encoder *encoder,245					     const void *buffer, size_t size)246{247	struct drm_device *dev = encoder->dev;248	struct radeon_device *rdev = dev->dev_private;249	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);250	struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;251	uint32_t offset = dig->afmt->offset;252	const u8 *frame = buffer + 3;253 254	WREG32(HDMI0_AUDIO_INFO0 + offset,255		frame[0x0] | (frame[0x1] << 8) | (frame[0x2] << 16) | (frame[0x3] << 24));256	WREG32(HDMI0_AUDIO_INFO1 + offset,257		frame[0x4] | (frame[0x5] << 8) | (frame[0x6] << 16) | (frame[0x8] << 24));258}259 260/*261 * test if audio buffer is filled enough to start playing262 */263static bool r600_hdmi_is_audio_buffer_filled(struct drm_encoder *encoder)264{265	struct drm_device *dev = encoder->dev;266	struct radeon_device *rdev = dev->dev_private;267	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);268	struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;269	uint32_t offset = dig->afmt->offset;270 271	return (RREG32(HDMI0_STATUS + offset) & 0x10) != 0;272}273 274/*275 * have buffer status changed since last call?276 */277int r600_hdmi_buffer_status_changed(struct drm_encoder *encoder)278{279	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);280	struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;281	int status, result;282 283	if (!dig->afmt || !dig->afmt->enabled)284		return 0;285 286	status = r600_hdmi_is_audio_buffer_filled(encoder);287	result = dig->afmt->last_buffer_filled_status != status;288	dig->afmt->last_buffer_filled_status = status;289 290	return result;291}292 293/*294 * write the audio workaround status to the hardware295 */296void r600_hdmi_audio_workaround(struct drm_encoder *encoder)297{298	struct drm_device *dev = encoder->dev;299	struct radeon_device *rdev = dev->dev_private;300	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);301	struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;302	uint32_t offset = dig->afmt->offset;303	bool hdmi_audio_workaround = false; /* FIXME */304	u32 value;305 306	if (!hdmi_audio_workaround ||307	    r600_hdmi_is_audio_buffer_filled(encoder))308		value = 0; /* disable workaround */309	else310		value = HDMI0_AUDIO_TEST_EN; /* enable workaround */311	WREG32_P(HDMI0_AUDIO_PACKET_CONTROL + offset,312		 value, ~HDMI0_AUDIO_TEST_EN);313}314 315void r600_hdmi_audio_set_dto(struct radeon_device *rdev,316			     struct radeon_crtc *crtc, unsigned int clock)317{318	struct radeon_encoder *radeon_encoder;319	struct radeon_encoder_atom_dig *dig;320 321	if (!crtc)322		return;323 324	radeon_encoder = to_radeon_encoder(crtc->encoder);325	dig = radeon_encoder->enc_priv;326 327	if (!dig)328		return;329 330	if (dig->dig_encoder == 0) {331		WREG32(DCCG_AUDIO_DTO0_PHASE, 24000 * 100);332		WREG32(DCCG_AUDIO_DTO0_MODULE, clock * 100);333		WREG32(DCCG_AUDIO_DTO_SELECT, 0); /* select DTO0 */334	} else {335		WREG32(DCCG_AUDIO_DTO1_PHASE, 24000 * 100);336		WREG32(DCCG_AUDIO_DTO1_MODULE, clock * 100);337		WREG32(DCCG_AUDIO_DTO_SELECT, 1); /* select DTO1 */338	}339}340 341void r600_set_vbi_packet(struct drm_encoder *encoder, u32 offset)342{343	struct drm_device *dev = encoder->dev;344	struct radeon_device *rdev = dev->dev_private;345 346	WREG32_OR(HDMI0_VBI_PACKET_CONTROL + offset,347		HDMI0_NULL_SEND |	/* send null packets when required */348		HDMI0_GC_SEND |		/* send general control packets */349		HDMI0_GC_CONT);		/* send general control packets every frame */350}351 352void r600_set_audio_packet(struct drm_encoder *encoder, u32 offset)353{354	struct drm_device *dev = encoder->dev;355	struct radeon_device *rdev = dev->dev_private;356 357	WREG32_P(HDMI0_AUDIO_PACKET_CONTROL + offset,358		HDMI0_AUDIO_SAMPLE_SEND |			/* send audio packets */359		HDMI0_AUDIO_DELAY_EN(1) |			/* default audio delay */360		HDMI0_AUDIO_PACKETS_PER_LINE(3) |	/* should be suffient for all audio modes and small enough for all hblanks */361		HDMI0_60958_CS_UPDATE,				/* allow 60958 channel status fields to be updated */362		~(HDMI0_AUDIO_SAMPLE_SEND |363		HDMI0_AUDIO_DELAY_EN_MASK |364		HDMI0_AUDIO_PACKETS_PER_LINE_MASK |365		HDMI0_60958_CS_UPDATE));366 367	WREG32_OR(HDMI0_INFOFRAME_CONTROL0 + offset,368		HDMI0_AUDIO_INFO_SEND |		/* enable audio info frames (frames won't be set until audio is enabled) */369		HDMI0_AUDIO_INFO_UPDATE);	/* required for audio info values to be updated */370 371	WREG32_P(HDMI0_INFOFRAME_CONTROL1 + offset,372		HDMI0_AUDIO_INFO_LINE(2),	/* anything other than 0 */373		~HDMI0_AUDIO_INFO_LINE_MASK);374 375	WREG32_AND(HDMI0_GENERIC_PACKET_CONTROL + offset,376		~(HDMI0_GENERIC0_SEND |377		HDMI0_GENERIC0_CONT |378		HDMI0_GENERIC0_UPDATE |379		HDMI0_GENERIC1_SEND |380		HDMI0_GENERIC1_CONT |381		HDMI0_GENERIC0_LINE_MASK |382		HDMI0_GENERIC1_LINE_MASK));383 384	WREG32_P(HDMI0_60958_0 + offset,385		HDMI0_60958_CS_CHANNEL_NUMBER_L(1),386		~(HDMI0_60958_CS_CHANNEL_NUMBER_L_MASK |387		HDMI0_60958_CS_CLOCK_ACCURACY_MASK));388 389	WREG32_P(HDMI0_60958_1 + offset,390		HDMI0_60958_CS_CHANNEL_NUMBER_R(2),391		~HDMI0_60958_CS_CHANNEL_NUMBER_R_MASK);392}393 394void r600_set_mute(struct drm_encoder *encoder, u32 offset, bool mute)395{396	struct drm_device *dev = encoder->dev;397	struct radeon_device *rdev = dev->dev_private;398 399	if (mute)400		WREG32_OR(HDMI0_GC + offset, HDMI0_GC_AVMUTE);401	else402		WREG32_AND(HDMI0_GC + offset, ~HDMI0_GC_AVMUTE);403}404 405/**406 * r600_hdmi_update_audio_settings - Update audio infoframe407 *408 * @encoder: drm encoder409 *410 * Gets info about current audio stream and updates audio infoframe.411 */412void r600_hdmi_update_audio_settings(struct drm_encoder *encoder)413{414	struct drm_device *dev = encoder->dev;415	struct radeon_device *rdev = dev->dev_private;416	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);417	struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;418	struct r600_audio_pin audio = r600_audio_status(rdev);419	uint8_t buffer[HDMI_INFOFRAME_HEADER_SIZE + HDMI_AUDIO_INFOFRAME_SIZE];420	struct hdmi_audio_infoframe frame;421	uint32_t offset;422	uint32_t value;423	ssize_t err;424 425	if (!dig->afmt || !dig->afmt->enabled)426		return;427	offset = dig->afmt->offset;428 429	DRM_DEBUG("%s with %d channels, %d Hz sampling rate, %d bits per sample,\n",430		 r600_hdmi_is_audio_buffer_filled(encoder) ? "playing" : "stopped",431		  audio.channels, audio.rate, audio.bits_per_sample);432	DRM_DEBUG("0x%02X IEC60958 status bits and 0x%02X category code\n",433		  (int)audio.status_bits, (int)audio.category_code);434 435	err = hdmi_audio_infoframe_init(&frame);436	if (err < 0) {437		DRM_ERROR("failed to setup audio infoframe\n");438		return;439	}440 441	frame.channels = audio.channels;442 443	err = hdmi_audio_infoframe_pack(&frame, buffer, sizeof(buffer));444	if (err < 0) {445		DRM_ERROR("failed to pack audio infoframe\n");446		return;447	}448 449	value = RREG32(HDMI0_AUDIO_PACKET_CONTROL + offset);450	if (value & HDMI0_AUDIO_TEST_EN)451		WREG32(HDMI0_AUDIO_PACKET_CONTROL + offset,452		       value & ~HDMI0_AUDIO_TEST_EN);453 454	WREG32_OR(HDMI0_CONTROL + offset,455		  HDMI0_ERROR_ACK);456 457	WREG32_AND(HDMI0_INFOFRAME_CONTROL0 + offset,458		   ~HDMI0_AUDIO_INFO_SOURCE);459 460	r600_hdmi_update_audio_infoframe(encoder, buffer, sizeof(buffer));461 462	WREG32_OR(HDMI0_INFOFRAME_CONTROL0 + offset,463		  HDMI0_AUDIO_INFO_CONT |464		  HDMI0_AUDIO_INFO_UPDATE);465}466 467/*468 * enable the HDMI engine469 */470void r600_hdmi_enable(struct drm_encoder *encoder, bool enable)471{472	struct drm_device *dev = encoder->dev;473	struct radeon_device *rdev = dev->dev_private;474	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);475	struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;476	u32 hdmi = HDMI0_ERROR_ACK;477 478	if (!dig || !dig->afmt)479		return;480 481	/* Older chipsets require setting HDMI and routing manually */482	if (!ASIC_IS_DCE3(rdev)) {483		if (enable)484			hdmi |= HDMI0_ENABLE;485		switch (radeon_encoder->encoder_id) {486		case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:487			if (enable) {488				WREG32_OR(AVIVO_TMDSA_CNTL, AVIVO_TMDSA_CNTL_HDMI_EN);489				hdmi |= HDMI0_STREAM(HDMI0_STREAM_TMDSA);490			} else {491				WREG32_AND(AVIVO_TMDSA_CNTL, ~AVIVO_TMDSA_CNTL_HDMI_EN);492			}493			break;494		case ENCODER_OBJECT_ID_INTERNAL_LVTM1:495			if (enable) {496				WREG32_OR(AVIVO_LVTMA_CNTL, AVIVO_LVTMA_CNTL_HDMI_EN);497				hdmi |= HDMI0_STREAM(HDMI0_STREAM_LVTMA);498			} else {499				WREG32_AND(AVIVO_LVTMA_CNTL, ~AVIVO_LVTMA_CNTL_HDMI_EN);500			}501			break;502		case ENCODER_OBJECT_ID_INTERNAL_DDI:503			if (enable) {504				WREG32_OR(DDIA_CNTL, DDIA_HDMI_EN);505				hdmi |= HDMI0_STREAM(HDMI0_STREAM_DDIA);506			} else {507				WREG32_AND(DDIA_CNTL, ~DDIA_HDMI_EN);508			}509			break;510		case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:511			if (enable)512				hdmi |= HDMI0_STREAM(HDMI0_STREAM_DVOA);513			break;514		default:515			dev_err(rdev->dev, "Invalid encoder for HDMI: 0x%X\n",516				radeon_encoder->encoder_id);517			break;518		}519		WREG32(HDMI0_CONTROL + dig->afmt->offset, hdmi);520	}521 522	if (rdev->irq.installed) {523		/* if irq is available use it */524		/* XXX: shouldn't need this on any asics.  Double check DCE2/3 */525		if (enable)526			radeon_irq_kms_enable_afmt(rdev, dig->afmt->id);527		else528			radeon_irq_kms_disable_afmt(rdev, dig->afmt->id);529	}530 531	dig->afmt->enabled = enable;532 533	DRM_DEBUG("%sabling HDMI interface @ 0x%04X for encoder 0x%x\n",534		  enable ? "En" : "Dis", dig->afmt->offset, radeon_encoder->encoder_id);535}536 537