···3030 via debugfs.31313232menu "I2C encoder or helper chips"3333- depends on DRM3333+ depends on DRM && I2C34343535config DRM_I2C_CH70063636 tristate "Chrontel ch7006 TV encoder"3737- default m if DRM_NOUVEAU3737+ depends on DRM_NOUVEAU3838+ default m3839 help3940 Support for Chrontel ch7006 and similar TV encoders, found4041 on some nVidia video cards.
+2
drivers/gpu/drm/nouveau/nouveau_bo.c
···311311 struct drm_device *dev = dev_priv->dev;312312313313 switch (dev_priv->gart_info.type) {314314+#if __OS_HAS_AGP314315 case NOUVEAU_GART_AGP:315316 return ttm_agp_backend_init(bdev, dev->agp->bridge);317317+#endif316318 case NOUVEAU_GART_SGDMA:317319 return nouveau_sgdma_init_ttm(dev);318320 default:
···11+/*22+ * Copyright 2008 Advanced Micro Devices, Inc.33+ * Copyright 2008 Red Hat Inc.44+ * Copyright 2009 Christian König.55+ *66+ * Permission is hereby granted, free of charge, to any person obtaining a77+ * copy of this software and associated documentation files (the "Software"),88+ * to deal in the Software without restriction, including without limitation99+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,1010+ * and/or sell copies of the Software, and to permit persons to whom the1111+ * Software is furnished to do so, subject to the following conditions:1212+ *1313+ * The above copyright notice and this permission notice shall be included in1414+ * all copies or substantial portions of the Software.1515+ *1616+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR1717+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,1818+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL1919+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR2020+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,2121+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR2222+ * OTHER DEALINGS IN THE SOFTWARE.2323+ *2424+ * Authors: Christian König2525+ */2626+#include "drmP.h"2727+#include "radeon.h"2828+#include "radeon_reg.h"2929+#include "atom.h"3030+3131+#define AUDIO_TIMER_INTERVALL 100 /* 1/10 sekund should be enough */3232+3333+/*3434+ * check if the chipset is supported3535+ */3636+static int r600_audio_chipset_supported(struct radeon_device *rdev)3737+{3838+ return rdev->family >= CHIP_R6003939+ || rdev->family == CHIP_RS6004040+ || rdev->family == CHIP_RS6904141+ || rdev->family == CHIP_RS740;4242+}4343+4444+/*4545+ * current number of channels4646+ */4747+static int r600_audio_channels(struct radeon_device *rdev)4848+{4949+ return (RREG32(R600_AUDIO_RATE_BPS_CHANNEL) & 0x7) + 1;5050+}5151+5252+/*5353+ * current bits per sample5454+ */5555+static int r600_audio_bits_per_sample(struct radeon_device *rdev)5656+{5757+ uint32_t value = (RREG32(R600_AUDIO_RATE_BPS_CHANNEL) & 0xF0) >> 4;5858+ switch (value) {5959+ case 0x0: return 8;6060+ case 0x1: return 16;6161+ case 0x2: return 20;6262+ case 0x3: return 24;6363+ case 0x4: return 32;6464+ }6565+6666+ DRM_ERROR("Unknown bits per sample 0x%x using 16 instead.\n", (int)value);6767+6868+ return 16;6969+}7070+7171+/*7272+ * current sampling rate in HZ7373+ */7474+static int r600_audio_rate(struct radeon_device *rdev)7575+{7676+ uint32_t value = RREG32(R600_AUDIO_RATE_BPS_CHANNEL);7777+ uint32_t result;7878+7979+ if (value & 0x4000)8080+ result = 44100;8181+ else8282+ result = 48000;8383+8484+ result *= ((value >> 11) & 0x7) + 1;8585+ result /= ((value >> 8) & 0x7) + 1;8686+8787+ return result;8888+}8989+9090+/*9191+ * iec 60958 status bits9292+ */9393+static uint8_t r600_audio_status_bits(struct radeon_device *rdev)9494+{9595+ return RREG32(R600_AUDIO_STATUS_BITS) & 0xff;9696+}9797+9898+/*9999+ * iec 60958 category code100100+ */101101+static uint8_t r600_audio_category_code(struct radeon_device *rdev)102102+{103103+ return (RREG32(R600_AUDIO_STATUS_BITS) >> 8) & 0xff;104104+}105105+106106+/*107107+ * update all hdmi interfaces with current audio parameters108108+ */109109+static void r600_audio_update_hdmi(unsigned long param)110110+{111111+ struct radeon_device *rdev = (struct radeon_device *)param;112112+ struct drm_device *dev = rdev->ddev;113113+114114+ int channels = r600_audio_channels(rdev);115115+ int rate = r600_audio_rate(rdev);116116+ int bps = r600_audio_bits_per_sample(rdev);117117+ uint8_t status_bits = r600_audio_status_bits(rdev);118118+ uint8_t category_code = r600_audio_category_code(rdev);119119+120120+ struct drm_encoder *encoder;121121+ int changes = 0;122122+123123+ changes |= channels != rdev->audio_channels;124124+ changes |= rate != rdev->audio_rate;125125+ changes |= bps != rdev->audio_bits_per_sample;126126+ changes |= status_bits != rdev->audio_status_bits;127127+ changes |= category_code != rdev->audio_category_code;128128+129129+ if (changes) {130130+ rdev->audio_channels = channels;131131+ rdev->audio_rate = rate;132132+ rdev->audio_bits_per_sample = bps;133133+ rdev->audio_status_bits = status_bits;134134+ rdev->audio_category_code = category_code;135135+ }136136+137137+ list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {138138+ if (changes || r600_hdmi_buffer_status_changed(encoder))139139+ r600_hdmi_update_audio_settings(140140+ encoder, channels,141141+ rate, bps, status_bits,142142+ category_code);143143+ }144144+145145+ mod_timer(&rdev->audio_timer,146146+ jiffies + msecs_to_jiffies(AUDIO_TIMER_INTERVALL));147147+}148148+149149+/*150150+ * initialize the audio vars and register the update timer151151+ */152152+int r600_audio_init(struct radeon_device *rdev)153153+{154154+ if (!r600_audio_chipset_supported(rdev))155155+ return 0;156156+157157+ DRM_INFO("%s audio support", radeon_audio ? "Enabling" : "Disabling");158158+ WREG32_P(R600_AUDIO_ENABLE, radeon_audio ? 0x81000000 : 0x0, ~0x81000000);159159+160160+ rdev->audio_channels = -1;161161+ rdev->audio_rate = -1;162162+ rdev->audio_bits_per_sample = -1;163163+ rdev->audio_status_bits = 0;164164+ rdev->audio_category_code = 0;165165+166166+ setup_timer(167167+ &rdev->audio_timer,168168+ r600_audio_update_hdmi,169169+ (unsigned long)rdev);170170+171171+ mod_timer(&rdev->audio_timer, jiffies + 1);172172+173173+ return 0;174174+}175175+176176+/*177177+ * determin how the encoders and audio interface is wired together178178+ */179179+int r600_audio_tmds_index(struct drm_encoder *encoder)180180+{181181+ struct drm_device *dev = encoder->dev;182182+ struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);183183+ struct drm_encoder *other;184184+185185+ switch (radeon_encoder->encoder_id) {186186+ case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:187187+ case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:188188+ case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:189189+ return 0;190190+191191+ case ENCODER_OBJECT_ID_INTERNAL_LVTM1:192192+ /* special case check if an TMDS1 is present */193193+ list_for_each_entry(other, &dev->mode_config.encoder_list, head) {194194+ if (to_radeon_encoder(other)->encoder_id ==195195+ ENCODER_OBJECT_ID_INTERNAL_TMDS1)196196+ return 1;197197+ }198198+ return 0;199199+200200+ case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:201201+ case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:202202+ return 1;203203+204204+ default:205205+ DRM_ERROR("Unsupported encoder type 0x%02X\n",206206+ radeon_encoder->encoder_id);207207+ return -1;208208+ }209209+}210210+211211+/*212212+ * atach the audio codec to the clock source of the encoder213213+ */214214+void r600_audio_set_clock(struct drm_encoder *encoder, int clock)215215+{216216+ struct drm_device *dev = encoder->dev;217217+ struct radeon_device *rdev = dev->dev_private;218218+ struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);219219+ int base_rate = 48000;220220+221221+ switch (radeon_encoder->encoder_id) {222222+ case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:223223+ case ENCODER_OBJECT_ID_INTERNAL_LVTM1:224224+ WREG32_P(R600_AUDIO_TIMING, 0, ~0x301);225225+ break;226226+227227+ case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:228228+ case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:229229+ case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:230230+ case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:231231+ WREG32_P(R600_AUDIO_TIMING, 0x100, ~0x301);232232+ break;233233+234234+ default:235235+ DRM_ERROR("Unsupported encoder type 0x%02X\n",236236+ radeon_encoder->encoder_id);237237+ return;238238+ }239239+240240+ switch (r600_audio_tmds_index(encoder)) {241241+ case 0:242242+ WREG32(R600_AUDIO_PLL1_MUL, base_rate*50);243243+ WREG32(R600_AUDIO_PLL1_DIV, clock*100);244244+ WREG32(R600_AUDIO_CLK_SRCSEL, 0);245245+ break;246246+247247+ case 1:248248+ WREG32(R600_AUDIO_PLL2_MUL, base_rate*50);249249+ WREG32(R600_AUDIO_PLL2_DIV, clock*100);250250+ WREG32(R600_AUDIO_CLK_SRCSEL, 1);251251+ break;252252+ }253253+}254254+255255+/*256256+ * release the audio timer257257+ * TODO: How to do this correctly on SMP systems?258258+ */259259+void r600_audio_fini(struct radeon_device *rdev)260260+{261261+ if (!r600_audio_chipset_supported(rdev))262262+ return;263263+264264+ WREG32_P(R600_AUDIO_ENABLE, 0x0, ~0x81000000);265265+266266+ del_timer(&rdev->audio_timer);267267+}
+506
drivers/gpu/drm/radeon/r600_hdmi.c
···11+/*22+ * Copyright 2008 Advanced Micro Devices, Inc.33+ * Copyright 2008 Red Hat Inc.44+ * Copyright 2009 Christian König.55+ *66+ * Permission is hereby granted, free of charge, to any person obtaining a77+ * copy of this software and associated documentation files (the "Software"),88+ * to deal in the Software without restriction, including without limitation99+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,1010+ * and/or sell copies of the Software, and to permit persons to whom the1111+ * Software is furnished to do so, subject to the following conditions:1212+ *1313+ * The above copyright notice and this permission notice shall be included in1414+ * all copies or substantial portions of the Software.1515+ *1616+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR1717+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,1818+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL1919+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR2020+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,2121+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR2222+ * OTHER DEALINGS IN THE SOFTWARE.2323+ *2424+ * Authors: Christian König2525+ */2626+#include "drmP.h"2727+#include "radeon_drm.h"2828+#include "radeon.h"2929+#include "atom.h"3030+3131+/*3232+ * HDMI color format3333+ */3434+enum r600_hdmi_color_format {3535+ RGB = 0,3636+ YCC_422 = 1,3737+ YCC_444 = 23838+};3939+4040+/*4141+ * IEC60958 status bits4242+ */4343+enum r600_hdmi_iec_status_bits {4444+ AUDIO_STATUS_DIG_ENABLE = 0x01,4545+ AUDIO_STATUS_V = 0x02,4646+ AUDIO_STATUS_VCFG = 0x04,4747+ AUDIO_STATUS_EMPHASIS = 0x08,4848+ AUDIO_STATUS_COPYRIGHT = 0x10,4949+ AUDIO_STATUS_NONAUDIO = 0x20,5050+ AUDIO_STATUS_PROFESSIONAL = 0x40,5151+ AUDIO_STATUS_LEVEL = 0x805252+};5353+5454+struct {5555+ uint32_t Clock;5656+5757+ int N_32kHz;5858+ int CTS_32kHz;5959+6060+ int N_44_1kHz;6161+ int CTS_44_1kHz;6262+6363+ int N_48kHz;6464+ int CTS_48kHz;6565+6666+} r600_hdmi_ACR[] = {6767+ /* 32kHz 44.1kHz 48kHz */6868+ /* Clock N CTS N CTS N CTS */6969+ { 25174, 4576, 28125, 7007, 31250, 6864, 28125 }, /* 25,20/1.001 MHz */7070+ { 25200, 4096, 25200, 6272, 28000, 6144, 25200 }, /* 25.20 MHz */7171+ { 27000, 4096, 27000, 6272, 30000, 6144, 27000 }, /* 27.00 MHz */7272+ { 27027, 4096, 27027, 6272, 30030, 6144, 27027 }, /* 27.00*1.001 MHz */7373+ { 54000, 4096, 54000, 6272, 60000, 6144, 54000 }, /* 54.00 MHz */7474+ { 54054, 4096, 54054, 6272, 60060, 6144, 54054 }, /* 54.00*1.001 MHz */7575+ { 74175, 11648, 210937, 17836, 234375, 11648, 140625 }, /* 74.25/1.001 MHz */7676+ { 74250, 4096, 74250, 6272, 82500, 6144, 74250 }, /* 74.25 MHz */7777+ { 148351, 11648, 421875, 8918, 234375, 5824, 140625 }, /* 148.50/1.001 MHz */7878+ { 148500, 4096, 148500, 6272, 165000, 6144, 148500 }, /* 148.50 MHz */7979+ { 0, 4096, 0, 6272, 0, 6144, 0 } /* Other */8080+};8181+8282+/*8383+ * calculate CTS value if it's not found in the table8484+ */8585+static void r600_hdmi_calc_CTS(uint32_t clock, int *CTS, int N, int freq)8686+{8787+ if (*CTS == 0)8888+ *CTS = clock*N/(128*freq)*1000;8989+ DRM_DEBUG("Using ACR timing N=%d CTS=%d for frequency %d\n",9090+ N, *CTS, freq);9191+}9292+9393+/*9494+ * update the N and CTS parameters for a given pixel clock rate9595+ */9696+static void r600_hdmi_update_ACR(struct drm_encoder *encoder, uint32_t clock)9797+{9898+ struct drm_device *dev = encoder->dev;9999+ struct radeon_device *rdev = dev->dev_private;100100+ uint32_t offset = to_radeon_encoder(encoder)->hdmi_offset;101101+ int CTS;102102+ int N;103103+ int i;104104+105105+ for (i = 0; r600_hdmi_ACR[i].Clock != clock && r600_hdmi_ACR[i].Clock != 0; i++);106106+107107+ CTS = r600_hdmi_ACR[i].CTS_32kHz;108108+ N = r600_hdmi_ACR[i].N_32kHz;109109+ r600_hdmi_calc_CTS(clock, &CTS, N, 32000);110110+ WREG32(offset+R600_HDMI_32kHz_CTS, CTS << 12);111111+ WREG32(offset+R600_HDMI_32kHz_N, N);112112+113113+ CTS = r600_hdmi_ACR[i].CTS_44_1kHz;114114+ N = r600_hdmi_ACR[i].N_44_1kHz;115115+ r600_hdmi_calc_CTS(clock, &CTS, N, 44100);116116+ WREG32(offset+R600_HDMI_44_1kHz_CTS, CTS << 12);117117+ WREG32(offset+R600_HDMI_44_1kHz_N, N);118118+119119+ CTS = r600_hdmi_ACR[i].CTS_48kHz;120120+ N = r600_hdmi_ACR[i].N_48kHz;121121+ r600_hdmi_calc_CTS(clock, &CTS, N, 48000);122122+ WREG32(offset+R600_HDMI_48kHz_CTS, CTS << 12);123123+ WREG32(offset+R600_HDMI_48kHz_N, N);124124+}125125+126126+/*127127+ * calculate the crc for a given info frame128128+ */129129+static void r600_hdmi_infoframe_checksum(uint8_t packetType,130130+ uint8_t versionNumber,131131+ uint8_t length,132132+ uint8_t *frame)133133+{134134+ int i;135135+ frame[0] = packetType + versionNumber + length;136136+ for (i = 1; i <= length; i++)137137+ frame[0] += frame[i];138138+ frame[0] = 0x100 - frame[0];139139+}140140+141141+/*142142+ * build a HDMI Video Info Frame143143+ */144144+static void r600_hdmi_videoinfoframe(145145+ struct drm_encoder *encoder,146146+ enum r600_hdmi_color_format color_format,147147+ int active_information_present,148148+ uint8_t active_format_aspect_ratio,149149+ uint8_t scan_information,150150+ uint8_t colorimetry,151151+ uint8_t ex_colorimetry,152152+ uint8_t quantization,153153+ int ITC,154154+ uint8_t picture_aspect_ratio,155155+ uint8_t video_format_identification,156156+ uint8_t pixel_repetition,157157+ uint8_t non_uniform_picture_scaling,158158+ uint8_t bar_info_data_valid,159159+ uint16_t top_bar,160160+ uint16_t bottom_bar,161161+ uint16_t left_bar,162162+ uint16_t right_bar163163+)164164+{165165+ struct drm_device *dev = encoder->dev;166166+ struct radeon_device *rdev = dev->dev_private;167167+ uint32_t offset = to_radeon_encoder(encoder)->hdmi_offset;168168+169169+ uint8_t frame[14];170170+171171+ frame[0x0] = 0;172172+ frame[0x1] =173173+ (scan_information & 0x3) |174174+ ((bar_info_data_valid & 0x3) << 2) |175175+ ((active_information_present & 0x1) << 4) |176176+ ((color_format & 0x3) << 5);177177+ frame[0x2] =178178+ (active_format_aspect_ratio & 0xF) |179179+ ((picture_aspect_ratio & 0x3) << 4) |180180+ ((colorimetry & 0x3) << 6);181181+ frame[0x3] =182182+ (non_uniform_picture_scaling & 0x3) |183183+ ((quantization & 0x3) << 2) |184184+ ((ex_colorimetry & 0x7) << 4) |185185+ ((ITC & 0x1) << 7);186186+ frame[0x4] = (video_format_identification & 0x7F);187187+ frame[0x5] = (pixel_repetition & 0xF);188188+ frame[0x6] = (top_bar & 0xFF);189189+ frame[0x7] = (top_bar >> 8);190190+ frame[0x8] = (bottom_bar & 0xFF);191191+ frame[0x9] = (bottom_bar >> 8);192192+ frame[0xA] = (left_bar & 0xFF);193193+ frame[0xB] = (left_bar >> 8);194194+ frame[0xC] = (right_bar & 0xFF);195195+ frame[0xD] = (right_bar >> 8);196196+197197+ r600_hdmi_infoframe_checksum(0x82, 0x02, 0x0D, frame);198198+199199+ WREG32(offset+R600_HDMI_VIDEOINFOFRAME_0,200200+ frame[0x0] | (frame[0x1] << 8) | (frame[0x2] << 16) | (frame[0x3] << 24));201201+ WREG32(offset+R600_HDMI_VIDEOINFOFRAME_1,202202+ frame[0x4] | (frame[0x5] << 8) | (frame[0x6] << 16) | (frame[0x7] << 24));203203+ WREG32(offset+R600_HDMI_VIDEOINFOFRAME_2,204204+ frame[0x8] | (frame[0x9] << 8) | (frame[0xA] << 16) | (frame[0xB] << 24));205205+ WREG32(offset+R600_HDMI_VIDEOINFOFRAME_3,206206+ frame[0xC] | (frame[0xD] << 8));207207+}208208+209209+/*210210+ * build a Audio Info Frame211211+ */212212+static void r600_hdmi_audioinfoframe(213213+ struct drm_encoder *encoder,214214+ uint8_t channel_count,215215+ uint8_t coding_type,216216+ uint8_t sample_size,217217+ uint8_t sample_frequency,218218+ uint8_t format,219219+ uint8_t channel_allocation,220220+ uint8_t level_shift,221221+ int downmix_inhibit222222+)223223+{224224+ struct drm_device *dev = encoder->dev;225225+ struct radeon_device *rdev = dev->dev_private;226226+ uint32_t offset = to_radeon_encoder(encoder)->hdmi_offset;227227+228228+ uint8_t frame[11];229229+230230+ frame[0x0] = 0;231231+ frame[0x1] = (channel_count & 0x7) | ((coding_type & 0xF) << 4);232232+ frame[0x2] = (sample_size & 0x3) | ((sample_frequency & 0x7) << 2);233233+ frame[0x3] = format;234234+ frame[0x4] = channel_allocation;235235+ frame[0x5] = ((level_shift & 0xF) << 3) | ((downmix_inhibit & 0x1) << 7);236236+ frame[0x6] = 0;237237+ frame[0x7] = 0;238238+ frame[0x8] = 0;239239+ frame[0x9] = 0;240240+ frame[0xA] = 0;241241+242242+ r600_hdmi_infoframe_checksum(0x84, 0x01, 0x0A, frame);243243+244244+ WREG32(offset+R600_HDMI_AUDIOINFOFRAME_0,245245+ frame[0x0] | (frame[0x1] << 8) | (frame[0x2] << 16) | (frame[0x3] << 24));246246+ WREG32(offset+R600_HDMI_AUDIOINFOFRAME_1,247247+ frame[0x4] | (frame[0x5] << 8) | (frame[0x6] << 16) | (frame[0x8] << 24));248248+}249249+250250+/*251251+ * test if audio buffer is filled enough to start playing252252+ */253253+static int r600_hdmi_is_audio_buffer_filled(struct drm_encoder *encoder)254254+{255255+ struct drm_device *dev = encoder->dev;256256+ struct radeon_device *rdev = dev->dev_private;257257+ uint32_t offset = to_radeon_encoder(encoder)->hdmi_offset;258258+259259+ return (RREG32(offset+R600_HDMI_STATUS) & 0x10) != 0;260260+}261261+262262+/*263263+ * have buffer status changed since last call?264264+ */265265+int r600_hdmi_buffer_status_changed(struct drm_encoder *encoder)266266+{267267+ struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);268268+ int status, result;269269+270270+ if (!radeon_encoder->hdmi_offset)271271+ return 0;272272+273273+ status = r600_hdmi_is_audio_buffer_filled(encoder);274274+ result = radeon_encoder->hdmi_buffer_status != status;275275+ radeon_encoder->hdmi_buffer_status = status;276276+277277+ return result;278278+}279279+280280+/*281281+ * write the audio workaround status to the hardware282282+ */283283+void r600_hdmi_audio_workaround(struct drm_encoder *encoder)284284+{285285+ struct drm_device *dev = encoder->dev;286286+ struct radeon_device *rdev = dev->dev_private;287287+ struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);288288+ uint32_t offset = radeon_encoder->hdmi_offset;289289+290290+ if (!offset)291291+ return;292292+293293+ if (r600_hdmi_is_audio_buffer_filled(encoder)) {294294+ /* disable audio workaround and start delivering of audio frames */295295+ WREG32_P(offset+R600_HDMI_CNTL, 0x00000001, ~0x00001001);296296+297297+ } else if (radeon_encoder->hdmi_audio_workaround) {298298+ /* enable audio workaround and start delivering of audio frames */299299+ WREG32_P(offset+R600_HDMI_CNTL, 0x00001001, ~0x00001001);300300+301301+ } else {302302+ /* disable audio workaround and stop delivering of audio frames */303303+ WREG32_P(offset+R600_HDMI_CNTL, 0x00000000, ~0x00001001);304304+ }305305+}306306+307307+308308+/*309309+ * update the info frames with the data from the current display mode310310+ */311311+void r600_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mode *mode)312312+{313313+ struct drm_device *dev = encoder->dev;314314+ struct radeon_device *rdev = dev->dev_private;315315+ uint32_t offset = to_radeon_encoder(encoder)->hdmi_offset;316316+317317+ if (!offset)318318+ return;319319+320320+ r600_audio_set_clock(encoder, mode->clock);321321+322322+ WREG32(offset+R600_HDMI_UNKNOWN_0, 0x1000);323323+ WREG32(offset+R600_HDMI_UNKNOWN_1, 0x0);324324+ WREG32(offset+R600_HDMI_UNKNOWN_2, 0x1000);325325+326326+ r600_hdmi_update_ACR(encoder, mode->clock);327327+328328+ WREG32(offset+R600_HDMI_VIDEOCNTL, 0x13);329329+330330+ WREG32(offset+R600_HDMI_VERSION, 0x202);331331+332332+ r600_hdmi_videoinfoframe(encoder, RGB, 0, 0, 0, 0,333333+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);334334+335335+ /* it's unknown what these bits do excatly, but it's indeed quite usefull for debugging */336336+ WREG32(offset+R600_HDMI_AUDIO_DEBUG_0, 0x00FFFFFF);337337+ WREG32(offset+R600_HDMI_AUDIO_DEBUG_1, 0x007FFFFF);338338+ WREG32(offset+R600_HDMI_AUDIO_DEBUG_2, 0x00000001);339339+ WREG32(offset+R600_HDMI_AUDIO_DEBUG_3, 0x00000001);340340+341341+ r600_hdmi_audio_workaround(encoder);342342+343343+ /* audio packets per line, does anyone know how to calc this ? */344344+ WREG32_P(offset+R600_HDMI_CNTL, 0x00040000, ~0x001F0000);345345+346346+ /* update? reset? don't realy know */347347+ WREG32_P(offset+R600_HDMI_CNTL, 0x14000000, ~0x14000000);348348+}349349+350350+/*351351+ * update settings with current parameters from audio engine352352+ */353353+void r600_hdmi_update_audio_settings(struct drm_encoder *encoder,354354+ int channels,355355+ int rate,356356+ int bps,357357+ uint8_t status_bits,358358+ uint8_t category_code)359359+{360360+ struct drm_device *dev = encoder->dev;361361+ struct radeon_device *rdev = dev->dev_private;362362+ uint32_t offset = to_radeon_encoder(encoder)->hdmi_offset;363363+364364+ uint32_t iec;365365+366366+ if (!offset)367367+ return;368368+369369+ DRM_DEBUG("%s with %d channels, %d Hz sampling rate, %d bits per sample,\n",370370+ r600_hdmi_is_audio_buffer_filled(encoder) ? "playing" : "stopped",371371+ channels, rate, bps);372372+ DRM_DEBUG("0x%02X IEC60958 status bits and 0x%02X category code\n",373373+ (int)status_bits, (int)category_code);374374+375375+ iec = 0;376376+ if (status_bits & AUDIO_STATUS_PROFESSIONAL)377377+ iec |= 1 << 0;378378+ if (status_bits & AUDIO_STATUS_NONAUDIO)379379+ iec |= 1 << 1;380380+ if (status_bits & AUDIO_STATUS_COPYRIGHT)381381+ iec |= 1 << 2;382382+ if (status_bits & AUDIO_STATUS_EMPHASIS)383383+ iec |= 1 << 3;384384+385385+ iec |= category_code << 8;386386+387387+ switch (rate) {388388+ case 32000: iec |= 0x3 << 24; break;389389+ case 44100: iec |= 0x0 << 24; break;390390+ case 88200: iec |= 0x8 << 24; break;391391+ case 176400: iec |= 0xc << 24; break;392392+ case 48000: iec |= 0x2 << 24; break;393393+ case 96000: iec |= 0xa << 24; break;394394+ case 192000: iec |= 0xe << 24; break;395395+ }396396+397397+ WREG32(offset+R600_HDMI_IEC60958_1, iec);398398+399399+ iec = 0;400400+ switch (bps) {401401+ case 16: iec |= 0x2; break;402402+ case 20: iec |= 0x3; break;403403+ case 24: iec |= 0xb; break;404404+ }405405+ if (status_bits & AUDIO_STATUS_V)406406+ iec |= 0x5 << 16;407407+408408+ WREG32_P(offset+R600_HDMI_IEC60958_2, iec, ~0x5000f);409409+410410+ /* 0x021 or 0x031 sets the audio frame length */411411+ WREG32(offset+R600_HDMI_AUDIOCNTL, 0x31);412412+ r600_hdmi_audioinfoframe(encoder, channels-1, 0, 0, 0, 0, 0, 0, 0);413413+414414+ r600_hdmi_audio_workaround(encoder);415415+416416+ /* update? reset? don't realy know */417417+ WREG32_P(offset+R600_HDMI_CNTL, 0x04000000, ~0x04000000);418418+}419419+420420+/*421421+ * enable/disable the HDMI engine422422+ */423423+void r600_hdmi_enable(struct drm_encoder *encoder, int enable)424424+{425425+ struct drm_device *dev = encoder->dev;426426+ struct radeon_device *rdev = dev->dev_private;427427+ struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);428428+ uint32_t offset = to_radeon_encoder(encoder)->hdmi_offset;429429+430430+ if (!offset)431431+ return;432432+433433+ DRM_DEBUG("%s HDMI interface @ 0x%04X\n", enable ? "Enabling" : "Disabling", offset);434434+435435+ /* some version of atombios ignore the enable HDMI flag436436+ * so enabling/disabling HDMI was moved here for TMDS1+2 */437437+ switch (radeon_encoder->encoder_id) {438438+ case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:439439+ WREG32_P(AVIVO_TMDSA_CNTL, enable ? 0x4 : 0x0, ~0x4);440440+ WREG32(offset+R600_HDMI_ENABLE, enable ? 0x101 : 0x0);441441+ break;442442+443443+ case ENCODER_OBJECT_ID_INTERNAL_LVTM1:444444+ WREG32_P(AVIVO_LVTMA_CNTL, enable ? 0x4 : 0x0, ~0x4);445445+ WREG32(offset+R600_HDMI_ENABLE, enable ? 0x105 : 0x0);446446+ break;447447+448448+ case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:449449+ case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:450450+ case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:451451+ case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:452452+ /* This part is doubtfull in my opinion */453453+ WREG32(offset+R600_HDMI_ENABLE, enable ? 0x110 : 0x0);454454+ break;455455+456456+ default:457457+ DRM_ERROR("unknown HDMI output type\n");458458+ break;459459+ }460460+}461461+462462+/*463463+ * determin at which register offset the HDMI encoder is464464+ */465465+void r600_hdmi_init(struct drm_encoder *encoder)466466+{467467+ struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);468468+469469+ switch (radeon_encoder->encoder_id) {470470+ case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1:471471+ case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:472472+ case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1:473473+ radeon_encoder->hdmi_offset = R600_HDMI_TMDS1;474474+ break;475475+476476+ case ENCODER_OBJECT_ID_INTERNAL_LVTM1:477477+ switch (r600_audio_tmds_index(encoder)) {478478+ case 0:479479+ radeon_encoder->hdmi_offset = R600_HDMI_TMDS1;480480+ break;481481+ case 1:482482+ radeon_encoder->hdmi_offset = R600_HDMI_TMDS2;483483+ break;484484+ default:485485+ radeon_encoder->hdmi_offset = 0;486486+ break;487487+ }488488+ case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2:489489+ radeon_encoder->hdmi_offset = R600_HDMI_TMDS2;490490+ break;491491+492492+ case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA:493493+ radeon_encoder->hdmi_offset = R600_HDMI_DIG;494494+ break;495495+496496+ default:497497+ radeon_encoder->hdmi_offset = 0;498498+ break;499499+ }500500+501501+ DRM_DEBUG("using HDMI engine at offset 0x%04X for encoder 0x%x\n",502502+ radeon_encoder->hdmi_offset, radeon_encoder->encoder_id);503503+504504+ /* TODO: make this configureable */505505+ radeon_encoder->hdmi_audio_workaround = 0;506506+}
···5959 *6060 * Returns:6161 * -EBUSY: buffer is busy and @no_wait is true6262- * -ERESTART: A wait for the buffer to become unreserved was interrupted by6262+ * -ERESTARTSYS: A wait for the buffer to become unreserved was interrupted by6363 * a signal. Release all buffer reservations and return to user-space.6464 */6565static inline int radeon_bo_reserve(struct radeon_bo *bo, bool no_wait)6666{6767 int r;68686969-retry:7069 r = ttm_bo_reserve(&bo->tbo, true, no_wait, false, 0);7170 if (unlikely(r != 0)) {7272- if (r == -ERESTART)7373- goto retry;7474- dev_err(bo->rdev->dev, "%p reserve failed\n", bo);7171+ if (r != -ERESTARTSYS)7272+ dev_err(bo->rdev->dev, "%p reserve failed\n", bo);7573 return r;7674 }7775 return 0;···123125{124126 int r;125127126126-retry:127128 r = ttm_bo_reserve(&bo->tbo, true, no_wait, false, 0);128129 if (unlikely(r != 0)) {129129- if (r == -ERESTART)130130- goto retry;131131- dev_err(bo->rdev->dev, "%p reserve failed for wait\n", bo);130130+ if (r != -ERESTARTSYS)131131+ dev_err(bo->rdev->dev, "%p reserve failed for wait\n", bo);132132 return r;133133 }134134 spin_lock(&bo->tbo.lock);···136140 r = ttm_bo_wait(&bo->tbo, true, true, no_wait);137141 spin_unlock(&bo->tbo.lock);138142 ttm_bo_unreserve(&bo->tbo);139139- if (unlikely(r == -ERESTART))140140- goto retry;141143 return r;142144}143145