1*04fcfa4fSriastradh /* $NetBSD: nouveau_connector.c,v 1.2 2014/08/06 15:01:33 riastradh Exp $ */ 29d5db0c2Sriastradh 3cb459498Sriastradh /* 4cb459498Sriastradh * Copyright (C) 2008 Maarten Maathuis. 5cb459498Sriastradh * All Rights Reserved. 6cb459498Sriastradh * 7cb459498Sriastradh * Permission is hereby granted, free of charge, to any person obtaining 8cb459498Sriastradh * a copy of this software and associated documentation files (the 9cb459498Sriastradh * "Software"), to deal in the Software without restriction, including 10cb459498Sriastradh * without limitation the rights to use, copy, modify, merge, publish, 11cb459498Sriastradh * distribute, sublicense, and/or sell copies of the Software, and to 12cb459498Sriastradh * permit persons to whom the Software is furnished to do so, subject to 13cb459498Sriastradh * the following conditions: 14cb459498Sriastradh * 15cb459498Sriastradh * The above copyright notice and this permission notice (including the 16cb459498Sriastradh * next paragraph) shall be included in all copies or substantial 17cb459498Sriastradh * portions of the Software. 18cb459498Sriastradh * 19cb459498Sriastradh * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 20cb459498Sriastradh * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 21cb459498Sriastradh * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 22cb459498Sriastradh * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE 23cb459498Sriastradh * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 24cb459498Sriastradh * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 25cb459498Sriastradh * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 26cb459498Sriastradh * 27cb459498Sriastradh */ 28cb459498Sriastradh 299d5db0c2Sriastradh #include <sys/cdefs.h> 30*04fcfa4fSriastradh __KERNEL_RCSID(0, "$NetBSD: nouveau_connector.c,v 1.2 2014/08/06 15:01:33 riastradh Exp $"); 319d5db0c2Sriastradh 32cb459498Sriastradh #include <acpi/button.h> 33cb459498Sriastradh 34*04fcfa4fSriastradh #include <linux/err.h> 35cb459498Sriastradh #include <linux/pm_runtime.h> 36*04fcfa4fSriastradh #include <linux/string.h> 37cb459498Sriastradh 38cb459498Sriastradh #include <drm/drmP.h> 39cb459498Sriastradh #include <drm/drm_edid.h> 40cb459498Sriastradh #include <drm/drm_crtc_helper.h> 41cb459498Sriastradh 42cb459498Sriastradh #include "nouveau_reg.h" 43cb459498Sriastradh #include "nouveau_drm.h" 44cb459498Sriastradh #include "dispnv04/hw.h" 45cb459498Sriastradh #include "nouveau_acpi.h" 46cb459498Sriastradh 47cb459498Sriastradh #include "nouveau_display.h" 48cb459498Sriastradh #include "nouveau_connector.h" 49cb459498Sriastradh #include "nouveau_encoder.h" 50cb459498Sriastradh #include "nouveau_crtc.h" 51cb459498Sriastradh 52cb459498Sriastradh #include <subdev/i2c.h> 53cb459498Sriastradh #include <subdev/gpio.h> 54cb459498Sriastradh 55cb459498Sriastradh MODULE_PARM_DESC(tv_disable, "Disable TV-out detection"); 56cb459498Sriastradh static int nouveau_tv_disable = 0; 57cb459498Sriastradh module_param_named(tv_disable, nouveau_tv_disable, int, 0400); 58cb459498Sriastradh 59*04fcfa4fSriastradh #if defined(CONFIG_ACPI_BUTTON) || \ 60*04fcfa4fSriastradh (defined(CONFIG_ACPI_BUTTON_MODULE) && defined(MODULE)) 61cb459498Sriastradh MODULE_PARM_DESC(ignorelid, "Ignore ACPI lid status"); 62cb459498Sriastradh static int nouveau_ignorelid = 0; 63cb459498Sriastradh module_param_named(ignorelid, nouveau_ignorelid, int, 0400); 64*04fcfa4fSriastradh #endif 65cb459498Sriastradh 66cb459498Sriastradh MODULE_PARM_DESC(duallink, "Allow dual-link TMDS (default: enabled)"); 67cb459498Sriastradh static int nouveau_duallink = 1; 68cb459498Sriastradh module_param_named(duallink, nouveau_duallink, int, 0400); 69cb459498Sriastradh 70cb459498Sriastradh struct nouveau_encoder * 71cb459498Sriastradh find_encoder(struct drm_connector *connector, int type) 72cb459498Sriastradh { 73cb459498Sriastradh struct drm_device *dev = connector->dev; 74cb459498Sriastradh struct nouveau_encoder *nv_encoder; 75cb459498Sriastradh struct drm_mode_object *obj; 76cb459498Sriastradh int i, id; 77cb459498Sriastradh 78cb459498Sriastradh for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { 79cb459498Sriastradh id = connector->encoder_ids[i]; 80cb459498Sriastradh if (!id) 81cb459498Sriastradh break; 82cb459498Sriastradh 83cb459498Sriastradh obj = drm_mode_object_find(dev, id, DRM_MODE_OBJECT_ENCODER); 84cb459498Sriastradh if (!obj) 85cb459498Sriastradh continue; 86cb459498Sriastradh nv_encoder = nouveau_encoder(obj_to_encoder(obj)); 87cb459498Sriastradh 88cb459498Sriastradh if (type == DCB_OUTPUT_ANY || nv_encoder->dcb->type == type) 89cb459498Sriastradh return nv_encoder; 90cb459498Sriastradh } 91cb459498Sriastradh 92cb459498Sriastradh return NULL; 93cb459498Sriastradh } 94cb459498Sriastradh 95cb459498Sriastradh struct nouveau_connector * 96cb459498Sriastradh nouveau_encoder_connector_get(struct nouveau_encoder *encoder) 97cb459498Sriastradh { 98cb459498Sriastradh struct drm_device *dev = to_drm_encoder(encoder)->dev; 99cb459498Sriastradh struct drm_connector *drm_connector; 100cb459498Sriastradh 101cb459498Sriastradh list_for_each_entry(drm_connector, &dev->mode_config.connector_list, head) { 102cb459498Sriastradh if (drm_connector->encoder == to_drm_encoder(encoder)) 103cb459498Sriastradh return nouveau_connector(drm_connector); 104cb459498Sriastradh } 105cb459498Sriastradh 106cb459498Sriastradh return NULL; 107cb459498Sriastradh } 108cb459498Sriastradh 109cb459498Sriastradh static void 110cb459498Sriastradh nouveau_connector_destroy(struct drm_connector *connector) 111cb459498Sriastradh { 112cb459498Sriastradh struct nouveau_connector *nv_connector = nouveau_connector(connector); 113cb459498Sriastradh nouveau_event_ref(NULL, &nv_connector->hpd_func); 114cb459498Sriastradh kfree(nv_connector->edid); 115cb459498Sriastradh drm_sysfs_connector_remove(connector); 116cb459498Sriastradh drm_connector_cleanup(connector); 117cb459498Sriastradh kfree(connector); 118cb459498Sriastradh } 119cb459498Sriastradh 120cb459498Sriastradh static struct nouveau_i2c_port * 121cb459498Sriastradh nouveau_connector_ddc_detect(struct drm_connector *connector, 122cb459498Sriastradh struct nouveau_encoder **pnv_encoder) 123cb459498Sriastradh { 124cb459498Sriastradh struct drm_device *dev = connector->dev; 125cb459498Sriastradh struct nouveau_connector *nv_connector = nouveau_connector(connector); 126cb459498Sriastradh struct nouveau_drm *drm = nouveau_drm(dev); 127cb459498Sriastradh struct nouveau_gpio *gpio = nouveau_gpio(drm->device); 128cb459498Sriastradh struct nouveau_i2c_port *port = NULL; 129cb459498Sriastradh int i, panel = -ENODEV; 130cb459498Sriastradh 131cb459498Sriastradh /* eDP panels need powering on by us (if the VBIOS doesn't default it 132cb459498Sriastradh * to on) before doing any AUX channel transactions. LVDS panel power 133cb459498Sriastradh * is handled by the SOR itself, and not required for LVDS DDC. 134cb459498Sriastradh */ 135cb459498Sriastradh if (nv_connector->type == DCB_CONNECTOR_eDP) { 136cb459498Sriastradh panel = gpio->get(gpio, 0, DCB_GPIO_PANEL_POWER, 0xff); 137cb459498Sriastradh if (panel == 0) { 138cb459498Sriastradh gpio->set(gpio, 0, DCB_GPIO_PANEL_POWER, 0xff, 1); 139cb459498Sriastradh msleep(300); 140cb459498Sriastradh } 141cb459498Sriastradh } 142cb459498Sriastradh 143cb459498Sriastradh for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { 144cb459498Sriastradh struct nouveau_encoder *nv_encoder; 145cb459498Sriastradh struct drm_mode_object *obj; 146cb459498Sriastradh int id; 147cb459498Sriastradh 148cb459498Sriastradh id = connector->encoder_ids[i]; 149cb459498Sriastradh if (!id) 150cb459498Sriastradh break; 151cb459498Sriastradh 152cb459498Sriastradh obj = drm_mode_object_find(dev, id, DRM_MODE_OBJECT_ENCODER); 153cb459498Sriastradh if (!obj) 154cb459498Sriastradh continue; 155cb459498Sriastradh nv_encoder = nouveau_encoder(obj_to_encoder(obj)); 156cb459498Sriastradh 157cb459498Sriastradh port = nv_encoder->i2c; 158cb459498Sriastradh if (port && nv_probe_i2c(port, 0x50)) { 159cb459498Sriastradh *pnv_encoder = nv_encoder; 160cb459498Sriastradh break; 161cb459498Sriastradh } 162cb459498Sriastradh 163cb459498Sriastradh port = NULL; 164cb459498Sriastradh } 165cb459498Sriastradh 166cb459498Sriastradh /* eDP panel not detected, restore panel power GPIO to previous 167cb459498Sriastradh * state to avoid confusing the SOR for other output types. 168cb459498Sriastradh */ 169cb459498Sriastradh if (!port && panel == 0) 170cb459498Sriastradh gpio->set(gpio, 0, DCB_GPIO_PANEL_POWER, 0xff, panel); 171cb459498Sriastradh 172cb459498Sriastradh return port; 173cb459498Sriastradh } 174cb459498Sriastradh 175cb459498Sriastradh static struct nouveau_encoder * 176cb459498Sriastradh nouveau_connector_of_detect(struct drm_connector *connector) 177cb459498Sriastradh { 178cb459498Sriastradh #ifdef __powerpc__ 179cb459498Sriastradh struct drm_device *dev = connector->dev; 180cb459498Sriastradh struct nouveau_connector *nv_connector = nouveau_connector(connector); 181cb459498Sriastradh struct nouveau_encoder *nv_encoder; 182cb459498Sriastradh struct device_node *cn, *dn = pci_device_to_OF_node(dev->pdev); 183cb459498Sriastradh 184cb459498Sriastradh if (!dn || 185cb459498Sriastradh !((nv_encoder = find_encoder(connector, DCB_OUTPUT_TMDS)) || 186cb459498Sriastradh (nv_encoder = find_encoder(connector, DCB_OUTPUT_ANALOG)))) 187cb459498Sriastradh return NULL; 188cb459498Sriastradh 189cb459498Sriastradh for_each_child_of_node(dn, cn) { 190cb459498Sriastradh const char *name = of_get_property(cn, "name", NULL); 191cb459498Sriastradh const void *edid = of_get_property(cn, "EDID", NULL); 192cb459498Sriastradh int idx = name ? name[strlen(name) - 1] - 'A' : 0; 193cb459498Sriastradh 194cb459498Sriastradh if (nv_encoder->dcb->i2c_index == idx && edid) { 195cb459498Sriastradh nv_connector->edid = 196cb459498Sriastradh kmemdup(edid, EDID_LENGTH, GFP_KERNEL); 197cb459498Sriastradh of_node_put(cn); 198cb459498Sriastradh return nv_encoder; 199cb459498Sriastradh } 200cb459498Sriastradh } 201cb459498Sriastradh #endif 202cb459498Sriastradh return NULL; 203cb459498Sriastradh } 204cb459498Sriastradh 205cb459498Sriastradh static void 206cb459498Sriastradh nouveau_connector_set_encoder(struct drm_connector *connector, 207cb459498Sriastradh struct nouveau_encoder *nv_encoder) 208cb459498Sriastradh { 209cb459498Sriastradh struct nouveau_connector *nv_connector = nouveau_connector(connector); 210cb459498Sriastradh struct nouveau_drm *drm = nouveau_drm(connector->dev); 211cb459498Sriastradh struct drm_device *dev = connector->dev; 212cb459498Sriastradh 213cb459498Sriastradh if (nv_connector->detected_encoder == nv_encoder) 214cb459498Sriastradh return; 215cb459498Sriastradh nv_connector->detected_encoder = nv_encoder; 216cb459498Sriastradh 217cb459498Sriastradh if (nv_device(drm->device)->card_type >= NV_50) { 218cb459498Sriastradh connector->interlace_allowed = true; 219cb459498Sriastradh connector->doublescan_allowed = true; 220cb459498Sriastradh } else 221cb459498Sriastradh if (nv_encoder->dcb->type == DCB_OUTPUT_LVDS || 222cb459498Sriastradh nv_encoder->dcb->type == DCB_OUTPUT_TMDS) { 223cb459498Sriastradh connector->doublescan_allowed = false; 224cb459498Sriastradh connector->interlace_allowed = false; 225cb459498Sriastradh } else { 226cb459498Sriastradh connector->doublescan_allowed = true; 227cb459498Sriastradh if (nv_device(drm->device)->card_type == NV_20 || 228cb459498Sriastradh ((nv_device(drm->device)->card_type == NV_10 || 229cb459498Sriastradh nv_device(drm->device)->card_type == NV_11) && 230cb459498Sriastradh (dev->pdev->device & 0x0ff0) != 0x0100 && 231cb459498Sriastradh (dev->pdev->device & 0x0ff0) != 0x0150)) 232cb459498Sriastradh /* HW is broken */ 233cb459498Sriastradh connector->interlace_allowed = false; 234cb459498Sriastradh else 235cb459498Sriastradh connector->interlace_allowed = true; 236cb459498Sriastradh } 237cb459498Sriastradh 238cb459498Sriastradh if (nv_connector->type == DCB_CONNECTOR_DVI_I) { 239cb459498Sriastradh drm_object_property_set_value(&connector->base, 240cb459498Sriastradh dev->mode_config.dvi_i_subconnector_property, 241cb459498Sriastradh nv_encoder->dcb->type == DCB_OUTPUT_TMDS ? 242cb459498Sriastradh DRM_MODE_SUBCONNECTOR_DVID : 243cb459498Sriastradh DRM_MODE_SUBCONNECTOR_DVIA); 244cb459498Sriastradh } 245cb459498Sriastradh } 246cb459498Sriastradh 247cb459498Sriastradh static enum drm_connector_status 248cb459498Sriastradh nouveau_connector_detect(struct drm_connector *connector, bool force) 249cb459498Sriastradh { 250cb459498Sriastradh struct drm_device *dev = connector->dev; 251cb459498Sriastradh struct nouveau_drm *drm = nouveau_drm(dev); 252cb459498Sriastradh struct nouveau_connector *nv_connector = nouveau_connector(connector); 253cb459498Sriastradh struct nouveau_encoder *nv_encoder = NULL; 254cb459498Sriastradh struct nouveau_encoder *nv_partner; 255cb459498Sriastradh struct nouveau_i2c_port *i2c; 256cb459498Sriastradh int type; 257cb459498Sriastradh int ret; 258cb459498Sriastradh enum drm_connector_status conn_status = connector_status_disconnected; 259cb459498Sriastradh 260cb459498Sriastradh /* Cleanup the previous EDID block. */ 261cb459498Sriastradh if (nv_connector->edid) { 262cb459498Sriastradh drm_mode_connector_update_edid_property(connector, NULL); 263cb459498Sriastradh kfree(nv_connector->edid); 264cb459498Sriastradh nv_connector->edid = NULL; 265cb459498Sriastradh } 266cb459498Sriastradh 267cb459498Sriastradh ret = pm_runtime_get_sync(connector->dev->dev); 268cb459498Sriastradh if (ret < 0 && ret != -EACCES) 269cb459498Sriastradh return conn_status; 270cb459498Sriastradh 271cb459498Sriastradh i2c = nouveau_connector_ddc_detect(connector, &nv_encoder); 272cb459498Sriastradh if (i2c) { 273cb459498Sriastradh nv_connector->edid = drm_get_edid(connector, &i2c->adapter); 274cb459498Sriastradh drm_mode_connector_update_edid_property(connector, 275cb459498Sriastradh nv_connector->edid); 276cb459498Sriastradh if (!nv_connector->edid) { 277cb459498Sriastradh NV_ERROR(drm, "DDC responded, but no EDID for %s\n", 278cb459498Sriastradh drm_get_connector_name(connector)); 279cb459498Sriastradh goto detect_analog; 280cb459498Sriastradh } 281cb459498Sriastradh 282cb459498Sriastradh if (nv_encoder->dcb->type == DCB_OUTPUT_DP && 283cb459498Sriastradh !nouveau_dp_detect(to_drm_encoder(nv_encoder))) { 284cb459498Sriastradh NV_ERROR(drm, "Detected %s, but failed init\n", 285cb459498Sriastradh drm_get_connector_name(connector)); 286cb459498Sriastradh conn_status = connector_status_disconnected; 287cb459498Sriastradh goto out; 288cb459498Sriastradh } 289cb459498Sriastradh 290cb459498Sriastradh /* Override encoder type for DVI-I based on whether EDID 291cb459498Sriastradh * says the display is digital or analog, both use the 292cb459498Sriastradh * same i2c channel so the value returned from ddc_detect 293cb459498Sriastradh * isn't necessarily correct. 294cb459498Sriastradh */ 295cb459498Sriastradh nv_partner = NULL; 296cb459498Sriastradh if (nv_encoder->dcb->type == DCB_OUTPUT_TMDS) 297cb459498Sriastradh nv_partner = find_encoder(connector, DCB_OUTPUT_ANALOG); 298cb459498Sriastradh if (nv_encoder->dcb->type == DCB_OUTPUT_ANALOG) 299cb459498Sriastradh nv_partner = find_encoder(connector, DCB_OUTPUT_TMDS); 300cb459498Sriastradh 301cb459498Sriastradh if (nv_partner && ((nv_encoder->dcb->type == DCB_OUTPUT_ANALOG && 302cb459498Sriastradh nv_partner->dcb->type == DCB_OUTPUT_TMDS) || 303cb459498Sriastradh (nv_encoder->dcb->type == DCB_OUTPUT_TMDS && 304cb459498Sriastradh nv_partner->dcb->type == DCB_OUTPUT_ANALOG))) { 305cb459498Sriastradh if (nv_connector->edid->input & DRM_EDID_INPUT_DIGITAL) 306cb459498Sriastradh type = DCB_OUTPUT_TMDS; 307cb459498Sriastradh else 308cb459498Sriastradh type = DCB_OUTPUT_ANALOG; 309cb459498Sriastradh 310cb459498Sriastradh nv_encoder = find_encoder(connector, type); 311cb459498Sriastradh } 312cb459498Sriastradh 313cb459498Sriastradh nouveau_connector_set_encoder(connector, nv_encoder); 314cb459498Sriastradh conn_status = connector_status_connected; 315cb459498Sriastradh goto out; 316cb459498Sriastradh } 317cb459498Sriastradh 318cb459498Sriastradh nv_encoder = nouveau_connector_of_detect(connector); 319cb459498Sriastradh if (nv_encoder) { 320cb459498Sriastradh nouveau_connector_set_encoder(connector, nv_encoder); 321cb459498Sriastradh conn_status = connector_status_connected; 322cb459498Sriastradh goto out; 323cb459498Sriastradh } 324cb459498Sriastradh 325cb459498Sriastradh detect_analog: 326cb459498Sriastradh nv_encoder = find_encoder(connector, DCB_OUTPUT_ANALOG); 327cb459498Sriastradh if (!nv_encoder && !nouveau_tv_disable) 328cb459498Sriastradh nv_encoder = find_encoder(connector, DCB_OUTPUT_TV); 329cb459498Sriastradh if (nv_encoder && force) { 330cb459498Sriastradh struct drm_encoder *encoder = to_drm_encoder(nv_encoder); 331cb459498Sriastradh struct drm_encoder_helper_funcs *helper = 332cb459498Sriastradh encoder->helper_private; 333cb459498Sriastradh 334cb459498Sriastradh if (helper->detect(encoder, connector) == 335cb459498Sriastradh connector_status_connected) { 336cb459498Sriastradh nouveau_connector_set_encoder(connector, nv_encoder); 337cb459498Sriastradh conn_status = connector_status_connected; 338cb459498Sriastradh goto out; 339cb459498Sriastradh } 340cb459498Sriastradh 341cb459498Sriastradh } 342cb459498Sriastradh 343cb459498Sriastradh out: 344cb459498Sriastradh 345cb459498Sriastradh pm_runtime_mark_last_busy(connector->dev->dev); 346cb459498Sriastradh pm_runtime_put_autosuspend(connector->dev->dev); 347cb459498Sriastradh 348cb459498Sriastradh return conn_status; 349cb459498Sriastradh } 350cb459498Sriastradh 351cb459498Sriastradh static enum drm_connector_status 352cb459498Sriastradh nouveau_connector_detect_lvds(struct drm_connector *connector, bool force) 353cb459498Sriastradh { 354cb459498Sriastradh struct drm_device *dev = connector->dev; 355cb459498Sriastradh struct nouveau_drm *drm = nouveau_drm(dev); 356cb459498Sriastradh struct nouveau_connector *nv_connector = nouveau_connector(connector); 357cb459498Sriastradh struct nouveau_encoder *nv_encoder = NULL; 358cb459498Sriastradh enum drm_connector_status status = connector_status_disconnected; 359cb459498Sriastradh 360cb459498Sriastradh /* Cleanup the previous EDID block. */ 361cb459498Sriastradh if (nv_connector->edid) { 362cb459498Sriastradh drm_mode_connector_update_edid_property(connector, NULL); 363cb459498Sriastradh kfree(nv_connector->edid); 364cb459498Sriastradh nv_connector->edid = NULL; 365cb459498Sriastradh } 366cb459498Sriastradh 367cb459498Sriastradh nv_encoder = find_encoder(connector, DCB_OUTPUT_LVDS); 368cb459498Sriastradh if (!nv_encoder) 369cb459498Sriastradh return connector_status_disconnected; 370cb459498Sriastradh 371cb459498Sriastradh /* Try retrieving EDID via DDC */ 372cb459498Sriastradh if (!drm->vbios.fp_no_ddc) { 373cb459498Sriastradh status = nouveau_connector_detect(connector, force); 374cb459498Sriastradh if (status == connector_status_connected) 375cb459498Sriastradh goto out; 376cb459498Sriastradh } 377cb459498Sriastradh 378cb459498Sriastradh /* On some laptops (Sony, i'm looking at you) there appears to 379cb459498Sriastradh * be no direct way of accessing the panel's EDID. The only 380cb459498Sriastradh * option available to us appears to be to ask ACPI for help.. 381cb459498Sriastradh * 382cb459498Sriastradh * It's important this check's before trying straps, one of the 383cb459498Sriastradh * said manufacturer's laptops are configured in such a way 384cb459498Sriastradh * the nouveau decides an entry in the VBIOS FP mode table is 385cb459498Sriastradh * valid - it's not (rh#613284) 386cb459498Sriastradh */ 387cb459498Sriastradh if (nv_encoder->dcb->lvdsconf.use_acpi_for_edid) { 388cb459498Sriastradh if ((nv_connector->edid = nouveau_acpi_edid(dev, connector))) { 389cb459498Sriastradh status = connector_status_connected; 390cb459498Sriastradh goto out; 391cb459498Sriastradh } 392cb459498Sriastradh } 393cb459498Sriastradh 394cb459498Sriastradh /* If no EDID found above, and the VBIOS indicates a hardcoded 395cb459498Sriastradh * modeline is avalilable for the panel, set it as the panel's 396cb459498Sriastradh * native mode and exit. 397cb459498Sriastradh */ 398cb459498Sriastradh if (nouveau_bios_fp_mode(dev, NULL) && (drm->vbios.fp_no_ddc || 399cb459498Sriastradh nv_encoder->dcb->lvdsconf.use_straps_for_mode)) { 400cb459498Sriastradh status = connector_status_connected; 401cb459498Sriastradh goto out; 402cb459498Sriastradh } 403cb459498Sriastradh 404cb459498Sriastradh /* Still nothing, some VBIOS images have a hardcoded EDID block 405cb459498Sriastradh * stored for the panel stored in them. 406cb459498Sriastradh */ 407cb459498Sriastradh if (!drm->vbios.fp_no_ddc) { 408cb459498Sriastradh struct edid *edid = 409cb459498Sriastradh (struct edid *)nouveau_bios_embedded_edid(dev); 410cb459498Sriastradh if (edid) { 411cb459498Sriastradh nv_connector->edid = 412cb459498Sriastradh kmemdup(edid, EDID_LENGTH, GFP_KERNEL); 413cb459498Sriastradh if (nv_connector->edid) 414cb459498Sriastradh status = connector_status_connected; 415cb459498Sriastradh } 416cb459498Sriastradh } 417cb459498Sriastradh 418cb459498Sriastradh out: 419cb459498Sriastradh #if defined(CONFIG_ACPI_BUTTON) || \ 420cb459498Sriastradh (defined(CONFIG_ACPI_BUTTON_MODULE) && defined(MODULE)) 421cb459498Sriastradh if (status == connector_status_connected && 422cb459498Sriastradh !nouveau_ignorelid && !acpi_lid_open()) 423cb459498Sriastradh status = connector_status_unknown; 424cb459498Sriastradh #endif 425cb459498Sriastradh 426cb459498Sriastradh drm_mode_connector_update_edid_property(connector, nv_connector->edid); 427cb459498Sriastradh nouveau_connector_set_encoder(connector, nv_encoder); 428cb459498Sriastradh return status; 429cb459498Sriastradh } 430cb459498Sriastradh 431cb459498Sriastradh static void 432cb459498Sriastradh nouveau_connector_force(struct drm_connector *connector) 433cb459498Sriastradh { 434cb459498Sriastradh struct nouveau_drm *drm = nouveau_drm(connector->dev); 435cb459498Sriastradh struct nouveau_connector *nv_connector = nouveau_connector(connector); 436cb459498Sriastradh struct nouveau_encoder *nv_encoder; 437cb459498Sriastradh int type; 438cb459498Sriastradh 439cb459498Sriastradh if (nv_connector->type == DCB_CONNECTOR_DVI_I) { 440cb459498Sriastradh if (connector->force == DRM_FORCE_ON_DIGITAL) 441cb459498Sriastradh type = DCB_OUTPUT_TMDS; 442cb459498Sriastradh else 443cb459498Sriastradh type = DCB_OUTPUT_ANALOG; 444cb459498Sriastradh } else 445cb459498Sriastradh type = DCB_OUTPUT_ANY; 446cb459498Sriastradh 447cb459498Sriastradh nv_encoder = find_encoder(connector, type); 448cb459498Sriastradh if (!nv_encoder) { 449cb459498Sriastradh NV_ERROR(drm, "can't find encoder to force %s on!\n", 450cb459498Sriastradh drm_get_connector_name(connector)); 451cb459498Sriastradh connector->status = connector_status_disconnected; 452cb459498Sriastradh return; 453cb459498Sriastradh } 454cb459498Sriastradh 455cb459498Sriastradh nouveau_connector_set_encoder(connector, nv_encoder); 456cb459498Sriastradh } 457cb459498Sriastradh 458cb459498Sriastradh static int 459cb459498Sriastradh nouveau_connector_set_property(struct drm_connector *connector, 460cb459498Sriastradh struct drm_property *property, uint64_t value) 461cb459498Sriastradh { 462cb459498Sriastradh struct nouveau_display *disp = nouveau_display(connector->dev); 463cb459498Sriastradh struct nouveau_connector *nv_connector = nouveau_connector(connector); 464cb459498Sriastradh struct nouveau_encoder *nv_encoder = nv_connector->detected_encoder; 465cb459498Sriastradh struct drm_encoder *encoder = to_drm_encoder(nv_encoder); 466cb459498Sriastradh struct drm_device *dev = connector->dev; 467cb459498Sriastradh struct nouveau_crtc *nv_crtc; 468cb459498Sriastradh int ret; 469cb459498Sriastradh 470cb459498Sriastradh nv_crtc = NULL; 471cb459498Sriastradh if (connector->encoder && connector->encoder->crtc) 472cb459498Sriastradh nv_crtc = nouveau_crtc(connector->encoder->crtc); 473cb459498Sriastradh 474cb459498Sriastradh /* Scaling mode */ 475cb459498Sriastradh if (property == dev->mode_config.scaling_mode_property) { 476cb459498Sriastradh bool modeset = false; 477cb459498Sriastradh 478cb459498Sriastradh switch (value) { 479cb459498Sriastradh case DRM_MODE_SCALE_NONE: 480cb459498Sriastradh case DRM_MODE_SCALE_FULLSCREEN: 481cb459498Sriastradh case DRM_MODE_SCALE_CENTER: 482cb459498Sriastradh case DRM_MODE_SCALE_ASPECT: 483cb459498Sriastradh break; 484cb459498Sriastradh default: 485cb459498Sriastradh return -EINVAL; 486cb459498Sriastradh } 487cb459498Sriastradh 488cb459498Sriastradh /* LVDS always needs gpu scaling */ 489cb459498Sriastradh if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS && 490cb459498Sriastradh value == DRM_MODE_SCALE_NONE) 491cb459498Sriastradh return -EINVAL; 492cb459498Sriastradh 493cb459498Sriastradh /* Changing between GPU and panel scaling requires a full 494cb459498Sriastradh * modeset 495cb459498Sriastradh */ 496cb459498Sriastradh if ((nv_connector->scaling_mode == DRM_MODE_SCALE_NONE) || 497cb459498Sriastradh (value == DRM_MODE_SCALE_NONE)) 498cb459498Sriastradh modeset = true; 499cb459498Sriastradh nv_connector->scaling_mode = value; 500cb459498Sriastradh 501cb459498Sriastradh if (!nv_crtc) 502cb459498Sriastradh return 0; 503cb459498Sriastradh 504cb459498Sriastradh if (modeset || !nv_crtc->set_scale) { 505cb459498Sriastradh ret = drm_crtc_helper_set_mode(&nv_crtc->base, 506cb459498Sriastradh &nv_crtc->base.mode, 507cb459498Sriastradh nv_crtc->base.x, 508cb459498Sriastradh nv_crtc->base.y, NULL); 509cb459498Sriastradh if (!ret) 510cb459498Sriastradh return -EINVAL; 511cb459498Sriastradh } else { 512cb459498Sriastradh ret = nv_crtc->set_scale(nv_crtc, true); 513cb459498Sriastradh if (ret) 514cb459498Sriastradh return ret; 515cb459498Sriastradh } 516cb459498Sriastradh 517cb459498Sriastradh return 0; 518cb459498Sriastradh } 519cb459498Sriastradh 520cb459498Sriastradh /* Underscan */ 521cb459498Sriastradh if (property == disp->underscan_property) { 522cb459498Sriastradh if (nv_connector->underscan != value) { 523cb459498Sriastradh nv_connector->underscan = value; 524cb459498Sriastradh if (!nv_crtc || !nv_crtc->set_scale) 525cb459498Sriastradh return 0; 526cb459498Sriastradh 527cb459498Sriastradh return nv_crtc->set_scale(nv_crtc, true); 528cb459498Sriastradh } 529cb459498Sriastradh 530cb459498Sriastradh return 0; 531cb459498Sriastradh } 532cb459498Sriastradh 533cb459498Sriastradh if (property == disp->underscan_hborder_property) { 534cb459498Sriastradh if (nv_connector->underscan_hborder != value) { 535cb459498Sriastradh nv_connector->underscan_hborder = value; 536cb459498Sriastradh if (!nv_crtc || !nv_crtc->set_scale) 537cb459498Sriastradh return 0; 538cb459498Sriastradh 539cb459498Sriastradh return nv_crtc->set_scale(nv_crtc, true); 540cb459498Sriastradh } 541cb459498Sriastradh 542cb459498Sriastradh return 0; 543cb459498Sriastradh } 544cb459498Sriastradh 545cb459498Sriastradh if (property == disp->underscan_vborder_property) { 546cb459498Sriastradh if (nv_connector->underscan_vborder != value) { 547cb459498Sriastradh nv_connector->underscan_vborder = value; 548cb459498Sriastradh if (!nv_crtc || !nv_crtc->set_scale) 549cb459498Sriastradh return 0; 550cb459498Sriastradh 551cb459498Sriastradh return nv_crtc->set_scale(nv_crtc, true); 552cb459498Sriastradh } 553cb459498Sriastradh 554cb459498Sriastradh return 0; 555cb459498Sriastradh } 556cb459498Sriastradh 557cb459498Sriastradh /* Dithering */ 558cb459498Sriastradh if (property == disp->dithering_mode) { 559cb459498Sriastradh nv_connector->dithering_mode = value; 560cb459498Sriastradh if (!nv_crtc || !nv_crtc->set_dither) 561cb459498Sriastradh return 0; 562cb459498Sriastradh 563cb459498Sriastradh return nv_crtc->set_dither(nv_crtc, true); 564cb459498Sriastradh } 565cb459498Sriastradh 566cb459498Sriastradh if (property == disp->dithering_depth) { 567cb459498Sriastradh nv_connector->dithering_depth = value; 568cb459498Sriastradh if (!nv_crtc || !nv_crtc->set_dither) 569cb459498Sriastradh return 0; 570cb459498Sriastradh 571cb459498Sriastradh return nv_crtc->set_dither(nv_crtc, true); 572cb459498Sriastradh } 573cb459498Sriastradh 574cb459498Sriastradh if (nv_crtc && nv_crtc->set_color_vibrance) { 575cb459498Sriastradh /* Hue */ 576cb459498Sriastradh if (property == disp->vibrant_hue_property) { 577cb459498Sriastradh nv_crtc->vibrant_hue = value - 90; 578cb459498Sriastradh return nv_crtc->set_color_vibrance(nv_crtc, true); 579cb459498Sriastradh } 580cb459498Sriastradh /* Saturation */ 581cb459498Sriastradh if (property == disp->color_vibrance_property) { 582cb459498Sriastradh nv_crtc->color_vibrance = value - 100; 583cb459498Sriastradh return nv_crtc->set_color_vibrance(nv_crtc, true); 584cb459498Sriastradh } 585cb459498Sriastradh } 586cb459498Sriastradh 587cb459498Sriastradh if (nv_encoder && nv_encoder->dcb->type == DCB_OUTPUT_TV) 588cb459498Sriastradh return get_slave_funcs(encoder)->set_property( 589cb459498Sriastradh encoder, connector, property, value); 590cb459498Sriastradh 591cb459498Sriastradh return -EINVAL; 592cb459498Sriastradh } 593cb459498Sriastradh 594cb459498Sriastradh static struct drm_display_mode * 595cb459498Sriastradh nouveau_connector_native_mode(struct drm_connector *connector) 596cb459498Sriastradh { 597cb459498Sriastradh struct drm_connector_helper_funcs *helper = connector->helper_private; 598cb459498Sriastradh struct nouveau_drm *drm = nouveau_drm(connector->dev); 599cb459498Sriastradh struct nouveau_connector *nv_connector = nouveau_connector(connector); 600cb459498Sriastradh struct drm_device *dev = connector->dev; 601cb459498Sriastradh struct drm_display_mode *mode, *largest = NULL; 602cb459498Sriastradh int high_w = 0, high_h = 0, high_v = 0; 603cb459498Sriastradh 604cb459498Sriastradh list_for_each_entry(mode, &nv_connector->base.probed_modes, head) { 605cb459498Sriastradh mode->vrefresh = drm_mode_vrefresh(mode); 606cb459498Sriastradh if (helper->mode_valid(connector, mode) != MODE_OK || 607cb459498Sriastradh (mode->flags & DRM_MODE_FLAG_INTERLACE)) 608cb459498Sriastradh continue; 609cb459498Sriastradh 610cb459498Sriastradh /* Use preferred mode if there is one.. */ 611cb459498Sriastradh if (mode->type & DRM_MODE_TYPE_PREFERRED) { 612cb459498Sriastradh NV_DEBUG(drm, "native mode from preferred\n"); 613cb459498Sriastradh return drm_mode_duplicate(dev, mode); 614cb459498Sriastradh } 615cb459498Sriastradh 616cb459498Sriastradh /* Otherwise, take the resolution with the largest width, then 617cb459498Sriastradh * height, then vertical refresh 618cb459498Sriastradh */ 619cb459498Sriastradh if (mode->hdisplay < high_w) 620cb459498Sriastradh continue; 621cb459498Sriastradh 622cb459498Sriastradh if (mode->hdisplay == high_w && mode->vdisplay < high_h) 623cb459498Sriastradh continue; 624cb459498Sriastradh 625cb459498Sriastradh if (mode->hdisplay == high_w && mode->vdisplay == high_h && 626cb459498Sriastradh mode->vrefresh < high_v) 627cb459498Sriastradh continue; 628cb459498Sriastradh 629cb459498Sriastradh high_w = mode->hdisplay; 630cb459498Sriastradh high_h = mode->vdisplay; 631cb459498Sriastradh high_v = mode->vrefresh; 632cb459498Sriastradh largest = mode; 633cb459498Sriastradh } 634cb459498Sriastradh 635cb459498Sriastradh NV_DEBUG(drm, "native mode from largest: %dx%d@%d\n", 636cb459498Sriastradh high_w, high_h, high_v); 637cb459498Sriastradh return largest ? drm_mode_duplicate(dev, largest) : NULL; 638cb459498Sriastradh } 639cb459498Sriastradh 640cb459498Sriastradh struct moderec { 641cb459498Sriastradh int hdisplay; 642cb459498Sriastradh int vdisplay; 643cb459498Sriastradh }; 644cb459498Sriastradh 645cb459498Sriastradh static struct moderec scaler_modes[] = { 646cb459498Sriastradh { 1920, 1200 }, 647cb459498Sriastradh { 1920, 1080 }, 648cb459498Sriastradh { 1680, 1050 }, 649cb459498Sriastradh { 1600, 1200 }, 650cb459498Sriastradh { 1400, 1050 }, 651cb459498Sriastradh { 1280, 1024 }, 652cb459498Sriastradh { 1280, 960 }, 653cb459498Sriastradh { 1152, 864 }, 654cb459498Sriastradh { 1024, 768 }, 655cb459498Sriastradh { 800, 600 }, 656cb459498Sriastradh { 720, 400 }, 657cb459498Sriastradh { 640, 480 }, 658cb459498Sriastradh { 640, 400 }, 659cb459498Sriastradh { 640, 350 }, 660cb459498Sriastradh {} 661cb459498Sriastradh }; 662cb459498Sriastradh 663cb459498Sriastradh static int 664cb459498Sriastradh nouveau_connector_scaler_modes_add(struct drm_connector *connector) 665cb459498Sriastradh { 666cb459498Sriastradh struct nouveau_connector *nv_connector = nouveau_connector(connector); 667cb459498Sriastradh struct drm_display_mode *native = nv_connector->native_mode, *m; 668cb459498Sriastradh struct drm_device *dev = connector->dev; 669cb459498Sriastradh struct moderec *mode = &scaler_modes[0]; 670cb459498Sriastradh int modes = 0; 671cb459498Sriastradh 672cb459498Sriastradh if (!native) 673cb459498Sriastradh return 0; 674cb459498Sriastradh 675cb459498Sriastradh while (mode->hdisplay) { 676cb459498Sriastradh if (mode->hdisplay <= native->hdisplay && 677cb459498Sriastradh mode->vdisplay <= native->vdisplay) { 678cb459498Sriastradh m = drm_cvt_mode(dev, mode->hdisplay, mode->vdisplay, 679cb459498Sriastradh drm_mode_vrefresh(native), false, 680cb459498Sriastradh false, false); 681cb459498Sriastradh if (!m) 682cb459498Sriastradh continue; 683cb459498Sriastradh 684cb459498Sriastradh m->type |= DRM_MODE_TYPE_DRIVER; 685cb459498Sriastradh 686cb459498Sriastradh drm_mode_probed_add(connector, m); 687cb459498Sriastradh modes++; 688cb459498Sriastradh } 689cb459498Sriastradh 690cb459498Sriastradh mode++; 691cb459498Sriastradh } 692cb459498Sriastradh 693cb459498Sriastradh return modes; 694cb459498Sriastradh } 695cb459498Sriastradh 696cb459498Sriastradh static void 697cb459498Sriastradh nouveau_connector_detect_depth(struct drm_connector *connector) 698cb459498Sriastradh { 699cb459498Sriastradh struct nouveau_drm *drm = nouveau_drm(connector->dev); 700cb459498Sriastradh struct nouveau_connector *nv_connector = nouveau_connector(connector); 701cb459498Sriastradh struct nouveau_encoder *nv_encoder = nv_connector->detected_encoder; 702cb459498Sriastradh struct nvbios *bios = &drm->vbios; 703cb459498Sriastradh struct drm_display_mode *mode = nv_connector->native_mode; 704cb459498Sriastradh bool duallink; 705cb459498Sriastradh 706cb459498Sriastradh /* if the edid is feeling nice enough to provide this info, use it */ 707cb459498Sriastradh if (nv_connector->edid && connector->display_info.bpc) 708cb459498Sriastradh return; 709cb459498Sriastradh 710cb459498Sriastradh /* EDID 1.4 is *supposed* to be supported on eDP, but, Apple... */ 711cb459498Sriastradh if (nv_connector->type == DCB_CONNECTOR_eDP) { 712cb459498Sriastradh connector->display_info.bpc = 6; 713cb459498Sriastradh return; 714cb459498Sriastradh } 715cb459498Sriastradh 716cb459498Sriastradh /* we're out of options unless we're LVDS, default to 8bpc */ 717cb459498Sriastradh if (nv_encoder->dcb->type != DCB_OUTPUT_LVDS) { 718cb459498Sriastradh connector->display_info.bpc = 8; 719cb459498Sriastradh return; 720cb459498Sriastradh } 721cb459498Sriastradh 722cb459498Sriastradh connector->display_info.bpc = 6; 723cb459498Sriastradh 724cb459498Sriastradh /* LVDS: panel straps */ 725cb459498Sriastradh if (bios->fp_no_ddc) { 726cb459498Sriastradh if (bios->fp.if_is_24bit) 727cb459498Sriastradh connector->display_info.bpc = 8; 728cb459498Sriastradh return; 729cb459498Sriastradh } 730cb459498Sriastradh 731cb459498Sriastradh /* LVDS: DDC panel, need to first determine the number of links to 732cb459498Sriastradh * know which if_is_24bit flag to check... 733cb459498Sriastradh */ 734cb459498Sriastradh if (nv_connector->edid && 735cb459498Sriastradh nv_connector->type == DCB_CONNECTOR_LVDS_SPWG) 736cb459498Sriastradh duallink = ((u8 *)nv_connector->edid)[121] == 2; 737cb459498Sriastradh else 738cb459498Sriastradh duallink = mode->clock >= bios->fp.duallink_transition_clk; 739cb459498Sriastradh 740cb459498Sriastradh if ((!duallink && (bios->fp.strapless_is_24bit & 1)) || 741cb459498Sriastradh ( duallink && (bios->fp.strapless_is_24bit & 2))) 742cb459498Sriastradh connector->display_info.bpc = 8; 743cb459498Sriastradh } 744cb459498Sriastradh 745cb459498Sriastradh static int 746cb459498Sriastradh nouveau_connector_get_modes(struct drm_connector *connector) 747cb459498Sriastradh { 748cb459498Sriastradh struct drm_device *dev = connector->dev; 749cb459498Sriastradh struct nouveau_drm *drm = nouveau_drm(dev); 750cb459498Sriastradh struct nouveau_connector *nv_connector = nouveau_connector(connector); 751cb459498Sriastradh struct nouveau_encoder *nv_encoder = nv_connector->detected_encoder; 752cb459498Sriastradh struct drm_encoder *encoder = to_drm_encoder(nv_encoder); 753cb459498Sriastradh int ret = 0; 754cb459498Sriastradh 755cb459498Sriastradh /* destroy the native mode, the attached monitor could have changed. 756cb459498Sriastradh */ 757cb459498Sriastradh if (nv_connector->native_mode) { 758cb459498Sriastradh drm_mode_destroy(dev, nv_connector->native_mode); 759cb459498Sriastradh nv_connector->native_mode = NULL; 760cb459498Sriastradh } 761cb459498Sriastradh 762cb459498Sriastradh if (nv_connector->edid) 763cb459498Sriastradh ret = drm_add_edid_modes(connector, nv_connector->edid); 764cb459498Sriastradh else 765cb459498Sriastradh if (nv_encoder->dcb->type == DCB_OUTPUT_LVDS && 766cb459498Sriastradh (nv_encoder->dcb->lvdsconf.use_straps_for_mode || 767cb459498Sriastradh drm->vbios.fp_no_ddc) && nouveau_bios_fp_mode(dev, NULL)) { 768cb459498Sriastradh struct drm_display_mode mode; 769cb459498Sriastradh 770cb459498Sriastradh nouveau_bios_fp_mode(dev, &mode); 771cb459498Sriastradh nv_connector->native_mode = drm_mode_duplicate(dev, &mode); 772cb459498Sriastradh } 773cb459498Sriastradh 774cb459498Sriastradh /* Determine display colour depth for everything except LVDS now, 775cb459498Sriastradh * DP requires this before mode_valid() is called. 776cb459498Sriastradh */ 777cb459498Sriastradh if (connector->connector_type != DRM_MODE_CONNECTOR_LVDS) 778cb459498Sriastradh nouveau_connector_detect_depth(connector); 779cb459498Sriastradh 780cb459498Sriastradh /* Find the native mode if this is a digital panel, if we didn't 781cb459498Sriastradh * find any modes through DDC previously add the native mode to 782cb459498Sriastradh * the list of modes. 783cb459498Sriastradh */ 784cb459498Sriastradh if (!nv_connector->native_mode) 785cb459498Sriastradh nv_connector->native_mode = 786cb459498Sriastradh nouveau_connector_native_mode(connector); 787cb459498Sriastradh if (ret == 0 && nv_connector->native_mode) { 788cb459498Sriastradh struct drm_display_mode *mode; 789cb459498Sriastradh 790cb459498Sriastradh mode = drm_mode_duplicate(dev, nv_connector->native_mode); 791cb459498Sriastradh drm_mode_probed_add(connector, mode); 792cb459498Sriastradh ret = 1; 793cb459498Sriastradh } 794cb459498Sriastradh 795cb459498Sriastradh /* Determine LVDS colour depth, must happen after determining 796cb459498Sriastradh * "native" mode as some VBIOS tables require us to use the 797cb459498Sriastradh * pixel clock as part of the lookup... 798cb459498Sriastradh */ 799cb459498Sriastradh if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS) 800cb459498Sriastradh nouveau_connector_detect_depth(connector); 801cb459498Sriastradh 802cb459498Sriastradh if (nv_encoder->dcb->type == DCB_OUTPUT_TV) 803cb459498Sriastradh ret = get_slave_funcs(encoder)->get_modes(encoder, connector); 804cb459498Sriastradh 805cb459498Sriastradh if (nv_connector->type == DCB_CONNECTOR_LVDS || 806cb459498Sriastradh nv_connector->type == DCB_CONNECTOR_LVDS_SPWG || 807cb459498Sriastradh nv_connector->type == DCB_CONNECTOR_eDP) 808cb459498Sriastradh ret += nouveau_connector_scaler_modes_add(connector); 809cb459498Sriastradh 810cb459498Sriastradh return ret; 811cb459498Sriastradh } 812cb459498Sriastradh 813cb459498Sriastradh static unsigned 814cb459498Sriastradh get_tmds_link_bandwidth(struct drm_connector *connector) 815cb459498Sriastradh { 816cb459498Sriastradh struct nouveau_connector *nv_connector = nouveau_connector(connector); 817cb459498Sriastradh struct nouveau_drm *drm = nouveau_drm(connector->dev); 818cb459498Sriastradh struct dcb_output *dcb = nv_connector->detected_encoder->dcb; 819cb459498Sriastradh 820cb459498Sriastradh if (dcb->location != DCB_LOC_ON_CHIP || 821cb459498Sriastradh nv_device(drm->device)->chipset >= 0x46) 822cb459498Sriastradh return 165000; 823cb459498Sriastradh else if (nv_device(drm->device)->chipset >= 0x40) 824cb459498Sriastradh return 155000; 825cb459498Sriastradh else if (nv_device(drm->device)->chipset >= 0x18) 826cb459498Sriastradh return 135000; 827cb459498Sriastradh else 828cb459498Sriastradh return 112000; 829cb459498Sriastradh } 830cb459498Sriastradh 831cb459498Sriastradh static int 832cb459498Sriastradh nouveau_connector_mode_valid(struct drm_connector *connector, 833cb459498Sriastradh struct drm_display_mode *mode) 834cb459498Sriastradh { 835cb459498Sriastradh struct nouveau_connector *nv_connector = nouveau_connector(connector); 836cb459498Sriastradh struct nouveau_encoder *nv_encoder = nv_connector->detected_encoder; 837cb459498Sriastradh struct drm_encoder *encoder = to_drm_encoder(nv_encoder); 838cb459498Sriastradh unsigned min_clock = 25000, max_clock = min_clock; 839cb459498Sriastradh unsigned clock = mode->clock; 840cb459498Sriastradh 841cb459498Sriastradh switch (nv_encoder->dcb->type) { 842cb459498Sriastradh case DCB_OUTPUT_LVDS: 843cb459498Sriastradh if (nv_connector->native_mode && 844cb459498Sriastradh (mode->hdisplay > nv_connector->native_mode->hdisplay || 845cb459498Sriastradh mode->vdisplay > nv_connector->native_mode->vdisplay)) 846cb459498Sriastradh return MODE_PANEL; 847cb459498Sriastradh 848cb459498Sriastradh min_clock = 0; 849cb459498Sriastradh max_clock = 400000; 850cb459498Sriastradh break; 851cb459498Sriastradh case DCB_OUTPUT_TMDS: 852cb459498Sriastradh max_clock = get_tmds_link_bandwidth(connector); 853cb459498Sriastradh if (nouveau_duallink && nv_encoder->dcb->duallink_possible) 854cb459498Sriastradh max_clock *= 2; 855cb459498Sriastradh break; 856cb459498Sriastradh case DCB_OUTPUT_ANALOG: 857cb459498Sriastradh max_clock = nv_encoder->dcb->crtconf.maxfreq; 858cb459498Sriastradh if (!max_clock) 859cb459498Sriastradh max_clock = 350000; 860cb459498Sriastradh break; 861cb459498Sriastradh case DCB_OUTPUT_TV: 862cb459498Sriastradh return get_slave_funcs(encoder)->mode_valid(encoder, mode); 863cb459498Sriastradh case DCB_OUTPUT_DP: 864cb459498Sriastradh max_clock = nv_encoder->dp.link_nr; 865cb459498Sriastradh max_clock *= nv_encoder->dp.link_bw; 866cb459498Sriastradh clock = clock * (connector->display_info.bpc * 3) / 10; 867cb459498Sriastradh break; 868cb459498Sriastradh default: 869cb459498Sriastradh BUG_ON(1); 870cb459498Sriastradh return MODE_BAD; 871cb459498Sriastradh } 872cb459498Sriastradh 873cb459498Sriastradh if (clock < min_clock) 874cb459498Sriastradh return MODE_CLOCK_LOW; 875cb459498Sriastradh 876cb459498Sriastradh if (clock > max_clock) 877cb459498Sriastradh return MODE_CLOCK_HIGH; 878cb459498Sriastradh 879cb459498Sriastradh return MODE_OK; 880cb459498Sriastradh } 881cb459498Sriastradh 882cb459498Sriastradh static struct drm_encoder * 883cb459498Sriastradh nouveau_connector_best_encoder(struct drm_connector *connector) 884cb459498Sriastradh { 885cb459498Sriastradh struct nouveau_connector *nv_connector = nouveau_connector(connector); 886cb459498Sriastradh 887cb459498Sriastradh if (nv_connector->detected_encoder) 888cb459498Sriastradh return to_drm_encoder(nv_connector->detected_encoder); 889cb459498Sriastradh 890cb459498Sriastradh return NULL; 891cb459498Sriastradh } 892cb459498Sriastradh 893cb459498Sriastradh static const struct drm_connector_helper_funcs 894cb459498Sriastradh nouveau_connector_helper_funcs = { 895cb459498Sriastradh .get_modes = nouveau_connector_get_modes, 896cb459498Sriastradh .mode_valid = nouveau_connector_mode_valid, 897cb459498Sriastradh .best_encoder = nouveau_connector_best_encoder, 898cb459498Sriastradh }; 899cb459498Sriastradh 900cb459498Sriastradh static const struct drm_connector_funcs 901cb459498Sriastradh nouveau_connector_funcs = { 902cb459498Sriastradh .dpms = drm_helper_connector_dpms, 903cb459498Sriastradh .save = NULL, 904cb459498Sriastradh .restore = NULL, 905cb459498Sriastradh .detect = nouveau_connector_detect, 906cb459498Sriastradh .destroy = nouveau_connector_destroy, 907cb459498Sriastradh .fill_modes = drm_helper_probe_single_connector_modes, 908cb459498Sriastradh .set_property = nouveau_connector_set_property, 909cb459498Sriastradh .force = nouveau_connector_force 910cb459498Sriastradh }; 911cb459498Sriastradh 912cb459498Sriastradh static const struct drm_connector_funcs 913cb459498Sriastradh nouveau_connector_funcs_lvds = { 914cb459498Sriastradh .dpms = drm_helper_connector_dpms, 915cb459498Sriastradh .save = NULL, 916cb459498Sriastradh .restore = NULL, 917cb459498Sriastradh .detect = nouveau_connector_detect_lvds, 918cb459498Sriastradh .destroy = nouveau_connector_destroy, 919cb459498Sriastradh .fill_modes = drm_helper_probe_single_connector_modes, 920cb459498Sriastradh .set_property = nouveau_connector_set_property, 921cb459498Sriastradh .force = nouveau_connector_force 922cb459498Sriastradh }; 923cb459498Sriastradh 924cb459498Sriastradh static void 925cb459498Sriastradh nouveau_connector_hotplug_work(struct work_struct *work) 926cb459498Sriastradh { 927cb459498Sriastradh struct nouveau_connector *nv_connector = 928cb459498Sriastradh container_of(work, struct nouveau_connector, hpd_work); 929cb459498Sriastradh struct drm_connector *connector = &nv_connector->base; 930cb459498Sriastradh struct drm_device *dev = connector->dev; 931cb459498Sriastradh struct nouveau_drm *drm = nouveau_drm(dev); 932cb459498Sriastradh struct nouveau_gpio *gpio = nouveau_gpio(drm->device); 933cb459498Sriastradh bool plugged = gpio->get(gpio, 0, nv_connector->hpd.func, 0xff); 934cb459498Sriastradh 935cb459498Sriastradh NV_DEBUG(drm, "%splugged %s\n", plugged ? "" : "un", 936cb459498Sriastradh drm_get_connector_name(connector)); 937cb459498Sriastradh 938cb459498Sriastradh if (plugged) 939cb459498Sriastradh drm_helper_connector_dpms(connector, DRM_MODE_DPMS_ON); 940cb459498Sriastradh else 941cb459498Sriastradh drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF); 942cb459498Sriastradh 943cb459498Sriastradh drm_helper_hpd_irq_event(dev); 944cb459498Sriastradh } 945cb459498Sriastradh 946cb459498Sriastradh static int 947cb459498Sriastradh nouveau_connector_hotplug(void *data, int index) 948cb459498Sriastradh { 949cb459498Sriastradh struct nouveau_connector *nv_connector = data; 950cb459498Sriastradh schedule_work(&nv_connector->hpd_work); 951cb459498Sriastradh return NVKM_EVENT_KEEP; 952cb459498Sriastradh } 953cb459498Sriastradh 954cb459498Sriastradh static int 955cb459498Sriastradh drm_conntype_from_dcb(enum dcb_connector_type dcb) 956cb459498Sriastradh { 957cb459498Sriastradh switch (dcb) { 958cb459498Sriastradh case DCB_CONNECTOR_VGA : return DRM_MODE_CONNECTOR_VGA; 959cb459498Sriastradh case DCB_CONNECTOR_TV_0 : 960cb459498Sriastradh case DCB_CONNECTOR_TV_1 : 961cb459498Sriastradh case DCB_CONNECTOR_TV_3 : return DRM_MODE_CONNECTOR_TV; 962cb459498Sriastradh case DCB_CONNECTOR_DMS59_0 : 963cb459498Sriastradh case DCB_CONNECTOR_DMS59_1 : 964cb459498Sriastradh case DCB_CONNECTOR_DVI_I : return DRM_MODE_CONNECTOR_DVII; 965cb459498Sriastradh case DCB_CONNECTOR_DVI_D : return DRM_MODE_CONNECTOR_DVID; 966cb459498Sriastradh case DCB_CONNECTOR_LVDS : 967cb459498Sriastradh case DCB_CONNECTOR_LVDS_SPWG: return DRM_MODE_CONNECTOR_LVDS; 968cb459498Sriastradh case DCB_CONNECTOR_DMS59_DP0: 969cb459498Sriastradh case DCB_CONNECTOR_DMS59_DP1: 970cb459498Sriastradh case DCB_CONNECTOR_DP : return DRM_MODE_CONNECTOR_DisplayPort; 971cb459498Sriastradh case DCB_CONNECTOR_eDP : return DRM_MODE_CONNECTOR_eDP; 972cb459498Sriastradh case DCB_CONNECTOR_HDMI_0 : 973cb459498Sriastradh case DCB_CONNECTOR_HDMI_1 : 974cb459498Sriastradh case DCB_CONNECTOR_HDMI_C : return DRM_MODE_CONNECTOR_HDMIA; 975cb459498Sriastradh default: 976cb459498Sriastradh break; 977cb459498Sriastradh } 978cb459498Sriastradh 979cb459498Sriastradh return DRM_MODE_CONNECTOR_Unknown; 980cb459498Sriastradh } 981cb459498Sriastradh 982cb459498Sriastradh struct drm_connector * 983cb459498Sriastradh nouveau_connector_create(struct drm_device *dev, int index) 984cb459498Sriastradh { 985cb459498Sriastradh const struct drm_connector_funcs *funcs = &nouveau_connector_funcs; 986cb459498Sriastradh struct nouveau_drm *drm = nouveau_drm(dev); 987cb459498Sriastradh struct nouveau_gpio *gpio = nouveau_gpio(drm->device); 988cb459498Sriastradh struct nouveau_display *disp = nouveau_display(dev); 989cb459498Sriastradh struct nouveau_connector *nv_connector = NULL; 990cb459498Sriastradh struct drm_connector *connector; 991cb459498Sriastradh int type, ret = 0; 992cb459498Sriastradh bool dummy; 993cb459498Sriastradh 994cb459498Sriastradh list_for_each_entry(connector, &dev->mode_config.connector_list, head) { 995cb459498Sriastradh nv_connector = nouveau_connector(connector); 996cb459498Sriastradh if (nv_connector->index == index) 997cb459498Sriastradh return connector; 998cb459498Sriastradh } 999cb459498Sriastradh 1000cb459498Sriastradh nv_connector = kzalloc(sizeof(*nv_connector), GFP_KERNEL); 1001cb459498Sriastradh if (!nv_connector) 1002cb459498Sriastradh return ERR_PTR(-ENOMEM); 1003cb459498Sriastradh 1004cb459498Sriastradh connector = &nv_connector->base; 1005cb459498Sriastradh INIT_WORK(&nv_connector->hpd_work, nouveau_connector_hotplug_work); 1006cb459498Sriastradh nv_connector->index = index; 1007cb459498Sriastradh 1008cb459498Sriastradh /* attempt to parse vbios connector type and hotplug gpio */ 1009cb459498Sriastradh nv_connector->dcb = olddcb_conn(dev, index); 1010cb459498Sriastradh if (nv_connector->dcb) { 1011cb459498Sriastradh static const u8 hpd[16] = { 1012cb459498Sriastradh 0xff, 0x07, 0x08, 0xff, 0xff, 0x51, 0x52, 0xff, 1013cb459498Sriastradh 0xff, 0xff, 0xff, 0xff, 0xff, 0x5e, 0x5f, 0x60, 1014cb459498Sriastradh }; 1015cb459498Sriastradh 1016cb459498Sriastradh u32 entry = ROM16(nv_connector->dcb[0]); 1017cb459498Sriastradh if (olddcb_conntab(dev)[3] >= 4) 1018cb459498Sriastradh entry |= (u32)ROM16(nv_connector->dcb[2]) << 16; 1019cb459498Sriastradh 1020cb459498Sriastradh ret = gpio->find(gpio, 0, hpd[ffs((entry & 0x07033000) >> 12)], 1021cb459498Sriastradh DCB_GPIO_UNUSED, &nv_connector->hpd); 1022cb459498Sriastradh if (ret) 1023cb459498Sriastradh nv_connector->hpd.func = DCB_GPIO_UNUSED; 1024cb459498Sriastradh 1025cb459498Sriastradh if (nv_connector->hpd.func != DCB_GPIO_UNUSED) { 1026cb459498Sriastradh nouveau_event_new(gpio->events, nv_connector->hpd.line, 1027cb459498Sriastradh nouveau_connector_hotplug, 1028cb459498Sriastradh nv_connector, 1029cb459498Sriastradh &nv_connector->hpd_func); 1030cb459498Sriastradh } 1031cb459498Sriastradh 1032cb459498Sriastradh nv_connector->type = nv_connector->dcb[0]; 1033cb459498Sriastradh if (drm_conntype_from_dcb(nv_connector->type) == 1034cb459498Sriastradh DRM_MODE_CONNECTOR_Unknown) { 1035cb459498Sriastradh NV_WARN(drm, "unknown connector type %02x\n", 1036cb459498Sriastradh nv_connector->type); 1037cb459498Sriastradh nv_connector->type = DCB_CONNECTOR_NONE; 1038cb459498Sriastradh } 1039cb459498Sriastradh 1040cb459498Sriastradh /* Gigabyte NX85T */ 1041cb459498Sriastradh if (nv_match_device(dev, 0x0421, 0x1458, 0x344c)) { 1042cb459498Sriastradh if (nv_connector->type == DCB_CONNECTOR_HDMI_1) 1043cb459498Sriastradh nv_connector->type = DCB_CONNECTOR_DVI_I; 1044cb459498Sriastradh } 1045cb459498Sriastradh 1046cb459498Sriastradh /* Gigabyte GV-NX86T512H */ 1047cb459498Sriastradh if (nv_match_device(dev, 0x0402, 0x1458, 0x3455)) { 1048cb459498Sriastradh if (nv_connector->type == DCB_CONNECTOR_HDMI_1) 1049cb459498Sriastradh nv_connector->type = DCB_CONNECTOR_DVI_I; 1050cb459498Sriastradh } 1051cb459498Sriastradh } else { 1052cb459498Sriastradh nv_connector->type = DCB_CONNECTOR_NONE; 1053cb459498Sriastradh nv_connector->hpd.func = DCB_GPIO_UNUSED; 1054cb459498Sriastradh } 1055cb459498Sriastradh 1056cb459498Sriastradh /* no vbios data, or an unknown dcb connector type - attempt to 1057cb459498Sriastradh * figure out something suitable ourselves 1058cb459498Sriastradh */ 1059cb459498Sriastradh if (nv_connector->type == DCB_CONNECTOR_NONE) { 1060cb459498Sriastradh struct dcb_table *dcbt = &drm->vbios.dcb; 1061cb459498Sriastradh u32 encoders = 0; 1062cb459498Sriastradh int i; 1063cb459498Sriastradh 1064cb459498Sriastradh for (i = 0; i < dcbt->entries; i++) { 1065cb459498Sriastradh if (dcbt->entry[i].connector == nv_connector->index) 1066cb459498Sriastradh encoders |= (1 << dcbt->entry[i].type); 1067cb459498Sriastradh } 1068cb459498Sriastradh 1069cb459498Sriastradh if (encoders & (1 << DCB_OUTPUT_DP)) { 1070cb459498Sriastradh if (encoders & (1 << DCB_OUTPUT_TMDS)) 1071cb459498Sriastradh nv_connector->type = DCB_CONNECTOR_DP; 1072cb459498Sriastradh else 1073cb459498Sriastradh nv_connector->type = DCB_CONNECTOR_eDP; 1074cb459498Sriastradh } else 1075cb459498Sriastradh if (encoders & (1 << DCB_OUTPUT_TMDS)) { 1076cb459498Sriastradh if (encoders & (1 << DCB_OUTPUT_ANALOG)) 1077cb459498Sriastradh nv_connector->type = DCB_CONNECTOR_DVI_I; 1078cb459498Sriastradh else 1079cb459498Sriastradh nv_connector->type = DCB_CONNECTOR_DVI_D; 1080cb459498Sriastradh } else 1081cb459498Sriastradh if (encoders & (1 << DCB_OUTPUT_ANALOG)) { 1082cb459498Sriastradh nv_connector->type = DCB_CONNECTOR_VGA; 1083cb459498Sriastradh } else 1084cb459498Sriastradh if (encoders & (1 << DCB_OUTPUT_LVDS)) { 1085cb459498Sriastradh nv_connector->type = DCB_CONNECTOR_LVDS; 1086cb459498Sriastradh } else 1087cb459498Sriastradh if (encoders & (1 << DCB_OUTPUT_TV)) { 1088cb459498Sriastradh nv_connector->type = DCB_CONNECTOR_TV_0; 1089cb459498Sriastradh } 1090cb459498Sriastradh } 1091cb459498Sriastradh 1092cb459498Sriastradh type = drm_conntype_from_dcb(nv_connector->type); 1093cb459498Sriastradh if (type == DRM_MODE_CONNECTOR_LVDS) { 1094cb459498Sriastradh ret = nouveau_bios_parse_lvds_table(dev, 0, &dummy, &dummy); 1095cb459498Sriastradh if (ret) { 1096cb459498Sriastradh NV_ERROR(drm, "Error parsing LVDS table, disabling\n"); 1097cb459498Sriastradh kfree(nv_connector); 1098cb459498Sriastradh return ERR_PTR(ret); 1099cb459498Sriastradh } 1100cb459498Sriastradh 1101cb459498Sriastradh funcs = &nouveau_connector_funcs_lvds; 1102cb459498Sriastradh } else { 1103cb459498Sriastradh funcs = &nouveau_connector_funcs; 1104cb459498Sriastradh } 1105cb459498Sriastradh 1106cb459498Sriastradh /* defaults, will get overridden in detect() */ 1107cb459498Sriastradh connector->interlace_allowed = false; 1108cb459498Sriastradh connector->doublescan_allowed = false; 1109cb459498Sriastradh 1110cb459498Sriastradh drm_connector_init(dev, connector, funcs, type); 1111cb459498Sriastradh drm_connector_helper_add(connector, &nouveau_connector_helper_funcs); 1112cb459498Sriastradh 1113cb459498Sriastradh /* Init DVI-I specific properties */ 1114cb459498Sriastradh if (nv_connector->type == DCB_CONNECTOR_DVI_I) 1115cb459498Sriastradh drm_object_attach_property(&connector->base, dev->mode_config.dvi_i_subconnector_property, 0); 1116cb459498Sriastradh 1117cb459498Sriastradh /* Add overscan compensation options to digital outputs */ 1118cb459498Sriastradh if (disp->underscan_property && 1119cb459498Sriastradh (type == DRM_MODE_CONNECTOR_DVID || 1120cb459498Sriastradh type == DRM_MODE_CONNECTOR_DVII || 1121cb459498Sriastradh type == DRM_MODE_CONNECTOR_HDMIA || 1122cb459498Sriastradh type == DRM_MODE_CONNECTOR_DisplayPort)) { 1123cb459498Sriastradh drm_object_attach_property(&connector->base, 1124cb459498Sriastradh disp->underscan_property, 1125cb459498Sriastradh UNDERSCAN_OFF); 1126cb459498Sriastradh drm_object_attach_property(&connector->base, 1127cb459498Sriastradh disp->underscan_hborder_property, 1128cb459498Sriastradh 0); 1129cb459498Sriastradh drm_object_attach_property(&connector->base, 1130cb459498Sriastradh disp->underscan_vborder_property, 1131cb459498Sriastradh 0); 1132cb459498Sriastradh } 1133cb459498Sriastradh 1134cb459498Sriastradh /* Add hue and saturation options */ 1135cb459498Sriastradh if (disp->vibrant_hue_property) 1136cb459498Sriastradh drm_object_attach_property(&connector->base, 1137cb459498Sriastradh disp->vibrant_hue_property, 1138cb459498Sriastradh 90); 1139cb459498Sriastradh if (disp->color_vibrance_property) 1140cb459498Sriastradh drm_object_attach_property(&connector->base, 1141cb459498Sriastradh disp->color_vibrance_property, 1142cb459498Sriastradh 150); 1143cb459498Sriastradh 1144cb459498Sriastradh switch (nv_connector->type) { 1145cb459498Sriastradh case DCB_CONNECTOR_VGA: 1146cb459498Sriastradh if (nv_device(drm->device)->card_type >= NV_50) { 1147cb459498Sriastradh drm_object_attach_property(&connector->base, 1148cb459498Sriastradh dev->mode_config.scaling_mode_property, 1149cb459498Sriastradh nv_connector->scaling_mode); 1150cb459498Sriastradh } 1151cb459498Sriastradh /* fall-through */ 1152cb459498Sriastradh case DCB_CONNECTOR_TV_0: 1153cb459498Sriastradh case DCB_CONNECTOR_TV_1: 1154cb459498Sriastradh case DCB_CONNECTOR_TV_3: 1155cb459498Sriastradh nv_connector->scaling_mode = DRM_MODE_SCALE_NONE; 1156cb459498Sriastradh break; 1157cb459498Sriastradh default: 1158cb459498Sriastradh nv_connector->scaling_mode = DRM_MODE_SCALE_FULLSCREEN; 1159cb459498Sriastradh 1160cb459498Sriastradh drm_object_attach_property(&connector->base, 1161cb459498Sriastradh dev->mode_config.scaling_mode_property, 1162cb459498Sriastradh nv_connector->scaling_mode); 1163cb459498Sriastradh if (disp->dithering_mode) { 1164cb459498Sriastradh nv_connector->dithering_mode = DITHERING_MODE_AUTO; 1165cb459498Sriastradh drm_object_attach_property(&connector->base, 1166cb459498Sriastradh disp->dithering_mode, 1167cb459498Sriastradh nv_connector->dithering_mode); 1168cb459498Sriastradh } 1169cb459498Sriastradh if (disp->dithering_depth) { 1170cb459498Sriastradh nv_connector->dithering_depth = DITHERING_DEPTH_AUTO; 1171cb459498Sriastradh drm_object_attach_property(&connector->base, 1172cb459498Sriastradh disp->dithering_depth, 1173cb459498Sriastradh nv_connector->dithering_depth); 1174cb459498Sriastradh } 1175cb459498Sriastradh break; 1176cb459498Sriastradh } 1177cb459498Sriastradh 1178cb459498Sriastradh connector->polled = DRM_CONNECTOR_POLL_CONNECT; 1179cb459498Sriastradh if (nv_connector->hpd.func != DCB_GPIO_UNUSED) 1180cb459498Sriastradh connector->polled = DRM_CONNECTOR_POLL_HPD; 1181cb459498Sriastradh 1182cb459498Sriastradh drm_sysfs_connector_add(connector); 1183cb459498Sriastradh return connector; 1184cb459498Sriastradh } 1185