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