linux/drivers/gpu/drm/gma500/oaktrail_hdmi.c
<<
>>
Prefs
   1/*
   2 * Copyright © 2010 Intel Corporation
   3 *
   4 * Permission is hereby granted, free of charge, to any person obtaining a
   5 * copy of this software and associated documentation files (the "Software"),
   6 * to deal in the Software without restriction, including without limitation
   7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
   8 * and/or sell copies of the Software, and to permit persons to whom the
   9 * Software is furnished to do so, subject to the following conditions:
  10 *
  11 * The above copyright notice and this permission notice (including the next
  12 * paragraph) shall be included in all copies or substantial portions of the
  13 * Software.
  14 *
  15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  21 * DEALINGS IN THE SOFTWARE.
  22 *
  23 * Authors:
  24 *      Li Peng <peng.li@intel.com>
  25 */
  26
  27#include <drm/drmP.h>
  28#include <drm/drm.h>
  29#include "psb_intel_drv.h"
  30#include "psb_intel_reg.h"
  31#include "psb_drv.h"
  32
  33#define HDMI_READ(reg)          readl(hdmi_dev->regs + (reg))
  34#define HDMI_WRITE(reg, val)    writel(val, hdmi_dev->regs + (reg))
  35
  36#define HDMI_HCR        0x1000
  37#define HCR_ENABLE_HDCP         (1 << 5)
  38#define HCR_ENABLE_AUDIO        (1 << 2)
  39#define HCR_ENABLE_PIXEL        (1 << 1)
  40#define HCR_ENABLE_TMDS         (1 << 0)
  41
  42#define HDMI_HICR       0x1004
  43#define HDMI_HSR        0x1008
  44#define HDMI_HISR       0x100C
  45#define HDMI_DETECT_HDP         (1 << 0)
  46
  47#define HDMI_VIDEO_REG  0x3000
  48#define HDMI_UNIT_EN            (1 << 7)
  49#define HDMI_MODE_OUTPUT        (1 << 0)
  50#define HDMI_HBLANK_A   0x3100
  51
  52#define HDMI_AUDIO_CTRL 0x4000
  53#define HDMI_ENABLE_AUDIO       (1 << 0)
  54
  55#define PCH_HTOTAL_B    0x3100
  56#define PCH_HBLANK_B    0x3104
  57#define PCH_HSYNC_B     0x3108
  58#define PCH_VTOTAL_B    0x310C
  59#define PCH_VBLANK_B    0x3110
  60#define PCH_VSYNC_B     0x3114
  61#define PCH_PIPEBSRC    0x311C
  62
  63#define PCH_PIPEB_DSL   0x3800
  64#define PCH_PIPEB_SLC   0x3804
  65#define PCH_PIPEBCONF   0x3808
  66#define PCH_PIPEBSTAT   0x3824
  67
  68#define CDVO_DFT        0x5000
  69#define CDVO_SLEWRATE   0x5004
  70#define CDVO_STRENGTH   0x5008
  71#define CDVO_RCOMP      0x500C
  72
  73#define DPLL_CTRL       0x6000
  74#define DPLL_PDIV_SHIFT         16
  75#define DPLL_PDIV_MASK          (0xf << 16)
  76#define DPLL_PWRDN              (1 << 4)
  77#define DPLL_RESET              (1 << 3)
  78#define DPLL_FASTEN             (1 << 2)
  79#define DPLL_ENSTAT             (1 << 1)
  80#define DPLL_DITHEN             (1 << 0)
  81
  82#define DPLL_DIV_CTRL   0x6004
  83#define DPLL_CLKF_MASK          0xffffffc0
  84#define DPLL_CLKR_MASK          (0x3f)
  85
  86#define DPLL_CLK_ENABLE 0x6008
  87#define DPLL_EN_DISP            (1 << 31)
  88#define DPLL_SEL_HDMI           (1 << 8)
  89#define DPLL_EN_HDMI            (1 << 1)
  90#define DPLL_EN_VGA             (1 << 0)
  91
  92#define DPLL_ADJUST     0x600C
  93#define DPLL_STATUS     0x6010
  94#define DPLL_UPDATE     0x6014
  95#define DPLL_DFT        0x6020
  96
  97struct intel_range {
  98        int     min, max;
  99};
 100
 101struct oaktrail_hdmi_limit {
 102        struct intel_range vco, np, nr, nf;
 103};
 104
 105struct oaktrail_hdmi_clock {
 106        int np;
 107        int nr;
 108        int nf;
 109        int dot;
 110};
 111
 112#define VCO_MIN         320000
 113#define VCO_MAX         1650000
 114#define NP_MIN          1
 115#define NP_MAX          15
 116#define NR_MIN          1
 117#define NR_MAX          64
 118#define NF_MIN          2
 119#define NF_MAX          4095
 120
 121static const struct oaktrail_hdmi_limit oaktrail_hdmi_limit = {
 122        .vco = { .min = VCO_MIN,                .max = VCO_MAX },
 123        .np  = { .min = NP_MIN,                 .max = NP_MAX  },
 124        .nr  = { .min = NR_MIN,                 .max = NR_MAX  },
 125        .nf  = { .min = NF_MIN,                 .max = NF_MAX  },
 126};
 127
 128static void oaktrail_hdmi_audio_enable(struct drm_device *dev)
 129{
 130        struct drm_psb_private *dev_priv = dev->dev_private;
 131        struct oaktrail_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv;
 132
 133        HDMI_WRITE(HDMI_HCR, 0x67);
 134        HDMI_READ(HDMI_HCR);
 135
 136        HDMI_WRITE(0x51a8, 0x10);
 137        HDMI_READ(0x51a8);
 138
 139        HDMI_WRITE(HDMI_AUDIO_CTRL, 0x1);
 140        HDMI_READ(HDMI_AUDIO_CTRL);
 141}
 142
 143static void oaktrail_hdmi_audio_disable(struct drm_device *dev)
 144{
 145        struct drm_psb_private *dev_priv = dev->dev_private;
 146        struct oaktrail_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv;
 147
 148        HDMI_WRITE(0x51a8, 0x0);
 149        HDMI_READ(0x51a8);
 150
 151        HDMI_WRITE(HDMI_AUDIO_CTRL, 0x0);
 152        HDMI_READ(HDMI_AUDIO_CTRL);
 153
 154        HDMI_WRITE(HDMI_HCR, 0x47);
 155        HDMI_READ(HDMI_HCR);
 156}
 157
 158static unsigned int htotal_calculate(struct drm_display_mode *mode)
 159{
 160        u32 htotal, new_crtc_htotal;
 161
 162        htotal = (mode->crtc_hdisplay - 1) | ((mode->crtc_htotal - 1) << 16);
 163
 164        /*
 165         * 1024 x 768  new_crtc_htotal = 0x1024;
 166         * 1280 x 1024 new_crtc_htotal = 0x0c34;
 167         */
 168        new_crtc_htotal = (mode->crtc_htotal - 1) * 200 * 1000 / mode->clock;
 169
 170        DRM_DEBUG_KMS("new crtc htotal 0x%4x\n", new_crtc_htotal);
 171        return (mode->crtc_hdisplay - 1) | (new_crtc_htotal << 16);
 172}
 173
 174static void oaktrail_hdmi_find_dpll(struct drm_crtc *crtc, int target,
 175                                int refclk, struct oaktrail_hdmi_clock *best_clock)
 176{
 177        int np_min, np_max, nr_min, nr_max;
 178        int np, nr, nf;
 179
 180        np_min = DIV_ROUND_UP(oaktrail_hdmi_limit.vco.min, target * 10);
 181        np_max = oaktrail_hdmi_limit.vco.max / (target * 10);
 182        if (np_min < oaktrail_hdmi_limit.np.min)
 183                np_min = oaktrail_hdmi_limit.np.min;
 184        if (np_max > oaktrail_hdmi_limit.np.max)
 185                np_max = oaktrail_hdmi_limit.np.max;
 186
 187        nr_min = DIV_ROUND_UP((refclk * 1000), (target * 10 * np_max));
 188        nr_max = DIV_ROUND_UP((refclk * 1000), (target * 10 * np_min));
 189        if (nr_min < oaktrail_hdmi_limit.nr.min)
 190                nr_min = oaktrail_hdmi_limit.nr.min;
 191        if (nr_max > oaktrail_hdmi_limit.nr.max)
 192                nr_max = oaktrail_hdmi_limit.nr.max;
 193
 194        np = DIV_ROUND_UP((refclk * 1000), (target * 10 * nr_max));
 195        nr = DIV_ROUND_UP((refclk * 1000), (target * 10 * np));
 196        nf = DIV_ROUND_CLOSEST((target * 10 * np * nr), refclk);
 197        DRM_DEBUG_KMS("np, nr, nf %d %d %d\n", np, nr, nf);
 198
 199        /*
 200         * 1024 x 768  np = 1; nr = 0x26; nf = 0x0fd8000;
 201         * 1280 x 1024 np = 1; nr = 0x17; nf = 0x1034000;
 202         */
 203        best_clock->np = np;
 204        best_clock->nr = nr - 1;
 205        best_clock->nf = (nf << 14);
 206}
 207
 208static void scu_busy_loop(void __iomem *scu_base)
 209{
 210        u32 status = 0;
 211        u32 loop_count = 0;
 212
 213        status = readl(scu_base + 0x04);
 214        while (status & 1) {
 215                udelay(1); /* scu processing time is in few u secods */
 216                status = readl(scu_base + 0x04);
 217                loop_count++;
 218                /* break if scu doesn't reset busy bit after huge retry */
 219                if (loop_count > 1000) {
 220                        DRM_DEBUG_KMS("SCU IPC timed out");
 221                        return;
 222                }
 223        }
 224}
 225
 226/*
 227 *      You don't want to know, you really really don't want to know....
 228 *
 229 *      This is magic. However it's safe magic because of the way the platform
 230 *      works and it is necessary magic.
 231 */
 232static void oaktrail_hdmi_reset(struct drm_device *dev)
 233{
 234        void __iomem *base;
 235        unsigned long scu_ipc_mmio = 0xff11c000UL;
 236        int scu_len = 1024;
 237
 238        base = ioremap((resource_size_t)scu_ipc_mmio, scu_len);
 239        if (base == NULL) {
 240                DRM_ERROR("failed to map scu mmio\n");
 241                return;
 242        }
 243
 244        /* scu ipc: assert hdmi controller reset */
 245        writel(0xff11d118, base + 0x0c);
 246        writel(0x7fffffdf, base + 0x80);
 247        writel(0x42005, base + 0x0);
 248        scu_busy_loop(base);
 249
 250        /* scu ipc: de-assert hdmi controller reset */
 251        writel(0xff11d118, base + 0x0c);
 252        writel(0x7fffffff, base + 0x80);
 253        writel(0x42005, base + 0x0);
 254        scu_busy_loop(base);
 255
 256        iounmap(base);
 257}
 258
 259int oaktrail_crtc_hdmi_mode_set(struct drm_crtc *crtc,
 260                            struct drm_display_mode *mode,
 261                            struct drm_display_mode *adjusted_mode,
 262                            int x, int y,
 263                            struct drm_framebuffer *old_fb)
 264{
 265        struct drm_device *dev = crtc->dev;
 266        struct drm_psb_private *dev_priv = dev->dev_private;
 267        struct oaktrail_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv;
 268        int pipe = 1;
 269        int htot_reg = (pipe == 0) ? HTOTAL_A : HTOTAL_B;
 270        int hblank_reg = (pipe == 0) ? HBLANK_A : HBLANK_B;
 271        int hsync_reg = (pipe == 0) ? HSYNC_A : HSYNC_B;
 272        int vtot_reg = (pipe == 0) ? VTOTAL_A : VTOTAL_B;
 273        int vblank_reg = (pipe == 0) ? VBLANK_A : VBLANK_B;
 274        int vsync_reg = (pipe == 0) ? VSYNC_A : VSYNC_B;
 275        int dspsize_reg = (pipe == 0) ? DSPASIZE : DSPBSIZE;
 276        int dsppos_reg = (pipe == 0) ? DSPAPOS : DSPBPOS;
 277        int pipesrc_reg = (pipe == 0) ? PIPEASRC : PIPEBSRC;
 278        int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF;
 279        int refclk;
 280        struct oaktrail_hdmi_clock clock;
 281        u32 dspcntr, pipeconf, dpll, temp;
 282        int dspcntr_reg = DSPBCNTR;
 283
 284        if (!gma_power_begin(dev, true))
 285                return 0;
 286
 287        /* Disable the VGA plane that we never use */
 288        REG_WRITE(VGACNTRL, VGA_DISP_DISABLE);
 289
 290        /* Disable dpll if necessary */
 291        dpll = REG_READ(DPLL_CTRL);
 292        if ((dpll & DPLL_PWRDN) == 0) {
 293                REG_WRITE(DPLL_CTRL, dpll | (DPLL_PWRDN | DPLL_RESET));
 294                REG_WRITE(DPLL_DIV_CTRL, 0x00000000);
 295                REG_WRITE(DPLL_STATUS, 0x1);
 296        }
 297        udelay(150);
 298
 299        /* Reset controller */
 300        oaktrail_hdmi_reset(dev);
 301
 302        /* program and enable dpll */
 303        refclk = 25000;
 304        oaktrail_hdmi_find_dpll(crtc, adjusted_mode->clock, refclk, &clock);
 305
 306        /* Set the DPLL */
 307        dpll = REG_READ(DPLL_CTRL);
 308        dpll &= ~DPLL_PDIV_MASK;
 309        dpll &= ~(DPLL_PWRDN | DPLL_RESET);
 310        REG_WRITE(DPLL_CTRL, 0x00000008);
 311        REG_WRITE(DPLL_DIV_CTRL, ((clock.nf << 6) | clock.nr));
 312        REG_WRITE(DPLL_ADJUST, ((clock.nf >> 14) - 1));
 313        REG_WRITE(DPLL_CTRL, (dpll | (clock.np << DPLL_PDIV_SHIFT) | DPLL_ENSTAT | DPLL_DITHEN));
 314        REG_WRITE(DPLL_UPDATE, 0x80000000);
 315        REG_WRITE(DPLL_CLK_ENABLE, 0x80050102);
 316        udelay(150);
 317
 318        /* configure HDMI */
 319        HDMI_WRITE(0x1004, 0x1fd);
 320        HDMI_WRITE(0x2000, 0x1);
 321        HDMI_WRITE(0x2008, 0x0);
 322        HDMI_WRITE(0x3130, 0x8);
 323        HDMI_WRITE(0x101c, 0x1800810);
 324
 325        temp = htotal_calculate(adjusted_mode);
 326        REG_WRITE(htot_reg, temp);
 327        REG_WRITE(hblank_reg, (adjusted_mode->crtc_hblank_start - 1) | ((adjusted_mode->crtc_hblank_end - 1) << 16));
 328        REG_WRITE(hsync_reg, (adjusted_mode->crtc_hsync_start - 1) | ((adjusted_mode->crtc_hsync_end - 1) << 16));
 329        REG_WRITE(vtot_reg, (adjusted_mode->crtc_vdisplay - 1) | ((adjusted_mode->crtc_vtotal - 1) << 16));
 330        REG_WRITE(vblank_reg, (adjusted_mode->crtc_vblank_start - 1) | ((adjusted_mode->crtc_vblank_end - 1) << 16));
 331        REG_WRITE(vsync_reg, (adjusted_mode->crtc_vsync_start - 1) | ((adjusted_mode->crtc_vsync_end - 1) << 16));
 332        REG_WRITE(pipesrc_reg, ((mode->crtc_hdisplay - 1) << 16) |  (mode->crtc_vdisplay - 1));
 333
 334        REG_WRITE(PCH_HTOTAL_B, (adjusted_mode->crtc_hdisplay - 1) | ((adjusted_mode->crtc_htotal - 1) << 16));
 335        REG_WRITE(PCH_HBLANK_B, (adjusted_mode->crtc_hblank_start - 1) | ((adjusted_mode->crtc_hblank_end - 1) << 16));
 336        REG_WRITE(PCH_HSYNC_B, (adjusted_mode->crtc_hsync_start - 1) | ((adjusted_mode->crtc_hsync_end - 1) << 16));
 337        REG_WRITE(PCH_VTOTAL_B, (adjusted_mode->crtc_vdisplay - 1) | ((adjusted_mode->crtc_vtotal - 1) << 16));
 338        REG_WRITE(PCH_VBLANK_B, (adjusted_mode->crtc_vblank_start - 1) | ((adjusted_mode->crtc_vblank_end - 1) << 16));
 339        REG_WRITE(PCH_VSYNC_B, (adjusted_mode->crtc_vsync_start - 1) | ((adjusted_mode->crtc_vsync_end - 1) << 16));
 340        REG_WRITE(PCH_PIPEBSRC, ((mode->crtc_hdisplay - 1) << 16) |  (mode->crtc_vdisplay - 1));
 341
 342        temp = adjusted_mode->crtc_hblank_end - adjusted_mode->crtc_hblank_start;
 343        HDMI_WRITE(HDMI_HBLANK_A, ((adjusted_mode->crtc_hdisplay - 1) << 16) |  temp);
 344
 345        REG_WRITE(dspsize_reg, ((mode->vdisplay - 1) << 16) | (mode->hdisplay - 1));
 346        REG_WRITE(dsppos_reg, 0);
 347
 348        /* Flush the plane changes */
 349        {
 350                struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
 351                crtc_funcs->mode_set_base(crtc, x, y, old_fb);
 352        }
 353
 354        /* Set up the display plane register */
 355        dspcntr = REG_READ(dspcntr_reg);
 356        dspcntr |= DISPPLANE_GAMMA_ENABLE;
 357        dspcntr |= DISPPLANE_SEL_PIPE_B;
 358        dspcntr |= DISPLAY_PLANE_ENABLE;
 359
 360        /* setup pipeconf */
 361        pipeconf = REG_READ(pipeconf_reg);
 362        pipeconf |= PIPEACONF_ENABLE;
 363
 364        REG_WRITE(pipeconf_reg, pipeconf);
 365        REG_READ(pipeconf_reg);
 366
 367        REG_WRITE(PCH_PIPEBCONF, pipeconf);
 368        REG_READ(PCH_PIPEBCONF);
 369        gma_wait_for_vblank(dev);
 370
 371        REG_WRITE(dspcntr_reg, dspcntr);
 372        gma_wait_for_vblank(dev);
 373
 374        gma_power_end(dev);
 375
 376        return 0;
 377}
 378
 379void oaktrail_crtc_hdmi_dpms(struct drm_crtc *crtc, int mode)
 380{
 381        struct drm_device *dev = crtc->dev;
 382        u32 temp;
 383
 384        DRM_DEBUG_KMS("%s %d\n", __func__, mode);
 385
 386        switch (mode) {
 387        case DRM_MODE_DPMS_OFF:
 388                REG_WRITE(VGACNTRL, 0x80000000);
 389
 390                /* Disable plane */
 391                temp = REG_READ(DSPBCNTR);
 392                if ((temp & DISPLAY_PLANE_ENABLE) != 0) {
 393                        REG_WRITE(DSPBCNTR, temp & ~DISPLAY_PLANE_ENABLE);
 394                        REG_READ(DSPBCNTR);
 395                        /* Flush the plane changes */
 396                        REG_WRITE(DSPBSURF, REG_READ(DSPBSURF));
 397                        REG_READ(DSPBSURF);
 398                }
 399
 400                /* Disable pipe B */
 401                temp = REG_READ(PIPEBCONF);
 402                if ((temp & PIPEACONF_ENABLE) != 0) {
 403                        REG_WRITE(PIPEBCONF, temp & ~PIPEACONF_ENABLE);
 404                        REG_READ(PIPEBCONF);
 405                }
 406
 407                /* Disable LNW Pipes, etc */
 408                temp = REG_READ(PCH_PIPEBCONF);
 409                if ((temp & PIPEACONF_ENABLE) != 0) {
 410                        REG_WRITE(PCH_PIPEBCONF, temp & ~PIPEACONF_ENABLE);
 411                        REG_READ(PCH_PIPEBCONF);
 412                }
 413
 414                /* wait for pipe off */
 415                udelay(150);
 416
 417                /* Disable dpll */
 418                temp = REG_READ(DPLL_CTRL);
 419                if ((temp & DPLL_PWRDN) == 0) {
 420                        REG_WRITE(DPLL_CTRL, temp | (DPLL_PWRDN | DPLL_RESET));
 421                        REG_WRITE(DPLL_STATUS, 0x1);
 422                }
 423
 424                /* wait for dpll off */
 425                udelay(150);
 426
 427                break;
 428        case DRM_MODE_DPMS_ON:
 429        case DRM_MODE_DPMS_STANDBY:
 430        case DRM_MODE_DPMS_SUSPEND:
 431                /* Enable dpll */
 432                temp = REG_READ(DPLL_CTRL);
 433                if ((temp & DPLL_PWRDN) != 0) {
 434                        REG_WRITE(DPLL_CTRL, temp & ~(DPLL_PWRDN | DPLL_RESET));
 435                        temp = REG_READ(DPLL_CLK_ENABLE);
 436                        REG_WRITE(DPLL_CLK_ENABLE, temp | DPLL_EN_DISP | DPLL_SEL_HDMI | DPLL_EN_HDMI);
 437                        REG_READ(DPLL_CLK_ENABLE);
 438                }
 439                /* wait for dpll warm up */
 440                udelay(150);
 441
 442                /* Enable pipe B */
 443                temp = REG_READ(PIPEBCONF);
 444                if ((temp & PIPEACONF_ENABLE) == 0) {
 445                        REG_WRITE(PIPEBCONF, temp | PIPEACONF_ENABLE);
 446                        REG_READ(PIPEBCONF);
 447                }
 448
 449                /* Enable LNW Pipe B */
 450                temp = REG_READ(PCH_PIPEBCONF);
 451                if ((temp & PIPEACONF_ENABLE) == 0) {
 452                        REG_WRITE(PCH_PIPEBCONF, temp | PIPEACONF_ENABLE);
 453                        REG_READ(PCH_PIPEBCONF);
 454                }
 455
 456                gma_wait_for_vblank(dev);
 457
 458                /* Enable plane */
 459                temp = REG_READ(DSPBCNTR);
 460                if ((temp & DISPLAY_PLANE_ENABLE) == 0) {
 461                        REG_WRITE(DSPBCNTR, temp | DISPLAY_PLANE_ENABLE);
 462                        /* Flush the plane changes */
 463                        REG_WRITE(DSPBSURF, REG_READ(DSPBSURF));
 464                        REG_READ(DSPBSURF);
 465                }
 466
 467                gma_crtc_load_lut(crtc);
 468        }
 469
 470        /* DSPARB */
 471        REG_WRITE(DSPARB, 0x00003fbf);
 472
 473        /* FW1 */
 474        REG_WRITE(0x70034, 0x3f880a0a);
 475
 476        /* FW2 */
 477        REG_WRITE(0x70038, 0x0b060808);
 478
 479        /* FW4 */
 480        REG_WRITE(0x70050, 0x08030404);
 481
 482        /* FW5 */
 483        REG_WRITE(0x70054, 0x04040404);
 484
 485        /* LNC Chicken Bits - Squawk! */
 486        REG_WRITE(0x70400, 0x4000);
 487
 488        return;
 489}
 490
 491static void oaktrail_hdmi_dpms(struct drm_encoder *encoder, int mode)
 492{
 493        static int dpms_mode = -1;
 494
 495        struct drm_device *dev = encoder->dev;
 496        struct drm_psb_private *dev_priv = dev->dev_private;
 497        struct oaktrail_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv;
 498        u32 temp;
 499
 500        if (dpms_mode == mode)
 501                return;
 502
 503        if (mode != DRM_MODE_DPMS_ON)
 504                temp = 0x0;
 505        else
 506                temp = 0x99;
 507
 508        dpms_mode = mode;
 509        HDMI_WRITE(HDMI_VIDEO_REG, temp);
 510}
 511
 512static int oaktrail_hdmi_mode_valid(struct drm_connector *connector,
 513                                struct drm_display_mode *mode)
 514{
 515        if (mode->clock > 165000)
 516                return MODE_CLOCK_HIGH;
 517        if (mode->clock < 20000)
 518                return MODE_CLOCK_LOW;
 519
 520        if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
 521                return MODE_NO_DBLESCAN;
 522
 523        return MODE_OK;
 524}
 525
 526static enum drm_connector_status
 527oaktrail_hdmi_detect(struct drm_connector *connector, bool force)
 528{
 529        enum drm_connector_status status;
 530        struct drm_device *dev = connector->dev;
 531        struct drm_psb_private *dev_priv = dev->dev_private;
 532        struct oaktrail_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv;
 533        u32 temp;
 534
 535        temp = HDMI_READ(HDMI_HSR);
 536        DRM_DEBUG_KMS("HDMI_HSR %x\n", temp);
 537
 538        if ((temp & HDMI_DETECT_HDP) != 0)
 539                status = connector_status_connected;
 540        else
 541                status = connector_status_disconnected;
 542
 543        return status;
 544}
 545
 546static const unsigned char raw_edid[] = {
 547        0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x10, 0xac, 0x2f, 0xa0,
 548        0x53, 0x55, 0x33, 0x30, 0x16, 0x13, 0x01, 0x03, 0x0e, 0x3a, 0x24, 0x78,
 549        0xea, 0xe9, 0xf5, 0xac, 0x51, 0x30, 0xb4, 0x25, 0x11, 0x50, 0x54, 0xa5,
 550        0x4b, 0x00, 0x81, 0x80, 0xa9, 0x40, 0x71, 0x4f, 0xb3, 0x00, 0x01, 0x01,
 551        0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x28, 0x3c, 0x80, 0xa0, 0x70, 0xb0,
 552        0x23, 0x40, 0x30, 0x20, 0x36, 0x00, 0x46, 0x6c, 0x21, 0x00, 0x00, 0x1a,
 553        0x00, 0x00, 0x00, 0xff, 0x00, 0x47, 0x4e, 0x37, 0x32, 0x31, 0x39, 0x35,
 554        0x52, 0x30, 0x33, 0x55, 0x53, 0x0a, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x44,
 555        0x45, 0x4c, 0x4c, 0x20, 0x32, 0x37, 0x30, 0x39, 0x57, 0x0a, 0x20, 0x20,
 556        0x00, 0x00, 0x00, 0xfd, 0x00, 0x38, 0x4c, 0x1e, 0x53, 0x11, 0x00, 0x0a,
 557        0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x8d
 558};
 559
 560static int oaktrail_hdmi_get_modes(struct drm_connector *connector)
 561{
 562        struct i2c_adapter *i2c_adap;
 563        struct edid *edid;
 564        int ret = 0;
 565
 566        /*
 567         *      FIXME: We need to figure this lot out. In theory we can
 568         *      read the EDID somehow but I've yet to find working reference
 569         *      code.
 570         */
 571        i2c_adap = i2c_get_adapter(3);
 572        if (i2c_adap == NULL) {
 573                DRM_ERROR("No ddc adapter available!\n");
 574                edid = (struct edid *)raw_edid;
 575        } else {
 576                edid = (struct edid *)raw_edid;
 577                /* FIXME ? edid = drm_get_edid(connector, i2c_adap); */
 578        }
 579
 580        if (edid) {
 581                drm_mode_connector_update_edid_property(connector, edid);
 582                ret = drm_add_edid_modes(connector, edid);
 583        }
 584        return ret;
 585}
 586
 587static void oaktrail_hdmi_mode_set(struct drm_encoder *encoder,
 588                               struct drm_display_mode *mode,
 589                               struct drm_display_mode *adjusted_mode)
 590{
 591        struct drm_device *dev = encoder->dev;
 592
 593        oaktrail_hdmi_audio_enable(dev);
 594        return;
 595}
 596
 597static void oaktrail_hdmi_destroy(struct drm_connector *connector)
 598{
 599        return;
 600}
 601
 602static const struct drm_encoder_helper_funcs oaktrail_hdmi_helper_funcs = {
 603        .dpms = oaktrail_hdmi_dpms,
 604        .mode_fixup = gma_encoder_mode_fixup,
 605        .prepare = gma_encoder_prepare,
 606        .mode_set = oaktrail_hdmi_mode_set,
 607        .commit = gma_encoder_commit,
 608};
 609
 610static const struct drm_connector_helper_funcs
 611                                        oaktrail_hdmi_connector_helper_funcs = {
 612        .get_modes = oaktrail_hdmi_get_modes,
 613        .mode_valid = oaktrail_hdmi_mode_valid,
 614        .best_encoder = gma_best_encoder,
 615};
 616
 617static const struct drm_connector_funcs oaktrail_hdmi_connector_funcs = {
 618        .dpms = drm_helper_connector_dpms,
 619        .detect = oaktrail_hdmi_detect,
 620        .fill_modes = drm_helper_probe_single_connector_modes,
 621        .destroy = oaktrail_hdmi_destroy,
 622};
 623
 624static void oaktrail_hdmi_enc_destroy(struct drm_encoder *encoder)
 625{
 626        drm_encoder_cleanup(encoder);
 627}
 628
 629static const struct drm_encoder_funcs oaktrail_hdmi_enc_funcs = {
 630        .destroy = oaktrail_hdmi_enc_destroy,
 631};
 632
 633void oaktrail_hdmi_init(struct drm_device *dev,
 634                                        struct psb_intel_mode_device *mode_dev)
 635{
 636        struct gma_encoder *gma_encoder;
 637        struct gma_connector *gma_connector;
 638        struct drm_connector *connector;
 639        struct drm_encoder *encoder;
 640
 641        gma_encoder = kzalloc(sizeof(struct gma_encoder), GFP_KERNEL);
 642        if (!gma_encoder)
 643                return;
 644
 645        gma_connector = kzalloc(sizeof(struct gma_connector), GFP_KERNEL);
 646        if (!gma_connector)
 647                goto failed_connector;
 648
 649        connector = &gma_connector->base;
 650        encoder = &gma_encoder->base;
 651        drm_connector_init(dev, connector,
 652                           &oaktrail_hdmi_connector_funcs,
 653                           DRM_MODE_CONNECTOR_DVID);
 654
 655        drm_encoder_init(dev, encoder,
 656                         &oaktrail_hdmi_enc_funcs,
 657                         DRM_MODE_ENCODER_TMDS);
 658
 659        gma_connector_attach_encoder(gma_connector, gma_encoder);
 660
 661        gma_encoder->type = INTEL_OUTPUT_HDMI;
 662        drm_encoder_helper_add(encoder, &oaktrail_hdmi_helper_funcs);
 663        drm_connector_helper_add(connector, &oaktrail_hdmi_connector_helper_funcs);
 664
 665        connector->display_info.subpixel_order = SubPixelHorizontalRGB;
 666        connector->interlace_allowed = false;
 667        connector->doublescan_allowed = false;
 668        drm_connector_register(connector);
 669        dev_info(dev->dev, "HDMI initialised.\n");
 670
 671        return;
 672
 673failed_connector:
 674        kfree(gma_encoder);
 675}
 676
 677static const struct pci_device_id hdmi_ids[] = {
 678        { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x080d) },
 679        { 0 }
 680};
 681
 682void oaktrail_hdmi_setup(struct drm_device *dev)
 683{
 684        struct drm_psb_private *dev_priv = dev->dev_private;
 685        struct pci_dev *pdev;
 686        struct oaktrail_hdmi_dev *hdmi_dev;
 687        int ret;
 688
 689        pdev = pci_get_device(PCI_VENDOR_ID_INTEL, 0x080d, NULL);
 690        if (!pdev)
 691                return;
 692
 693        hdmi_dev = kzalloc(sizeof(struct oaktrail_hdmi_dev), GFP_KERNEL);
 694        if (!hdmi_dev) {
 695                dev_err(dev->dev, "failed to allocate memory\n");
 696                goto out;
 697        }
 698
 699
 700        ret = pci_enable_device(pdev);
 701        if (ret) {
 702                dev_err(dev->dev, "failed to enable hdmi controller\n");
 703                goto free;
 704        }
 705
 706        hdmi_dev->mmio = pci_resource_start(pdev, 0);
 707        hdmi_dev->mmio_len = pci_resource_len(pdev, 0);
 708        hdmi_dev->regs = ioremap(hdmi_dev->mmio, hdmi_dev->mmio_len);
 709        if (!hdmi_dev->regs) {
 710                dev_err(dev->dev, "failed to map hdmi mmio\n");
 711                goto free;
 712        }
 713
 714        hdmi_dev->dev = pdev;
 715        pci_set_drvdata(pdev, hdmi_dev);
 716
 717        /* Initialize i2c controller */
 718        ret = oaktrail_hdmi_i2c_init(hdmi_dev->dev);
 719        if (ret)
 720                dev_err(dev->dev, "HDMI I2C initialization failed\n");
 721
 722        dev_priv->hdmi_priv = hdmi_dev;
 723        oaktrail_hdmi_audio_disable(dev);
 724
 725        dev_info(dev->dev, "HDMI hardware present.\n");
 726
 727        return;
 728
 729free:
 730        kfree(hdmi_dev);
 731out:
 732        return;
 733}
 734
 735void oaktrail_hdmi_teardown(struct drm_device *dev)
 736{
 737        struct drm_psb_private *dev_priv = dev->dev_private;
 738        struct oaktrail_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv;
 739        struct pci_dev *pdev;
 740
 741        if (hdmi_dev) {
 742                pdev = hdmi_dev->dev;
 743                pci_set_drvdata(pdev, NULL);
 744                oaktrail_hdmi_i2c_exit(pdev);
 745                iounmap(hdmi_dev->regs);
 746                kfree(hdmi_dev);
 747                pci_dev_put(pdev);
 748        }
 749}
 750
 751/* save HDMI register state */
 752void oaktrail_hdmi_save(struct drm_device *dev)
 753{
 754        struct drm_psb_private *dev_priv = dev->dev_private;
 755        struct oaktrail_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv;
 756        struct psb_state *regs = &dev_priv->regs.psb;
 757        struct psb_pipe *pipeb = &dev_priv->regs.pipe[1];
 758        int i;
 759
 760        /* dpll */
 761        hdmi_dev->saveDPLL_CTRL = PSB_RVDC32(DPLL_CTRL);
 762        hdmi_dev->saveDPLL_DIV_CTRL = PSB_RVDC32(DPLL_DIV_CTRL);
 763        hdmi_dev->saveDPLL_ADJUST = PSB_RVDC32(DPLL_ADJUST);
 764        hdmi_dev->saveDPLL_UPDATE = PSB_RVDC32(DPLL_UPDATE);
 765        hdmi_dev->saveDPLL_CLK_ENABLE = PSB_RVDC32(DPLL_CLK_ENABLE);
 766
 767        /* pipe B */
 768        pipeb->conf = PSB_RVDC32(PIPEBCONF);
 769        pipeb->src = PSB_RVDC32(PIPEBSRC);
 770        pipeb->htotal = PSB_RVDC32(HTOTAL_B);
 771        pipeb->hblank = PSB_RVDC32(HBLANK_B);
 772        pipeb->hsync = PSB_RVDC32(HSYNC_B);
 773        pipeb->vtotal = PSB_RVDC32(VTOTAL_B);
 774        pipeb->vblank = PSB_RVDC32(VBLANK_B);
 775        pipeb->vsync = PSB_RVDC32(VSYNC_B);
 776
 777        hdmi_dev->savePCH_PIPEBCONF = PSB_RVDC32(PCH_PIPEBCONF);
 778        hdmi_dev->savePCH_PIPEBSRC = PSB_RVDC32(PCH_PIPEBSRC);
 779        hdmi_dev->savePCH_HTOTAL_B = PSB_RVDC32(PCH_HTOTAL_B);
 780        hdmi_dev->savePCH_HBLANK_B = PSB_RVDC32(PCH_HBLANK_B);
 781        hdmi_dev->savePCH_HSYNC_B  = PSB_RVDC32(PCH_HSYNC_B);
 782        hdmi_dev->savePCH_VTOTAL_B = PSB_RVDC32(PCH_VTOTAL_B);
 783        hdmi_dev->savePCH_VBLANK_B = PSB_RVDC32(PCH_VBLANK_B);
 784        hdmi_dev->savePCH_VSYNC_B  = PSB_RVDC32(PCH_VSYNC_B);
 785
 786        /* plane */
 787        pipeb->cntr = PSB_RVDC32(DSPBCNTR);
 788        pipeb->stride = PSB_RVDC32(DSPBSTRIDE);
 789        pipeb->addr = PSB_RVDC32(DSPBBASE);
 790        pipeb->surf = PSB_RVDC32(DSPBSURF);
 791        pipeb->linoff = PSB_RVDC32(DSPBLINOFF);
 792        pipeb->tileoff = PSB_RVDC32(DSPBTILEOFF);
 793
 794        /* cursor B */
 795        regs->saveDSPBCURSOR_CTRL = PSB_RVDC32(CURBCNTR);
 796        regs->saveDSPBCURSOR_BASE = PSB_RVDC32(CURBBASE);
 797        regs->saveDSPBCURSOR_POS = PSB_RVDC32(CURBPOS);
 798
 799        /* save palette */
 800        for (i = 0; i < 256; i++)
 801                pipeb->palette[i] = PSB_RVDC32(PALETTE_B + (i << 2));
 802}
 803
 804/* restore HDMI register state */
 805void oaktrail_hdmi_restore(struct drm_device *dev)
 806{
 807        struct drm_psb_private *dev_priv = dev->dev_private;
 808        struct oaktrail_hdmi_dev *hdmi_dev = dev_priv->hdmi_priv;
 809        struct psb_state *regs = &dev_priv->regs.psb;
 810        struct psb_pipe *pipeb = &dev_priv->regs.pipe[1];
 811        int i;
 812
 813        /* dpll */
 814        PSB_WVDC32(hdmi_dev->saveDPLL_CTRL, DPLL_CTRL);
 815        PSB_WVDC32(hdmi_dev->saveDPLL_DIV_CTRL, DPLL_DIV_CTRL);
 816        PSB_WVDC32(hdmi_dev->saveDPLL_ADJUST, DPLL_ADJUST);
 817        PSB_WVDC32(hdmi_dev->saveDPLL_UPDATE, DPLL_UPDATE);
 818        PSB_WVDC32(hdmi_dev->saveDPLL_CLK_ENABLE, DPLL_CLK_ENABLE);
 819        DRM_UDELAY(150);
 820
 821        /* pipe */
 822        PSB_WVDC32(pipeb->src, PIPEBSRC);
 823        PSB_WVDC32(pipeb->htotal, HTOTAL_B);
 824        PSB_WVDC32(pipeb->hblank, HBLANK_B);
 825        PSB_WVDC32(pipeb->hsync,  HSYNC_B);
 826        PSB_WVDC32(pipeb->vtotal, VTOTAL_B);
 827        PSB_WVDC32(pipeb->vblank, VBLANK_B);
 828        PSB_WVDC32(pipeb->vsync,  VSYNC_B);
 829
 830        PSB_WVDC32(hdmi_dev->savePCH_PIPEBSRC, PCH_PIPEBSRC);
 831        PSB_WVDC32(hdmi_dev->savePCH_HTOTAL_B, PCH_HTOTAL_B);
 832        PSB_WVDC32(hdmi_dev->savePCH_HBLANK_B, PCH_HBLANK_B);
 833        PSB_WVDC32(hdmi_dev->savePCH_HSYNC_B,  PCH_HSYNC_B);
 834        PSB_WVDC32(hdmi_dev->savePCH_VTOTAL_B, PCH_VTOTAL_B);
 835        PSB_WVDC32(hdmi_dev->savePCH_VBLANK_B, PCH_VBLANK_B);
 836        PSB_WVDC32(hdmi_dev->savePCH_VSYNC_B,  PCH_VSYNC_B);
 837
 838        PSB_WVDC32(pipeb->conf, PIPEBCONF);
 839        PSB_WVDC32(hdmi_dev->savePCH_PIPEBCONF, PCH_PIPEBCONF);
 840
 841        /* plane */
 842        PSB_WVDC32(pipeb->linoff, DSPBLINOFF);
 843        PSB_WVDC32(pipeb->stride, DSPBSTRIDE);
 844        PSB_WVDC32(pipeb->tileoff, DSPBTILEOFF);
 845        PSB_WVDC32(pipeb->cntr, DSPBCNTR);
 846        PSB_WVDC32(pipeb->surf, DSPBSURF);
 847
 848        /* cursor B */
 849        PSB_WVDC32(regs->saveDSPBCURSOR_CTRL, CURBCNTR);
 850        PSB_WVDC32(regs->saveDSPBCURSOR_POS, CURBPOS);
 851        PSB_WVDC32(regs->saveDSPBCURSOR_BASE, CURBBASE);
 852
 853        /* restore palette */
 854        for (i = 0; i < 256; i++)
 855                PSB_WVDC32(pipeb->palette[i], PALETTE_B + (i << 2));
 856}
 857
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.