[RFH] Add HDMI audio support
From: Luis R. Rodriguez <lrodriguez@atheros.com> This is based on radeonhd driver, this is a port to radeon. Cc: Egbert Eich <eich@novell.com> Cc: Matthias Hopf <mhopf@novell.com> Cc: Luc Verhaegen <libv@exsuse.de> Cc: Christian König <deathsimple@vodafone.de> Signed-off-by: Luis R. Rodriguez <mcgrof@gmail.com> --- RFT - Request For Help/patch takeover I've taken a stab at porting HDMI support from the radeonhd driver onto the radeon driver. Mind you this is my first video patch, so not sure if it was done properly. I kept telling myself I was going to finish this during my night hours but my night hours are now reserved. So if it is at least done some-what right was hoping someone could take this on themselves and complete it... The missing piece should be the generic HDMI stuff which I thought was not required but in fact is. Forgot if I compile tested.. definitely didn't try loading yet. I just rebased this onto today's git HEAD. I do have an HD4800 which I can test. Anyway, hope someone with more time can take this over. src/atombios_output.c | 2 + src/radeon.h | 96 ++++++++++ src/radeon_atombios.c | 17 ++ src/radeon_hdmi_audio.c | 442 +++++++++++++++++++++++++++++++++++++++++++++++ src/radeon_macros.h | 3 + src/radeon_probe.h | 1 + src/radeon_reg.h | 6 + 7 files changed, 567 insertions(+), 0 deletions(-) create mode 100644 src/radeon_hdmi_audio.c diff --git a/src/atombios_output.c b/src/atombios_output.c index 00d17cb..73196c0 100644 --- a/src/atombios_output.c +++ b/src/atombios_output.c @@ -1509,6 +1509,8 @@ atombios_output_mode_set(xf86OutputPtr output, atombios_output_dig_encoder_setup(output, ATOM_ENABLE); atombios_output_dig_transmitter_setup(output, ATOM_TRANSMITTER_ACTION_SETUP); atombios_output_dig_transmitter_setup(output, ATOM_TRANSMITTER_ACTION_ENABLE); + if (atombios_get_encoder_mode(output) == ATOM_ENCODER_MODE_HDMI) + radeon_hdmi_audio_register(); break; case ENCODER_OBJECT_ID_INTERNAL_DDI: atombios_output_ddia_setup(output, ATOM_ENABLE); diff --git a/src/radeon.h b/src/radeon.h index 3c62fd9..7d280e5 100644 --- a/src/radeon.h +++ b/src/radeon.h @@ -1,6 +1,11 @@ /* * Copyright 2000 ATI Technologies Inc., Markham, Ontario, and * VA Linux Systems Inc., Fremont, California. + * Copyright 2008 Christian König <deathsimple@vodafone.de> + * Copyright 2007 Luc Verhaegen <libv@exsuse.de> + * Copyright 2007 Matthias Hopf <mhopf@novell.com> + * Copyright 2007 Egbert Eich <eich@novell.com> + * Copyright 2007 Advanced Micro Devices, Inc. * * All Rights Reserved. * @@ -775,6 +780,34 @@ struct radeon_accel_state { }; +struct radeon_hdmi_audio { + + int scrnIndex; + + //struct rhdHdmi* Registered; + OsTimerPtr Timer; + + Bool SavedPlaying; + int SavedChannels; + int SavedRate; + int SavedBitsPerSample; + CARD8 SavedStatusBits; + CARD8 SavedCategoryCode; + + Bool Stored; + + CARD32 StoreEnabled; + CARD32 StoreTiming; + CARD32 StoreSupportedSizeRate; + CARD32 StoreSupportedCodec; + + CARD32 StorePll1Mul; + CARD32 StorePll1Div; + CARD32 StorePll2Mul; + CARD32 StorePll2Div; + CARD32 StoreClockSrcSel; +}; + typedef struct { EntityInfoPtr pEnt; pciVideoPtr PciInfo; @@ -979,6 +1012,7 @@ typedef struct { float igp_system_mclk; float igp_ht_link_clk; float igp_ht_link_width; + struct radeon_hdmi_audio *hdmi_audio; int can_resize; void (*reemit_current2d)(ScrnInfoPtr pScrn, int op); // emit the current 2D state into the IB @@ -1005,6 +1039,53 @@ typedef struct { int bicubic_offset; } RADEONInfoRec, *RADEONInfoPtr; +/* + * used for config value of radeon_hmdi_audio_set_supported + */ +enum { + AUDIO_RATE_8000_HZ = 0x00000001, + AUDIO_RATE_11025_HZ = 0x00000002, + AUDIO_RATE_16000_HZ = 0x00000004, + AUDIO_RATE_22050_HZ = 0x00000008, + AUDIO_RATE_32000_HZ = 0x00000010, + AUDIO_RATE_44100_HZ = 0x00000020, + AUDIO_RATE_48000_HZ = 0x00000040, + AUDIO_RATE_88200_HZ = 0x00000080, + AUDIO_RATE_96000_HZ = 0x00000100, + AUDIO_RATE_176400_HZ = 0x00000200, + AUDIO_RATE_192000_HZ = 0x00000400, + AUDIO_RATE_384000_HZ = 0x00000800, + + AUDIO_BPS_8 = 0x00010000, + AUDIO_BPS_16 = 0x00020000, + AUDIO_BPS_20 = 0x00040000, + AUDIO_BPS_24 = 0x00080000, + AUDIO_BPS_32 = 0x00100000 +}; + +/* + * used for codec value of radeon_hmdi_audio_set_supported + */ +enum { + AUDIO_CODEC_PCM = 0x00000001, + AUDIO_CODEC_FLOAT32 = 0x00000002, + AUDIO_CODEC_AC3 = 0x00000004 +}; + +/* + * used for status bist value in radeon_update_hdmi_audio + */ +enum { + AUDIO_STATUS_DIG_ENABLE = 0x01, + AUDIO_STATUS_V = 0x02, + AUDIO_STATUS_VCFG = 0x04, + AUDIO_STATUS_EMPHASIS = 0x08, + AUDIO_STATUS_COPYRIGHT = 0x10, + AUDIO_STATUS_NONAUDIO = 0x20, + AUDIO_STATUS_PROFESSIONAL = 0x40, + AUDIO_STATUS_LEVEL = 0x80 +}; + #define RADEONWaitForFifo(pScrn, entries) \ do { \ if (info->accel_state->fifo_slots < entries) \ @@ -1284,6 +1365,21 @@ extern void radeon_ddx_cs_start(ScrnInfoPtr pScrn, struct radeon_bo *radeon_get_pixmap_bo(PixmapPtr pPix); void radeon_set_pixmap_bo(PixmapPtr pPix, struct radeon_bo *bo); +/* radeon_hdmi_audio.c */ +extern void radeon_hdmi_audio_init(RHDPtr rhdPtr); + +extern void radeon_hdmi_audio_set_supported(RHDPtr rhdPtr, Bool clear, CARD32 config, CARD32 codec); +extern void radeon_hdmi_audio_set_enable(RHDPtr rhdPtr, Bool Enable); +extern void radeon_hdmi_audio_set_clock(RHDPtr rhdPtr, struct rhdOutput* Output, CARD32 Clock); + +extern void radeon_hdmi_audio_register(RHDPtr rhdPtr, struct rhdHdmi* rhdHdmi); +extern void radeon_hdmi_audio_unregister(RHDPtr rhdPtr, struct rhdHdmi* rhdHdmi); + +extern void radeon_hdmi_audio_save(RHDPtr rhdPtr); +extern void radeon_hdmi_audio_restore(RHDPtr rhdPtr); + +extern void radeon_hdmi_audio_destroy(RHDPtr rhdPtr); + #ifdef XF86DRI # ifdef USE_XAA /* radeon_accelfuncs.c */ diff --git a/src/radeon_atombios.c b/src/radeon_atombios.c index f590d5b..ff8c11d 100644 --- a/src/radeon_atombios.c +++ b/src/radeon_atombios.c @@ -1771,6 +1771,23 @@ radeon_add_encoder(ScrnInfoPtr pScrn, uint32_t encoder_id, uint32_t device_suppo } break; } + + /* This time around we'll just set the HDMI offset */ + switch (encoder_id) { + case ENCODER_OBJECT_ID_INTERNAL_TMDS1: + case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: + info->encoders[device_index]->hdmi_offset = RADEON_HDMI_TMDS; + break; + case ENCODER_OBJECT_ID_INTERNAL_LVTM1: + info->encoders[device_index]->hdmi_offset = RADEON_HDMI_LVTMA; + break; + case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: + info->encoders[device_index]->hdmi_offset = RADEON_HDMI_DIG; + break; + default: + info->encoders[device_index]->hdmi_offset = 0; + break; + } return TRUE; } else { ErrorF("xalloc failed\n"); diff --git a/src/radeon_hdmi_audio.c b/src/radeon_hdmi_audio.c new file mode 100644 index 0000000..931cb6d --- /dev/null +++ b/src/radeon_hdmi_audio.c @@ -0,0 +1,442 @@ +/* + * Copyright 2009 Luis R. Rodriguez <mcgrof@gmail.com> + * Copyright 2008 Christian König <deathsimple@vodafone.de> + * Copyright 2007 Luc Verhaegen <libv@exsuse.de> + * Copyright 2007 Matthias Hopf <mhopf@novell.com> + * Copyright 2007 Egbert Eich <eich@novell.com> + * Copyright 2007 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. + */ + +#include "radeon.h" + +#define RADEON_HDMI_AUDIO_TIMER_INTERVALL 100 /* 1/10 sekund should be enough */ + +/* + * current number of channels + */ +static int radeon_hdmi_audio_channels(xf86OutputPtr output) +{ + RADEONInfoPtr info = RADEONPTR(output->scrn); + unsigned char *RADEONMMIO = info->MMIO; + return (INREG(AUDIO_RATE_BPS_CHANNEL) & 0x7) + 1; +} + +/* + * current bits per sample + */ +static int radeon_hdmi_audio_bits_per_sample(xf86OutputPtr output) +{ + RADEONOutputPrivatePtr radeon_output = output->driver_private; + struct radeon_hdmi_audio *Audio = radeon_output->hdmi_audio; + RADEONInfoPtr info = RADEONPTR(output->scrn); + unsigned char *RADEONMMIO = info->MMIO; + + CARD32 value = (INREG(AUDIO_RATE_BPS_CHANNEL) & 0xF0) >> 4; + switch(value) + { + case 0x0: return 8; + case 0x1: return 16; + case 0x2: return 20; + case 0x3: return 24; + case 0x4: return 32; + } + + xf86DrvMsg(Audio->scrnIndex, X_WARNING, "%s: unknown bits per sample 0x%x " + "using 16 instead.\n", __func__, (int) value); + + return 16; +} + +/* + * current sampling rate in HZ + */ +static int radeon_hdmi_audio_rate(xf86OutputPtr output) +{ + RADEONInfoPtr info = RADEONPTR(output->scrn); + unsigned char *RADEONMMIO = info->MMIO; + + CARD32 value = INREG(AUDIO_RATE_BPS_CHANNEL); + CARD32 result; + + if(value & 0x4000) + result = 44100; + else + result = 48000; + + result *= ((value >> 11) & 0x7) + 1; + result /= ((value >> 8) & 0x7) + 1; + + return result; +} + +/* + * something playing ? + */ +static Bool radeon_hdmi_audio_playing(xf86OutputPtr output) +{ + RADEONInfoPtr info = RADEONPTR(output->scrn); + unsigned char *RADEONMMIO = info->MMIO; + return (INREG(AUDIO_PLAYING) >> 4) & 1; +} + +/* + * iec 60958 status bits + */ +static CARD8 radeon_hdmi_audio_status_bits(xf86OutputPtr output) +{ + RADEONInfoPtr info = RADEONPTR(output->scrn); + unsigned char *RADEONMMIO = info->MMIO; + return INREG(AUDIO_STATUS_BITS) & 0xff; +} + +/* + * iec 60958 category code + */ +static CARD8 radeon_hdmi_audio_category_code(xf86OutputPtr output) +{ + RADEONInfoPtr info = RADEONPTR(output->scrn); + unsigned char *RADEONMMIO = info->MMIO; + return (INREG(AUDIO_STATUS_BITS) >> 8) & 0xff; +} + +/* + * update all registered hdmi interfaces with current audio parameters + */ +static CARD32 radeon_timer_hdmi_audio(OsTimerPtr timer, CARD32 time, pointer ptr) +{ + struct radeon_hdmi_audio *Audio = (struct radeon_hdmi_audio*)ptr; + Bool playing = radeon_hdmi_audio_playing(Audio); + int channels = radeon_hdmi_audio_hannels(Audio); + int rate = radeon_hdmi_audio_rate(Audio); + int bps = radeon_hdmi_audio_bits_per_sample(Audio); + CARD8 status_bits = radeon_audio_status_bits(Audio); + CARD8 category_code = radeon_audio_category_code(Audio); + + struct rhdHdmi* hdmi; + + if (playing != Audio->SavedPlaying || + channels != Audio->SavedChannels || + rate != Audio->SavedRate || + bps != Audio->SavedBitsPerSample || + status_bits != Audio->SavedStatusBits || + category_code != Audio->SavedCategoryCode) { + + Audio->SavedPlaying = playing; + Audio->SavedChannels = channels; + Audio->SavedRate = rate; + Audio->SavedBitsPerSample = bps; + Audio->SavedStatusBits = status_bits; + Audio->SavedCategoryCode = category_code; + + /* XXX: port hdmi struct usage */ + for (hdmi=Audio->Registered; hdmi != NULL; hdmi=hdmi->Next) + radeon_hdmi_update_audio_settings( + hdmi, playing, channels, + rate, bps, status_bits, + category_code); + } + + return RADEON_HDMI_AUDIO_TIMER_INTERVALL; +} + +/* + * allocate and init the audio structure + */ +void +radeon_hdmi_audio_init(xf86OutputPtr output) +{ + RADEONInfoPtr info = RADEONPTR(output->scrn); + RADEONOutputPrivatePtr radeon_output = output->driver_private; + struct radeon_hdmi_audio *Audio; + + if (info->ChipFamily < CHIP_FAMILY_RS600) { + radeon_output->Audio = NULL; + return; + } + + Audio = (struct radeon_hdmi_audio *) xnfcalloc(sizeof(struct radeon_hdmi_audio), 1); + Audio->scrnIndex = info->atomBIOS->scrnIndex; + Audio->Registered = NULL; + Audio->Stored = FALSE; + + radeon_output->Audio = Audio; +} + +/* + * enable or disable the complete audio engine + */ +void +radeon_hdmi_audio_set_enable(xf86OutputPtr output, Bool Enable) +{ + RADEONOutputPrivatePtr radeon_output = output->driver_private; + struct radeon_hdmi_audio *Audio = radeon_output->hdmi_audio; + + if (!Audio) + return; + + REG_RMW(AUDIO_ENABLE, Enable ? 0x80000000 : 0x0, 0x80000000); + if (!Enable) { + TimerFree(Audio->Timer); + Audio->Timer = NULL; + return; + } + + /* + * the hardware generates an interrupt if audio starts/stops playing, + * but since drm doesn't support this interrupt, we check + * every RADEON_HDMI_AUDIO_TIMER_INTERVALL ms if something has changed + */ + + Audio->SavedChannels = -1; + Audio->SavedRate = -1; + Audio->SavedBitsPerSample = -1; + Audio->SavedStatusBits = 0; + Audio->SavedCategoryCode = 0; + Audio->Timer = TimerSet(NULL, 0, RADEON_HDMI_AUDIO_TIMER_INTERVALL, + radeon_hdmi_audio_update, Audio); + + /* 48kHz and 16/20 bits per sample are always supported */ + radeon_hdmi_audio_set_supported(output, TRUE, + AUDIO_RATE_48000_HZ | + AUDIO_BPS_16 | + AUDIO_BPS_20, + AUDIO_CODEC_PCM); +} + +/* + * programm the audio clock and timing registers + */ +void +radeon_hdmi_audio_set_clock(xf86OutputPtr output, CARD32 Clock) +{ + RADEONOutputPrivatePtr radeon_output = output->driver_private; + struct radeon_hdmi_audio *Audio = radeon_output->hdmi_audio; + radeon_encoder_ptr radeon_encoder; + RADEONInfoPtr info = RADEONPTR(output->scrn); + unsigned char *RADEONMMIO = info->MMIO; + + int Rate = 48000; + + if (!Audio) + return; + + radeon_encoder = radeon_get_encoder(output); + + xf86DrvMsg(Audio->scrnIndex, X_INFO, "%s: using %s as clock source with %d khz\n", + __func__, + device_name[radeon_get_device_index(radeon_output->active_device)], + (int) Clock); + + switch(radeon_encoder->encoder_id) { + case ENCODER_OBJECT_ID_INTERNAL_TMDS1: + case ENCODER_OBJECT_ID_INTERNAL_LVTM1: + REG_RMW(AUDIO_TIMING, 0, 0x301); + break; + case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: + case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: + case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: + REG_RMW(AUDIO_TIMING, 0x100, 0x301); + break; + + default: + break; + } + + switch(radeon_encoder->encoder_id) { + case ENCODER_OBJECT_ID_INTERNAL_TMDS1: + case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: + OUTREG(AUDIO_PLL1_MUL, Rate*50); + OUTREG(AUDIO_PLL1_DIV, Clock*100); + OUTREG(AUDIO_CLK_SRCSEL, 0); + break; + + case ENCODER_OBJECT_ID_INTERNAL_LVTM1: + case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: + case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: + OUTREG(AUDIO_PLL2_MUL, Rate*50); + OUTREG(AUDIO_PLL2_DIV, Clock*100); + OUTREG(AUDIO_CLK_SRCSEL, 1); + break; + + default: + xf86DrvMsg(Audio->scrnIndex, X_ERROR, "%s: unsupported output type\n", __func__); + break; + } +} + +/* + * set the supported audio rates, bits per sample and codecs + */ +void +radeon_hdmi_audio_set_supported(xf86OutputPtr output, Bool clear, CARD32 config, CARD32 codec) +{ + RADEONOutputPrivatePtr radeon_output = output->driver_private; + struct radeon_hdmi_audio *Audio = radeon_output->hdmi_audio; + RADEONInfoPtr info = RADEONPTR(output->scrn); + unsigned char *RADEONMMIO = info->MMIO; + + if (!Audio) + return; + + xf86DrvMsg(Audio->scrnIndex, X_INFO, "%s: config 0x%x codec 0x%x\n", + __func__, (int) config, (int) codec); + + if(config & 0xFFE0F000) + xf86DrvMsg(Audio->scrnIndex, X_WARNING, "%s: reserved config bits set 0x%x\n", + __func__, (int) config); + + if(codec & 0xFFFFFFF8) + xf86DrvMsg(Audio->scrnIndex, X_WARNING, "%s: reserved codec bits set 0x%x\n", + __func__, (int) codec); + + if (clear) { + OUTREG(AUDIO_SUPPORTED_SIZE_RATE, config); + OUTREG(AUDIO_SUPPORTED_CODEC, codec); + } else { + OUTREG(AUDIO_SUPPORTED_SIZE_RATE, config, config); + OUTREG(AUDIO_SUPPORTED_CODEC, codec, codec); + } +} + +/* + * register and hdmi interface for getting updates when audio parameters change. + * The right approach here is to use DRM interrupts for Audio updates but until + * DRM does not suppor that we use a timer to update it regularly. + */ +void radeon_hdmi_audio_register(xf86OutputPtr output, struct rhdHdmi* rhdHdmi) +{ + RADEONOutputPrivatePtr radeon_output = output->driver_private; + struct radeon_hdmi_audio *Audio = radeon_output->hdmi_audio; + + if (!Audio) + return; + + /* XXX: How to port rhdHmdi to ati driver from radeonhd */ + if(!rhdHdmi) + return; + + rhdHdmi->Next = Audio->Registered; + Audio->Registered = rhdHdmi; +} + + +/* + * unregister the hdmi interface + */ +void radeon_hdmi_audio_unregister(xf86OutputPtr output, struct rhdHdmi* rhdHdmi) +{ + RADEONOutputPrivatePtr radeon_output = output->driver_private; + struct radeon_hdmi_audio *Audio = radeon_output->hdmi_audio; + struct rhdHdmi** hdmiPtr; + + if (!Audio) + return; + + for (hdmiPtr=&Audio->Registered; hdmiPtr!=NULL; hdmiPtr=&(*hdmiPtr)->Next) { + if(*hdmiPtr != rhdHdmi) + continue; + *hdmiPtr = rhdHdmi->Next; + rhdHdmi->Next = NULL; + return; + } + +} + +/* + * save the current config of audio engine + */ +void +radeon_hdmi_audio_save(xf86OutputPtr output) +{ + RADEONOutputPrivatePtr radeon_output = output->driver_private; + struct radeon_hdmi_audio *Audio = radeon_output->hdmi_audio; + unsigned char *RADEONMMIO = info->MMIO; + + if (!Audio) + return; + + Audio->StoreEnabled = INREG(AUDIO_ENABLE); + Audio->StoreTiming = INREG(AUDIO_TIMING); + + Audio->StoreSupportedSizeRate = INREG(AUDIO_SUPPORTED_SIZE_RATE); + Audio->StoreSupportedCodec = INREG(AUDIO_SUPPORTED_CODEC); + + Audio->StorePll1Mul = INREG(AUDIO_PLL1_MUL); + Audio->StorePll1Div = INREG(AUDIO_PLL1_DIV); + Audio->StorePll2Mul = INREG(AUDIO_PLL2_MUL); + Audio->StorePll2Div = INREG(AUDIO_PLL2_DIV); + Audio->StoreClockSrcSel = INREG(AUDIO_CLK_SRCSEL); + + Audio->Stored = TRUE; +} + +/* + * restore the saved config of audio engine + */ +void +radeon_hdmi_audio_restore(xf86OutputPtr output) +{ + RADEONOutputPrivatePtr radeon_output = output->driver_private; + struct radeon_hdmi_audio *Audio = radeon_output->hdmi_audio; + RADEONInfoPtr info = RADEONPTR(output->scrn); + unsigned char *RADEONMMIO = info->MMIO; + + if (!Audio) + return; + + if (!Audio->Stored) { + xf86DrvMsg(Audio->scrnIndex, X_ERROR, "%s: trying to restore " + "uninitialized values.\n", __func__); + return; + } + + /* shoutdown the audio engine before doing anything else */ + radeon_hdmi_audio_set_enable(output, FALSE); + + OUTREG(AUDIO_TIMING, Audio->StoreTiming); + OUTREG(AUDIO_SUPPORTED_SIZE_RATE, Audio->StoreSupportedSizeRate); + OUTREG(AUDIO_SUPPORTED_CODEC, Audio->StoreSupportedCodec); + + OUTREG(AUDIO_PLL1_MUL, Audio->StorePll1Mul); + OUTREG(AUDIO_PLL1_DIV, Audio->StorePll1Div); + OUTREG(AUDIO_PLL2_MUL, Audio->StorePll2Mul); + OUTREG(AUDIO_PLL2_DIV, Audio->StorePll2Div); + OUTREG(AUDIO_CLK_SRCSEL, Audio->StoreClockSrcSel); + OUTREG(AUDIO_ENABLE, Audio->StoreEnabled); +} + +/* + * release the allocated memory + */ +void +radeon_hdmi_audio_destroy(xf86OutputPtr output) +{ + RADEONOutputPrivatePtr radeon_output = output->driver_private; + + if (!radeon_output->hdmi_audio) + return; + + if(radeon_output->hdmi_audio->Timer) + TimerFree(radeon_output->hdmi_audio->Timer); + + xfree(radeon_output->hdmi_audio); + radeon_output->hdmi_audio = NULL; +} diff --git a/src/radeon_macros.h b/src/radeon_macros.h index 26d9825..a51f2f4 100644 --- a/src/radeon_macros.h +++ b/src/radeon_macros.h @@ -69,6 +69,9 @@ #define ADDRREG(addr) ((volatile uint32_t *)(pointer)(RADEONMMIO + (addr))) +#define REG_RMW(_r, _m, _v) \ + OUTREG((_r), \ + (INREG(_r) & ~_m) | ((_v) & _m)) #define OUTREGP(addr, val, mask) \ do { \ diff --git a/src/radeon_probe.h b/src/radeon_probe.h index 9cac15c..b62f019 100644 --- a/src/radeon_probe.h +++ b/src/radeon_probe.h @@ -167,6 +167,7 @@ typedef struct _RADEONCrtcPrivateRec { typedef struct _radeon_encoder { uint16_t encoder_id; int devices; + uint32_t hdmi_offset; void *dev_priv; } radeon_encoder_rec, *radeon_encoder_ptr; diff --git a/src/radeon_reg.h b/src/radeon_reg.h index 9df7fff..0e1e9a4 100644 --- a/src/radeon_reg.h +++ b/src/radeon_reg.h @@ -3833,6 +3833,12 @@ #define AVIVO_D2SCL_SCALER_TAP_CONTROL 0x6d94 #define AVIVO_D2SCL_UPDATE 0x6dcc +/* HDMI offsets */ +#define RADEON_HDMI_TMDS 0x7400 +#define RADEON_HDMI_LVTMA 0x7700 +#define RADEON_HDMI_DIG 0x7800 + + #define AVIVO_DDIA_BIT_DEPTH_CONTROL 0x7214 #define AVIVO_DACA_ENABLE 0x7800 -- 1.6.3.3 -- To unsubscribe, e-mail: radeonhd+unsubscribe@opensuse.org For additional commands, e-mail: radeonhd+help@opensuse.org
RFT - Request For Help/patch takeover
I've taken a stab at porting HDMI support from the radeonhd driver onto the radeon driver. Mind you this is my first video patch, so not sure if it was done properly. I kept telling myself I was going to finish this during my night hours but my night hours are now reserved. So if it is at least done some-what right was hoping someone could take this on themselves and complete it... The missing piece should be the generic HDMI stuff which I thought was not required but in fact is. as far as i have read the patch you are still missing some quite essential stuff. The generic hdmi stuff is not only for the encoder/transmitter setup, but also for audio clock recovery and feeding
Hi, Am Freitag, den 24.07.2009, 13:12 -0400 schrieb Luis R. Rodriguez: the television with the right audio parameters (sampling rate, bit per sampel etc.). I always wondered when somebody starts to port this over to radeon. I considered doing it myself, but as far as i know the radeon driver it's relying complete on atombios to do the tmdsa and lvtma transmitter setup, and at least for hdmi support that's bad. I fought quite allot with radeonhd to get atombios+hdmi support running at the same time, for RV630 i reverted to move setting a missing bit with the TMDSA and LVTMA control register to the hdmi enabling function, but i couldn't find a good solution for my RS780 (with DIG interface). Maybe i am just not feeding the right values to atombios so it can set the registers right, but since even fglrx revert to programming the registers directly i assume that atombios is simply not capable of doing this. Beside from that i don't have time to support another implementation of this stuff, so i am sorry but at least i can't take it over. Bye, Christian. -- To unsubscribe, e-mail: radeonhd+unsubscribe@opensuse.org For additional commands, e-mail: radeonhd+help@opensuse.org
2009/7/26 Christian König <deathsimple@vodafone.de>:
Hi,
Am Freitag, den 24.07.2009, 13:12 -0400 schrieb Luis R. Rodriguez:
RFT - Request For Help/patch takeover
I've taken a stab at porting HDMI support from the radeonhd driver onto the radeon driver. Mind you this is my first video patch, so not sure if it was done properly. I kept telling myself I was going to finish this during my night hours but my night hours are now reserved. So if it is at least done some-what right was hoping someone could take this on themselves and complete it... The missing piece should be the generic HDMI stuff which I thought was not required but in fact is.
as far as i have read the patch you are still missing some quite essential stuff. The generic hdmi stuff is not only for the encoder/transmitter setup, but also for audio clock recovery and feeding the television with the right audio parameters (sampling rate, bit per sampel etc.).
Yeah, that stuff is missing.
I always wondered when somebody starts to port this over to radeon. I considered doing it myself, but as far as i know the radeon driver it's relying complete on atombios to do the tmdsa and lvtma transmitter setup, and at least for hdmi support that's bad.
Interesting..
I fought quite allot with radeonhd to get atombios+hdmi support running at the same time, for RV630 i reverted to move setting a missing bit with the TMDSA and LVTMA control register to the hdmi enabling function, but i couldn't find a good solution for my RS780 (with DIG interface).
Maybe i am just not feeding the right values to atombios so it can set the registers right, but since even fglrx revert to programming the registers directly i assume that atombios is simply not capable of doing this.
So radeonhd HDMI stuff really may only work for some cards?
Beside from that i don't have time to support another implementation of this stuff, so i am sorry but at least i can't take it over.
No problem, I appreciate the feedback. If I ever really get the urge to use my HDMI cable I guess I will finish this. Problem is, if the way radeonhd is doing it is not the good way (through atombios), do we have documentation to do it the right way? FWIW, fglx is completely fucking useless for me. Luis -- To unsubscribe, e-mail: radeonhd+unsubscribe@opensuse.org For additional commands, e-mail: radeonhd+help@opensuse.org
2009/7/28 Luis R. Rodriguez <mcgrof@gmail.com>:
2009/7/26 Christian König <deathsimple@vodafone.de>:
Hi,
Am Freitag, den 24.07.2009, 13:12 -0400 schrieb Luis R. Rodriguez:
RFT - Request For Help/patch takeover
I've taken a stab at porting HDMI support from the radeonhd driver onto the radeon driver. Mind you this is my first video patch, so not sure if it was done properly. I kept telling myself I was going to finish this during my night hours but my night hours are now reserved. So if it is at least done some-what right was hoping someone could take this on themselves and complete it... The missing piece should be the generic HDMI stuff which I thought was not required but in fact is.
as far as i have read the patch you are still missing some quite essential stuff. The generic hdmi stuff is not only for the encoder/transmitter setup, but also for audio clock recovery and feeding the television with the right audio parameters (sampling rate, bit per sampel etc.).
Yeah, that stuff is missing.
I always wondered when somebody starts to port this over to radeon. I considered doing it myself, but as far as i know the radeon driver it's relying complete on atombios to do the tmdsa and lvtma transmitter setup, and at least for hdmi support that's bad.
Interesting..
I fought quite allot with radeonhd to get atombios+hdmi support running at the same time, for RV630 i reverted to move setting a missing bit with the TMDSA and LVTMA control register to the hdmi enabling function, but i couldn't find a good solution for my RS780 (with DIG interface).
Maybe i am just not feeding the right values to atombios so it can set the registers right, but since even fglrx revert to programming the registers directly i assume that atombios is simply not capable of doing this.
So radeonhd HDMI stuff really may only work for some cards?
Beside from that i don't have time to support another implementation of this stuff, so i am sorry but at least i can't take it over.
No problem, I appreciate the feedback. If I ever really get the urge to use my HDMI cable I guess I will finish this.
Problem is, if the way radeonhd is doing it is not the good way (through atombios), do we have documentation to do it the right way?
We plan to look at the info for a possible documentation or code release at some point, but we haven't had the time to compile and review it yet. Alex -- To unsubscribe, e-mail: radeonhd+unsubscribe@opensuse.org For additional commands, e-mail: radeonhd+help@opensuse.org
2009/7/28 Alex Deucher <alexdeucher@gmail.com>:
2009/7/28 Luis R. Rodriguez <mcgrof@gmail.com>:
2009/7/26 Christian König <deathsimple@vodafone.de>:
Hi,
Am Freitag, den 24.07.2009, 13:12 -0400 schrieb Luis R. Rodriguez:
RFT - Request For Help/patch takeover
I've taken a stab at porting HDMI support from the radeonhd driver onto the radeon driver. Mind you this is my first video patch, so not sure if it was done properly. I kept telling myself I was going to finish this during my night hours but my night hours are now reserved. So if it is at least done some-what right was hoping someone could take this on themselves and complete it... The missing piece should be the generic HDMI stuff which I thought was not required but in fact is.
as far as i have read the patch you are still missing some quite essential stuff. The generic hdmi stuff is not only for the encoder/transmitter setup, but also for audio clock recovery and feeding the television with the right audio parameters (sampling rate, bit per sampel etc.).
Yeah, that stuff is missing.
I always wondered when somebody starts to port this over to radeon. I considered doing it myself, but as far as i know the radeon driver it's relying complete on atombios to do the tmdsa and lvtma transmitter setup, and at least for hdmi support that's bad.
Interesting..
I fought quite allot with radeonhd to get atombios+hdmi support running at the same time, for RV630 i reverted to move setting a missing bit with the TMDSA and LVTMA control register to the hdmi enabling function, but i couldn't find a good solution for my RS780 (with DIG interface).
Maybe i am just not feeding the right values to atombios so it can set the registers right, but since even fglrx revert to programming the registers directly i assume that atombios is simply not capable of doing this.
So radeonhd HDMI stuff really may only work for some cards?
Beside from that i don't have time to support another implementation of this stuff, so i am sorry but at least i can't take it over.
No problem, I appreciate the feedback. If I ever really get the urge to use my HDMI cable I guess I will finish this.
Problem is, if the way radeonhd is doing it is not the good way (through atombios), do we have documentation to do it the right way?
We plan to look at the info for a possible documentation or code release at some point, but we haven't had the time to compile and review it yet.
So if I do have time to finish the port, is that worth it? Or is that time not spent well at this point? Luis -- To unsubscribe, e-mail: radeonhd+unsubscribe@opensuse.org For additional commands, e-mail: radeonhd+help@opensuse.org
2009/7/28 Luis R. Rodriguez <mcgrof@gmail.com>:
2009/7/28 Alex Deucher <alexdeucher@gmail.com>:
2009/7/28 Luis R. Rodriguez <mcgrof@gmail.com>:
2009/7/26 Christian König <deathsimple@vodafone.de>:
Hi,
Am Freitag, den 24.07.2009, 13:12 -0400 schrieb Luis R. Rodriguez:
RFT - Request For Help/patch takeover
I've taken a stab at porting HDMI support from the radeonhd driver onto the radeon driver. Mind you this is my first video patch, so not sure if it was done properly. I kept telling myself I was going to finish this during my night hours but my night hours are now reserved. So if it is at least done some-what right was hoping someone could take this on themselves and complete it... The missing piece should be the generic HDMI stuff which I thought was not required but in fact is.
as far as i have read the patch you are still missing some quite essential stuff. The generic hdmi stuff is not only for the encoder/transmitter setup, but also for audio clock recovery and feeding the television with the right audio parameters (sampling rate, bit per sampel etc.).
Yeah, that stuff is missing.
I always wondered when somebody starts to port this over to radeon. I considered doing it myself, but as far as i know the radeon driver it's relying complete on atombios to do the tmdsa and lvtma transmitter setup, and at least for hdmi support that's bad.
Interesting..
I fought quite allot with radeonhd to get atombios+hdmi support running at the same time, for RV630 i reverted to move setting a missing bit with the TMDSA and LVTMA control register to the hdmi enabling function, but i couldn't find a good solution for my RS780 (with DIG interface).
Maybe i am just not feeding the right values to atombios so it can set the registers right, but since even fglrx revert to programming the registers directly i assume that atombios is simply not capable of doing this.
So radeonhd HDMI stuff really may only work for some cards?
Beside from that i don't have time to support another implementation of this stuff, so i am sorry but at least i can't take it over.
No problem, I appreciate the feedback. If I ever really get the urge to use my HDMI cable I guess I will finish this.
Problem is, if the way radeonhd is doing it is not the good way (through atombios), do we have documentation to do it the right way?
We plan to look at the info for a possible documentation or code release at some point, but we haven't had the time to compile and review it yet.
So if I do have time to finish the port, is that worth it? Or is that time not spent well at this point?
Depends how quickly you want support. I'm not sure when or what we'll be able to release yet. Alex -- To unsubscribe, e-mail: radeonhd+unsubscribe@opensuse.org For additional commands, e-mail: radeonhd+help@opensuse.org
2009/7/28 Alex Deucher <alexdeucher@gmail.com>:
2009/7/28 Luis R. Rodriguez <mcgrof@gmail.com>:
2009/7/28 Alex Deucher <alexdeucher@gmail.com>:
2009/7/28 Luis R. Rodriguez <mcgrof@gmail.com>:
2009/7/26 Christian König <deathsimple@vodafone.de>:
Hi,
Am Freitag, den 24.07.2009, 13:12 -0400 schrieb Luis R. Rodriguez:
RFT - Request For Help/patch takeover
I've taken a stab at porting HDMI support from the radeonhd driver onto the radeon driver. Mind you this is my first video patch, so not sure if it was done properly. I kept telling myself I was going to finish this during my night hours but my night hours are now reserved. So if it is at least done some-what right was hoping someone could take this on themselves and complete it... The missing piece should be the generic HDMI stuff which I thought was not required but in fact is.
as far as i have read the patch you are still missing some quite essential stuff. The generic hdmi stuff is not only for the encoder/transmitter setup, but also for audio clock recovery and feeding the television with the right audio parameters (sampling rate, bit per sampel etc.).
Yeah, that stuff is missing.
I always wondered when somebody starts to port this over to radeon. I considered doing it myself, but as far as i know the radeon driver it's relying complete on atombios to do the tmdsa and lvtma transmitter setup, and at least for hdmi support that's bad.
Interesting..
I fought quite allot with radeonhd to get atombios+hdmi support running at the same time, for RV630 i reverted to move setting a missing bit with the TMDSA and LVTMA control register to the hdmi enabling function, but i couldn't find a good solution for my RS780 (with DIG interface).
Maybe i am just not feeding the right values to atombios so it can set the registers right, but since even fglrx revert to programming the registers directly i assume that atombios is simply not capable of doing this.
So radeonhd HDMI stuff really may only work for some cards?
Beside from that i don't have time to support another implementation of this stuff, so i am sorry but at least i can't take it over.
No problem, I appreciate the feedback. If I ever really get the urge to use my HDMI cable I guess I will finish this.
Problem is, if the way radeonhd is doing it is not the good way (through atombios), do we have documentation to do it the right way?
We plan to look at the info for a possible documentation or code release at some point, but we haven't had the time to compile and review it yet.
So if I do have time to finish the port, is that worth it? Or is that time not spent well at this point?
Depends how quickly you want support. I'm not sure when or what we'll be able to release yet.
OK thanks. My motivation was audio was not working, but now it is somehow through my sound card on line 1, so I'm set for a while I guess. Luis -- To unsubscribe, e-mail: radeonhd+unsubscribe@opensuse.org For additional commands, e-mail: radeonhd+help@opensuse.org
Am Dienstag, den 28.07.2009, 14:26 -0400 schrieb Alex Deucher:
We plan to look at the info for a possible documentation or code release at some point, but we haven't had the time to compile and review it yet. Is there any possible way i could get a look at those documentation? I am also willing to sign an NDA, as long as i can publish the resulting code, if this is the only way on getting some more info about the hardware.
Thanks, Christian. -- To unsubscribe, e-mail: radeonhd+unsubscribe@opensuse.org For additional commands, e-mail: radeonhd+help@opensuse.org
Am Dienstag, den 28.07.2009, 11:10 -0700 schrieb Luis R. Rodriguez:
So radeonhd HDMI stuff really may only work for some cards? Yes, the R6xx, RS6xx and the Mobile versions seems to work quite well, but i am still having a bunch of problems getting the RV7xx series to work.
Beside from that i don't have time to support another implementation of this stuff, so i am sorry but at least i can't take it over.
No problem, I appreciate the feedback. If I ever really get the urge to use my HDMI cable I guess I will finish this. Your HD4800 has an RV770 chipset, and those one i haven't got working jet, so even if you want to finish this port, i won't expect it to work out of the box.
Problem is, if the way radeonhd is doing it is not the good way (through atombios), do we have documentation to do it the right way? The bits to set the transfer mode to hdmi are documented quite well in the source code, but AFAIK they don't work. Since this problem is not prio 1 on my todo list i stoped working on it some time ago.
FWIW, fglx is completely fucking useless for me. Same here, fglrx is crashing the system constantly, but it is the only working reference implementation for reverse engineering all that stuff.
Christian. -- To unsubscribe, e-mail: radeonhd+unsubscribe@opensuse.org For additional commands, e-mail: radeonhd+help@opensuse.org
participants (3)
-
Alex Deucher
-
Christian König
-
Luis R. Rodriguez