Path: blob/master/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c
49213 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_put_autosuspend(connector->dev->dev);738739return ret;740}741742static void amdgpu_connector_unregister(struct drm_connector *connector)743{744struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector);745746if (amdgpu_connector->ddc_bus && amdgpu_connector->ddc_bus->has_aux) {747drm_dp_aux_unregister(&amdgpu_connector->ddc_bus->aux);748amdgpu_connector->ddc_bus->has_aux = false;749}750}751752static void amdgpu_connector_destroy(struct drm_connector *connector)753{754struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector);755756amdgpu_connector_free_edid(connector);757kfree(amdgpu_connector->con_priv);758drm_connector_unregister(connector);759drm_connector_cleanup(connector);760kfree(connector);761}762763static int amdgpu_connector_set_lcd_property(struct drm_connector *connector,764struct drm_property *property,765uint64_t value)766{767struct drm_device *dev = connector->dev;768struct amdgpu_encoder *amdgpu_encoder;769enum amdgpu_rmx_type rmx_type;770771DRM_DEBUG_KMS("\n");772if (property != dev->mode_config.scaling_mode_property)773return 0;774775if (connector->encoder)776amdgpu_encoder = to_amdgpu_encoder(connector->encoder);777else {778const struct drm_connector_helper_funcs *connector_funcs = connector->helper_private;779780amdgpu_encoder = to_amdgpu_encoder(connector_funcs->best_encoder(connector));781}782783switch (value) {784case DRM_MODE_SCALE_NONE:785rmx_type = RMX_OFF;786break;787case DRM_MODE_SCALE_CENTER:788rmx_type = RMX_CENTER;789break;790case DRM_MODE_SCALE_ASPECT:791rmx_type = RMX_ASPECT;792break;793default:794case DRM_MODE_SCALE_FULLSCREEN:795rmx_type = RMX_FULL;796break;797}798799if (amdgpu_encoder->rmx_type == rmx_type)800return 0;801802amdgpu_encoder->rmx_type = rmx_type;803804amdgpu_connector_property_change_mode(&amdgpu_encoder->base);805return 0;806}807808809static const struct drm_connector_helper_funcs amdgpu_connector_lvds_helper_funcs = {810.get_modes = amdgpu_connector_lvds_get_modes,811.mode_valid = amdgpu_connector_lvds_mode_valid,812.best_encoder = amdgpu_connector_best_single_encoder,813};814815static const struct drm_connector_funcs amdgpu_connector_lvds_funcs = {816.dpms = drm_helper_connector_dpms,817.detect = amdgpu_connector_lvds_detect,818.fill_modes = drm_helper_probe_single_connector_modes,819.early_unregister = amdgpu_connector_unregister,820.destroy = amdgpu_connector_destroy,821.set_property = amdgpu_connector_set_lcd_property,822};823824static int amdgpu_connector_vga_get_modes(struct drm_connector *connector)825{826int ret;827828amdgpu_connector_get_edid(connector);829ret = amdgpu_connector_ddc_get_modes(connector);830amdgpu_get_native_mode(connector);831832return ret;833}834835static enum drm_mode_status amdgpu_connector_vga_mode_valid(struct drm_connector *connector,836const struct drm_display_mode *mode)837{838struct drm_device *dev = connector->dev;839struct amdgpu_device *adev = drm_to_adev(dev);840841/* XXX check mode bandwidth */842843if ((mode->clock / 10) > adev->clock.max_pixel_clock)844return MODE_CLOCK_HIGH;845846return MODE_OK;847}848849static enum drm_connector_status850amdgpu_connector_vga_detect(struct drm_connector *connector, bool force)851{852struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector);853struct drm_encoder *encoder;854const struct drm_encoder_helper_funcs *encoder_funcs;855bool dret = false;856enum drm_connector_status ret = connector_status_disconnected;857int r;858859if (!drm_kms_helper_is_poll_worker()) {860r = pm_runtime_get_sync(connector->dev->dev);861if (r < 0) {862pm_runtime_put_autosuspend(connector->dev->dev);863return connector_status_disconnected;864}865}866867encoder = amdgpu_connector_best_single_encoder(connector);868if (!encoder)869ret = connector_status_disconnected;870871if (amdgpu_connector->ddc_bus)872dret = amdgpu_display_ddc_probe(amdgpu_connector, false);873if (dret) {874amdgpu_connector->detected_by_load = false;875amdgpu_connector_free_edid(connector);876amdgpu_connector_get_edid(connector);877878if (!amdgpu_connector->edid) {879DRM_ERROR("%s: probed a monitor but no|invalid EDID\n",880connector->name);881ret = connector_status_connected;882} else {883amdgpu_connector->use_digital =884!!(amdgpu_connector->edid->input & DRM_EDID_INPUT_DIGITAL);885886/* some oems have boards with separate digital and analog connectors887* with a shared ddc line (often vga + hdmi)888*/889if (amdgpu_connector->use_digital && amdgpu_connector->shared_ddc) {890amdgpu_connector_free_edid(connector);891ret = connector_status_disconnected;892} else {893ret = connector_status_connected;894}895}896} else {897898/* if we aren't forcing don't do destructive polling */899if (!force) {900/* only return the previous status if we last901* detected a monitor via load.902*/903if (amdgpu_connector->detected_by_load)904ret = connector->status;905goto out;906}907908if (amdgpu_connector->dac_load_detect && encoder) {909encoder_funcs = encoder->helper_private;910ret = encoder_funcs->detect(encoder, connector);911if (ret != connector_status_disconnected)912amdgpu_connector->detected_by_load = true;913}914}915916amdgpu_connector_update_scratch_regs(connector, ret);917918out:919if (!drm_kms_helper_is_poll_worker())920pm_runtime_put_autosuspend(connector->dev->dev);921922return ret;923}924925static const struct drm_connector_helper_funcs amdgpu_connector_vga_helper_funcs = {926.get_modes = amdgpu_connector_vga_get_modes,927.mode_valid = amdgpu_connector_vga_mode_valid,928.best_encoder = amdgpu_connector_best_single_encoder,929};930931static const struct drm_connector_funcs amdgpu_connector_vga_funcs = {932.dpms = drm_helper_connector_dpms,933.detect = amdgpu_connector_vga_detect,934.fill_modes = drm_helper_probe_single_connector_modes,935.early_unregister = amdgpu_connector_unregister,936.destroy = amdgpu_connector_destroy,937.set_property = amdgpu_connector_set_property,938};939940static bool941amdgpu_connector_check_hpd_status_unchanged(struct drm_connector *connector)942{943struct drm_device *dev = connector->dev;944struct amdgpu_device *adev = drm_to_adev(dev);945struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector);946enum drm_connector_status status;947948if (amdgpu_connector->hpd.hpd != AMDGPU_HPD_NONE) {949if (amdgpu_display_hpd_sense(adev, amdgpu_connector->hpd.hpd))950status = connector_status_connected;951else952status = connector_status_disconnected;953if (connector->status == status)954return true;955}956957return false;958}959960static void amdgpu_connector_shared_ddc(enum drm_connector_status *status,961struct drm_connector *connector,962struct amdgpu_connector *amdgpu_connector)963{964struct drm_connector *list_connector;965struct drm_connector_list_iter iter;966struct amdgpu_connector *list_amdgpu_connector;967struct drm_device *dev = connector->dev;968struct amdgpu_device *adev = drm_to_adev(dev);969970if (amdgpu_connector->shared_ddc && *status == connector_status_connected) {971drm_connector_list_iter_begin(dev, &iter);972drm_for_each_connector_iter(list_connector,973&iter) {974if (connector == list_connector)975continue;976list_amdgpu_connector = to_amdgpu_connector(list_connector);977if (list_amdgpu_connector->shared_ddc &&978list_amdgpu_connector->ddc_bus->rec.i2c_id ==979amdgpu_connector->ddc_bus->rec.i2c_id) {980/* cases where both connectors are digital */981if (list_connector->connector_type != DRM_MODE_CONNECTOR_VGA) {982/* hpd is our only option in this case */983if (!amdgpu_display_hpd_sense(adev,984amdgpu_connector->hpd.hpd)) {985amdgpu_connector_free_edid(connector);986*status = connector_status_disconnected;987}988}989}990}991drm_connector_list_iter_end(&iter);992}993}994995/*996* DVI is complicated997* Do a DDC probe, if DDC probe passes, get the full EDID so998* we can do analog/digital monitor detection at this point.999* If the monitor is an analog monitor or we got no DDC,1000* we need to find the DAC encoder object for this connector.1001* If we got no DDC, we do load detection on the DAC encoder object.1002* If we got analog DDC or load detection passes on the DAC encoder1003* we have to check if this analog encoder is shared with anyone else (TV)1004* if its shared we have to set the other connector to disconnected.1005*/1006static enum drm_connector_status1007amdgpu_connector_dvi_detect(struct drm_connector *connector, bool force)1008{1009struct drm_device *dev = connector->dev;1010struct amdgpu_device *adev = drm_to_adev(dev);1011struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector);1012const struct drm_encoder_helper_funcs *encoder_funcs;1013int r;1014enum drm_connector_status ret = connector_status_disconnected;1015bool dret = false, broken_edid = false;10161017if (!drm_kms_helper_is_poll_worker()) {1018r = pm_runtime_get_sync(connector->dev->dev);1019if (r < 0) {1020pm_runtime_put_autosuspend(connector->dev->dev);1021return connector_status_disconnected;1022}1023}10241025if (amdgpu_connector->detected_hpd_without_ddc) {1026force = true;1027amdgpu_connector->detected_hpd_without_ddc = false;1028}10291030if (!force && amdgpu_connector_check_hpd_status_unchanged(connector)) {1031ret = connector->status;1032goto exit;1033}10341035if (amdgpu_connector->ddc_bus) {1036dret = amdgpu_display_ddc_probe(amdgpu_connector, false);10371038/* Sometimes the pins required for the DDC probe on DVI1039* connectors don't make contact at the same time that the ones1040* for HPD do. If the DDC probe fails even though we had an HPD1041* signal, try again later1042*/1043if (!dret && !force &&1044amdgpu_display_hpd_sense(adev, amdgpu_connector->hpd.hpd)) {1045DRM_DEBUG_KMS("hpd detected without ddc, retrying in 1 second\n");1046amdgpu_connector->detected_hpd_without_ddc = true;1047schedule_delayed_work(&adev->hotplug_work,1048msecs_to_jiffies(1000));1049goto exit;1050}1051}1052if (dret) {1053amdgpu_connector->detected_by_load = false;1054amdgpu_connector_free_edid(connector);1055amdgpu_connector_get_edid(connector);10561057if (!amdgpu_connector->edid) {1058DRM_ERROR("%s: probed a monitor but no|invalid EDID\n",1059connector->name);1060ret = connector_status_connected;1061broken_edid = true; /* defer use_digital to later */1062} else {1063amdgpu_connector->use_digital =1064!!(amdgpu_connector->edid->input & DRM_EDID_INPUT_DIGITAL);10651066/* some oems have boards with separate digital and analog connectors1067* with a shared ddc line (often vga + hdmi)1068*/1069if ((!amdgpu_connector->use_digital) && amdgpu_connector->shared_ddc) {1070amdgpu_connector_free_edid(connector);1071ret = connector_status_disconnected;1072} else {1073ret = connector_status_connected;1074}10751076/* This gets complicated. We have boards with VGA + HDMI with a1077* shared DDC line and we have boards with DVI-D + HDMI with a shared1078* DDC line. The latter is more complex because with DVI<->HDMI adapters1079* you don't really know what's connected to which port as both are digital.1080*/1081amdgpu_connector_shared_ddc(&ret, connector, amdgpu_connector);1082}1083}10841085if ((ret == connector_status_connected) && (amdgpu_connector->use_digital == true))1086goto out;10871088/* DVI-D and HDMI-A are digital only */1089if ((connector->connector_type == DRM_MODE_CONNECTOR_DVID) ||1090(connector->connector_type == DRM_MODE_CONNECTOR_HDMIA))1091goto out;10921093/* if we aren't forcing don't do destructive polling */1094if (!force) {1095/* only return the previous status if we last1096* detected a monitor via load.1097*/1098if (amdgpu_connector->detected_by_load)1099ret = connector->status;1100goto out;1101}11021103/* find analog encoder */1104if (amdgpu_connector->dac_load_detect) {1105struct drm_encoder *encoder;11061107drm_connector_for_each_possible_encoder(connector, encoder) {1108if (encoder->encoder_type != DRM_MODE_ENCODER_DAC &&1109encoder->encoder_type != DRM_MODE_ENCODER_TVDAC)1110continue;11111112encoder_funcs = encoder->helper_private;1113if (encoder_funcs->detect) {1114if (!broken_edid) {1115if (ret != connector_status_connected) {1116/* deal with analog monitors without DDC */1117ret = encoder_funcs->detect(encoder, connector);1118if (ret == connector_status_connected) {1119amdgpu_connector->use_digital = false;1120}1121if (ret != connector_status_disconnected)1122amdgpu_connector->detected_by_load = true;1123}1124} else {1125enum drm_connector_status lret;1126/* assume digital unless load detected otherwise */1127amdgpu_connector->use_digital = true;1128lret = encoder_funcs->detect(encoder, connector);1129DRM_DEBUG_KMS("load_detect %x returned: %x\n",1130encoder->encoder_type, lret);1131if (lret == connector_status_connected)1132amdgpu_connector->use_digital = false;1133}1134break;1135}1136}1137}11381139out:1140/* updated in get modes as well since we need to know if it's analog or digital */1141amdgpu_connector_update_scratch_regs(connector, ret);11421143exit:1144if (!drm_kms_helper_is_poll_worker())1145pm_runtime_put_autosuspend(connector->dev->dev);11461147return ret;1148}11491150/* okay need to be smart in here about which encoder to pick */1151static struct drm_encoder *1152amdgpu_connector_dvi_encoder(struct drm_connector *connector)1153{1154struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector);1155struct drm_encoder *encoder;11561157drm_connector_for_each_possible_encoder(connector, encoder) {1158if (amdgpu_connector->use_digital == true) {1159if (encoder->encoder_type == DRM_MODE_ENCODER_TMDS)1160return encoder;1161} else {1162if (encoder->encoder_type == DRM_MODE_ENCODER_DAC ||1163encoder->encoder_type == DRM_MODE_ENCODER_TVDAC)1164return encoder;1165}1166}11671168/* see if we have a default encoder TODO */11691170/* then check use digitial */1171/* pick the first one */1172drm_connector_for_each_possible_encoder(connector, encoder)1173return encoder;11741175return NULL;1176}11771178static void amdgpu_connector_dvi_force(struct drm_connector *connector)1179{1180struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector);11811182if (connector->force == DRM_FORCE_ON)1183amdgpu_connector->use_digital = false;1184if (connector->force == DRM_FORCE_ON_DIGITAL)1185amdgpu_connector->use_digital = true;1186}11871188/**1189* amdgpu_max_hdmi_pixel_clock - Return max supported HDMI (TMDS) pixel clock1190* @adev: pointer to amdgpu_device1191*1192* Return: maximum supported HDMI (TMDS) pixel clock in KHz.1193*/1194static int amdgpu_max_hdmi_pixel_clock(const struct amdgpu_device *adev)1195{1196if (adev->asic_type >= CHIP_POLARIS10)1197return 600000;1198else if (adev->asic_type >= CHIP_TONGA)1199return 300000;1200else1201return 297000;1202}12031204/**1205* amdgpu_connector_dvi_mode_valid - Validate a mode on DVI/HDMI connectors1206* @connector: DRM connector to validate the mode on1207* @mode: display mode to validate1208*1209* Validate the given display mode on DVI and HDMI connectors, including1210* analog signals on DVI-I.1211*1212* Return: drm_mode_status indicating whether the mode is valid.1213*/1214static enum drm_mode_status amdgpu_connector_dvi_mode_valid(struct drm_connector *connector,1215const struct drm_display_mode *mode)1216{1217struct drm_device *dev = connector->dev;1218struct amdgpu_device *adev = drm_to_adev(dev);1219struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector);1220const int max_hdmi_pixel_clock = amdgpu_max_hdmi_pixel_clock(adev);1221const int max_dvi_single_link_pixel_clock = 165000;1222int max_digital_pixel_clock_khz;12231224/* XXX check mode bandwidth */12251226if (amdgpu_connector->use_digital) {1227switch (amdgpu_connector->connector_object_id) {1228case CONNECTOR_OBJECT_ID_HDMI_TYPE_A:1229max_digital_pixel_clock_khz = max_hdmi_pixel_clock;1230break;1231case CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I:1232case CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D:1233max_digital_pixel_clock_khz = max_dvi_single_link_pixel_clock;1234break;1235case CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_I:1236case CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D:1237case CONNECTOR_OBJECT_ID_HDMI_TYPE_B:1238max_digital_pixel_clock_khz = max_dvi_single_link_pixel_clock * 2;1239break;1240}12411242/* When the display EDID claims that it's an HDMI display,1243* we use the HDMI encoder mode of the display HW,1244* so we should verify against the max HDMI clock here.1245*/1246if (connector->display_info.is_hdmi)1247max_digital_pixel_clock_khz = max_hdmi_pixel_clock;12481249if (mode->clock > max_digital_pixel_clock_khz)1250return MODE_CLOCK_HIGH;1251}12521253/* check against the max pixel clock */1254if ((mode->clock / 10) > adev->clock.max_pixel_clock)1255return MODE_CLOCK_HIGH;12561257return MODE_OK;1258}12591260static const struct drm_connector_helper_funcs amdgpu_connector_dvi_helper_funcs = {1261.get_modes = amdgpu_connector_vga_get_modes,1262.mode_valid = amdgpu_connector_dvi_mode_valid,1263.best_encoder = amdgpu_connector_dvi_encoder,1264};12651266static const struct drm_connector_funcs amdgpu_connector_dvi_funcs = {1267.dpms = drm_helper_connector_dpms,1268.detect = amdgpu_connector_dvi_detect,1269.fill_modes = drm_helper_probe_single_connector_modes,1270.set_property = amdgpu_connector_set_property,1271.early_unregister = amdgpu_connector_unregister,1272.destroy = amdgpu_connector_destroy,1273.force = amdgpu_connector_dvi_force,1274};12751276static int amdgpu_connector_dp_get_modes(struct drm_connector *connector)1277{1278struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector);1279struct amdgpu_connector_atom_dig *amdgpu_dig_connector = amdgpu_connector->con_priv;1280struct drm_encoder *encoder = amdgpu_connector_best_single_encoder(connector);1281int ret;12821283if ((connector->connector_type == DRM_MODE_CONNECTOR_eDP) ||1284(connector->connector_type == DRM_MODE_CONNECTOR_LVDS)) {1285struct drm_display_mode *mode;12861287if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) {1288if (!amdgpu_dig_connector->edp_on)1289amdgpu_atombios_encoder_set_edp_panel_power(connector,1290ATOM_TRANSMITTER_ACTION_POWER_ON);1291amdgpu_connector_get_edid(connector);1292ret = amdgpu_connector_ddc_get_modes(connector);1293if (!amdgpu_dig_connector->edp_on)1294amdgpu_atombios_encoder_set_edp_panel_power(connector,1295ATOM_TRANSMITTER_ACTION_POWER_OFF);1296} else {1297/* need to setup ddc on the bridge */1298if (amdgpu_connector_encoder_get_dp_bridge_encoder_id(connector) !=1299ENCODER_OBJECT_ID_NONE) {1300if (encoder)1301amdgpu_atombios_encoder_setup_ext_encoder_ddc(encoder);1302}1303amdgpu_connector_get_edid(connector);1304ret = amdgpu_connector_ddc_get_modes(connector);1305}13061307if (ret > 0) {1308if (encoder) {1309amdgpu_connector_fixup_lcd_native_mode(encoder, connector);1310/* add scaled modes */1311amdgpu_connector_add_common_modes(encoder, connector);1312}1313return ret;1314}13151316if (!encoder)1317return 0;13181319/* we have no EDID modes */1320mode = amdgpu_connector_lcd_native_mode(encoder);1321if (mode) {1322ret = 1;1323drm_mode_probed_add(connector, mode);1324/* add the width/height from vbios tables if available */1325connector->display_info.width_mm = mode->width_mm;1326connector->display_info.height_mm = mode->height_mm;1327/* add scaled modes */1328amdgpu_connector_add_common_modes(encoder, connector);1329}1330} else {1331/* need to setup ddc on the bridge */1332if (amdgpu_connector_encoder_get_dp_bridge_encoder_id(connector) !=1333ENCODER_OBJECT_ID_NONE) {1334if (encoder)1335amdgpu_atombios_encoder_setup_ext_encoder_ddc(encoder);1336}1337amdgpu_connector_get_edid(connector);1338ret = amdgpu_connector_ddc_get_modes(connector);13391340amdgpu_get_native_mode(connector);1341}13421343return ret;1344}13451346u16 amdgpu_connector_encoder_get_dp_bridge_encoder_id(struct drm_connector *connector)1347{1348struct drm_encoder *encoder;1349struct amdgpu_encoder *amdgpu_encoder;13501351drm_connector_for_each_possible_encoder(connector, encoder) {1352amdgpu_encoder = to_amdgpu_encoder(encoder);13531354switch (amdgpu_encoder->encoder_id) {1355case ENCODER_OBJECT_ID_TRAVIS:1356case ENCODER_OBJECT_ID_NUTMEG:1357return amdgpu_encoder->encoder_id;1358default:1359break;1360}1361}13621363return ENCODER_OBJECT_ID_NONE;1364}13651366static bool amdgpu_connector_encoder_is_hbr2(struct drm_connector *connector)1367{1368struct drm_encoder *encoder;1369struct amdgpu_encoder *amdgpu_encoder;1370bool found = false;13711372drm_connector_for_each_possible_encoder(connector, encoder) {1373amdgpu_encoder = to_amdgpu_encoder(encoder);1374if (amdgpu_encoder->caps & ATOM_ENCODER_CAP_RECORD_HBR2)1375found = true;1376}13771378return found;1379}13801381bool amdgpu_connector_is_dp12_capable(struct drm_connector *connector)1382{1383struct drm_device *dev = connector->dev;1384struct amdgpu_device *adev = drm_to_adev(dev);13851386if ((adev->clock.default_dispclk >= 53900) &&1387amdgpu_connector_encoder_is_hbr2(connector)) {1388return true;1389}13901391return false;1392}13931394static enum drm_connector_status1395amdgpu_connector_dp_detect(struct drm_connector *connector, bool force)1396{1397struct drm_device *dev = connector->dev;1398struct amdgpu_device *adev = drm_to_adev(dev);1399struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector);1400enum drm_connector_status ret = connector_status_disconnected;1401struct amdgpu_connector_atom_dig *amdgpu_dig_connector = amdgpu_connector->con_priv;1402struct drm_encoder *encoder = amdgpu_connector_best_single_encoder(connector);1403int r;14041405if (!drm_kms_helper_is_poll_worker()) {1406r = pm_runtime_get_sync(connector->dev->dev);1407if (r < 0) {1408pm_runtime_put_autosuspend(connector->dev->dev);1409return connector_status_disconnected;1410}1411}14121413if (!force && amdgpu_connector_check_hpd_status_unchanged(connector)) {1414ret = connector->status;1415goto out;1416}14171418amdgpu_connector_free_edid(connector);14191420if ((connector->connector_type == DRM_MODE_CONNECTOR_eDP) ||1421(connector->connector_type == DRM_MODE_CONNECTOR_LVDS)) {1422if (encoder) {1423struct amdgpu_encoder *amdgpu_encoder = to_amdgpu_encoder(encoder);1424struct drm_display_mode *native_mode = &amdgpu_encoder->native_mode;14251426/* check if panel is valid */1427if (native_mode->hdisplay >= 320 && native_mode->vdisplay >= 240)1428ret = connector_status_connected;1429}1430/* eDP is always DP */1431amdgpu_dig_connector->dp_sink_type = CONNECTOR_OBJECT_ID_DISPLAYPORT;1432if (!amdgpu_dig_connector->edp_on)1433amdgpu_atombios_encoder_set_edp_panel_power(connector,1434ATOM_TRANSMITTER_ACTION_POWER_ON);1435if (!amdgpu_atombios_dp_get_dpcd(amdgpu_connector))1436ret = connector_status_connected;1437if (!amdgpu_dig_connector->edp_on)1438amdgpu_atombios_encoder_set_edp_panel_power(connector,1439ATOM_TRANSMITTER_ACTION_POWER_OFF);1440} else if (amdgpu_connector_encoder_get_dp_bridge_encoder_id(connector) !=1441ENCODER_OBJECT_ID_NONE) {1442/* DP bridges are always DP */1443amdgpu_dig_connector->dp_sink_type = CONNECTOR_OBJECT_ID_DISPLAYPORT;1444/* get the DPCD from the bridge */1445amdgpu_atombios_dp_get_dpcd(amdgpu_connector);14461447if (encoder) {1448/* setup ddc on the bridge */1449amdgpu_atombios_encoder_setup_ext_encoder_ddc(encoder);1450/* bridge chips are always aux */1451/* try DDC */1452if (amdgpu_display_ddc_probe(amdgpu_connector, true))1453ret = connector_status_connected;1454else if (amdgpu_connector->dac_load_detect) { /* try load detection */1455const struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private;14561457ret = encoder_funcs->detect(encoder, connector);1458}1459}1460} else {1461amdgpu_dig_connector->dp_sink_type =1462amdgpu_atombios_dp_get_sinktype(amdgpu_connector);1463if (amdgpu_display_hpd_sense(adev, amdgpu_connector->hpd.hpd)) {1464ret = connector_status_connected;1465if (amdgpu_dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT)1466amdgpu_atombios_dp_get_dpcd(amdgpu_connector);1467} else {1468if (amdgpu_dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) {1469if (!amdgpu_atombios_dp_get_dpcd(amdgpu_connector))1470ret = connector_status_connected;1471} else {1472/* try non-aux ddc (DP to DVI/HDMI/etc. adapter) */1473if (amdgpu_display_ddc_probe(amdgpu_connector,1474false))1475ret = connector_status_connected;1476}1477}1478}14791480amdgpu_connector_update_scratch_regs(connector, ret);1481out:1482if (!drm_kms_helper_is_poll_worker())1483pm_runtime_put_autosuspend(connector->dev->dev);14841485if (connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort ||1486connector->connector_type == DRM_MODE_CONNECTOR_eDP)1487drm_dp_set_subconnector_property(&amdgpu_connector->base,1488ret,1489amdgpu_dig_connector->dpcd,1490amdgpu_dig_connector->downstream_ports);1491return ret;1492}14931494static enum drm_mode_status amdgpu_connector_dp_mode_valid(struct drm_connector *connector,1495const struct drm_display_mode *mode)1496{1497struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector);1498struct amdgpu_connector_atom_dig *amdgpu_dig_connector = amdgpu_connector->con_priv;14991500/* XXX check mode bandwidth */15011502if ((connector->connector_type == DRM_MODE_CONNECTOR_eDP) ||1503(connector->connector_type == DRM_MODE_CONNECTOR_LVDS)) {1504struct drm_encoder *encoder = amdgpu_connector_best_single_encoder(connector);15051506if ((mode->hdisplay < 320) || (mode->vdisplay < 240))1507return MODE_PANEL;15081509if (encoder) {1510struct amdgpu_encoder *amdgpu_encoder = to_amdgpu_encoder(encoder);1511struct drm_display_mode *native_mode = &amdgpu_encoder->native_mode;15121513/* AVIVO hardware supports downscaling modes larger than the panel1514* to the panel size, but I'm not sure this is desirable.1515*/1516if ((mode->hdisplay > native_mode->hdisplay) ||1517(mode->vdisplay > native_mode->vdisplay))1518return MODE_PANEL;15191520/* if scaling is disabled, block non-native modes */1521if (amdgpu_encoder->rmx_type == RMX_OFF) {1522if ((mode->hdisplay != native_mode->hdisplay) ||1523(mode->vdisplay != native_mode->vdisplay))1524return MODE_PANEL;1525}1526}1527return MODE_OK;1528} else {1529if ((amdgpu_dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) ||1530(amdgpu_dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP)) {1531return amdgpu_atombios_dp_mode_valid_helper(connector, mode);1532} else {1533if (connector->display_info.is_hdmi) {1534/* HDMI 1.3+ supports max clock of 340 Mhz */1535if (mode->clock > 340000)1536return MODE_CLOCK_HIGH;1537} else {1538if (mode->clock > 165000)1539return MODE_CLOCK_HIGH;1540}1541}1542}15431544return MODE_OK;1545}15461547static int1548amdgpu_connector_late_register(struct drm_connector *connector)1549{1550struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector);1551int r = 0;15521553if (amdgpu_connector->ddc_bus->has_aux) {1554amdgpu_connector->ddc_bus->aux.dev = amdgpu_connector->base.kdev;1555r = drm_dp_aux_register(&amdgpu_connector->ddc_bus->aux);1556}15571558return r;1559}15601561static const struct drm_connector_helper_funcs amdgpu_connector_dp_helper_funcs = {1562.get_modes = amdgpu_connector_dp_get_modes,1563.mode_valid = amdgpu_connector_dp_mode_valid,1564.best_encoder = amdgpu_connector_dvi_encoder,1565};15661567static const struct drm_connector_funcs amdgpu_connector_dp_funcs = {1568.dpms = drm_helper_connector_dpms,1569.detect = amdgpu_connector_dp_detect,1570.fill_modes = drm_helper_probe_single_connector_modes,1571.set_property = amdgpu_connector_set_property,1572.early_unregister = amdgpu_connector_unregister,1573.destroy = amdgpu_connector_destroy,1574.force = amdgpu_connector_dvi_force,1575.late_register = amdgpu_connector_late_register,1576};15771578static const struct drm_connector_funcs amdgpu_connector_edp_funcs = {1579.dpms = drm_helper_connector_dpms,1580.detect = amdgpu_connector_dp_detect,1581.fill_modes = drm_helper_probe_single_connector_modes,1582.set_property = amdgpu_connector_set_lcd_property,1583.early_unregister = amdgpu_connector_unregister,1584.destroy = amdgpu_connector_destroy,1585.force = amdgpu_connector_dvi_force,1586.late_register = amdgpu_connector_late_register,1587};15881589void1590amdgpu_connector_add(struct amdgpu_device *adev,1591uint32_t connector_id,1592uint32_t supported_device,1593int connector_type,1594struct amdgpu_i2c_bus_rec *i2c_bus,1595uint16_t connector_object_id,1596struct amdgpu_hpd *hpd,1597struct amdgpu_router *router)1598{1599struct drm_device *dev = adev_to_drm(adev);1600struct drm_connector *connector;1601struct drm_connector_list_iter iter;1602struct amdgpu_connector *amdgpu_connector;1603struct amdgpu_connector_atom_dig *amdgpu_dig_connector;1604struct drm_encoder *encoder;1605struct amdgpu_encoder *amdgpu_encoder;1606struct i2c_adapter *ddc = NULL;1607uint32_t subpixel_order = SubPixelNone;1608bool shared_ddc = false;1609bool is_dp_bridge = false;1610bool has_aux = false;16111612if (connector_type == DRM_MODE_CONNECTOR_Unknown)1613return;16141615/* see if we already added it */1616drm_connector_list_iter_begin(dev, &iter);1617drm_for_each_connector_iter(connector, &iter) {1618amdgpu_connector = to_amdgpu_connector(connector);1619if (amdgpu_connector->connector_id == connector_id) {1620amdgpu_connector->devices |= supported_device;1621drm_connector_list_iter_end(&iter);1622return;1623}1624if (amdgpu_connector->ddc_bus && i2c_bus->valid) {1625if (amdgpu_connector->ddc_bus->rec.i2c_id == i2c_bus->i2c_id) {1626amdgpu_connector->shared_ddc = true;1627shared_ddc = true;1628}1629if (amdgpu_connector->router_bus && router->ddc_valid &&1630(amdgpu_connector->router.router_id == router->router_id)) {1631amdgpu_connector->shared_ddc = false;1632shared_ddc = false;1633}1634}1635}1636drm_connector_list_iter_end(&iter);16371638/* check if it's a dp bridge */1639list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {1640amdgpu_encoder = to_amdgpu_encoder(encoder);1641if (amdgpu_encoder->devices & supported_device) {1642switch (amdgpu_encoder->encoder_id) {1643case ENCODER_OBJECT_ID_TRAVIS:1644case ENCODER_OBJECT_ID_NUTMEG:1645is_dp_bridge = true;1646break;1647default:1648break;1649}1650}1651}16521653amdgpu_connector = kzalloc(sizeof(struct amdgpu_connector), GFP_KERNEL);1654if (!amdgpu_connector)1655return;16561657connector = &amdgpu_connector->base;16581659amdgpu_connector->connector_id = connector_id;1660amdgpu_connector->devices = supported_device;1661amdgpu_connector->shared_ddc = shared_ddc;1662amdgpu_connector->connector_object_id = connector_object_id;1663amdgpu_connector->hpd = *hpd;16641665amdgpu_connector->router = *router;1666if (router->ddc_valid || router->cd_valid) {1667amdgpu_connector->router_bus = amdgpu_i2c_lookup(adev, &router->i2c_info);1668if (!amdgpu_connector->router_bus)1669DRM_ERROR("Failed to assign router i2c bus! Check dmesg for i2c errors.\n");1670}16711672if (is_dp_bridge) {1673amdgpu_dig_connector = kzalloc(sizeof(struct amdgpu_connector_atom_dig), GFP_KERNEL);1674if (!amdgpu_dig_connector)1675goto failed;1676amdgpu_connector->con_priv = amdgpu_dig_connector;1677if (i2c_bus->valid) {1678amdgpu_connector->ddc_bus = amdgpu_i2c_lookup(adev, i2c_bus);1679if (amdgpu_connector->ddc_bus) {1680has_aux = true;1681ddc = &amdgpu_connector->ddc_bus->adapter;1682} else {1683DRM_ERROR("DP: Failed to assign ddc bus! Check dmesg for i2c errors.\n");1684}1685}1686switch (connector_type) {1687case DRM_MODE_CONNECTOR_VGA:1688case DRM_MODE_CONNECTOR_DVIA:1689default:1690drm_connector_init_with_ddc(dev, &amdgpu_connector->base,1691&amdgpu_connector_dp_funcs,1692connector_type,1693ddc);1694drm_connector_helper_add(&amdgpu_connector->base,1695&amdgpu_connector_dp_helper_funcs);1696connector->interlace_allowed = true;1697connector->doublescan_allowed = true;1698amdgpu_connector->dac_load_detect = true;1699drm_object_attach_property(&amdgpu_connector->base.base,1700adev->mode_info.load_detect_property,17011);1702drm_object_attach_property(&amdgpu_connector->base.base,1703dev->mode_config.scaling_mode_property,1704DRM_MODE_SCALE_NONE);1705break;1706case DRM_MODE_CONNECTOR_DVII:1707case DRM_MODE_CONNECTOR_DVID:1708case DRM_MODE_CONNECTOR_HDMIA:1709case DRM_MODE_CONNECTOR_HDMIB:1710case DRM_MODE_CONNECTOR_DisplayPort:1711drm_connector_init_with_ddc(dev, &amdgpu_connector->base,1712&amdgpu_connector_dp_funcs,1713connector_type,1714ddc);1715drm_connector_helper_add(&amdgpu_connector->base,1716&amdgpu_connector_dp_helper_funcs);1717drm_object_attach_property(&amdgpu_connector->base.base,1718adev->mode_info.underscan_property,1719UNDERSCAN_OFF);1720drm_object_attach_property(&amdgpu_connector->base.base,1721adev->mode_info.underscan_hborder_property,17220);1723drm_object_attach_property(&amdgpu_connector->base.base,1724adev->mode_info.underscan_vborder_property,17250);17261727drm_object_attach_property(&amdgpu_connector->base.base,1728dev->mode_config.scaling_mode_property,1729DRM_MODE_SCALE_NONE);17301731drm_object_attach_property(&amdgpu_connector->base.base,1732adev->mode_info.dither_property,1733AMDGPU_FMT_DITHER_DISABLE);17341735if (amdgpu_audio != 0) {1736drm_object_attach_property(&amdgpu_connector->base.base,1737adev->mode_info.audio_property,1738AMDGPU_AUDIO_AUTO);1739amdgpu_connector->audio = AMDGPU_AUDIO_AUTO;1740}17411742subpixel_order = SubPixelHorizontalRGB;1743connector->interlace_allowed = true;1744if (connector_type == DRM_MODE_CONNECTOR_HDMIB)1745connector->doublescan_allowed = true;1746else1747connector->doublescan_allowed = false;1748if (connector_type == DRM_MODE_CONNECTOR_DVII) {1749amdgpu_connector->dac_load_detect = true;1750drm_object_attach_property(&amdgpu_connector->base.base,1751adev->mode_info.load_detect_property,17521);1753}1754break;1755case DRM_MODE_CONNECTOR_LVDS:1756case DRM_MODE_CONNECTOR_eDP:1757drm_connector_init_with_ddc(dev, &amdgpu_connector->base,1758&amdgpu_connector_edp_funcs,1759connector_type,1760ddc);1761drm_connector_helper_add(&amdgpu_connector->base,1762&amdgpu_connector_dp_helper_funcs);1763drm_object_attach_property(&amdgpu_connector->base.base,1764dev->mode_config.scaling_mode_property,1765DRM_MODE_SCALE_FULLSCREEN);1766subpixel_order = SubPixelHorizontalRGB;1767connector->interlace_allowed = false;1768connector->doublescan_allowed = false;1769break;1770}1771} else {1772switch (connector_type) {1773case DRM_MODE_CONNECTOR_VGA:1774if (i2c_bus->valid) {1775amdgpu_connector->ddc_bus = amdgpu_i2c_lookup(adev, i2c_bus);1776if (!amdgpu_connector->ddc_bus)1777DRM_ERROR("VGA: Failed to assign ddc bus! Check dmesg for i2c errors.\n");1778else1779ddc = &amdgpu_connector->ddc_bus->adapter;1780}1781drm_connector_init_with_ddc(dev, &amdgpu_connector->base,1782&amdgpu_connector_vga_funcs,1783connector_type,1784ddc);1785drm_connector_helper_add(&amdgpu_connector->base, &amdgpu_connector_vga_helper_funcs);1786amdgpu_connector->dac_load_detect = true;1787drm_object_attach_property(&amdgpu_connector->base.base,1788adev->mode_info.load_detect_property,17891);1790drm_object_attach_property(&amdgpu_connector->base.base,1791dev->mode_config.scaling_mode_property,1792DRM_MODE_SCALE_NONE);1793/* no HPD on analog connectors */1794amdgpu_connector->hpd.hpd = AMDGPU_HPD_NONE;1795connector->interlace_allowed = true;1796connector->doublescan_allowed = true;1797break;1798case DRM_MODE_CONNECTOR_DVIA:1799if (i2c_bus->valid) {1800amdgpu_connector->ddc_bus = amdgpu_i2c_lookup(adev, i2c_bus);1801if (!amdgpu_connector->ddc_bus)1802DRM_ERROR("DVIA: Failed to assign ddc bus! Check dmesg for i2c errors.\n");1803else1804ddc = &amdgpu_connector->ddc_bus->adapter;1805}1806drm_connector_init_with_ddc(dev, &amdgpu_connector->base,1807&amdgpu_connector_vga_funcs,1808connector_type,1809ddc);1810drm_connector_helper_add(&amdgpu_connector->base, &amdgpu_connector_vga_helper_funcs);1811amdgpu_connector->dac_load_detect = true;1812drm_object_attach_property(&amdgpu_connector->base.base,1813adev->mode_info.load_detect_property,18141);1815drm_object_attach_property(&amdgpu_connector->base.base,1816dev->mode_config.scaling_mode_property,1817DRM_MODE_SCALE_NONE);1818/* no HPD on analog connectors */1819amdgpu_connector->hpd.hpd = AMDGPU_HPD_NONE;1820connector->interlace_allowed = true;1821connector->doublescan_allowed = true;1822break;1823case DRM_MODE_CONNECTOR_DVII:1824case DRM_MODE_CONNECTOR_DVID:1825amdgpu_dig_connector = kzalloc(sizeof(struct amdgpu_connector_atom_dig), GFP_KERNEL);1826if (!amdgpu_dig_connector)1827goto failed;1828amdgpu_connector->con_priv = amdgpu_dig_connector;1829if (i2c_bus->valid) {1830amdgpu_connector->ddc_bus = amdgpu_i2c_lookup(adev, i2c_bus);1831if (!amdgpu_connector->ddc_bus)1832DRM_ERROR("DVI: Failed to assign ddc bus! Check dmesg for i2c errors.\n");1833else1834ddc = &amdgpu_connector->ddc_bus->adapter;1835}1836drm_connector_init_with_ddc(dev, &amdgpu_connector->base,1837&amdgpu_connector_dvi_funcs,1838connector_type,1839ddc);1840drm_connector_helper_add(&amdgpu_connector->base, &amdgpu_connector_dvi_helper_funcs);1841subpixel_order = SubPixelHorizontalRGB;1842drm_object_attach_property(&amdgpu_connector->base.base,1843adev->mode_info.coherent_mode_property,18441);1845drm_object_attach_property(&amdgpu_connector->base.base,1846adev->mode_info.underscan_property,1847UNDERSCAN_OFF);1848drm_object_attach_property(&amdgpu_connector->base.base,1849adev->mode_info.underscan_hborder_property,18500);1851drm_object_attach_property(&amdgpu_connector->base.base,1852adev->mode_info.underscan_vborder_property,18530);1854drm_object_attach_property(&amdgpu_connector->base.base,1855dev->mode_config.scaling_mode_property,1856DRM_MODE_SCALE_NONE);18571858if (amdgpu_audio != 0) {1859drm_object_attach_property(&amdgpu_connector->base.base,1860adev->mode_info.audio_property,1861AMDGPU_AUDIO_AUTO);1862amdgpu_connector->audio = AMDGPU_AUDIO_AUTO;1863}1864drm_object_attach_property(&amdgpu_connector->base.base,1865adev->mode_info.dither_property,1866AMDGPU_FMT_DITHER_DISABLE);1867if (connector_type == DRM_MODE_CONNECTOR_DVII) {1868amdgpu_connector->dac_load_detect = true;1869drm_object_attach_property(&amdgpu_connector->base.base,1870adev->mode_info.load_detect_property,18711);1872}1873connector->interlace_allowed = true;1874if (connector_type == DRM_MODE_CONNECTOR_DVII)1875connector->doublescan_allowed = true;1876else1877connector->doublescan_allowed = false;1878break;1879case DRM_MODE_CONNECTOR_HDMIA:1880case DRM_MODE_CONNECTOR_HDMIB:1881amdgpu_dig_connector = kzalloc(sizeof(struct amdgpu_connector_atom_dig), GFP_KERNEL);1882if (!amdgpu_dig_connector)1883goto failed;1884amdgpu_connector->con_priv = amdgpu_dig_connector;1885if (i2c_bus->valid) {1886amdgpu_connector->ddc_bus = amdgpu_i2c_lookup(adev, i2c_bus);1887if (!amdgpu_connector->ddc_bus)1888DRM_ERROR("HDMI: Failed to assign ddc bus! Check dmesg for i2c errors.\n");1889else1890ddc = &amdgpu_connector->ddc_bus->adapter;1891}1892drm_connector_init_with_ddc(dev, &amdgpu_connector->base,1893&amdgpu_connector_dvi_funcs,1894connector_type,1895ddc);1896drm_connector_helper_add(&amdgpu_connector->base, &amdgpu_connector_dvi_helper_funcs);1897drm_object_attach_property(&amdgpu_connector->base.base,1898adev->mode_info.coherent_mode_property,18991);1900drm_object_attach_property(&amdgpu_connector->base.base,1901adev->mode_info.underscan_property,1902UNDERSCAN_OFF);1903drm_object_attach_property(&amdgpu_connector->base.base,1904adev->mode_info.underscan_hborder_property,19050);1906drm_object_attach_property(&amdgpu_connector->base.base,1907adev->mode_info.underscan_vborder_property,19080);1909drm_object_attach_property(&amdgpu_connector->base.base,1910dev->mode_config.scaling_mode_property,1911DRM_MODE_SCALE_NONE);1912if (amdgpu_audio != 0) {1913drm_object_attach_property(&amdgpu_connector->base.base,1914adev->mode_info.audio_property,1915AMDGPU_AUDIO_AUTO);1916amdgpu_connector->audio = AMDGPU_AUDIO_AUTO;1917}1918drm_object_attach_property(&amdgpu_connector->base.base,1919adev->mode_info.dither_property,1920AMDGPU_FMT_DITHER_DISABLE);1921subpixel_order = SubPixelHorizontalRGB;1922connector->interlace_allowed = true;1923if (connector_type == DRM_MODE_CONNECTOR_HDMIB)1924connector->doublescan_allowed = true;1925else1926connector->doublescan_allowed = false;1927break;1928case DRM_MODE_CONNECTOR_DisplayPort:1929amdgpu_dig_connector = kzalloc(sizeof(struct amdgpu_connector_atom_dig), GFP_KERNEL);1930if (!amdgpu_dig_connector)1931goto failed;1932amdgpu_connector->con_priv = amdgpu_dig_connector;1933if (i2c_bus->valid) {1934amdgpu_connector->ddc_bus = amdgpu_i2c_lookup(adev, i2c_bus);1935if (amdgpu_connector->ddc_bus) {1936has_aux = true;1937ddc = &amdgpu_connector->ddc_bus->adapter;1938} else {1939DRM_ERROR("DP: Failed to assign ddc bus! Check dmesg for i2c errors.\n");1940}1941}1942drm_connector_init_with_ddc(dev, &amdgpu_connector->base,1943&amdgpu_connector_dp_funcs,1944connector_type,1945ddc);1946drm_connector_helper_add(&amdgpu_connector->base, &amdgpu_connector_dp_helper_funcs);1947subpixel_order = SubPixelHorizontalRGB;1948drm_object_attach_property(&amdgpu_connector->base.base,1949adev->mode_info.coherent_mode_property,19501);1951drm_object_attach_property(&amdgpu_connector->base.base,1952adev->mode_info.underscan_property,1953UNDERSCAN_OFF);1954drm_object_attach_property(&amdgpu_connector->base.base,1955adev->mode_info.underscan_hborder_property,19560);1957drm_object_attach_property(&amdgpu_connector->base.base,1958adev->mode_info.underscan_vborder_property,19590);1960drm_object_attach_property(&amdgpu_connector->base.base,1961dev->mode_config.scaling_mode_property,1962DRM_MODE_SCALE_NONE);1963if (amdgpu_audio != 0) {1964drm_object_attach_property(&amdgpu_connector->base.base,1965adev->mode_info.audio_property,1966AMDGPU_AUDIO_AUTO);1967amdgpu_connector->audio = AMDGPU_AUDIO_AUTO;1968}1969drm_object_attach_property(&amdgpu_connector->base.base,1970adev->mode_info.dither_property,1971AMDGPU_FMT_DITHER_DISABLE);1972connector->interlace_allowed = true;1973/* in theory with a DP to VGA converter... */1974connector->doublescan_allowed = false;1975break;1976case DRM_MODE_CONNECTOR_eDP:1977amdgpu_dig_connector = kzalloc(sizeof(struct amdgpu_connector_atom_dig), GFP_KERNEL);1978if (!amdgpu_dig_connector)1979goto failed;1980amdgpu_connector->con_priv = amdgpu_dig_connector;1981if (i2c_bus->valid) {1982amdgpu_connector->ddc_bus = amdgpu_i2c_lookup(adev, i2c_bus);1983if (amdgpu_connector->ddc_bus) {1984has_aux = true;1985ddc = &amdgpu_connector->ddc_bus->adapter;1986} else {1987DRM_ERROR("DP: Failed to assign ddc bus! Check dmesg for i2c errors.\n");1988}1989}1990drm_connector_init_with_ddc(dev, &amdgpu_connector->base,1991&amdgpu_connector_edp_funcs,1992connector_type,1993ddc);1994drm_connector_helper_add(&amdgpu_connector->base, &amdgpu_connector_dp_helper_funcs);1995drm_object_attach_property(&amdgpu_connector->base.base,1996dev->mode_config.scaling_mode_property,1997DRM_MODE_SCALE_FULLSCREEN);1998subpixel_order = SubPixelHorizontalRGB;1999connector->interlace_allowed = false;2000connector->doublescan_allowed = false;2001break;2002case DRM_MODE_CONNECTOR_LVDS:2003amdgpu_dig_connector = kzalloc(sizeof(struct amdgpu_connector_atom_dig), GFP_KERNEL);2004if (!amdgpu_dig_connector)2005goto failed;2006amdgpu_connector->con_priv = amdgpu_dig_connector;2007if (i2c_bus->valid) {2008amdgpu_connector->ddc_bus = amdgpu_i2c_lookup(adev, i2c_bus);2009if (!amdgpu_connector->ddc_bus)2010DRM_ERROR("LVDS: Failed to assign ddc bus! Check dmesg for i2c errors.\n");2011else2012ddc = &amdgpu_connector->ddc_bus->adapter;2013}2014drm_connector_init_with_ddc(dev, &amdgpu_connector->base,2015&amdgpu_connector_lvds_funcs,2016connector_type,2017ddc);2018drm_connector_helper_add(&amdgpu_connector->base, &amdgpu_connector_lvds_helper_funcs);2019drm_object_attach_property(&amdgpu_connector->base.base,2020dev->mode_config.scaling_mode_property,2021DRM_MODE_SCALE_FULLSCREEN);2022subpixel_order = SubPixelHorizontalRGB;2023connector->interlace_allowed = false;2024connector->doublescan_allowed = false;2025break;2026}2027}20282029if (amdgpu_connector->hpd.hpd == AMDGPU_HPD_NONE) {2030if (i2c_bus->valid) {2031connector->polled = DRM_CONNECTOR_POLL_CONNECT |2032DRM_CONNECTOR_POLL_DISCONNECT;2033}2034} else2035connector->polled = DRM_CONNECTOR_POLL_HPD;20362037connector->display_info.subpixel_order = subpixel_order;20382039if (has_aux)2040amdgpu_atombios_dp_aux_init(amdgpu_connector);20412042if (connector_type == DRM_MODE_CONNECTOR_DisplayPort ||2043connector_type == DRM_MODE_CONNECTOR_eDP) {2044drm_connector_attach_dp_subconnector_property(&amdgpu_connector->base);2045}20462047return;20482049failed:2050drm_connector_cleanup(connector);2051kfree(connector);2052}205320542055