linux/drivers/gpu/drm/i915/intel_dvo.c
<<
>>
Prefs
   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 <linux/slab.h>
  29#include <drm/drmP.h>
  30#include <drm/drm_crtc.h>
  31#include "intel_drv.h"
  32#include <drm/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#define NS2501_ADDR     0x38
  40
  41static const struct intel_dvo_device intel_dvo_devices[] = {
  42        {
  43                .type = INTEL_DVO_CHIP_TMDS,
  44                .name = "sil164",
  45                .dvo_reg = DVOC,
  46                .slave_addr = SIL164_ADDR,
  47                .dev_ops = &sil164_ops,
  48        },
  49        {
  50                .type = INTEL_DVO_CHIP_TMDS,
  51                .name = "ch7xxx",
  52                .dvo_reg = DVOC,
  53                .slave_addr = CH7xxx_ADDR,
  54                .dev_ops = &ch7xxx_ops,
  55        },
  56        {
  57                .type = INTEL_DVO_CHIP_TMDS,
  58                .name = "ch7xxx",
  59                .dvo_reg = DVOC,
  60                .slave_addr = 0x75, /* For some ch7010 */
  61                .dev_ops = &ch7xxx_ops,
  62        },
  63        {
  64                .type = INTEL_DVO_CHIP_LVDS,
  65                .name = "ivch",
  66                .dvo_reg = DVOA,
  67                .slave_addr = 0x02, /* Might also be 0x44, 0x84, 0xc4 */
  68                .dev_ops = &ivch_ops,
  69        },
  70        {
  71                .type = INTEL_DVO_CHIP_TMDS,
  72                .name = "tfp410",
  73                .dvo_reg = DVOC,
  74                .slave_addr = TFP410_ADDR,
  75                .dev_ops = &tfp410_ops,
  76        },
  77        {
  78                .type = INTEL_DVO_CHIP_LVDS,
  79                .name = "ch7017",
  80                .dvo_reg = DVOC,
  81                .slave_addr = 0x75,
  82                .gpio = GMBUS_PORT_DPB,
  83                .dev_ops = &ch7017_ops,
  84        },
  85        {
  86                .type = INTEL_DVO_CHIP_TMDS,
  87                .name = "ns2501",
  88                .dvo_reg = DVOC,
  89                .slave_addr = NS2501_ADDR,
  90                .dev_ops = &ns2501_ops,
  91       }
  92};
  93
  94struct intel_dvo {
  95        struct intel_encoder base;
  96
  97        struct intel_dvo_device dev;
  98
  99        struct drm_display_mode *panel_fixed_mode;
 100        bool panel_wants_dither;
 101};
 102
 103static struct intel_dvo *enc_to_intel_dvo(struct drm_encoder *encoder)
 104{
 105        return container_of(encoder, struct intel_dvo, base.base);
 106}
 107
 108static struct intel_dvo *intel_attached_dvo(struct drm_connector *connector)
 109{
 110        return container_of(intel_attached_encoder(connector),
 111                            struct intel_dvo, base);
 112}
 113
 114static bool intel_dvo_connector_get_hw_state(struct intel_connector *connector)
 115{
 116        struct intel_dvo *intel_dvo = intel_attached_dvo(&connector->base);
 117
 118        return intel_dvo->dev.dev_ops->get_hw_state(&intel_dvo->dev);
 119}
 120
 121static bool intel_dvo_get_hw_state(struct intel_encoder *encoder,
 122                                   enum pipe *pipe)
 123{
 124        struct drm_device *dev = encoder->base.dev;
 125        struct drm_i915_private *dev_priv = dev->dev_private;
 126        struct intel_dvo *intel_dvo = enc_to_intel_dvo(&encoder->base);
 127        u32 tmp;
 128
 129        tmp = I915_READ(intel_dvo->dev.dvo_reg);
 130
 131        if (!(tmp & DVO_ENABLE))
 132                return false;
 133
 134        *pipe = PORT_TO_PIPE(tmp);
 135
 136        return true;
 137}
 138
 139static void intel_dvo_get_config(struct intel_encoder *encoder,
 140                                 struct intel_crtc_config *pipe_config)
 141{
 142        struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
 143        struct intel_dvo *intel_dvo = enc_to_intel_dvo(&encoder->base);
 144        u32 tmp, flags = 0;
 145
 146        tmp = I915_READ(intel_dvo->dev.dvo_reg);
 147        if (tmp & DVO_HSYNC_ACTIVE_HIGH)
 148                flags |= DRM_MODE_FLAG_PHSYNC;
 149        else
 150                flags |= DRM_MODE_FLAG_NHSYNC;
 151        if (tmp & DVO_VSYNC_ACTIVE_HIGH)
 152                flags |= DRM_MODE_FLAG_PVSYNC;
 153        else
 154                flags |= DRM_MODE_FLAG_NVSYNC;
 155
 156        pipe_config->adjusted_mode.flags |= flags;
 157}
 158
 159static void intel_disable_dvo(struct intel_encoder *encoder)
 160{
 161        struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
 162        struct intel_dvo *intel_dvo = enc_to_intel_dvo(&encoder->base);
 163        u32 dvo_reg = intel_dvo->dev.dvo_reg;
 164        u32 temp = I915_READ(dvo_reg);
 165
 166        intel_dvo->dev.dev_ops->dpms(&intel_dvo->dev, false);
 167        I915_WRITE(dvo_reg, temp & ~DVO_ENABLE);
 168        I915_READ(dvo_reg);
 169}
 170
 171static void intel_enable_dvo(struct intel_encoder *encoder)
 172{
 173        struct drm_i915_private *dev_priv = encoder->base.dev->dev_private;
 174        struct intel_dvo *intel_dvo = enc_to_intel_dvo(&encoder->base);
 175        u32 dvo_reg = intel_dvo->dev.dvo_reg;
 176        u32 temp = I915_READ(dvo_reg);
 177
 178        I915_WRITE(dvo_reg, temp | DVO_ENABLE);
 179        I915_READ(dvo_reg);
 180        intel_dvo->dev.dev_ops->dpms(&intel_dvo->dev, true);
 181}
 182
 183/* Special dpms function to support cloning between dvo/sdvo/crt. */
 184static void intel_dvo_dpms(struct drm_connector *connector, int mode)
 185{
 186        struct intel_dvo *intel_dvo = intel_attached_dvo(connector);
 187        struct drm_crtc *crtc;
 188
 189        /* dvo supports only 2 dpms states. */
 190        if (mode != DRM_MODE_DPMS_ON)
 191                mode = DRM_MODE_DPMS_OFF;
 192
 193        if (mode == connector->dpms)
 194                return;
 195
 196        connector->dpms = mode;
 197
 198        /* Only need to change hw state when actually enabled */
 199        crtc = intel_dvo->base.base.crtc;
 200        if (!crtc) {
 201                intel_dvo->base.connectors_active = false;
 202                return;
 203        }
 204
 205        /* We call connector dpms manually below in case pipe dpms doesn't
 206         * change due to cloning. */
 207        if (mode == DRM_MODE_DPMS_ON) {
 208                intel_dvo->base.connectors_active = true;
 209
 210                intel_crtc_update_dpms(crtc);
 211
 212                intel_dvo->dev.dev_ops->dpms(&intel_dvo->dev, true);
 213        } else {
 214                intel_dvo->dev.dev_ops->dpms(&intel_dvo->dev, false);
 215
 216                intel_dvo->base.connectors_active = false;
 217
 218                intel_crtc_update_dpms(crtc);
 219        }
 220
 221        intel_modeset_check_state(connector->dev);
 222}
 223
 224static int intel_dvo_mode_valid(struct drm_connector *connector,
 225                                struct drm_display_mode *mode)
 226{
 227        struct intel_dvo *intel_dvo = intel_attached_dvo(connector);
 228
 229        if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
 230                return MODE_NO_DBLESCAN;
 231
 232        /* XXX: Validate clock range */
 233
 234        if (intel_dvo->panel_fixed_mode) {
 235                if (mode->hdisplay > intel_dvo->panel_fixed_mode->hdisplay)
 236                        return MODE_PANEL;
 237                if (mode->vdisplay > intel_dvo->panel_fixed_mode->vdisplay)
 238                        return MODE_PANEL;
 239        }
 240
 241        return intel_dvo->dev.dev_ops->mode_valid(&intel_dvo->dev, mode);
 242}
 243
 244static bool intel_dvo_mode_fixup(struct drm_encoder *encoder,
 245                                 const struct drm_display_mode *mode,
 246                                 struct drm_display_mode *adjusted_mode)
 247{
 248        struct intel_dvo *intel_dvo = enc_to_intel_dvo(encoder);
 249
 250        /* If we have timings from the BIOS for the panel, put them in
 251         * to the adjusted mode.  The CRTC will be set up for this mode,
 252         * with the panel scaling set up to source from the H/VDisplay
 253         * of the original mode.
 254         */
 255        if (intel_dvo->panel_fixed_mode != NULL) {
 256#define C(x) adjusted_mode->x = intel_dvo->panel_fixed_mode->x
 257                C(hdisplay);
 258                C(hsync_start);
 259                C(hsync_end);
 260                C(htotal);
 261                C(vdisplay);
 262                C(vsync_start);
 263                C(vsync_end);
 264                C(vtotal);
 265                C(clock);
 266#undef C
 267        }
 268
 269        if (intel_dvo->dev.dev_ops->mode_fixup)
 270                return intel_dvo->dev.dev_ops->mode_fixup(&intel_dvo->dev, mode, adjusted_mode);
 271
 272        return true;
 273}
 274
 275static void intel_dvo_mode_set(struct drm_encoder *encoder,
 276                               struct drm_display_mode *mode,
 277                               struct drm_display_mode *adjusted_mode)
 278{
 279        struct drm_device *dev = encoder->dev;
 280        struct drm_i915_private *dev_priv = dev->dev_private;
 281        struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
 282        struct intel_dvo *intel_dvo = enc_to_intel_dvo(encoder);
 283        int pipe = intel_crtc->pipe;
 284        u32 dvo_val;
 285        u32 dvo_reg = intel_dvo->dev.dvo_reg, dvo_srcdim_reg;
 286        int dpll_reg = DPLL(pipe);
 287
 288        switch (dvo_reg) {
 289        case DVOA:
 290        default:
 291                dvo_srcdim_reg = DVOA_SRCDIM;
 292                break;
 293        case DVOB:
 294                dvo_srcdim_reg = DVOB_SRCDIM;
 295                break;
 296        case DVOC:
 297                dvo_srcdim_reg = DVOC_SRCDIM;
 298                break;
 299        }
 300
 301        intel_dvo->dev.dev_ops->mode_set(&intel_dvo->dev, mode, adjusted_mode);
 302
 303        /* Save the data order, since I don't know what it should be set to. */
 304        dvo_val = I915_READ(dvo_reg) &
 305                  (DVO_PRESERVE_MASK | DVO_DATA_ORDER_GBRG);
 306        dvo_val |= DVO_DATA_ORDER_FP | DVO_BORDER_ENABLE |
 307                   DVO_BLANK_ACTIVE_HIGH;
 308
 309        if (pipe == 1)
 310                dvo_val |= DVO_PIPE_B_SELECT;
 311        dvo_val |= DVO_PIPE_STALL;
 312        if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC)
 313                dvo_val |= DVO_HSYNC_ACTIVE_HIGH;
 314        if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC)
 315                dvo_val |= DVO_VSYNC_ACTIVE_HIGH;
 316
 317        I915_WRITE(dpll_reg, I915_READ(dpll_reg) | DPLL_DVO_HIGH_SPEED);
 318
 319        /*I915_WRITE(DVOB_SRCDIM,
 320          (adjusted_mode->hdisplay << DVO_SRCDIM_HORIZONTAL_SHIFT) |
 321          (adjusted_mode->VDisplay << DVO_SRCDIM_VERTICAL_SHIFT));*/
 322        I915_WRITE(dvo_srcdim_reg,
 323                   (adjusted_mode->hdisplay << DVO_SRCDIM_HORIZONTAL_SHIFT) |
 324                   (adjusted_mode->vdisplay << DVO_SRCDIM_VERTICAL_SHIFT));
 325        /*I915_WRITE(DVOB, dvo_val);*/
 326        I915_WRITE(dvo_reg, dvo_val);
 327}
 328
 329/**
 330 * Detect the output connection on our DVO device.
 331 *
 332 * Unimplemented.
 333 */
 334static enum drm_connector_status
 335intel_dvo_detect(struct drm_connector *connector, bool force)
 336{
 337        struct intel_dvo *intel_dvo = intel_attached_dvo(connector);
 338        return intel_dvo->dev.dev_ops->detect(&intel_dvo->dev);
 339}
 340
 341static int intel_dvo_get_modes(struct drm_connector *connector)
 342{
 343        struct intel_dvo *intel_dvo = intel_attached_dvo(connector);
 344        struct drm_i915_private *dev_priv = connector->dev->dev_private;
 345
 346        /* We should probably have an i2c driver get_modes function for those
 347         * devices which will have a fixed set of modes determined by the chip
 348         * (TV-out, for example), but for now with just TMDS and LVDS,
 349         * that's not the case.
 350         */
 351        intel_ddc_get_modes(connector,
 352                            intel_gmbus_get_adapter(dev_priv, GMBUS_PORT_DPC));
 353        if (!list_empty(&connector->probed_modes))
 354                return 1;
 355
 356        if (intel_dvo->panel_fixed_mode != NULL) {
 357                struct drm_display_mode *mode;
 358                mode = drm_mode_duplicate(connector->dev, intel_dvo->panel_fixed_mode);
 359                if (mode) {
 360                        drm_mode_probed_add(connector, mode);
 361                        return 1;
 362                }
 363        }
 364
 365        return 0;
 366}
 367
 368static void intel_dvo_destroy(struct drm_connector *connector)
 369{
 370        drm_sysfs_connector_remove(connector);
 371        drm_connector_cleanup(connector);
 372        kfree(connector);
 373}
 374
 375static const struct drm_encoder_helper_funcs intel_dvo_helper_funcs = {
 376        .mode_fixup = intel_dvo_mode_fixup,
 377        .mode_set = intel_dvo_mode_set,
 378};
 379
 380static const struct drm_connector_funcs intel_dvo_connector_funcs = {
 381        .dpms = intel_dvo_dpms,
 382        .detect = intel_dvo_detect,
 383        .destroy = intel_dvo_destroy,
 384        .fill_modes = drm_helper_probe_single_connector_modes,
 385};
 386
 387static const struct drm_connector_helper_funcs intel_dvo_connector_helper_funcs = {
 388        .mode_valid = intel_dvo_mode_valid,
 389        .get_modes = intel_dvo_get_modes,
 390        .best_encoder = intel_best_encoder,
 391};
 392
 393static void intel_dvo_enc_destroy(struct drm_encoder *encoder)
 394{
 395        struct intel_dvo *intel_dvo = enc_to_intel_dvo(encoder);
 396
 397        if (intel_dvo->dev.dev_ops->destroy)
 398                intel_dvo->dev.dev_ops->destroy(&intel_dvo->dev);
 399
 400        kfree(intel_dvo->panel_fixed_mode);
 401
 402        intel_encoder_destroy(encoder);
 403}
 404
 405static const struct drm_encoder_funcs intel_dvo_enc_funcs = {
 406        .destroy = intel_dvo_enc_destroy,
 407};
 408
 409/**
 410 * Attempts to get a fixed panel timing for LVDS (currently only the i830).
 411 *
 412 * Other chips with DVO LVDS will need to extend this to deal with the LVDS
 413 * chip being on DVOB/C and having multiple pipes.
 414 */
 415static struct drm_display_mode *
 416intel_dvo_get_current_mode(struct drm_connector *connector)
 417{
 418        struct drm_device *dev = connector->dev;
 419        struct drm_i915_private *dev_priv = dev->dev_private;
 420        struct intel_dvo *intel_dvo = intel_attached_dvo(connector);
 421        uint32_t dvo_val = I915_READ(intel_dvo->dev.dvo_reg);
 422        struct drm_display_mode *mode = NULL;
 423
 424        /* If the DVO port is active, that'll be the LVDS, so we can pull out
 425         * its timings to get how the BIOS set up the panel.
 426         */
 427        if (dvo_val & DVO_ENABLE) {
 428                struct drm_crtc *crtc;
 429                int pipe = (dvo_val & DVO_PIPE_B_SELECT) ? 1 : 0;
 430
 431                crtc = intel_get_crtc_for_pipe(dev, pipe);
 432                if (crtc) {
 433                        mode = intel_crtc_mode_get(dev, crtc);
 434                        if (mode) {
 435                                mode->type |= DRM_MODE_TYPE_PREFERRED;
 436                                if (dvo_val & DVO_HSYNC_ACTIVE_HIGH)
 437                                        mode->flags |= DRM_MODE_FLAG_PHSYNC;
 438                                if (dvo_val & DVO_VSYNC_ACTIVE_HIGH)
 439                                        mode->flags |= DRM_MODE_FLAG_PVSYNC;
 440                        }
 441                }
 442        }
 443
 444        return mode;
 445}
 446
 447void intel_dvo_init(struct drm_device *dev)
 448{
 449        struct drm_i915_private *dev_priv = dev->dev_private;
 450        struct intel_encoder *intel_encoder;
 451        struct intel_dvo *intel_dvo;
 452        struct intel_connector *intel_connector;
 453        int i;
 454        int encoder_type = DRM_MODE_ENCODER_NONE;
 455
 456        intel_dvo = kzalloc(sizeof(struct intel_dvo), GFP_KERNEL);
 457        if (!intel_dvo)
 458                return;
 459
 460        intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL);
 461        if (!intel_connector) {
 462                kfree(intel_dvo);
 463                return;
 464        }
 465
 466        intel_encoder = &intel_dvo->base;
 467        drm_encoder_init(dev, &intel_encoder->base,
 468                         &intel_dvo_enc_funcs, encoder_type);
 469
 470        intel_encoder->disable = intel_disable_dvo;
 471        intel_encoder->enable = intel_enable_dvo;
 472        intel_encoder->get_hw_state = intel_dvo_get_hw_state;
 473        intel_encoder->get_config = intel_dvo_get_config;
 474        intel_connector->get_hw_state = intel_dvo_connector_get_hw_state;
 475
 476        /* Now, try to find a controller */
 477        for (i = 0; i < ARRAY_SIZE(intel_dvo_devices); i++) {
 478                struct drm_connector *connector = &intel_connector->base;
 479                const struct intel_dvo_device *dvo = &intel_dvo_devices[i];
 480                struct i2c_adapter *i2c;
 481                int gpio;
 482                bool dvoinit;
 483
 484                /* Allow the I2C driver info to specify the GPIO to be used in
 485                 * special cases, but otherwise default to what's defined
 486                 * in the spec.
 487                 */
 488                if (intel_gmbus_is_port_valid(dvo->gpio))
 489                        gpio = dvo->gpio;
 490                else if (dvo->type == INTEL_DVO_CHIP_LVDS)
 491                        gpio = GMBUS_PORT_SSC;
 492                else
 493                        gpio = GMBUS_PORT_DPB;
 494
 495                /* Set up the I2C bus necessary for the chip we're probing.
 496                 * It appears that everything is on GPIOE except for panels
 497                 * on i830 laptops, which are on GPIOB (DVOA).
 498                 */
 499                i2c = intel_gmbus_get_adapter(dev_priv, gpio);
 500
 501                intel_dvo->dev = *dvo;
 502
 503                /* GMBUS NAK handling seems to be unstable, hence let the
 504                 * transmitter detection run in bit banging mode for now.
 505                 */
 506                intel_gmbus_force_bit(i2c, true);
 507
 508                dvoinit = dvo->dev_ops->init(&intel_dvo->dev, i2c);
 509
 510                intel_gmbus_force_bit(i2c, false);
 511
 512                if (!dvoinit)
 513                        continue;
 514
 515                intel_encoder->type = INTEL_OUTPUT_DVO;
 516                intel_encoder->crtc_mask = (1 << 0) | (1 << 1);
 517                switch (dvo->type) {
 518                case INTEL_DVO_CHIP_TMDS:
 519                        intel_encoder->cloneable = true;
 520                        drm_connector_init(dev, connector,
 521                                           &intel_dvo_connector_funcs,
 522                                           DRM_MODE_CONNECTOR_DVII);
 523                        encoder_type = DRM_MODE_ENCODER_TMDS;
 524                        break;
 525                case INTEL_DVO_CHIP_LVDS:
 526                        intel_encoder->cloneable = false;
 527                        drm_connector_init(dev, connector,
 528                                           &intel_dvo_connector_funcs,
 529                                           DRM_MODE_CONNECTOR_LVDS);
 530                        encoder_type = DRM_MODE_ENCODER_LVDS;
 531                        break;
 532                }
 533
 534                drm_connector_helper_add(connector,
 535                                         &intel_dvo_connector_helper_funcs);
 536                connector->display_info.subpixel_order = SubPixelHorizontalRGB;
 537                connector->interlace_allowed = false;
 538                connector->doublescan_allowed = false;
 539
 540                drm_encoder_helper_add(&intel_encoder->base,
 541                                       &intel_dvo_helper_funcs);
 542
 543                intel_connector_attach_encoder(intel_connector, intel_encoder);
 544                if (dvo->type == INTEL_DVO_CHIP_LVDS) {
 545                        /* For our LVDS chipsets, we should hopefully be able
 546                         * to dig the fixed panel mode out of the BIOS data.
 547                         * However, it's in a different format from the BIOS
 548                         * data on chipsets with integrated LVDS (stored in AIM
 549                         * headers, likely), so for now, just get the current
 550                         * mode being output through DVO.
 551                         */
 552                        intel_dvo->panel_fixed_mode =
 553                                intel_dvo_get_current_mode(connector);
 554                        intel_dvo->panel_wants_dither = true;
 555                }
 556
 557                drm_sysfs_connector_add(connector);
 558                return;
 559        }
 560
 561        drm_encoder_cleanup(&intel_encoder->base);
 562        kfree(intel_dvo);
 563        kfree(intel_connector);
 564}
 565