intel_dvo.c revision 79e539453b34e35f39299a899d263b0a1f1670bd
1/* 2 * Copyright 2006 Dave Airlie <airlied@linux.ie> 3 * Copyright © 2006-2007 Intel Corporation 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining a 6 * copy of this software and associated documentation files (the "Software"), 7 * to deal in the Software without restriction, including without limitation 8 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 9 * and/or sell copies of the Software, and to permit persons to whom the 10 * Software is furnished to do so, subject to the following conditions: 11 * 12 * The above copyright notice and this permission notice (including the next 13 * paragraph) shall be included in all copies or substantial portions of the 14 * Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22 * DEALINGS IN THE SOFTWARE. 23 * 24 * Authors: 25 * Eric Anholt <eric@anholt.net> 26 */ 27#include <linux/i2c.h> 28#include "drmP.h" 29#include "drm.h" 30#include "drm_crtc.h" 31#include "intel_drv.h" 32#include "i915_drm.h" 33#include "i915_drv.h" 34#include "dvo.h" 35 36#define SIL164_ADDR 0x38 37#define CH7xxx_ADDR 0x76 38#define TFP410_ADDR 0x38 39 40extern struct intel_dvo_dev_ops sil164_ops; 41extern struct intel_dvo_dev_ops ch7xxx_ops; 42extern struct intel_dvo_dev_ops ivch_ops; 43extern struct intel_dvo_dev_ops tfp410_ops; 44extern struct intel_dvo_dev_ops ch7017_ops; 45 46struct intel_dvo_device intel_dvo_devices[] = { 47 { 48 .type = INTEL_DVO_CHIP_TMDS, 49 .name = "sil164", 50 .dvo_reg = DVOC, 51 .slave_addr = SIL164_ADDR, 52 .dev_ops = &sil164_ops, 53 }, 54 { 55 .type = INTEL_DVO_CHIP_TMDS, 56 .name = "ch7xxx", 57 .dvo_reg = DVOC, 58 .slave_addr = CH7xxx_ADDR, 59 .dev_ops = &ch7xxx_ops, 60 }, 61 { 62 .type = INTEL_DVO_CHIP_LVDS, 63 .name = "ivch", 64 .dvo_reg = DVOA, 65 .slave_addr = 0x02, /* Might also be 0x44, 0x84, 0xc4 */ 66 .dev_ops = &ivch_ops, 67 }, 68 { 69 .type = INTEL_DVO_CHIP_TMDS, 70 .name = "tfp410", 71 .dvo_reg = DVOC, 72 .slave_addr = TFP410_ADDR, 73 .dev_ops = &tfp410_ops, 74 }, 75 { 76 .type = INTEL_DVO_CHIP_LVDS, 77 .name = "ch7017", 78 .dvo_reg = DVOC, 79 .slave_addr = 0x75, 80 .gpio = GPIOE, 81 .dev_ops = &ch7017_ops, 82 } 83}; 84 85static void intel_dvo_dpms(struct drm_encoder *encoder, int mode) 86{ 87 struct drm_i915_private *dev_priv = encoder->dev->dev_private; 88 struct intel_output *intel_output = enc_to_intel_output(encoder); 89 struct intel_dvo_device *dvo = intel_output->dev_priv; 90 u32 dvo_reg = dvo->dvo_reg; 91 u32 temp = I915_READ(dvo_reg); 92 93 if (mode == DRM_MODE_DPMS_ON) { 94 I915_WRITE(dvo_reg, temp | DVO_ENABLE); 95 I915_READ(dvo_reg); 96 dvo->dev_ops->dpms(dvo, mode); 97 } else { 98 dvo->dev_ops->dpms(dvo, mode); 99 I915_WRITE(dvo_reg, temp & ~DVO_ENABLE); 100 I915_READ(dvo_reg); 101 } 102} 103 104static void intel_dvo_save(struct drm_connector *connector) 105{ 106 struct drm_i915_private *dev_priv = connector->dev->dev_private; 107 struct intel_output *intel_output = to_intel_output(connector); 108 struct intel_dvo_device *dvo = intel_output->dev_priv; 109 110 /* Each output should probably just save the registers it touches, 111 * but for now, use more overkill. 112 */ 113 dev_priv->saveDVOA = I915_READ(DVOA); 114 dev_priv->saveDVOB = I915_READ(DVOB); 115 dev_priv->saveDVOC = I915_READ(DVOC); 116 117 dvo->dev_ops->save(dvo); 118} 119 120static void intel_dvo_restore(struct drm_connector *connector) 121{ 122 struct drm_i915_private *dev_priv = connector->dev->dev_private; 123 struct intel_output *intel_output = to_intel_output(connector); 124 struct intel_dvo_device *dvo = intel_output->dev_priv; 125 126 dvo->dev_ops->restore(dvo); 127 128 I915_WRITE(DVOA, dev_priv->saveDVOA); 129 I915_WRITE(DVOB, dev_priv->saveDVOB); 130 I915_WRITE(DVOC, dev_priv->saveDVOC); 131} 132 133static int intel_dvo_mode_valid(struct drm_connector *connector, 134 struct drm_display_mode *mode) 135{ 136 struct intel_output *intel_output = to_intel_output(connector); 137 struct intel_dvo_device *dvo = intel_output->dev_priv; 138 139 if (mode->flags & DRM_MODE_FLAG_DBLSCAN) 140 return MODE_NO_DBLESCAN; 141 142 /* XXX: Validate clock range */ 143 144 if (dvo->panel_fixed_mode) { 145 if (mode->hdisplay > dvo->panel_fixed_mode->hdisplay) 146 return MODE_PANEL; 147 if (mode->vdisplay > dvo->panel_fixed_mode->vdisplay) 148 return MODE_PANEL; 149 } 150 151 return dvo->dev_ops->mode_valid(dvo, mode); 152} 153 154static bool intel_dvo_mode_fixup(struct drm_encoder *encoder, 155 struct drm_display_mode *mode, 156 struct drm_display_mode *adjusted_mode) 157{ 158 struct intel_output *intel_output = enc_to_intel_output(encoder); 159 struct intel_dvo_device *dvo = intel_output->dev_priv; 160 161 /* If we have timings from the BIOS for the panel, put them in 162 * to the adjusted mode. The CRTC will be set up for this mode, 163 * with the panel scaling set up to source from the H/VDisplay 164 * of the original mode. 165 */ 166 if (dvo->panel_fixed_mode != NULL) { 167#define C(x) adjusted_mode->x = dvo->panel_fixed_mode->x 168 C(hdisplay); 169 C(hsync_start); 170 C(hsync_end); 171 C(htotal); 172 C(vdisplay); 173 C(vsync_start); 174 C(vsync_end); 175 C(vtotal); 176 C(clock); 177 drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V); 178#undef C 179 } 180 181 if (dvo->dev_ops->mode_fixup) 182 return dvo->dev_ops->mode_fixup(dvo, mode, adjusted_mode); 183 184 return true; 185} 186 187static void intel_dvo_mode_set(struct drm_encoder *encoder, 188 struct drm_display_mode *mode, 189 struct drm_display_mode *adjusted_mode) 190{ 191 struct drm_device *dev = encoder->dev; 192 struct drm_i915_private *dev_priv = dev->dev_private; 193 struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); 194 struct intel_output *intel_output = enc_to_intel_output(encoder); 195 struct intel_dvo_device *dvo = intel_output->dev_priv; 196 int pipe = intel_crtc->pipe; 197 u32 dvo_val; 198 u32 dvo_reg = dvo->dvo_reg, dvo_srcdim_reg; 199 int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B; 200 201 switch (dvo_reg) { 202 case DVOA: 203 default: 204 dvo_srcdim_reg = DVOA_SRCDIM; 205 break; 206 case DVOB: 207 dvo_srcdim_reg = DVOB_SRCDIM; 208 break; 209 case DVOC: 210 dvo_srcdim_reg = DVOC_SRCDIM; 211 break; 212 } 213 214 dvo->dev_ops->mode_set(dvo, mode, adjusted_mode); 215 216 /* Save the data order, since I don't know what it should be set to. */ 217 dvo_val = I915_READ(dvo_reg) & 218 (DVO_PRESERVE_MASK | DVO_DATA_ORDER_GBRG); 219 dvo_val |= DVO_DATA_ORDER_FP | DVO_BORDER_ENABLE | 220 DVO_BLANK_ACTIVE_HIGH; 221 222 if (pipe == 1) 223 dvo_val |= DVO_PIPE_B_SELECT; 224 dvo_val |= DVO_PIPE_STALL; 225 if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC) 226 dvo_val |= DVO_HSYNC_ACTIVE_HIGH; 227 if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC) 228 dvo_val |= DVO_VSYNC_ACTIVE_HIGH; 229 230 I915_WRITE(dpll_reg, I915_READ(dpll_reg) | DPLL_DVO_HIGH_SPEED); 231 232 /*I915_WRITE(DVOB_SRCDIM, 233 (adjusted_mode->hdisplay << DVO_SRCDIM_HORIZONTAL_SHIFT) | 234 (adjusted_mode->VDisplay << DVO_SRCDIM_VERTICAL_SHIFT));*/ 235 I915_WRITE(dvo_srcdim_reg, 236 (adjusted_mode->hdisplay << DVO_SRCDIM_HORIZONTAL_SHIFT) | 237 (adjusted_mode->vdisplay << DVO_SRCDIM_VERTICAL_SHIFT)); 238 /*I915_WRITE(DVOB, dvo_val);*/ 239 I915_WRITE(dvo_reg, dvo_val); 240} 241 242/** 243 * Detect the output connection on our DVO device. 244 * 245 * Unimplemented. 246 */ 247static enum drm_connector_status intel_dvo_detect(struct drm_connector *connector) 248{ 249 struct intel_output *intel_output = to_intel_output(connector); 250 struct intel_dvo_device *dvo = intel_output->dev_priv; 251 252 return dvo->dev_ops->detect(dvo); 253} 254 255static int intel_dvo_get_modes(struct drm_connector *connector) 256{ 257 struct intel_output *intel_output = to_intel_output(connector); 258 struct intel_dvo_device *dvo = intel_output->dev_priv; 259 260 /* We should probably have an i2c driver get_modes function for those 261 * devices which will have a fixed set of modes determined by the chip 262 * (TV-out, for example), but for now with just TMDS and LVDS, 263 * that's not the case. 264 */ 265 intel_ddc_get_modes(intel_output); 266 if (!list_empty(&connector->probed_modes)) 267 return 1; 268 269 270 if (dvo->panel_fixed_mode != NULL) { 271 struct drm_display_mode *mode; 272 mode = drm_mode_duplicate(connector->dev, dvo->panel_fixed_mode); 273 if (mode) { 274 drm_mode_probed_add(connector, mode); 275 return 1; 276 } 277 } 278 return 0; 279} 280 281static void intel_dvo_destroy (struct drm_connector *connector) 282{ 283 struct intel_output *intel_output = to_intel_output(connector); 284 struct intel_dvo_device *dvo = intel_output->dev_priv; 285 286 if (dvo) { 287 if (dvo->dev_ops->destroy) 288 dvo->dev_ops->destroy(dvo); 289 if (dvo->panel_fixed_mode) 290 kfree(dvo->panel_fixed_mode); 291 /* no need, in i830_dvoices[] now */ 292 //kfree(dvo); 293 } 294 if (intel_output->i2c_bus) 295 intel_i2c_destroy(intel_output->i2c_bus); 296 if (intel_output->ddc_bus) 297 intel_i2c_destroy(intel_output->ddc_bus); 298 drm_sysfs_connector_remove(connector); 299 drm_connector_cleanup(connector); 300 kfree(intel_output); 301} 302 303#ifdef RANDR_GET_CRTC_INTERFACE 304static struct drm_crtc *intel_dvo_get_crtc(struct drm_connector *connector) 305{ 306 struct drm_device *dev = connector->dev; 307 struct drm_i915_private *dev_priv = dev->dev_private; 308 struct intel_output *intel_output = to_intel_output(connector); 309 struct intel_dvo_device *dvo = intel_output->dev_priv; 310 int pipe = !!(I915_READ(dvo->dvo_reg) & SDVO_PIPE_B_SELECT); 311 312 return intel_pipe_to_crtc(pScrn, pipe); 313} 314#endif 315 316static const struct drm_encoder_helper_funcs intel_dvo_helper_funcs = { 317 .dpms = intel_dvo_dpms, 318 .mode_fixup = intel_dvo_mode_fixup, 319 .prepare = intel_encoder_prepare, 320 .mode_set = intel_dvo_mode_set, 321 .commit = intel_encoder_commit, 322}; 323 324static const struct drm_connector_funcs intel_dvo_connector_funcs = { 325 .save = intel_dvo_save, 326 .restore = intel_dvo_restore, 327 .detect = intel_dvo_detect, 328 .destroy = intel_dvo_destroy, 329 .fill_modes = drm_helper_probe_single_connector_modes, 330}; 331 332static const struct drm_connector_helper_funcs intel_dvo_connector_helper_funcs = { 333 .mode_valid = intel_dvo_mode_valid, 334 .get_modes = intel_dvo_get_modes, 335 .best_encoder = intel_best_encoder, 336}; 337 338void intel_dvo_enc_destroy(struct drm_encoder *encoder) 339{ 340 drm_encoder_cleanup(encoder); 341} 342 343static const struct drm_encoder_funcs intel_dvo_enc_funcs = { 344 .destroy = intel_dvo_enc_destroy, 345}; 346 347 348/** 349 * Attempts to get a fixed panel timing for LVDS (currently only the i830). 350 * 351 * Other chips with DVO LVDS will need to extend this to deal with the LVDS 352 * chip being on DVOB/C and having multiple pipes. 353 */ 354static struct drm_display_mode * 355intel_dvo_get_current_mode (struct drm_connector *connector) 356{ 357 struct drm_device *dev = connector->dev; 358 struct drm_i915_private *dev_priv = dev->dev_private; 359 struct intel_output *intel_output = to_intel_output(connector); 360 struct intel_dvo_device *dvo = intel_output->dev_priv; 361 uint32_t dvo_reg = dvo->dvo_reg; 362 uint32_t dvo_val = I915_READ(dvo_reg); 363 struct drm_display_mode *mode = NULL; 364 365 /* If the DVO port is active, that'll be the LVDS, so we can pull out 366 * its timings to get how the BIOS set up the panel. 367 */ 368 if (dvo_val & DVO_ENABLE) { 369 struct drm_crtc *crtc; 370 int pipe = (dvo_val & DVO_PIPE_B_SELECT) ? 1 : 0; 371 372 crtc = intel_get_crtc_from_pipe(dev, pipe); 373 if (crtc) { 374 mode = intel_crtc_mode_get(dev, crtc); 375 376 if (mode) { 377 mode->type |= DRM_MODE_TYPE_PREFERRED; 378 if (dvo_val & DVO_HSYNC_ACTIVE_HIGH) 379 mode->flags |= DRM_MODE_FLAG_PHSYNC; 380 if (dvo_val & DVO_VSYNC_ACTIVE_HIGH) 381 mode->flags |= DRM_MODE_FLAG_PVSYNC; 382 } 383 } 384 } 385 return mode; 386} 387 388void intel_dvo_init(struct drm_device *dev) 389{ 390 struct intel_output *intel_output; 391 struct intel_dvo_device *dvo; 392 struct intel_i2c_chan *i2cbus = NULL; 393 int ret = 0; 394 int i; 395 int gpio_inited = 0; 396 int encoder_type = DRM_MODE_ENCODER_NONE; 397 intel_output = kzalloc (sizeof(struct intel_output), GFP_KERNEL); 398 if (!intel_output) 399 return; 400 401 /* Set up the DDC bus */ 402 intel_output->ddc_bus = intel_i2c_create(dev, GPIOD, "DVODDC_D"); 403 if (!intel_output->ddc_bus) 404 goto free_intel; 405 406 /* Now, try to find a controller */ 407 for (i = 0; i < ARRAY_SIZE(intel_dvo_devices); i++) { 408 struct drm_connector *connector = &intel_output->base; 409 int gpio; 410 411 dvo = &intel_dvo_devices[i]; 412 413 /* Allow the I2C driver info to specify the GPIO to be used in 414 * special cases, but otherwise default to what's defined 415 * in the spec. 416 */ 417 if (dvo->gpio != 0) 418 gpio = dvo->gpio; 419 else if (dvo->type == INTEL_DVO_CHIP_LVDS) 420 gpio = GPIOB; 421 else 422 gpio = GPIOE; 423 424 /* Set up the I2C bus necessary for the chip we're probing. 425 * It appears that everything is on GPIOE except for panels 426 * on i830 laptops, which are on GPIOB (DVOA). 427 */ 428 if (gpio_inited != gpio) { 429 if (i2cbus != NULL) 430 intel_i2c_destroy(i2cbus); 431 if (!(i2cbus = intel_i2c_create(dev, gpio, 432 gpio == GPIOB ? "DVOI2C_B" : "DVOI2C_E"))) { 433 continue; 434 } 435 gpio_inited = gpio; 436 } 437 438 if (dvo->dev_ops!= NULL) 439 ret = dvo->dev_ops->init(dvo, i2cbus); 440 else 441 ret = false; 442 443 if (!ret) 444 continue; 445 446 intel_output->type = INTEL_OUTPUT_DVO; 447 switch (dvo->type) { 448 case INTEL_DVO_CHIP_TMDS: 449 drm_connector_init(dev, connector, 450 &intel_dvo_connector_funcs, 451 DRM_MODE_CONNECTOR_DVII); 452 encoder_type = DRM_MODE_ENCODER_TMDS; 453 break; 454 case INTEL_DVO_CHIP_LVDS: 455 drm_connector_init(dev, connector, 456 &intel_dvo_connector_funcs, 457 DRM_MODE_CONNECTOR_LVDS); 458 encoder_type = DRM_MODE_ENCODER_LVDS; 459 break; 460 } 461 462 drm_connector_helper_add(connector, 463 &intel_dvo_connector_helper_funcs); 464 connector->display_info.subpixel_order = SubPixelHorizontalRGB; 465 connector->interlace_allowed = false; 466 connector->doublescan_allowed = false; 467 468 intel_output->dev_priv = dvo; 469 intel_output->i2c_bus = i2cbus; 470 471 drm_encoder_init(dev, &intel_output->enc, 472 &intel_dvo_enc_funcs, encoder_type); 473 drm_encoder_helper_add(&intel_output->enc, 474 &intel_dvo_helper_funcs); 475 476 drm_mode_connector_attach_encoder(&intel_output->base, 477 &intel_output->enc); 478 if (dvo->type == INTEL_DVO_CHIP_LVDS) { 479 /* For our LVDS chipsets, we should hopefully be able 480 * to dig the fixed panel mode out of the BIOS data. 481 * However, it's in a different format from the BIOS 482 * data on chipsets with integrated LVDS (stored in AIM 483 * headers, likely), so for now, just get the current 484 * mode being output through DVO. 485 */ 486 dvo->panel_fixed_mode = 487 intel_dvo_get_current_mode(connector); 488 dvo->panel_wants_dither = true; 489 } 490 491 drm_sysfs_connector_add(connector); 492 return; 493 } 494 495 intel_i2c_destroy(intel_output->ddc_bus); 496 /* Didn't find a chip, so tear down. */ 497 if (i2cbus != NULL) 498 intel_i2c_destroy(i2cbus); 499free_intel: 500 kfree(intel_output); 501} 502