Path: blob/master/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c
29285 views
/*1* Copyright 2007-8 Advanced Micro Devices, Inc.2* Copyright 2008 Red Hat Inc.3*4* Permission is hereby granted, free of charge, to any person obtaining a5* copy of this software and associated documentation files (the "Software"),6* to deal in the Software without restriction, including without limitation7* the rights to use, copy, modify, merge, publish, distribute, sublicense,8* and/or sell copies of the Software, and to permit persons to whom the9* Software is furnished to do so, subject to the following conditions:10*11* The above copyright notice and this permission notice shall be included in12* all copies or substantial portions of the Software.13*14* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR15* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,16* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL17* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR18* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,19* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR20* OTHER DEALINGS IN THE SOFTWARE.21*22* Authors: Dave Airlie23* Alex Deucher24*/2526#include <drm/display/drm_dp_helper.h>27#include <drm/drm_crtc_helper.h>28#include <drm/drm_edid.h>29#include <drm/drm_modeset_helper_vtables.h>30#include <drm/drm_probe_helper.h>31#include <drm/amdgpu_drm.h>32#include "amdgpu.h"33#include "atom.h"34#include "atombios_encoders.h"35#include "atombios_dp.h"36#include "amdgpu_connectors.h"37#include "amdgpu_i2c.h"38#include "amdgpu_display.h"3940#include <linux/pm_runtime.h>4142void amdgpu_connector_hotplug(struct drm_connector *connector)43{44struct drm_device *dev = connector->dev;45struct amdgpu_device *adev = drm_to_adev(dev);46struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector);4748/* bail if the connector does not have hpd pin, e.g.,49* VGA, TV, etc.50*/51if (amdgpu_connector->hpd.hpd == AMDGPU_HPD_NONE)52return;5354amdgpu_display_hpd_set_polarity(adev, amdgpu_connector->hpd.hpd);5556/* if the connector is already off, don't turn it back on */57if (connector->dpms != DRM_MODE_DPMS_ON)58return;5960/* just deal with DP (not eDP) here. */61if (connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort) {62struct amdgpu_connector_atom_dig *dig_connector =63amdgpu_connector->con_priv;6465/* if existing sink type was not DP no need to retrain */66if (dig_connector->dp_sink_type != CONNECTOR_OBJECT_ID_DISPLAYPORT)67return;6869/* first get sink type as it may be reset after (un)plug */70dig_connector->dp_sink_type = amdgpu_atombios_dp_get_sinktype(amdgpu_connector);71/* don't do anything if sink is not display port, i.e.,72* passive dp->(dvi|hdmi) adaptor73*/74if (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT &&75amdgpu_display_hpd_sense(adev, amdgpu_connector->hpd.hpd) &&76amdgpu_atombios_dp_needs_link_train(amdgpu_connector)) {77/* Don't start link training before we have the DPCD */78if (amdgpu_atombios_dp_get_dpcd(amdgpu_connector))79return;8081/* Turn the connector off and back on immediately, which82* will trigger link training83*/84drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF);85drm_helper_connector_dpms(connector, DRM_MODE_DPMS_ON);86}87}88}8990static void amdgpu_connector_property_change_mode(struct drm_encoder *encoder)91{92struct drm_crtc *crtc = encoder->crtc;9394if (crtc && crtc->enabled) {95drm_crtc_helper_set_mode(crtc, &crtc->mode,96crtc->x, crtc->y, crtc->primary->fb);97}98}99100int amdgpu_connector_get_monitor_bpc(struct drm_connector *connector)101{102struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector);103struct amdgpu_connector_atom_dig *dig_connector;104int bpc = 8;105unsigned int mode_clock, max_tmds_clock;106107switch (connector->connector_type) {108case DRM_MODE_CONNECTOR_DVII:109case DRM_MODE_CONNECTOR_HDMIB:110if (amdgpu_connector->use_digital) {111if (connector->display_info.is_hdmi) {112if (connector->display_info.bpc)113bpc = connector->display_info.bpc;114}115}116break;117case DRM_MODE_CONNECTOR_DVID:118case DRM_MODE_CONNECTOR_HDMIA:119if (connector->display_info.is_hdmi) {120if (connector->display_info.bpc)121bpc = connector->display_info.bpc;122}123break;124case DRM_MODE_CONNECTOR_DisplayPort:125dig_connector = amdgpu_connector->con_priv;126if ((dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) ||127(dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP) ||128connector->display_info.is_hdmi) {129if (connector->display_info.bpc)130bpc = connector->display_info.bpc;131}132break;133case DRM_MODE_CONNECTOR_eDP:134case DRM_MODE_CONNECTOR_LVDS:135if (connector->display_info.bpc)136bpc = connector->display_info.bpc;137else {138const struct drm_connector_helper_funcs *connector_funcs =139connector->helper_private;140struct drm_encoder *encoder = connector_funcs->best_encoder(connector);141struct amdgpu_encoder *amdgpu_encoder = to_amdgpu_encoder(encoder);142struct amdgpu_encoder_atom_dig *dig = amdgpu_encoder->enc_priv;143144if (dig->lcd_misc & ATOM_PANEL_MISC_V13_6BIT_PER_COLOR)145bpc = 6;146else if (dig->lcd_misc & ATOM_PANEL_MISC_V13_8BIT_PER_COLOR)147bpc = 8;148}149break;150}151152if (connector->display_info.is_hdmi) {153/*154* Pre DCE-8 hw can't handle > 12 bpc, and more than 12 bpc doesn't make155* much sense without support for > 12 bpc framebuffers. RGB 4:4:4 at156* 12 bpc is always supported on hdmi deep color sinks, as this is157* required by the HDMI-1.3 spec. Clamp to a safe 12 bpc maximum.158*/159if (bpc > 12) {160DRM_DEBUG("%s: HDMI deep color %d bpc unsupported. Using 12 bpc.\n",161connector->name, bpc);162bpc = 12;163}164165/* Any defined maximum tmds clock limit we must not exceed? */166if (connector->display_info.max_tmds_clock > 0) {167/* mode_clock is clock in kHz for mode to be modeset on this connector */168mode_clock = amdgpu_connector->pixelclock_for_modeset;169170/* Maximum allowable input clock in kHz */171max_tmds_clock = connector->display_info.max_tmds_clock;172173DRM_DEBUG("%s: hdmi mode dotclock %d kHz, max tmds input clock %d kHz.\n",174connector->name, mode_clock, max_tmds_clock);175176/* Check if bpc is within clock limit. Try to degrade gracefully otherwise */177if ((bpc == 12) && (mode_clock * 3/2 > max_tmds_clock)) {178if ((connector->display_info.edid_hdmi_rgb444_dc_modes & DRM_EDID_HDMI_DC_30) &&179(mode_clock * 5/4 <= max_tmds_clock))180bpc = 10;181else182bpc = 8;183184DRM_DEBUG("%s: HDMI deep color 12 bpc exceeds max tmds clock. Using %d bpc.\n",185connector->name, bpc);186}187188if ((bpc == 10) && (mode_clock * 5/4 > max_tmds_clock)) {189bpc = 8;190DRM_DEBUG("%s: HDMI deep color 10 bpc exceeds max tmds clock. Using %d bpc.\n",191connector->name, bpc);192}193} else if (bpc > 8) {194/* max_tmds_clock missing, but hdmi spec mandates it for deep color. */195DRM_DEBUG("%s: Required max tmds clock for HDMI deep color missing. Using 8 bpc.\n",196connector->name);197bpc = 8;198}199}200201if ((amdgpu_deep_color == 0) && (bpc > 8)) {202DRM_DEBUG("%s: Deep color disabled. Set amdgpu module param deep_color=1 to enable.\n",203connector->name);204bpc = 8;205}206207DRM_DEBUG("%s: Display bpc=%d, returned bpc=%d\n",208connector->name, connector->display_info.bpc, bpc);209210return bpc;211}212213static void214amdgpu_connector_update_scratch_regs(struct drm_connector *connector,215enum drm_connector_status status)216{217struct drm_encoder *best_encoder;218struct drm_encoder *encoder;219const struct drm_connector_helper_funcs *connector_funcs = connector->helper_private;220bool connected;221222best_encoder = connector_funcs->best_encoder(connector);223224drm_connector_for_each_possible_encoder(connector, encoder) {225if ((encoder == best_encoder) && (status == connector_status_connected))226connected = true;227else228connected = false;229230amdgpu_atombios_encoder_set_bios_scratch_regs(connector, encoder, connected);231}232}233234static struct drm_encoder *235amdgpu_connector_find_encoder(struct drm_connector *connector,236int encoder_type)237{238struct drm_encoder *encoder;239240drm_connector_for_each_possible_encoder(connector, encoder) {241if (encoder->encoder_type == encoder_type)242return encoder;243}244245return NULL;246}247248static struct edid *249amdgpu_connector_get_hardcoded_edid(struct amdgpu_device *adev)250{251return drm_edid_duplicate(drm_edid_raw(adev->mode_info.bios_hardcoded_edid));252}253254static void amdgpu_connector_get_edid(struct drm_connector *connector)255{256struct drm_device *dev = connector->dev;257struct amdgpu_device *adev = drm_to_adev(dev);258struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector);259260if (amdgpu_connector->edid)261return;262263/* on hw with routers, select right port */264if (amdgpu_connector->router.ddc_valid)265amdgpu_i2c_router_select_ddc_port(amdgpu_connector);266267if ((amdgpu_connector_encoder_get_dp_bridge_encoder_id(connector) !=268ENCODER_OBJECT_ID_NONE) &&269amdgpu_connector->ddc_bus->has_aux) {270amdgpu_connector->edid = drm_get_edid(connector,271&amdgpu_connector->ddc_bus->aux.ddc);272} else if ((connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort) ||273(connector->connector_type == DRM_MODE_CONNECTOR_eDP)) {274struct amdgpu_connector_atom_dig *dig = amdgpu_connector->con_priv;275276if ((dig->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT ||277dig->dp_sink_type == CONNECTOR_OBJECT_ID_eDP) &&278amdgpu_connector->ddc_bus->has_aux)279amdgpu_connector->edid = drm_get_edid(connector,280&amdgpu_connector->ddc_bus->aux.ddc);281else if (amdgpu_connector->ddc_bus)282amdgpu_connector->edid = drm_get_edid(connector,283&amdgpu_connector->ddc_bus->adapter);284} else if (amdgpu_connector->ddc_bus) {285amdgpu_connector->edid = drm_get_edid(connector,286&amdgpu_connector->ddc_bus->adapter);287}288289if (!amdgpu_connector->edid) {290/* some laptops provide a hardcoded edid in rom for LCDs */291if (((connector->connector_type == DRM_MODE_CONNECTOR_LVDS) ||292(connector->connector_type == DRM_MODE_CONNECTOR_eDP))) {293amdgpu_connector->edid = amdgpu_connector_get_hardcoded_edid(adev);294drm_connector_update_edid_property(connector, amdgpu_connector->edid);295}296}297}298299static void amdgpu_connector_free_edid(struct drm_connector *connector)300{301struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector);302303kfree(amdgpu_connector->edid);304amdgpu_connector->edid = NULL;305}306307static int amdgpu_connector_ddc_get_modes(struct drm_connector *connector)308{309struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector);310int ret;311312if (amdgpu_connector->edid) {313drm_connector_update_edid_property(connector, amdgpu_connector->edid);314ret = drm_add_edid_modes(connector, amdgpu_connector->edid);315return ret;316}317drm_connector_update_edid_property(connector, NULL);318return 0;319}320321static struct drm_encoder *322amdgpu_connector_best_single_encoder(struct drm_connector *connector)323{324struct drm_encoder *encoder;325326/* pick the first one */327drm_connector_for_each_possible_encoder(connector, encoder)328return encoder;329330return NULL;331}332333static void amdgpu_get_native_mode(struct drm_connector *connector)334{335struct drm_encoder *encoder = amdgpu_connector_best_single_encoder(connector);336struct amdgpu_encoder *amdgpu_encoder;337338if (encoder == NULL)339return;340341amdgpu_encoder = to_amdgpu_encoder(encoder);342343if (!list_empty(&connector->probed_modes)) {344struct drm_display_mode *preferred_mode =345list_first_entry(&connector->probed_modes,346struct drm_display_mode, head);347348amdgpu_encoder->native_mode = *preferred_mode;349} else {350amdgpu_encoder->native_mode.clock = 0;351}352}353354static struct drm_display_mode *355amdgpu_connector_lcd_native_mode(struct drm_encoder *encoder)356{357struct drm_device *dev = encoder->dev;358struct amdgpu_encoder *amdgpu_encoder = to_amdgpu_encoder(encoder);359struct drm_display_mode *mode = NULL;360struct drm_display_mode *native_mode = &amdgpu_encoder->native_mode;361362if (native_mode->hdisplay != 0 &&363native_mode->vdisplay != 0 &&364native_mode->clock != 0) {365mode = drm_mode_duplicate(dev, native_mode);366if (!mode)367return NULL;368369mode->type = DRM_MODE_TYPE_PREFERRED | DRM_MODE_TYPE_DRIVER;370drm_mode_set_name(mode);371372DRM_DEBUG_KMS("Adding native panel mode %s\n", mode->name);373} else if (native_mode->hdisplay != 0 &&374native_mode->vdisplay != 0) {375/* mac laptops without an edid */376/* Note that this is not necessarily the exact panel mode,377* but an approximation based on the cvt formula. For these378* systems we should ideally read the mode info out of the379* registers or add a mode table, but this works and is much380* simpler.381*/382mode = drm_cvt_mode(dev, native_mode->hdisplay, native_mode->vdisplay, 60, true, false, false);383if (!mode)384return NULL;385386mode->type = DRM_MODE_TYPE_PREFERRED | DRM_MODE_TYPE_DRIVER;387DRM_DEBUG_KMS("Adding cvt approximation of native panel mode %s\n", mode->name);388}389return mode;390}391392static void amdgpu_connector_add_common_modes(struct drm_encoder *encoder,393struct drm_connector *connector)394{395struct drm_device *dev = encoder->dev;396struct amdgpu_encoder *amdgpu_encoder = to_amdgpu_encoder(encoder);397struct drm_display_mode *mode = NULL;398struct drm_display_mode *native_mode = &amdgpu_encoder->native_mode;399int i;400int n;401struct mode_size {402char name[DRM_DISPLAY_MODE_LEN];403int w;404int h;405} common_modes[] = {406{ "640x480", 640, 480},407{ "800x600", 800, 600},408{ "1024x768", 1024, 768},409{ "1280x720", 1280, 720},410{ "1280x800", 1280, 800},411{"1280x1024", 1280, 1024},412{ "1440x900", 1440, 900},413{"1680x1050", 1680, 1050},414{"1600x1200", 1600, 1200},415{"1920x1080", 1920, 1080},416{"1920x1200", 1920, 1200}417};418419n = ARRAY_SIZE(common_modes);420421for (i = 0; i < n; i++) {422if (amdgpu_encoder->devices & (ATOM_DEVICE_TV_SUPPORT)) {423if (common_modes[i].w > 1024 ||424common_modes[i].h > 768)425continue;426}427if (amdgpu_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) {428if (common_modes[i].w > native_mode->hdisplay ||429common_modes[i].h > native_mode->vdisplay ||430(common_modes[i].w == native_mode->hdisplay &&431common_modes[i].h == native_mode->vdisplay))432continue;433}434435mode = drm_cvt_mode(dev, common_modes[i].w, common_modes[i].h, 60, false, false, false);436if (!mode)437return;438strscpy(mode->name, common_modes[i].name, DRM_DISPLAY_MODE_LEN);439440drm_mode_probed_add(connector, mode);441}442}443444static int amdgpu_connector_set_property(struct drm_connector *connector,445struct drm_property *property,446uint64_t val)447{448struct drm_device *dev = connector->dev;449struct amdgpu_device *adev = drm_to_adev(dev);450struct drm_encoder *encoder;451struct amdgpu_encoder *amdgpu_encoder;452453if (property == adev->mode_info.coherent_mode_property) {454struct amdgpu_encoder_atom_dig *dig;455bool new_coherent_mode;456457/* need to find digital encoder on connector */458encoder = amdgpu_connector_find_encoder(connector, DRM_MODE_ENCODER_TMDS);459if (!encoder)460return 0;461462amdgpu_encoder = to_amdgpu_encoder(encoder);463464if (!amdgpu_encoder->enc_priv)465return 0;466467dig = amdgpu_encoder->enc_priv;468new_coherent_mode = val ? true : false;469if (dig->coherent_mode != new_coherent_mode) {470dig->coherent_mode = new_coherent_mode;471amdgpu_connector_property_change_mode(&amdgpu_encoder->base);472}473}474475if (property == adev->mode_info.audio_property) {476struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector);477/* need to find digital encoder on connector */478encoder = amdgpu_connector_find_encoder(connector, DRM_MODE_ENCODER_TMDS);479if (!encoder)480return 0;481482amdgpu_encoder = to_amdgpu_encoder(encoder);483484if (amdgpu_connector->audio != val) {485amdgpu_connector->audio = val;486amdgpu_connector_property_change_mode(&amdgpu_encoder->base);487}488}489490if (property == adev->mode_info.dither_property) {491struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector);492/* need to find digital encoder on connector */493encoder = amdgpu_connector_find_encoder(connector, DRM_MODE_ENCODER_TMDS);494if (!encoder)495return 0;496497amdgpu_encoder = to_amdgpu_encoder(encoder);498499if (amdgpu_connector->dither != val) {500amdgpu_connector->dither = val;501amdgpu_connector_property_change_mode(&amdgpu_encoder->base);502}503}504505if (property == adev->mode_info.underscan_property) {506/* need to find digital encoder on connector */507encoder = amdgpu_connector_find_encoder(connector, DRM_MODE_ENCODER_TMDS);508if (!encoder)509return 0;510511amdgpu_encoder = to_amdgpu_encoder(encoder);512513if (amdgpu_encoder->underscan_type != val) {514amdgpu_encoder->underscan_type = val;515amdgpu_connector_property_change_mode(&amdgpu_encoder->base);516}517}518519if (property == adev->mode_info.underscan_hborder_property) {520/* need to find digital encoder on connector */521encoder = amdgpu_connector_find_encoder(connector, DRM_MODE_ENCODER_TMDS);522if (!encoder)523return 0;524525amdgpu_encoder = to_amdgpu_encoder(encoder);526527if (amdgpu_encoder->underscan_hborder != val) {528amdgpu_encoder->underscan_hborder = val;529amdgpu_connector_property_change_mode(&amdgpu_encoder->base);530}531}532533if (property == adev->mode_info.underscan_vborder_property) {534/* need to find digital encoder on connector */535encoder = amdgpu_connector_find_encoder(connector, DRM_MODE_ENCODER_TMDS);536if (!encoder)537return 0;538539amdgpu_encoder = to_amdgpu_encoder(encoder);540541if (amdgpu_encoder->underscan_vborder != val) {542amdgpu_encoder->underscan_vborder = val;543amdgpu_connector_property_change_mode(&amdgpu_encoder->base);544}545}546547if (property == adev->mode_info.load_detect_property) {548struct amdgpu_connector *amdgpu_connector =549to_amdgpu_connector(connector);550551if (val == 0)552amdgpu_connector->dac_load_detect = false;553else554amdgpu_connector->dac_load_detect = true;555}556557if (property == dev->mode_config.scaling_mode_property) {558enum amdgpu_rmx_type rmx_type;559560if (connector->encoder) {561amdgpu_encoder = to_amdgpu_encoder(connector->encoder);562} else {563const struct drm_connector_helper_funcs *connector_funcs = connector->helper_private;564565amdgpu_encoder = to_amdgpu_encoder(connector_funcs->best_encoder(connector));566}567568switch (val) {569default:570case DRM_MODE_SCALE_NONE:571rmx_type = RMX_OFF;572break;573case DRM_MODE_SCALE_CENTER:574rmx_type = RMX_CENTER;575break;576case DRM_MODE_SCALE_ASPECT:577rmx_type = RMX_ASPECT;578break;579case DRM_MODE_SCALE_FULLSCREEN:580rmx_type = RMX_FULL;581break;582}583584if (amdgpu_encoder->rmx_type == rmx_type)585return 0;586587if ((rmx_type != DRM_MODE_SCALE_NONE) &&588(amdgpu_encoder->native_mode.clock == 0))589return 0;590591amdgpu_encoder->rmx_type = rmx_type;592593amdgpu_connector_property_change_mode(&amdgpu_encoder->base);594}595596return 0;597}598599static void600amdgpu_connector_fixup_lcd_native_mode(struct drm_encoder *encoder,601struct drm_connector *connector)602{603struct amdgpu_encoder *amdgpu_encoder = to_amdgpu_encoder(encoder);604struct drm_display_mode *native_mode = &amdgpu_encoder->native_mode;605struct drm_display_mode *t, *mode;606607/* If the EDID preferred mode doesn't match the native mode, use it */608list_for_each_entry_safe(mode, t, &connector->probed_modes, head) {609if (mode->type & DRM_MODE_TYPE_PREFERRED) {610if (mode->hdisplay != native_mode->hdisplay ||611mode->vdisplay != native_mode->vdisplay)612drm_mode_copy(native_mode, mode);613}614}615616/* Try to get native mode details from EDID if necessary */617if (!native_mode->clock) {618list_for_each_entry_safe(mode, t, &connector->probed_modes, head) {619if (mode->hdisplay == native_mode->hdisplay &&620mode->vdisplay == native_mode->vdisplay) {621drm_mode_copy(native_mode, mode);622drm_mode_set_crtcinfo(native_mode, CRTC_INTERLACE_HALVE_V);623DRM_DEBUG_KMS("Determined LVDS native mode details from EDID\n");624break;625}626}627}628629if (!native_mode->clock) {630DRM_DEBUG_KMS("No LVDS native mode details, disabling RMX\n");631amdgpu_encoder->rmx_type = RMX_OFF;632}633}634635static int amdgpu_connector_lvds_get_modes(struct drm_connector *connector)636{637struct drm_encoder *encoder;638int ret = 0;639struct drm_display_mode *mode;640641amdgpu_connector_get_edid(connector);642ret = amdgpu_connector_ddc_get_modes(connector);643if (ret > 0) {644encoder = amdgpu_connector_best_single_encoder(connector);645if (encoder) {646amdgpu_connector_fixup_lcd_native_mode(encoder, connector);647/* add scaled modes */648amdgpu_connector_add_common_modes(encoder, connector);649}650return ret;651}652653encoder = amdgpu_connector_best_single_encoder(connector);654if (!encoder)655return 0;656657/* we have no EDID modes */658mode = amdgpu_connector_lcd_native_mode(encoder);659if (mode) {660ret = 1;661drm_mode_probed_add(connector, mode);662/* add the width/height from vbios tables if available */663connector->display_info.width_mm = mode->width_mm;664connector->display_info.height_mm = mode->height_mm;665/* add scaled modes */666amdgpu_connector_add_common_modes(encoder, connector);667}668669return ret;670}671672static enum drm_mode_status amdgpu_connector_lvds_mode_valid(struct drm_connector *connector,673const struct drm_display_mode *mode)674{675struct drm_encoder *encoder = amdgpu_connector_best_single_encoder(connector);676677if ((mode->hdisplay < 320) || (mode->vdisplay < 240))678return MODE_PANEL;679680if (encoder) {681struct amdgpu_encoder *amdgpu_encoder = to_amdgpu_encoder(encoder);682struct drm_display_mode *native_mode = &amdgpu_encoder->native_mode;683684/* AVIVO hardware supports downscaling modes larger than the panel685* to the panel size, but I'm not sure this is desirable.686*/687if ((mode->hdisplay > native_mode->hdisplay) ||688(mode->vdisplay > native_mode->vdisplay))689return MODE_PANEL;690691/* if scaling is disabled, block non-native modes */692if (amdgpu_encoder->rmx_type == RMX_OFF) {693if ((mode->hdisplay != native_mode->hdisplay) ||694(mode->vdisplay != native_mode->vdisplay))695return MODE_PANEL;696}697}698699return MODE_OK;700}701702static enum drm_connector_status703amdgpu_connector_lvds_detect(struct drm_connector *connector, bool force)704{705struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector);706struct drm_encoder *encoder = amdgpu_connector_best_single_encoder(connector);707enum drm_connector_status ret = connector_status_disconnected;708int r;709710if (!drm_kms_helper_is_poll_worker()) {711r = pm_runtime_get_sync(connector->dev->dev);712if (r < 0) {713pm_runtime_put_autosuspend(connector->dev->dev);714return connector_status_disconnected;715}716}717718if (encoder) {719struct amdgpu_encoder *amdgpu_encoder = to_amdgpu_encoder(encoder);720struct drm_display_mode *native_mode = &amdgpu_encoder->native_mode;721722/* check if panel is valid */723if (native_mode->hdisplay >= 320 && native_mode->vdisplay >= 240)724ret = connector_status_connected;725726}727728/* check for edid as well */729amdgpu_connector_get_edid(connector);730if (amdgpu_connector->edid)731ret = connector_status_connected;732/* check acpi lid status ??? */733734amdgpu_connector_update_scratch_regs(connector, ret);735736if (!drm_kms_helper_is_poll_worker()) {737pm_runtime_mark_last_busy(connector->dev->dev);738pm_runtime_put_autosuspend(connector->dev->dev);739}740741return ret;742}743744static void amdgpu_connector_unregister(struct drm_connector *connector)745{746struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector);747748if (amdgpu_connector->ddc_bus && amdgpu_connector->ddc_bus->has_aux) {749drm_dp_aux_unregister(&amdgpu_connector->ddc_bus->aux);750amdgpu_connector->ddc_bus->has_aux = false;751}752}753754static void amdgpu_connector_destroy(struct drm_connector *connector)755{756struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector);757758amdgpu_connector_free_edid(connector);759kfree(amdgpu_connector->con_priv);760drm_connector_unregister(connector);761drm_connector_cleanup(connector);762kfree(connector);763}764765static int amdgpu_connector_set_lcd_property(struct drm_connector *connector,766struct drm_property *property,767uint64_t value)768{769struct drm_device *dev = connector->dev;770struct amdgpu_encoder *amdgpu_encoder;771enum amdgpu_rmx_type rmx_type;772773DRM_DEBUG_KMS("\n");774if (property != dev->mode_config.scaling_mode_property)775return 0;776777if (connector->encoder)778amdgpu_encoder = to_amdgpu_encoder(connector->encoder);779else {780const struct drm_connector_helper_funcs *connector_funcs = connector->helper_private;781782amdgpu_encoder = to_amdgpu_encoder(connector_funcs->best_encoder(connector));783}784785switch (value) {786case DRM_MODE_SCALE_NONE:787rmx_type = RMX_OFF;788break;789case DRM_MODE_SCALE_CENTER:790rmx_type = RMX_CENTER;791break;792case DRM_MODE_SCALE_ASPECT:793rmx_type = RMX_ASPECT;794break;795default:796case DRM_MODE_SCALE_FULLSCREEN:797rmx_type = RMX_FULL;798break;799}800801if (amdgpu_encoder->rmx_type == rmx_type)802return 0;803804amdgpu_encoder->rmx_type = rmx_type;805806amdgpu_connector_property_change_mode(&amdgpu_encoder->base);807return 0;808}809810811static const struct drm_connector_helper_funcs amdgpu_connector_lvds_helper_funcs = {812.get_modes = amdgpu_connector_lvds_get_modes,813.mode_valid = amdgpu_connector_lvds_mode_valid,814.best_encoder = amdgpu_connector_best_single_encoder,815};816817static const struct drm_connector_funcs amdgpu_connector_lvds_funcs = {818.dpms = drm_helper_connector_dpms,819.detect = amdgpu_connector_lvds_detect,820.fill_modes = drm_helper_probe_single_connector_modes,821.early_unregister = amdgpu_connector_unregister,822.destroy = amdgpu_connector_destroy,823.set_property = amdgpu_connector_set_lcd_property,824};825826static int amdgpu_connector_vga_get_modes(struct drm_connector *connector)827{828int ret;829830amdgpu_connector_get_edid(connector);831ret = amdgpu_connector_ddc_get_modes(connector);832amdgpu_get_native_mode(connector);833834return ret;835}836837static enum drm_mode_status amdgpu_connector_vga_mode_valid(struct drm_connector *connector,838const struct drm_display_mode *mode)839{840struct drm_device *dev = connector->dev;841struct amdgpu_device *adev = drm_to_adev(dev);842843/* XXX check mode bandwidth */844845if ((mode->clock / 10) > adev->clock.max_pixel_clock)846return MODE_CLOCK_HIGH;847848return MODE_OK;849}850851static enum drm_connector_status852amdgpu_connector_vga_detect(struct drm_connector *connector, bool force)853{854struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector);855struct drm_encoder *encoder;856const struct drm_encoder_helper_funcs *encoder_funcs;857bool dret = false;858enum drm_connector_status ret = connector_status_disconnected;859int r;860861if (!drm_kms_helper_is_poll_worker()) {862r = pm_runtime_get_sync(connector->dev->dev);863if (r < 0) {864pm_runtime_put_autosuspend(connector->dev->dev);865return connector_status_disconnected;866}867}868869encoder = amdgpu_connector_best_single_encoder(connector);870if (!encoder)871ret = connector_status_disconnected;872873if (amdgpu_connector->ddc_bus)874dret = amdgpu_display_ddc_probe(amdgpu_connector, false);875if (dret) {876amdgpu_connector->detected_by_load = false;877amdgpu_connector_free_edid(connector);878amdgpu_connector_get_edid(connector);879880if (!amdgpu_connector->edid) {881DRM_ERROR("%s: probed a monitor but no|invalid EDID\n",882connector->name);883ret = connector_status_connected;884} else {885amdgpu_connector->use_digital =886!!(amdgpu_connector->edid->input & DRM_EDID_INPUT_DIGITAL);887888/* some oems have boards with separate digital and analog connectors889* with a shared ddc line (often vga + hdmi)890*/891if (amdgpu_connector->use_digital && amdgpu_connector->shared_ddc) {892amdgpu_connector_free_edid(connector);893ret = connector_status_disconnected;894} else {895ret = connector_status_connected;896}897}898} else {899900/* if we aren't forcing don't do destructive polling */901if (!force) {902/* only return the previous status if we last903* detected a monitor via load.904*/905if (amdgpu_connector->detected_by_load)906ret = connector->status;907goto out;908}909910if (amdgpu_connector->dac_load_detect && encoder) {911encoder_funcs = encoder->helper_private;912ret = encoder_funcs->detect(encoder, connector);913if (ret != connector_status_disconnected)914amdgpu_connector->detected_by_load = true;915}916}917918amdgpu_connector_update_scratch_regs(connector, ret);919920out:921if (!drm_kms_helper_is_poll_worker()) {922pm_runtime_mark_last_busy(connector->dev->dev);923pm_runtime_put_autosuspend(connector->dev->dev);924}925926return ret;927}928929static const struct drm_connector_helper_funcs amdgpu_connector_vga_helper_funcs = {930.get_modes = amdgpu_connector_vga_get_modes,931.mode_valid = amdgpu_connector_vga_mode_valid,932.best_encoder = amdgpu_connector_best_single_encoder,933};934935static const struct drm_connector_funcs amdgpu_connector_vga_funcs = {936.dpms = drm_helper_connector_dpms,937.detect = amdgpu_connector_vga_detect,938.fill_modes = drm_helper_probe_single_connector_modes,939.early_unregister = amdgpu_connector_unregister,940.destroy = amdgpu_connector_destroy,941.set_property = amdgpu_connector_set_property,942};943944static bool945amdgpu_connector_check_hpd_status_unchanged(struct drm_connector *connector)946{947struct drm_device *dev = connector->dev;948struct amdgpu_device *adev = drm_to_adev(dev);949struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector);950enum drm_connector_status status;951952if (amdgpu_connector->hpd.hpd != AMDGPU_HPD_NONE) {953if (amdgpu_display_hpd_sense(adev, amdgpu_connector->hpd.hpd))954status = connector_status_connected;955else956status = connector_status_disconnected;957if (connector->status == status)958return true;959}960961return false;962}963964static void amdgpu_connector_shared_ddc(enum drm_connector_status *status,965struct drm_connector *connector,966struct amdgpu_connector *amdgpu_connector)967{968struct drm_connector *list_connector;969struct drm_connector_list_iter iter;970struct amdgpu_connector *list_amdgpu_connector;971struct drm_device *dev = connector->dev;972struct amdgpu_device *adev = drm_to_adev(dev);973974if (amdgpu_connector->shared_ddc && *status == connector_status_connected) {975drm_connector_list_iter_begin(dev, &iter);976drm_for_each_connector_iter(list_connector,977&iter) {978if (connector == list_connector)979continue;980list_amdgpu_connector = to_amdgpu_connector(list_connector);981if (list_amdgpu_connector->shared_ddc &&982list_amdgpu_connector->ddc_bus->rec.i2c_id ==983amdgpu_connector->ddc_bus->rec.i2c_id) {984/* cases where both connectors are digital */985if (list_connector->connector_type != DRM_MODE_CONNECTOR_VGA) {986/* hpd is our only option in this case */987if (!amdgpu_display_hpd_sense(adev,988amdgpu_connector->hpd.hpd)) {989amdgpu_connector_free_edid(connector);990*status = connector_status_disconnected;991}992}993}994}995drm_connector_list_iter_end(&iter);996}997}998999/*1000* DVI is complicated1001* Do a DDC probe, if DDC probe passes, get the full EDID so1002* we can do analog/digital monitor detection at this point.1003* If the monitor is an analog monitor or we got no DDC,1004* we need to find the DAC encoder object for this connector.1005* If we got no DDC, we do load detection on the DAC encoder object.1006* If we got analog DDC or load detection passes on the DAC encoder1007* we have to check if this analog encoder is shared with anyone else (TV)1008* if its shared we have to set the other connector to disconnected.1009*/1010static enum drm_connector_status1011amdgpu_connector_dvi_detect(struct drm_connector *connector, bool force)1012{1013struct drm_device *dev = connector->dev;1014struct amdgpu_device *adev = drm_to_adev(dev);1015struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector);1016const struct drm_encoder_helper_funcs *encoder_funcs;1017int r;1018enum drm_connector_status ret = connector_status_disconnected;1019bool dret = false, broken_edid = false;10201021if (!drm_kms_helper_is_poll_worker()) {1022r = pm_runtime_get_sync(connector->dev->dev);1023if (r < 0) {1024pm_runtime_put_autosuspend(connector->dev->dev);1025return connector_status_disconnected;1026}1027}10281029if (amdgpu_connector->detected_hpd_without_ddc) {1030force = true;1031amdgpu_connector->detected_hpd_without_ddc = false;1032}10331034if (!force && amdgpu_connector_check_hpd_status_unchanged(connector)) {1035ret = connector->status;1036goto exit;1037}10381039if (amdgpu_connector->ddc_bus) {1040dret = amdgpu_display_ddc_probe(amdgpu_connector, false);10411042/* Sometimes the pins required for the DDC probe on DVI1043* connectors don't make contact at the same time that the ones1044* for HPD do. If the DDC probe fails even though we had an HPD1045* signal, try again later1046*/1047if (!dret && !force &&1048amdgpu_display_hpd_sense(adev, amdgpu_connector->hpd.hpd)) {1049DRM_DEBUG_KMS("hpd detected without ddc, retrying in 1 second\n");1050amdgpu_connector->detected_hpd_without_ddc = true;1051schedule_delayed_work(&adev->hotplug_work,1052msecs_to_jiffies(1000));1053goto exit;1054}1055}1056if (dret) {1057amdgpu_connector->detected_by_load = false;1058amdgpu_connector_free_edid(connector);1059amdgpu_connector_get_edid(connector);10601061if (!amdgpu_connector->edid) {1062DRM_ERROR("%s: probed a monitor but no|invalid EDID\n",1063connector->name);1064ret = connector_status_connected;1065broken_edid = true; /* defer use_digital to later */1066} else {1067amdgpu_connector->use_digital =1068!!(amdgpu_connector->edid->input & DRM_EDID_INPUT_DIGITAL);10691070/* some oems have boards with separate digital and analog connectors1071* with a shared ddc line (often vga + hdmi)1072*/1073if ((!amdgpu_connector->use_digital) && amdgpu_connector->shared_ddc) {1074amdgpu_connector_free_edid(connector);1075ret = connector_status_disconnected;1076} else {1077ret = connector_status_connected;1078}10791080/* This gets complicated. We have boards with VGA + HDMI with a1081* shared DDC line and we have boards with DVI-D + HDMI with a shared1082* DDC line. The latter is more complex because with DVI<->HDMI adapters1083* you don't really know what's connected to which port as both are digital.1084*/1085amdgpu_connector_shared_ddc(&ret, connector, amdgpu_connector);1086}1087}10881089if ((ret == connector_status_connected) && (amdgpu_connector->use_digital == true))1090goto out;10911092/* DVI-D and HDMI-A are digital only */1093if ((connector->connector_type == DRM_MODE_CONNECTOR_DVID) ||1094(connector->connector_type == DRM_MODE_CONNECTOR_HDMIA))1095goto out;10961097/* if we aren't forcing don't do destructive polling */1098if (!force) {1099/* only return the previous status if we last1100* detected a monitor via load.1101*/1102if (amdgpu_connector->detected_by_load)1103ret = connector->status;1104goto out;1105}11061107/* find analog encoder */1108if (amdgpu_connector->dac_load_detect) {1109struct drm_encoder *encoder;11101111drm_connector_for_each_possible_encoder(connector, encoder) {1112if (encoder->encoder_type != DRM_MODE_ENCODER_DAC &&1113encoder->encoder_type != DRM_MODE_ENCODER_TVDAC)1114continue;11151116encoder_funcs = encoder->helper_private;1117if (encoder_funcs->detect) {1118if (!broken_edid) {1119if (ret != connector_status_connected) {1120/* deal with analog monitors without DDC */1121ret = encoder_funcs->detect(encoder, connector);1122if (ret == connector_status_connected) {1123amdgpu_connector->use_digital = false;1124}1125if (ret != connector_status_disconnected)1126amdgpu_connector->detected_by_load = true;1127}1128} else {1129enum drm_connector_status lret;1130/* assume digital unless load detected otherwise */1131amdgpu_connector->use_digital = true;1132lret = encoder_funcs->detect(encoder, connector);1133DRM_DEBUG_KMS("load_detect %x returned: %x\n",1134encoder->encoder_type, lret);1135if (lret == connector_status_connected)1136amdgpu_connector->use_digital = false;1137}1138break;1139}1140}1141}11421143out:1144/* updated in get modes as well since we need to know if it's analog or digital */1145amdgpu_connector_update_scratch_regs(connector, ret);11461147exit:1148if (!drm_kms_helper_is_poll_worker()) {1149pm_runtime_mark_last_busy(connector->dev->dev);1150pm_runtime_put_autosuspend(connector->dev->dev);1151}11521153return ret;1154}11551156/* okay need to be smart in here about which encoder to pick */1157static struct drm_encoder *1158amdgpu_connector_dvi_encoder(struct drm_connector *connector)1159{1160struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector);1161struct drm_encoder *encoder;11621163drm_connector_for_each_possible_encoder(connector, encoder) {1164if (amdgpu_connector->use_digital == true) {1165if (encoder->encoder_type == DRM_MODE_ENCODER_TMDS)1166return encoder;1167} else {1168if (encoder->encoder_type == DRM_MODE_ENCODER_DAC ||1169encoder->encoder_type == DRM_MODE_ENCODER_TVDAC)1170return encoder;1171}1172}11731174/* see if we have a default encoder TODO */11751176/* then check use digitial */1177/* pick the first one */1178drm_connector_for_each_possible_encoder(connector, encoder)1179return encoder;11801181return NULL;1182}11831184static void amdgpu_connector_dvi_force(struct drm_connector *connector)1185{1186struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector);11871188if (connector->force == DRM_FORCE_ON)1189amdgpu_connector->use_digital = false;1190if (connector->force == DRM_FORCE_ON_DIGITAL)1191amdgpu_connector->use_digital = true;1192}11931194/**1195* amdgpu_max_hdmi_pixel_clock - Return max supported HDMI (TMDS) pixel clock1196* @adev: pointer to amdgpu_device1197*1198* Return: maximum supported HDMI (TMDS) pixel clock in KHz.1199*/1200static int amdgpu_max_hdmi_pixel_clock(const struct amdgpu_device *adev)1201{1202if (adev->asic_type >= CHIP_POLARIS10)1203return 600000;1204else if (adev->asic_type >= CHIP_TONGA)1205return 300000;1206else1207return 297000;1208}12091210/**1211* amdgpu_connector_dvi_mode_valid - Validate a mode on DVI/HDMI connectors1212* @connector: DRM connector to validate the mode on1213* @mode: display mode to validate1214*1215* Validate the given display mode on DVI and HDMI connectors, including1216* analog signals on DVI-I.1217*1218* Return: drm_mode_status indicating whether the mode is valid.1219*/1220static enum drm_mode_status amdgpu_connector_dvi_mode_valid(struct drm_connector *connector,1221const struct drm_display_mode *mode)1222{1223struct drm_device *dev = connector->dev;1224struct amdgpu_device *adev = drm_to_adev(dev);1225struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector);1226const int max_hdmi_pixel_clock = amdgpu_max_hdmi_pixel_clock(adev);1227const int max_dvi_single_link_pixel_clock = 165000;1228int max_digital_pixel_clock_khz;12291230/* XXX check mode bandwidth */12311232if (amdgpu_connector->use_digital) {1233switch (amdgpu_connector->connector_object_id) {1234case CONNECTOR_OBJECT_ID_HDMI_TYPE_A:1235max_digital_pixel_clock_khz = max_hdmi_pixel_clock;1236break;1237case CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I:1238case CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D:1239max_digital_pixel_clock_khz = max_dvi_single_link_pixel_clock;1240break;1241case CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I:1242case CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D:1243case CONNECTOR_OBJECT_ID_HDMI_TYPE_B:1244max_digital_pixel_clock_khz = max_dvi_single_link_pixel_clock * 2;1245break;1246}12471248/* When the display EDID claims that it's an HDMI display,1249* we use the HDMI encoder mode of the display HW,1250* so we should verify against the max HDMI clock here.1251*/1252if (connector->display_info.is_hdmi)1253max_digital_pixel_clock_khz = max_hdmi_pixel_clock;12541255if (mode->clock > max_digital_pixel_clock_khz)1256return MODE_CLOCK_HIGH;1257}12581259/* check against the max pixel clock */1260if ((mode->clock / 10) > adev->clock.max_pixel_clock)1261return MODE_CLOCK_HIGH;12621263return MODE_OK;1264}12651266static const struct drm_connector_helper_funcs amdgpu_connector_dvi_helper_funcs = {1267.get_modes = amdgpu_connector_vga_get_modes,1268.mode_valid = amdgpu_connector_dvi_mode_valid,1269.best_encoder = amdgpu_connector_dvi_encoder,1270};12711272static const struct drm_connector_funcs amdgpu_connector_dvi_funcs = {1273.dpms = drm_helper_connector_dpms,1274.detect = amdgpu_connector_dvi_detect,1275.fill_modes = drm_helper_probe_single_connector_modes,1276.set_property = amdgpu_connector_set_property,1277.early_unregister = amdgpu_connector_unregister,1278.destroy = amdgpu_connector_destroy,1279.force = amdgpu_connector_dvi_force,1280};12811282static int amdgpu_connector_dp_get_modes(struct drm_connector *connector)1283{1284struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector);1285struct amdgpu_connector_atom_dig *amdgpu_dig_connector = amdgpu_connector->con_priv;1286struct drm_encoder *encoder = amdgpu_connector_best_single_encoder(connector);1287int ret;12881289if ((connector->connector_type == DRM_MODE_CONNECTOR_eDP) ||1290(connector->connector_type == DRM_MODE_CONNECTOR_LVDS)) {1291struct drm_display_mode *mode;12921293if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) {1294if (!amdgpu_dig_connector->edp_on)1295amdgpu_atombios_encoder_set_edp_panel_power(connector,1296ATOM_TRANSMITTER_ACTION_POWER_ON);1297amdgpu_connector_get_edid(connector);1298ret = amdgpu_connector_ddc_get_modes(connector);1299if (!amdgpu_dig_connector->edp_on)1300amdgpu_atombios_encoder_set_edp_panel_power(connector,1301ATOM_TRANSMITTER_ACTION_POWER_OFF);1302} else {1303/* need to setup ddc on the bridge */1304if (amdgpu_connector_encoder_get_dp_bridge_encoder_id(connector) !=1305ENCODER_OBJECT_ID_NONE) {1306if (encoder)1307amdgpu_atombios_encoder_setup_ext_encoder_ddc(encoder);1308}1309amdgpu_connector_get_edid(connector);1310ret = amdgpu_connector_ddc_get_modes(connector);1311}13121313if (ret > 0) {1314if (encoder) {1315amdgpu_connector_fixup_lcd_native_mode(encoder, connector);1316/* add scaled modes */1317amdgpu_connector_add_common_modes(encoder, connector);1318}1319return ret;1320}13211322if (!encoder)1323return 0;13241325/* we have no EDID modes */1326mode = amdgpu_connector_lcd_native_mode(encoder);1327if (mode) {1328ret = 1;1329drm_mode_probed_add(connector, mode);1330/* add the width/height from vbios tables if available */1331connector->display_info.width_mm = mode->width_mm;1332connector->display_info.height_mm = mode->height_mm;1333/* add scaled modes */1334amdgpu_connector_add_common_modes(encoder, connector);1335}1336} else {1337/* need to setup ddc on the bridge */1338if (amdgpu_connector_encoder_get_dp_bridge_encoder_id(connector) !=1339ENCODER_OBJECT_ID_NONE) {1340if (encoder)1341amdgpu_atombios_encoder_setup_ext_encoder_ddc(encoder);1342}1343amdgpu_connector_get_edid(connector);1344ret = amdgpu_connector_ddc_get_modes(connector);13451346amdgpu_get_native_mode(connector);1347}13481349return ret;1350}13511352u16 amdgpu_connector_encoder_get_dp_bridge_encoder_id(struct drm_connector *connector)1353{1354struct drm_encoder *encoder;1355struct amdgpu_encoder *amdgpu_encoder;13561357drm_connector_for_each_possible_encoder(connector, encoder) {1358amdgpu_encoder = to_amdgpu_encoder(encoder);13591360switch (amdgpu_encoder->encoder_id) {1361case ENCODER_OBJECT_ID_TRAVIS:1362case ENCODER_OBJECT_ID_NUTMEG:1363return amdgpu_encoder->encoder_id;1364default:1365break;1366}1367}13681369return ENCODER_OBJECT_ID_NONE;1370}13711372static bool amdgpu_connector_encoder_is_hbr2(struct drm_connector *connector)1373{1374struct drm_encoder *encoder;1375struct amdgpu_encoder *amdgpu_encoder;1376bool found = false;13771378drm_connector_for_each_possible_encoder(connector, encoder) {1379amdgpu_encoder = to_amdgpu_encoder(encoder);1380if (amdgpu_encoder->caps & ATOM_ENCODER_CAP_RECORD_HBR2)1381found = true;1382}13831384return found;1385}13861387bool amdgpu_connector_is_dp12_capable(struct drm_connector *connector)1388{1389struct drm_device *dev = connector->dev;1390struct amdgpu_device *adev = drm_to_adev(dev);13911392if ((adev->clock.default_dispclk >= 53900) &&1393amdgpu_connector_encoder_is_hbr2(connector)) {1394return true;1395}13961397return false;1398}13991400static enum drm_connector_status1401amdgpu_connector_dp_detect(struct drm_connector *connector, bool force)1402{1403struct drm_device *dev = connector->dev;1404struct amdgpu_device *adev = drm_to_adev(dev);1405struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector);1406enum drm_connector_status ret = connector_status_disconnected;1407struct amdgpu_connector_atom_dig *amdgpu_dig_connector = amdgpu_connector->con_priv;1408struct drm_encoder *encoder = amdgpu_connector_best_single_encoder(connector);1409int r;14101411if (!drm_kms_helper_is_poll_worker()) {1412r = pm_runtime_get_sync(connector->dev->dev);1413if (r < 0) {1414pm_runtime_put_autosuspend(connector->dev->dev);1415return connector_status_disconnected;1416}1417}14181419if (!force && amdgpu_connector_check_hpd_status_unchanged(connector)) {1420ret = connector->status;1421goto out;1422}14231424amdgpu_connector_free_edid(connector);14251426if ((connector->connector_type == DRM_MODE_CONNECTOR_eDP) ||1427(connector->connector_type == DRM_MODE_CONNECTOR_LVDS)) {1428if (encoder) {1429struct amdgpu_encoder *amdgpu_encoder = to_amdgpu_encoder(encoder);1430struct drm_display_mode *native_mode = &amdgpu_encoder->native_mode;14311432/* check if panel is valid */1433if (native_mode->hdisplay >= 320 && native_mode->vdisplay >= 240)1434ret = connector_status_connected;1435}1436/* eDP is always DP */1437amdgpu_dig_connector->dp_sink_type = CONNECTOR_OBJECT_ID_DISPLAYPORT;1438if (!amdgpu_dig_connector->edp_on)1439amdgpu_atombios_encoder_set_edp_panel_power(connector,1440ATOM_TRANSMITTER_ACTION_POWER_ON);1441if (!amdgpu_atombios_dp_get_dpcd(amdgpu_connector))1442ret = connector_status_connected;1443if (!amdgpu_dig_connector->edp_on)1444amdgpu_atombios_encoder_set_edp_panel_power(connector,1445ATOM_TRANSMITTER_ACTION_POWER_OFF);1446} else if (amdgpu_connector_encoder_get_dp_bridge_encoder_id(connector) !=1447ENCODER_OBJECT_ID_NONE) {1448/* DP bridges are always DP */1449amdgpu_dig_connector->dp_sink_type = CONNECTOR_OBJECT_ID_DISPLAYPORT;1450/* get the DPCD from the bridge */1451amdgpu_atombios_dp_get_dpcd(amdgpu_connector);14521453if (encoder) {1454/* setup ddc on the bridge */1455amdgpu_atombios_encoder_setup_ext_encoder_ddc(encoder);1456/* bridge chips are always aux */1457/* try DDC */1458if (amdgpu_display_ddc_probe(amdgpu_connector, true))1459ret = connector_status_connected;1460else if (amdgpu_connector->dac_load_detect) { /* try load detection */1461const struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private;14621463ret = encoder_funcs->detect(encoder, connector);1464}1465}1466} else {1467amdgpu_dig_connector->dp_sink_type =1468amdgpu_atombios_dp_get_sinktype(amdgpu_connector);1469if (amdgpu_display_hpd_sense(adev, amdgpu_connector->hpd.hpd)) {1470ret = connector_status_connected;1471if (amdgpu_dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT)1472amdgpu_atombios_dp_get_dpcd(amdgpu_connector);1473} else {1474if (amdgpu_dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) {1475if (!amdgpu_atombios_dp_get_dpcd(amdgpu_connector))1476ret = connector_status_connected;1477} else {1478/* try non-aux ddc (DP to DVI/HDMI/etc. adapter) */1479if (amdgpu_display_ddc_probe(amdgpu_connector,1480false))1481ret = connector_status_connected;1482}1483}1484}14851486amdgpu_connector_update_scratch_regs(connector, ret);1487out:1488if (!drm_kms_helper_is_poll_worker()) {1489pm_runtime_mark_last_busy(connector->dev->dev);1490pm_runtime_put_autosuspend(connector->dev->dev);1491}14921493if (connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort ||1494connector->connector_type == DRM_MODE_CONNECTOR_eDP)1495drm_dp_set_subconnector_property(&amdgpu_connector->base,1496ret,1497amdgpu_dig_connector->dpcd,1498amdgpu_dig_connector->downstream_ports);1499return ret;1500}15011502static enum drm_mode_status amdgpu_connector_dp_mode_valid(struct drm_connector *connector,1503const struct drm_display_mode *mode)1504{1505struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector);1506struct amdgpu_connector_atom_dig *amdgpu_dig_connector = amdgpu_connector->con_priv;15071508/* XXX check mode bandwidth */15091510if ((connector->connector_type == DRM_MODE_CONNECTOR_eDP) ||1511(connector->connector_type == DRM_MODE_CONNECTOR_LVDS)) {1512struct drm_encoder *encoder = amdgpu_connector_best_single_encoder(connector);15131514if ((mode->hdisplay < 320) || (mode->vdisplay < 240))1515return MODE_PANEL;15161517if (encoder) {1518struct amdgpu_encoder *amdgpu_encoder = to_amdgpu_encoder(encoder);1519struct drm_display_mode *native_mode = &amdgpu_encoder->native_mode;15201521/* AVIVO hardware supports downscaling modes larger than the panel1522* to the panel size, but I'm not sure this is desirable.1523*/1524if ((mode->hdisplay > native_mode->hdisplay) ||1525(mode->vdisplay > native_mode->vdisplay))1526return MODE_PANEL;15271528/* if scaling is disabled, block non-native modes */1529if (amdgpu_encoder->rmx_type == RMX_OFF) {1530if ((mode->hdisplay != native_mode->hdisplay) ||1531(mode->vdisplay != native_mode->vdisplay))1532return MODE_PANEL;1533}1534}1535return MODE_OK;1536} else {1537if ((amdgpu_dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) ||1538(amdgpu_dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP)) {1539return amdgpu_atombios_dp_mode_valid_helper(connector, mode);1540} else {1541if (connector->display_info.is_hdmi) {1542/* HDMI 1.3+ supports max clock of 340 Mhz */1543if (mode->clock > 340000)1544return MODE_CLOCK_HIGH;1545} else {1546if (mode->clock > 165000)1547return MODE_CLOCK_HIGH;1548}1549}1550}15511552return MODE_OK;1553}15541555static int1556amdgpu_connector_late_register(struct drm_connector *connector)1557{1558struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector);1559int r = 0;15601561if (amdgpu_connector->ddc_bus->has_aux) {1562amdgpu_connector->ddc_bus->aux.dev = amdgpu_connector->base.kdev;1563r = drm_dp_aux_register(&amdgpu_connector->ddc_bus->aux);1564}15651566return r;1567}15681569static const struct drm_connector_helper_funcs amdgpu_connector_dp_helper_funcs = {1570.get_modes = amdgpu_connector_dp_get_modes,1571.mode_valid = amdgpu_connector_dp_mode_valid,1572.best_encoder = amdgpu_connector_dvi_encoder,1573};15741575static const struct drm_connector_funcs amdgpu_connector_dp_funcs = {1576.dpms = drm_helper_connector_dpms,1577.detect = amdgpu_connector_dp_detect,1578.fill_modes = drm_helper_probe_single_connector_modes,1579.set_property = amdgpu_connector_set_property,1580.early_unregister = amdgpu_connector_unregister,1581.destroy = amdgpu_connector_destroy,1582.force = amdgpu_connector_dvi_force,1583.late_register = amdgpu_connector_late_register,1584};15851586static const struct drm_connector_funcs amdgpu_connector_edp_funcs = {1587.dpms = drm_helper_connector_dpms,1588.detect = amdgpu_connector_dp_detect,1589.fill_modes = drm_helper_probe_single_connector_modes,1590.set_property = amdgpu_connector_set_lcd_property,1591.early_unregister = amdgpu_connector_unregister,1592.destroy = amdgpu_connector_destroy,1593.force = amdgpu_connector_dvi_force,1594.late_register = amdgpu_connector_late_register,1595};15961597void1598amdgpu_connector_add(struct amdgpu_device *adev,1599uint32_t connector_id,1600uint32_t supported_device,1601int connector_type,1602struct amdgpu_i2c_bus_rec *i2c_bus,1603uint16_t connector_object_id,1604struct amdgpu_hpd *hpd,1605struct amdgpu_router *router)1606{1607struct drm_device *dev = adev_to_drm(adev);1608struct drm_connector *connector;1609struct drm_connector_list_iter iter;1610struct amdgpu_connector *amdgpu_connector;1611struct amdgpu_connector_atom_dig *amdgpu_dig_connector;1612struct drm_encoder *encoder;1613struct amdgpu_encoder *amdgpu_encoder;1614struct i2c_adapter *ddc = NULL;1615uint32_t subpixel_order = SubPixelNone;1616bool shared_ddc = false;1617bool is_dp_bridge = false;1618bool has_aux = false;16191620if (connector_type == DRM_MODE_CONNECTOR_Unknown)1621return;16221623/* see if we already added it */1624drm_connector_list_iter_begin(dev, &iter);1625drm_for_each_connector_iter(connector, &iter) {1626amdgpu_connector = to_amdgpu_connector(connector);1627if (amdgpu_connector->connector_id == connector_id) {1628amdgpu_connector->devices |= supported_device;1629drm_connector_list_iter_end(&iter);1630return;1631}1632if (amdgpu_connector->ddc_bus && i2c_bus->valid) {1633if (amdgpu_connector->ddc_bus->rec.i2c_id == i2c_bus->i2c_id) {1634amdgpu_connector->shared_ddc = true;1635shared_ddc = true;1636}1637if (amdgpu_connector->router_bus && router->ddc_valid &&1638(amdgpu_connector->router.router_id == router->router_id)) {1639amdgpu_connector->shared_ddc = false;1640shared_ddc = false;1641}1642}1643}1644drm_connector_list_iter_end(&iter);16451646/* check if it's a dp bridge */1647list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {1648amdgpu_encoder = to_amdgpu_encoder(encoder);1649if (amdgpu_encoder->devices & supported_device) {1650switch (amdgpu_encoder->encoder_id) {1651case ENCODER_OBJECT_ID_TRAVIS:1652case ENCODER_OBJECT_ID_NUTMEG:1653is_dp_bridge = true;1654break;1655default:1656break;1657}1658}1659}16601661amdgpu_connector = kzalloc(sizeof(struct amdgpu_connector), GFP_KERNEL);1662if (!amdgpu_connector)1663return;16641665connector = &amdgpu_connector->base;16661667amdgpu_connector->connector_id = connector_id;1668amdgpu_connector->devices = supported_device;1669amdgpu_connector->shared_ddc = shared_ddc;1670amdgpu_connector->connector_object_id = connector_object_id;1671amdgpu_connector->hpd = *hpd;16721673amdgpu_connector->router = *router;1674if (router->ddc_valid || router->cd_valid) {1675amdgpu_connector->router_bus = amdgpu_i2c_lookup(adev, &router->i2c_info);1676if (!amdgpu_connector->router_bus)1677DRM_ERROR("Failed to assign router i2c bus! Check dmesg for i2c errors.\n");1678}16791680if (is_dp_bridge) {1681amdgpu_dig_connector = kzalloc(sizeof(struct amdgpu_connector_atom_dig), GFP_KERNEL);1682if (!amdgpu_dig_connector)1683goto failed;1684amdgpu_connector->con_priv = amdgpu_dig_connector;1685if (i2c_bus->valid) {1686amdgpu_connector->ddc_bus = amdgpu_i2c_lookup(adev, i2c_bus);1687if (amdgpu_connector->ddc_bus) {1688has_aux = true;1689ddc = &amdgpu_connector->ddc_bus->adapter;1690} else {1691DRM_ERROR("DP: Failed to assign ddc bus! Check dmesg for i2c errors.\n");1692}1693}1694switch (connector_type) {1695case DRM_MODE_CONNECTOR_VGA:1696case DRM_MODE_CONNECTOR_DVIA:1697default:1698drm_connector_init_with_ddc(dev, &amdgpu_connector->base,1699&amdgpu_connector_dp_funcs,1700connector_type,1701ddc);1702drm_connector_helper_add(&amdgpu_connector->base,1703&amdgpu_connector_dp_helper_funcs);1704connector->interlace_allowed = true;1705connector->doublescan_allowed = true;1706amdgpu_connector->dac_load_detect = true;1707drm_object_attach_property(&amdgpu_connector->base.base,1708adev->mode_info.load_detect_property,17091);1710drm_object_attach_property(&amdgpu_connector->base.base,1711dev->mode_config.scaling_mode_property,1712DRM_MODE_SCALE_NONE);1713break;1714case DRM_MODE_CONNECTOR_DVII:1715case DRM_MODE_CONNECTOR_DVID:1716case DRM_MODE_CONNECTOR_HDMIA:1717case DRM_MODE_CONNECTOR_HDMIB:1718case DRM_MODE_CONNECTOR_DisplayPort:1719drm_connector_init_with_ddc(dev, &amdgpu_connector->base,1720&amdgpu_connector_dp_funcs,1721connector_type,1722ddc);1723drm_connector_helper_add(&amdgpu_connector->base,1724&amdgpu_connector_dp_helper_funcs);1725drm_object_attach_property(&amdgpu_connector->base.base,1726adev->mode_info.underscan_property,1727UNDERSCAN_OFF);1728drm_object_attach_property(&amdgpu_connector->base.base,1729adev->mode_info.underscan_hborder_property,17300);1731drm_object_attach_property(&amdgpu_connector->base.base,1732adev->mode_info.underscan_vborder_property,17330);17341735drm_object_attach_property(&amdgpu_connector->base.base,1736dev->mode_config.scaling_mode_property,1737DRM_MODE_SCALE_NONE);17381739drm_object_attach_property(&amdgpu_connector->base.base,1740adev->mode_info.dither_property,1741AMDGPU_FMT_DITHER_DISABLE);17421743if (amdgpu_audio != 0) {1744drm_object_attach_property(&amdgpu_connector->base.base,1745adev->mode_info.audio_property,1746AMDGPU_AUDIO_AUTO);1747amdgpu_connector->audio = AMDGPU_AUDIO_AUTO;1748}17491750subpixel_order = SubPixelHorizontalRGB;1751connector->interlace_allowed = true;1752if (connector_type == DRM_MODE_CONNECTOR_HDMIB)1753connector->doublescan_allowed = true;1754else1755connector->doublescan_allowed = false;1756if (connector_type == DRM_MODE_CONNECTOR_DVII) {1757amdgpu_connector->dac_load_detect = true;1758drm_object_attach_property(&amdgpu_connector->base.base,1759adev->mode_info.load_detect_property,17601);1761}1762break;1763case DRM_MODE_CONNECTOR_LVDS:1764case DRM_MODE_CONNECTOR_eDP:1765drm_connector_init_with_ddc(dev, &amdgpu_connector->base,1766&amdgpu_connector_edp_funcs,1767connector_type,1768ddc);1769drm_connector_helper_add(&amdgpu_connector->base,1770&amdgpu_connector_dp_helper_funcs);1771drm_object_attach_property(&amdgpu_connector->base.base,1772dev->mode_config.scaling_mode_property,1773DRM_MODE_SCALE_FULLSCREEN);1774subpixel_order = SubPixelHorizontalRGB;1775connector->interlace_allowed = false;1776connector->doublescan_allowed = false;1777break;1778}1779} else {1780switch (connector_type) {1781case DRM_MODE_CONNECTOR_VGA:1782if (i2c_bus->valid) {1783amdgpu_connector->ddc_bus = amdgpu_i2c_lookup(adev, i2c_bus);1784if (!amdgpu_connector->ddc_bus)1785DRM_ERROR("VGA: Failed to assign ddc bus! Check dmesg for i2c errors.\n");1786else1787ddc = &amdgpu_connector->ddc_bus->adapter;1788}1789drm_connector_init_with_ddc(dev, &amdgpu_connector->base,1790&amdgpu_connector_vga_funcs,1791connector_type,1792ddc);1793drm_connector_helper_add(&amdgpu_connector->base, &amdgpu_connector_vga_helper_funcs);1794amdgpu_connector->dac_load_detect = true;1795drm_object_attach_property(&amdgpu_connector->base.base,1796adev->mode_info.load_detect_property,17971);1798drm_object_attach_property(&amdgpu_connector->base.base,1799dev->mode_config.scaling_mode_property,1800DRM_MODE_SCALE_NONE);1801/* no HPD on analog connectors */1802amdgpu_connector->hpd.hpd = AMDGPU_HPD_NONE;1803connector->interlace_allowed = true;1804connector->doublescan_allowed = true;1805break;1806case DRM_MODE_CONNECTOR_DVIA:1807if (i2c_bus->valid) {1808amdgpu_connector->ddc_bus = amdgpu_i2c_lookup(adev, i2c_bus);1809if (!amdgpu_connector->ddc_bus)1810DRM_ERROR("DVIA: Failed to assign ddc bus! Check dmesg for i2c errors.\n");1811else1812ddc = &amdgpu_connector->ddc_bus->adapter;1813}1814drm_connector_init_with_ddc(dev, &amdgpu_connector->base,1815&amdgpu_connector_vga_funcs,1816connector_type,1817ddc);1818drm_connector_helper_add(&amdgpu_connector->base, &amdgpu_connector_vga_helper_funcs);1819amdgpu_connector->dac_load_detect = true;1820drm_object_attach_property(&amdgpu_connector->base.base,1821adev->mode_info.load_detect_property,18221);1823drm_object_attach_property(&amdgpu_connector->base.base,1824dev->mode_config.scaling_mode_property,1825DRM_MODE_SCALE_NONE);1826/* no HPD on analog connectors */1827amdgpu_connector->hpd.hpd = AMDGPU_HPD_NONE;1828connector->interlace_allowed = true;1829connector->doublescan_allowed = true;1830break;1831case DRM_MODE_CONNECTOR_DVII:1832case DRM_MODE_CONNECTOR_DVID:1833amdgpu_dig_connector = kzalloc(sizeof(struct amdgpu_connector_atom_dig), GFP_KERNEL);1834if (!amdgpu_dig_connector)1835goto failed;1836amdgpu_connector->con_priv = amdgpu_dig_connector;1837if (i2c_bus->valid) {1838amdgpu_connector->ddc_bus = amdgpu_i2c_lookup(adev, i2c_bus);1839if (!amdgpu_connector->ddc_bus)1840DRM_ERROR("DVI: Failed to assign ddc bus! Check dmesg for i2c errors.\n");1841else1842ddc = &amdgpu_connector->ddc_bus->adapter;1843}1844drm_connector_init_with_ddc(dev, &amdgpu_connector->base,1845&amdgpu_connector_dvi_funcs,1846connector_type,1847ddc);1848drm_connector_helper_add(&amdgpu_connector->base, &amdgpu_connector_dvi_helper_funcs);1849subpixel_order = SubPixelHorizontalRGB;1850drm_object_attach_property(&amdgpu_connector->base.base,1851adev->mode_info.coherent_mode_property,18521);1853drm_object_attach_property(&amdgpu_connector->base.base,1854adev->mode_info.underscan_property,1855UNDERSCAN_OFF);1856drm_object_attach_property(&amdgpu_connector->base.base,1857adev->mode_info.underscan_hborder_property,18580);1859drm_object_attach_property(&amdgpu_connector->base.base,1860adev->mode_info.underscan_vborder_property,18610);1862drm_object_attach_property(&amdgpu_connector->base.base,1863dev->mode_config.scaling_mode_property,1864DRM_MODE_SCALE_NONE);18651866if (amdgpu_audio != 0) {1867drm_object_attach_property(&amdgpu_connector->base.base,1868adev->mode_info.audio_property,1869AMDGPU_AUDIO_AUTO);1870amdgpu_connector->audio = AMDGPU_AUDIO_AUTO;1871}1872drm_object_attach_property(&amdgpu_connector->base.base,1873adev->mode_info.dither_property,1874AMDGPU_FMT_DITHER_DISABLE);1875if (connector_type == DRM_MODE_CONNECTOR_DVII) {1876amdgpu_connector->dac_load_detect = true;1877drm_object_attach_property(&amdgpu_connector->base.base,1878adev->mode_info.load_detect_property,18791);1880}1881connector->interlace_allowed = true;1882if (connector_type == DRM_MODE_CONNECTOR_DVII)1883connector->doublescan_allowed = true;1884else1885connector->doublescan_allowed = false;1886break;1887case DRM_MODE_CONNECTOR_HDMIA:1888case DRM_MODE_CONNECTOR_HDMIB:1889amdgpu_dig_connector = kzalloc(sizeof(struct amdgpu_connector_atom_dig), GFP_KERNEL);1890if (!amdgpu_dig_connector)1891goto failed;1892amdgpu_connector->con_priv = amdgpu_dig_connector;1893if (i2c_bus->valid) {1894amdgpu_connector->ddc_bus = amdgpu_i2c_lookup(adev, i2c_bus);1895if (!amdgpu_connector->ddc_bus)1896DRM_ERROR("HDMI: Failed to assign ddc bus! Check dmesg for i2c errors.\n");1897else1898ddc = &amdgpu_connector->ddc_bus->adapter;1899}1900drm_connector_init_with_ddc(dev, &amdgpu_connector->base,1901&amdgpu_connector_dvi_funcs,1902connector_type,1903ddc);1904drm_connector_helper_add(&amdgpu_connector->base, &amdgpu_connector_dvi_helper_funcs);1905drm_object_attach_property(&amdgpu_connector->base.base,1906adev->mode_info.coherent_mode_property,19071);1908drm_object_attach_property(&amdgpu_connector->base.base,1909adev->mode_info.underscan_property,1910UNDERSCAN_OFF);1911drm_object_attach_property(&amdgpu_connector->base.base,1912adev->mode_info.underscan_hborder_property,19130);1914drm_object_attach_property(&amdgpu_connector->base.base,1915adev->mode_info.underscan_vborder_property,19160);1917drm_object_attach_property(&amdgpu_connector->base.base,1918dev->mode_config.scaling_mode_property,1919DRM_MODE_SCALE_NONE);1920if (amdgpu_audio != 0) {1921drm_object_attach_property(&amdgpu_connector->base.base,1922adev->mode_info.audio_property,1923AMDGPU_AUDIO_AUTO);1924amdgpu_connector->audio = AMDGPU_AUDIO_AUTO;1925}1926drm_object_attach_property(&amdgpu_connector->base.base,1927adev->mode_info.dither_property,1928AMDGPU_FMT_DITHER_DISABLE);1929subpixel_order = SubPixelHorizontalRGB;1930connector->interlace_allowed = true;1931if (connector_type == DRM_MODE_CONNECTOR_HDMIB)1932connector->doublescan_allowed = true;1933else1934connector->doublescan_allowed = false;1935break;1936case DRM_MODE_CONNECTOR_DisplayPort:1937amdgpu_dig_connector = kzalloc(sizeof(struct amdgpu_connector_atom_dig), GFP_KERNEL);1938if (!amdgpu_dig_connector)1939goto failed;1940amdgpu_connector->con_priv = amdgpu_dig_connector;1941if (i2c_bus->valid) {1942amdgpu_connector->ddc_bus = amdgpu_i2c_lookup(adev, i2c_bus);1943if (amdgpu_connector->ddc_bus) {1944has_aux = true;1945ddc = &amdgpu_connector->ddc_bus->adapter;1946} else {1947DRM_ERROR("DP: Failed to assign ddc bus! Check dmesg for i2c errors.\n");1948}1949}1950drm_connector_init_with_ddc(dev, &amdgpu_connector->base,1951&amdgpu_connector_dp_funcs,1952connector_type,1953ddc);1954drm_connector_helper_add(&amdgpu_connector->base, &amdgpu_connector_dp_helper_funcs);1955subpixel_order = SubPixelHorizontalRGB;1956drm_object_attach_property(&amdgpu_connector->base.base,1957adev->mode_info.coherent_mode_property,19581);1959drm_object_attach_property(&amdgpu_connector->base.base,1960adev->mode_info.underscan_property,1961UNDERSCAN_OFF);1962drm_object_attach_property(&amdgpu_connector->base.base,1963adev->mode_info.underscan_hborder_property,19640);1965drm_object_attach_property(&amdgpu_connector->base.base,1966adev->mode_info.underscan_vborder_property,19670);1968drm_object_attach_property(&amdgpu_connector->base.base,1969dev->mode_config.scaling_mode_property,1970DRM_MODE_SCALE_NONE);1971if (amdgpu_audio != 0) {1972drm_object_attach_property(&amdgpu_connector->base.base,1973adev->mode_info.audio_property,1974AMDGPU_AUDIO_AUTO);1975amdgpu_connector->audio = AMDGPU_AUDIO_AUTO;1976}1977drm_object_attach_property(&amdgpu_connector->base.base,1978adev->mode_info.dither_property,1979AMDGPU_FMT_DITHER_DISABLE);1980connector->interlace_allowed = true;1981/* in theory with a DP to VGA converter... */1982connector->doublescan_allowed = false;1983break;1984case DRM_MODE_CONNECTOR_eDP:1985amdgpu_dig_connector = kzalloc(sizeof(struct amdgpu_connector_atom_dig), GFP_KERNEL);1986if (!amdgpu_dig_connector)1987goto failed;1988amdgpu_connector->con_priv = amdgpu_dig_connector;1989if (i2c_bus->valid) {1990amdgpu_connector->ddc_bus = amdgpu_i2c_lookup(adev, i2c_bus);1991if (amdgpu_connector->ddc_bus) {1992has_aux = true;1993ddc = &amdgpu_connector->ddc_bus->adapter;1994} else {1995DRM_ERROR("DP: Failed to assign ddc bus! Check dmesg for i2c errors.\n");1996}1997}1998drm_connector_init_with_ddc(dev, &amdgpu_connector->base,1999&amdgpu_connector_edp_funcs,2000connector_type,2001ddc);2002drm_connector_helper_add(&amdgpu_connector->base, &amdgpu_connector_dp_helper_funcs);2003drm_object_attach_property(&amdgpu_connector->base.base,2004dev->mode_config.scaling_mode_property,2005DRM_MODE_SCALE_FULLSCREEN);2006subpixel_order = SubPixelHorizontalRGB;2007connector->interlace_allowed = false;2008connector->doublescan_allowed = false;2009break;2010case DRM_MODE_CONNECTOR_LVDS:2011amdgpu_dig_connector = kzalloc(sizeof(struct amdgpu_connector_atom_dig), GFP_KERNEL);2012if (!amdgpu_dig_connector)2013goto failed;2014amdgpu_connector->con_priv = amdgpu_dig_connector;2015if (i2c_bus->valid) {2016amdgpu_connector->ddc_bus = amdgpu_i2c_lookup(adev, i2c_bus);2017if (!amdgpu_connector->ddc_bus)2018DRM_ERROR("LVDS: Failed to assign ddc bus! Check dmesg for i2c errors.\n");2019else2020ddc = &amdgpu_connector->ddc_bus->adapter;2021}2022drm_connector_init_with_ddc(dev, &amdgpu_connector->base,2023&amdgpu_connector_lvds_funcs,2024connector_type,2025ddc);2026drm_connector_helper_add(&amdgpu_connector->base, &amdgpu_connector_lvds_helper_funcs);2027drm_object_attach_property(&amdgpu_connector->base.base,2028dev->mode_config.scaling_mode_property,2029DRM_MODE_SCALE_FULLSCREEN);2030subpixel_order = SubPixelHorizontalRGB;2031connector->interlace_allowed = false;2032connector->doublescan_allowed = false;2033break;2034}2035}20362037if (amdgpu_connector->hpd.hpd == AMDGPU_HPD_NONE) {2038if (i2c_bus->valid) {2039connector->polled = DRM_CONNECTOR_POLL_CONNECT |2040DRM_CONNECTOR_POLL_DISCONNECT;2041}2042} else2043connector->polled = DRM_CONNECTOR_POLL_HPD;20442045connector->display_info.subpixel_order = subpixel_order;20462047if (has_aux)2048amdgpu_atombios_dp_aux_init(amdgpu_connector);20492050if (connector_type == DRM_MODE_CONNECTOR_DisplayPort ||2051connector_type == DRM_MODE_CONNECTOR_eDP) {2052drm_connector_attach_dp_subconnector_property(&amdgpu_connector->base);2053}20542055return;20562057failed:2058drm_connector_cleanup(connector);2059kfree(connector);2060}206120622063