linux/drivers/gpu/drm/gma500/psb_irq.c
<<
>>
Prefs
   1/**************************************************************************
   2 * Copyright (c) 2007, Intel Corporation.
   3 * All Rights Reserved.
   4 *
   5 * This program is free software; you can redistribute it and/or modify it
   6 * under the terms and conditions of the GNU General Public License,
   7 * version 2, as published by the Free Software Foundation.
   8 *
   9 * This program is distributed in the hope it will be useful, but WITHOUT
  10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
  12 * more details.
  13 *
  14 * You should have received a copy of the GNU General Public License along with
  15 * this program; if not, write to the Free Software Foundation, Inc.,
  16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
  17 *
  18 * Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
  19 * develop this driver.
  20 *
  21 **************************************************************************/
  22/*
  23 */
  24
  25#include <drm/drmP.h>
  26#include "psb_drv.h"
  27#include "psb_reg.h"
  28#include "psb_intel_reg.h"
  29#include "power.h"
  30#include "psb_irq.h"
  31#include "mdfld_output.h"
  32
  33/*
  34 * inline functions
  35 */
  36
  37static inline u32
  38psb_pipestat(int pipe)
  39{
  40        if (pipe == 0)
  41                return PIPEASTAT;
  42        if (pipe == 1)
  43                return PIPEBSTAT;
  44        if (pipe == 2)
  45                return PIPECSTAT;
  46        BUG();
  47}
  48
  49static inline u32
  50mid_pipe_event(int pipe)
  51{
  52        if (pipe == 0)
  53                return _PSB_PIPEA_EVENT_FLAG;
  54        if (pipe == 1)
  55                return _MDFLD_PIPEB_EVENT_FLAG;
  56        if (pipe == 2)
  57                return _MDFLD_PIPEC_EVENT_FLAG;
  58        BUG();
  59}
  60
  61static inline u32
  62mid_pipe_vsync(int pipe)
  63{
  64        if (pipe == 0)
  65                return _PSB_VSYNC_PIPEA_FLAG;
  66        if (pipe == 1)
  67                return _PSB_VSYNC_PIPEB_FLAG;
  68        if (pipe == 2)
  69                return _MDFLD_PIPEC_VBLANK_FLAG;
  70        BUG();
  71}
  72
  73static inline u32
  74mid_pipeconf(int pipe)
  75{
  76        if (pipe == 0)
  77                return PIPEACONF;
  78        if (pipe == 1)
  79                return PIPEBCONF;
  80        if (pipe == 2)
  81                return PIPECCONF;
  82        BUG();
  83}
  84
  85void
  86psb_enable_pipestat(struct drm_psb_private *dev_priv, int pipe, u32 mask)
  87{
  88        if ((dev_priv->pipestat[pipe] & mask) != mask) {
  89                u32 reg = psb_pipestat(pipe);
  90                dev_priv->pipestat[pipe] |= mask;
  91                /* Enable the interrupt, clear any pending status */
  92                if (gma_power_begin(dev_priv->dev, false)) {
  93                        u32 writeVal = PSB_RVDC32(reg);
  94                        writeVal |= (mask | (mask >> 16));
  95                        PSB_WVDC32(writeVal, reg);
  96                        (void) PSB_RVDC32(reg);
  97                        gma_power_end(dev_priv->dev);
  98                }
  99        }
 100}
 101
 102void
 103psb_disable_pipestat(struct drm_psb_private *dev_priv, int pipe, u32 mask)
 104{
 105        if ((dev_priv->pipestat[pipe] & mask) != 0) {
 106                u32 reg = psb_pipestat(pipe);
 107                dev_priv->pipestat[pipe] &= ~mask;
 108                if (gma_power_begin(dev_priv->dev, false)) {
 109                        u32 writeVal = PSB_RVDC32(reg);
 110                        writeVal &= ~mask;
 111                        PSB_WVDC32(writeVal, reg);
 112                        (void) PSB_RVDC32(reg);
 113                        gma_power_end(dev_priv->dev);
 114                }
 115        }
 116}
 117
 118static void mid_enable_pipe_event(struct drm_psb_private *dev_priv, int pipe)
 119{
 120        if (gma_power_begin(dev_priv->dev, false)) {
 121                u32 pipe_event = mid_pipe_event(pipe);
 122                dev_priv->vdc_irq_mask |= pipe_event;
 123                PSB_WVDC32(~dev_priv->vdc_irq_mask, PSB_INT_MASK_R);
 124                PSB_WVDC32(dev_priv->vdc_irq_mask, PSB_INT_ENABLE_R);
 125                gma_power_end(dev_priv->dev);
 126        }
 127}
 128
 129static void mid_disable_pipe_event(struct drm_psb_private *dev_priv, int pipe)
 130{
 131        if (dev_priv->pipestat[pipe] == 0) {
 132                if (gma_power_begin(dev_priv->dev, false)) {
 133                        u32 pipe_event = mid_pipe_event(pipe);
 134                        dev_priv->vdc_irq_mask &= ~pipe_event;
 135                        PSB_WVDC32(~dev_priv->vdc_irq_mask, PSB_INT_MASK_R);
 136                        PSB_WVDC32(dev_priv->vdc_irq_mask, PSB_INT_ENABLE_R);
 137                        gma_power_end(dev_priv->dev);
 138                }
 139        }
 140}
 141
 142/**
 143 * Display controller interrupt handler for pipe event.
 144 *
 145 */
 146static void mid_pipe_event_handler(struct drm_device *dev, int pipe)
 147{
 148        struct drm_psb_private *dev_priv =
 149            (struct drm_psb_private *) dev->dev_private;
 150
 151        uint32_t pipe_stat_val = 0;
 152        uint32_t pipe_stat_reg = psb_pipestat(pipe);
 153        uint32_t pipe_enable = dev_priv->pipestat[pipe];
 154        uint32_t pipe_status = dev_priv->pipestat[pipe] >> 16;
 155        uint32_t pipe_clear;
 156        uint32_t i = 0;
 157
 158        spin_lock(&dev_priv->irqmask_lock);
 159
 160        pipe_stat_val = PSB_RVDC32(pipe_stat_reg);
 161        pipe_stat_val &= pipe_enable | pipe_status;
 162        pipe_stat_val &= pipe_stat_val >> 16;
 163
 164        spin_unlock(&dev_priv->irqmask_lock);
 165
 166        /* Clear the 2nd level interrupt status bits
 167         * Sometimes the bits are very sticky so we repeat until they unstick */
 168        for (i = 0; i < 0xffff; i++) {
 169                PSB_WVDC32(PSB_RVDC32(pipe_stat_reg), pipe_stat_reg);
 170                pipe_clear = PSB_RVDC32(pipe_stat_reg) & pipe_status;
 171
 172                if (pipe_clear == 0)
 173                        break;
 174        }
 175
 176        if (pipe_clear)
 177                dev_err(dev->dev,
 178                "%s, can't clear status bits for pipe %d, its value = 0x%x.\n",
 179                __func__, pipe, PSB_RVDC32(pipe_stat_reg));
 180
 181        if (pipe_stat_val & PIPE_VBLANK_STATUS)
 182                drm_handle_vblank(dev, pipe);
 183
 184        if (pipe_stat_val & PIPE_TE_STATUS)
 185                drm_handle_vblank(dev, pipe);
 186}
 187
 188/*
 189 * Display controller interrupt handler.
 190 */
 191static void psb_vdc_interrupt(struct drm_device *dev, uint32_t vdc_stat)
 192{
 193        if (vdc_stat & _PSB_IRQ_ASLE)
 194                psb_intel_opregion_asle_intr(dev);
 195
 196        if (vdc_stat & _PSB_VSYNC_PIPEA_FLAG)
 197                mid_pipe_event_handler(dev, 0);
 198
 199        if (vdc_stat & _PSB_VSYNC_PIPEB_FLAG)
 200                mid_pipe_event_handler(dev, 1);
 201}
 202
 203/*
 204 * SGX interrupt handler
 205 */
 206static void psb_sgx_interrupt(struct drm_device *dev, u32 stat_1, u32 stat_2)
 207{
 208        struct drm_psb_private *dev_priv = dev->dev_private;
 209        u32 val, addr;
 210        int error = false;
 211
 212        if (stat_1 & _PSB_CE_TWOD_COMPLETE)
 213                val = PSB_RSGX32(PSB_CR_2D_BLIT_STATUS);
 214
 215        if (stat_2 & _PSB_CE2_BIF_REQUESTER_FAULT) {
 216                val = PSB_RSGX32(PSB_CR_BIF_INT_STAT);
 217                addr = PSB_RSGX32(PSB_CR_BIF_FAULT);
 218                if (val) {
 219                        if (val & _PSB_CBI_STAT_PF_N_RW)
 220                                DRM_ERROR("SGX MMU page fault:");
 221                        else
 222                                DRM_ERROR("SGX MMU read / write protection fault:");
 223
 224                        if (val & _PSB_CBI_STAT_FAULT_CACHE)
 225                                DRM_ERROR("\tCache requestor");
 226                        if (val & _PSB_CBI_STAT_FAULT_TA)
 227                                DRM_ERROR("\tTA requestor");
 228                        if (val & _PSB_CBI_STAT_FAULT_VDM)
 229                                DRM_ERROR("\tVDM requestor");
 230                        if (val & _PSB_CBI_STAT_FAULT_2D)
 231                                DRM_ERROR("\t2D requestor");
 232                        if (val & _PSB_CBI_STAT_FAULT_PBE)
 233                                DRM_ERROR("\tPBE requestor");
 234                        if (val & _PSB_CBI_STAT_FAULT_TSP)
 235                                DRM_ERROR("\tTSP requestor");
 236                        if (val & _PSB_CBI_STAT_FAULT_ISP)
 237                                DRM_ERROR("\tISP requestor");
 238                        if (val & _PSB_CBI_STAT_FAULT_USSEPDS)
 239                                DRM_ERROR("\tUSSEPDS requestor");
 240                        if (val & _PSB_CBI_STAT_FAULT_HOST)
 241                                DRM_ERROR("\tHost requestor");
 242
 243                        DRM_ERROR("\tMMU failing address is 0x%08x.\n",
 244                                  (unsigned int)addr);
 245                        error = true;
 246                }
 247        }
 248
 249        /* Clear bits */
 250        PSB_WSGX32(stat_1, PSB_CR_EVENT_HOST_CLEAR);
 251        PSB_WSGX32(stat_2, PSB_CR_EVENT_HOST_CLEAR2);
 252        PSB_RSGX32(PSB_CR_EVENT_HOST_CLEAR2);
 253}
 254
 255irqreturn_t psb_irq_handler(int irq, void *arg)
 256{
 257        struct drm_device *dev = arg;
 258        struct drm_psb_private *dev_priv = dev->dev_private;
 259        uint32_t vdc_stat, dsp_int = 0, sgx_int = 0, hotplug_int = 0;
 260        u32 sgx_stat_1, sgx_stat_2;
 261        int handled = 0;
 262
 263        spin_lock(&dev_priv->irqmask_lock);
 264
 265        vdc_stat = PSB_RVDC32(PSB_INT_IDENTITY_R);
 266
 267        if (vdc_stat & (_PSB_PIPE_EVENT_FLAG|_PSB_IRQ_ASLE))
 268                dsp_int = 1;
 269
 270        /* FIXME: Handle Medfield
 271        if (vdc_stat & _MDFLD_DISP_ALL_IRQ_FLAG)
 272                dsp_int = 1;
 273        */
 274
 275        if (vdc_stat & _PSB_IRQ_SGX_FLAG)
 276                sgx_int = 1;
 277        if (vdc_stat & _PSB_IRQ_DISP_HOTSYNC)
 278                hotplug_int = 1;
 279
 280        vdc_stat &= dev_priv->vdc_irq_mask;
 281        spin_unlock(&dev_priv->irqmask_lock);
 282
 283        if (dsp_int && gma_power_is_on(dev)) {
 284                psb_vdc_interrupt(dev, vdc_stat);
 285                handled = 1;
 286        }
 287
 288        if (sgx_int) {
 289                sgx_stat_1 = PSB_RSGX32(PSB_CR_EVENT_STATUS);
 290                sgx_stat_2 = PSB_RSGX32(PSB_CR_EVENT_STATUS2);
 291                psb_sgx_interrupt(dev, sgx_stat_1, sgx_stat_2);
 292                handled = 1;
 293        }
 294
 295        /* Note: this bit has other meanings on some devices, so we will
 296           need to address that later if it ever matters */
 297        if (hotplug_int && dev_priv->ops->hotplug) {
 298                handled = dev_priv->ops->hotplug(dev);
 299                REG_WRITE(PORT_HOTPLUG_STAT, REG_READ(PORT_HOTPLUG_STAT));
 300        }
 301
 302        PSB_WVDC32(vdc_stat, PSB_INT_IDENTITY_R);
 303        (void) PSB_RVDC32(PSB_INT_IDENTITY_R);
 304        rmb();
 305
 306        if (!handled)
 307                return IRQ_NONE;
 308
 309        return IRQ_HANDLED;
 310}
 311
 312void psb_irq_preinstall(struct drm_device *dev)
 313{
 314        struct drm_psb_private *dev_priv =
 315            (struct drm_psb_private *) dev->dev_private;
 316        unsigned long irqflags;
 317
 318        spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags);
 319
 320        if (gma_power_is_on(dev)) {
 321                PSB_WVDC32(0xFFFFFFFF, PSB_HWSTAM);
 322                PSB_WVDC32(0x00000000, PSB_INT_MASK_R);
 323                PSB_WVDC32(0x00000000, PSB_INT_ENABLE_R);
 324                PSB_WSGX32(0x00000000, PSB_CR_EVENT_HOST_ENABLE);
 325                PSB_RSGX32(PSB_CR_EVENT_HOST_ENABLE);
 326        }
 327        if (dev->vblank[0].enabled)
 328                dev_priv->vdc_irq_mask |= _PSB_VSYNC_PIPEA_FLAG;
 329        if (dev->vblank[1].enabled)
 330                dev_priv->vdc_irq_mask |= _PSB_VSYNC_PIPEB_FLAG;
 331
 332        /* FIXME: Handle Medfield irq mask
 333        if (dev->vblank[1].enabled)
 334                dev_priv->vdc_irq_mask |= _MDFLD_PIPEB_EVENT_FLAG;
 335        if (dev->vblank[2].enabled)
 336                dev_priv->vdc_irq_mask |= _MDFLD_PIPEC_EVENT_FLAG;
 337        */
 338
 339        /* Revisit this area - want per device masks ? */
 340        if (dev_priv->ops->hotplug)
 341                dev_priv->vdc_irq_mask |= _PSB_IRQ_DISP_HOTSYNC;
 342        dev_priv->vdc_irq_mask |= _PSB_IRQ_ASLE | _PSB_IRQ_SGX_FLAG;
 343
 344        /* This register is safe even if display island is off */
 345        PSB_WVDC32(~dev_priv->vdc_irq_mask, PSB_INT_MASK_R);
 346        spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags);
 347}
 348
 349int psb_irq_postinstall(struct drm_device *dev)
 350{
 351        struct drm_psb_private *dev_priv = dev->dev_private;
 352        unsigned long irqflags;
 353
 354        spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags);
 355
 356        /* Enable 2D and MMU fault interrupts */
 357        PSB_WSGX32(_PSB_CE2_BIF_REQUESTER_FAULT, PSB_CR_EVENT_HOST_ENABLE2);
 358        PSB_WSGX32(_PSB_CE_TWOD_COMPLETE, PSB_CR_EVENT_HOST_ENABLE);
 359        PSB_RSGX32(PSB_CR_EVENT_HOST_ENABLE); /* Post */
 360
 361        /* This register is safe even if display island is off */
 362        PSB_WVDC32(dev_priv->vdc_irq_mask, PSB_INT_ENABLE_R);
 363        PSB_WVDC32(0xFFFFFFFF, PSB_HWSTAM);
 364
 365        if (dev->vblank[0].enabled)
 366                psb_enable_pipestat(dev_priv, 0, PIPE_VBLANK_INTERRUPT_ENABLE);
 367        else
 368                psb_disable_pipestat(dev_priv, 0, PIPE_VBLANK_INTERRUPT_ENABLE);
 369
 370        if (dev->vblank[1].enabled)
 371                psb_enable_pipestat(dev_priv, 1, PIPE_VBLANK_INTERRUPT_ENABLE);
 372        else
 373                psb_disable_pipestat(dev_priv, 1, PIPE_VBLANK_INTERRUPT_ENABLE);
 374
 375        if (dev->vblank[2].enabled)
 376                psb_enable_pipestat(dev_priv, 2, PIPE_VBLANK_INTERRUPT_ENABLE);
 377        else
 378                psb_disable_pipestat(dev_priv, 2, PIPE_VBLANK_INTERRUPT_ENABLE);
 379
 380        if (dev_priv->ops->hotplug_enable)
 381                dev_priv->ops->hotplug_enable(dev, true);
 382
 383        spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags);
 384        return 0;
 385}
 386
 387void psb_irq_uninstall(struct drm_device *dev)
 388{
 389        struct drm_psb_private *dev_priv = dev->dev_private;
 390        unsigned long irqflags;
 391
 392        spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags);
 393
 394        if (dev_priv->ops->hotplug_enable)
 395                dev_priv->ops->hotplug_enable(dev, false);
 396
 397        PSB_WVDC32(0xFFFFFFFF, PSB_HWSTAM);
 398
 399        if (dev->vblank[0].enabled)
 400                psb_disable_pipestat(dev_priv, 0, PIPE_VBLANK_INTERRUPT_ENABLE);
 401
 402        if (dev->vblank[1].enabled)
 403                psb_disable_pipestat(dev_priv, 1, PIPE_VBLANK_INTERRUPT_ENABLE);
 404
 405        if (dev->vblank[2].enabled)
 406                psb_disable_pipestat(dev_priv, 2, PIPE_VBLANK_INTERRUPT_ENABLE);
 407
 408        dev_priv->vdc_irq_mask &= _PSB_IRQ_SGX_FLAG |
 409                                  _PSB_IRQ_MSVDX_FLAG |
 410                                  _LNC_IRQ_TOPAZ_FLAG;
 411
 412        /* These two registers are safe even if display island is off */
 413        PSB_WVDC32(~dev_priv->vdc_irq_mask, PSB_INT_MASK_R);
 414        PSB_WVDC32(dev_priv->vdc_irq_mask, PSB_INT_ENABLE_R);
 415
 416        wmb();
 417
 418        /* This register is safe even if display island is off */
 419        PSB_WVDC32(PSB_RVDC32(PSB_INT_IDENTITY_R), PSB_INT_IDENTITY_R);
 420        spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags);
 421}
 422
 423void psb_irq_turn_on_dpst(struct drm_device *dev)
 424{
 425        struct drm_psb_private *dev_priv =
 426                (struct drm_psb_private *) dev->dev_private;
 427        u32 hist_reg;
 428        u32 pwm_reg;
 429
 430        if (gma_power_begin(dev, false)) {
 431                PSB_WVDC32(1 << 31, HISTOGRAM_LOGIC_CONTROL);
 432                hist_reg = PSB_RVDC32(HISTOGRAM_LOGIC_CONTROL);
 433                PSB_WVDC32(1 << 31, HISTOGRAM_INT_CONTROL);
 434                hist_reg = PSB_RVDC32(HISTOGRAM_INT_CONTROL);
 435
 436                PSB_WVDC32(0x80010100, PWM_CONTROL_LOGIC);
 437                pwm_reg = PSB_RVDC32(PWM_CONTROL_LOGIC);
 438                PSB_WVDC32(pwm_reg | PWM_PHASEIN_ENABLE
 439                                                | PWM_PHASEIN_INT_ENABLE,
 440                                                           PWM_CONTROL_LOGIC);
 441                pwm_reg = PSB_RVDC32(PWM_CONTROL_LOGIC);
 442
 443                psb_enable_pipestat(dev_priv, 0, PIPE_DPST_EVENT_ENABLE);
 444
 445                hist_reg = PSB_RVDC32(HISTOGRAM_INT_CONTROL);
 446                PSB_WVDC32(hist_reg | HISTOGRAM_INT_CTRL_CLEAR,
 447                                                        HISTOGRAM_INT_CONTROL);
 448                pwm_reg = PSB_RVDC32(PWM_CONTROL_LOGIC);
 449                PSB_WVDC32(pwm_reg | 0x80010100 | PWM_PHASEIN_ENABLE,
 450                                                        PWM_CONTROL_LOGIC);
 451
 452                gma_power_end(dev);
 453        }
 454}
 455
 456int psb_irq_enable_dpst(struct drm_device *dev)
 457{
 458        struct drm_psb_private *dev_priv =
 459                (struct drm_psb_private *) dev->dev_private;
 460        unsigned long irqflags;
 461
 462        spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags);
 463
 464        /* enable DPST */
 465        mid_enable_pipe_event(dev_priv, 0);
 466        psb_irq_turn_on_dpst(dev);
 467
 468        spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags);
 469        return 0;
 470}
 471
 472void psb_irq_turn_off_dpst(struct drm_device *dev)
 473{
 474        struct drm_psb_private *dev_priv =
 475            (struct drm_psb_private *) dev->dev_private;
 476        u32 hist_reg;
 477        u32 pwm_reg;
 478
 479        if (gma_power_begin(dev, false)) {
 480                PSB_WVDC32(0x00000000, HISTOGRAM_INT_CONTROL);
 481                hist_reg = PSB_RVDC32(HISTOGRAM_INT_CONTROL);
 482
 483                psb_disable_pipestat(dev_priv, 0, PIPE_DPST_EVENT_ENABLE);
 484
 485                pwm_reg = PSB_RVDC32(PWM_CONTROL_LOGIC);
 486                PSB_WVDC32(pwm_reg & ~PWM_PHASEIN_INT_ENABLE,
 487                                                        PWM_CONTROL_LOGIC);
 488                pwm_reg = PSB_RVDC32(PWM_CONTROL_LOGIC);
 489
 490                gma_power_end(dev);
 491        }
 492}
 493
 494int psb_irq_disable_dpst(struct drm_device *dev)
 495{
 496        struct drm_psb_private *dev_priv =
 497            (struct drm_psb_private *) dev->dev_private;
 498        unsigned long irqflags;
 499
 500        spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags);
 501
 502        mid_disable_pipe_event(dev_priv, 0);
 503        psb_irq_turn_off_dpst(dev);
 504
 505        spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags);
 506
 507        return 0;
 508}
 509
 510/*
 511 * It is used to enable VBLANK interrupt
 512 */
 513int psb_enable_vblank(struct drm_device *dev, unsigned int pipe)
 514{
 515        struct drm_psb_private *dev_priv = dev->dev_private;
 516        unsigned long irqflags;
 517        uint32_t reg_val = 0;
 518        uint32_t pipeconf_reg = mid_pipeconf(pipe);
 519
 520        /* Medfield is different - we should perhaps extract out vblank
 521           and blacklight etc ops */
 522        if (IS_MFLD(dev))
 523                return mdfld_enable_te(dev, pipe);
 524
 525        if (gma_power_begin(dev, false)) {
 526                reg_val = REG_READ(pipeconf_reg);
 527                gma_power_end(dev);
 528        }
 529
 530        if (!(reg_val & PIPEACONF_ENABLE))
 531                return -EINVAL;
 532
 533        spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags);
 534
 535        if (pipe == 0)
 536                dev_priv->vdc_irq_mask |= _PSB_VSYNC_PIPEA_FLAG;
 537        else if (pipe == 1)
 538                dev_priv->vdc_irq_mask |= _PSB_VSYNC_PIPEB_FLAG;
 539
 540        PSB_WVDC32(~dev_priv->vdc_irq_mask, PSB_INT_MASK_R);
 541        PSB_WVDC32(dev_priv->vdc_irq_mask, PSB_INT_ENABLE_R);
 542        psb_enable_pipestat(dev_priv, pipe, PIPE_VBLANK_INTERRUPT_ENABLE);
 543
 544        spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags);
 545
 546        return 0;
 547}
 548
 549/*
 550 * It is used to disable VBLANK interrupt
 551 */
 552void psb_disable_vblank(struct drm_device *dev, unsigned int pipe)
 553{
 554        struct drm_psb_private *dev_priv = dev->dev_private;
 555        unsigned long irqflags;
 556
 557        if (IS_MFLD(dev))
 558                mdfld_disable_te(dev, pipe);
 559        spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags);
 560
 561        if (pipe == 0)
 562                dev_priv->vdc_irq_mask &= ~_PSB_VSYNC_PIPEA_FLAG;
 563        else if (pipe == 1)
 564                dev_priv->vdc_irq_mask &= ~_PSB_VSYNC_PIPEB_FLAG;
 565
 566        PSB_WVDC32(~dev_priv->vdc_irq_mask, PSB_INT_MASK_R);
 567        PSB_WVDC32(dev_priv->vdc_irq_mask, PSB_INT_ENABLE_R);
 568        psb_disable_pipestat(dev_priv, pipe, PIPE_VBLANK_INTERRUPT_ENABLE);
 569
 570        spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags);
 571}
 572
 573/*
 574 * It is used to enable TE interrupt
 575 */
 576int mdfld_enable_te(struct drm_device *dev, int pipe)
 577{
 578        struct drm_psb_private *dev_priv =
 579                (struct drm_psb_private *) dev->dev_private;
 580        unsigned long irqflags;
 581        uint32_t reg_val = 0;
 582        uint32_t pipeconf_reg = mid_pipeconf(pipe);
 583
 584        if (gma_power_begin(dev, false)) {
 585                reg_val = REG_READ(pipeconf_reg);
 586                gma_power_end(dev);
 587        }
 588
 589        if (!(reg_val & PIPEACONF_ENABLE))
 590                return -EINVAL;
 591
 592        spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags);
 593
 594        mid_enable_pipe_event(dev_priv, pipe);
 595        psb_enable_pipestat(dev_priv, pipe, PIPE_TE_ENABLE);
 596
 597        spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags);
 598
 599        return 0;
 600}
 601
 602/*
 603 * It is used to disable TE interrupt
 604 */
 605void mdfld_disable_te(struct drm_device *dev, int pipe)
 606{
 607        struct drm_psb_private *dev_priv =
 608                (struct drm_psb_private *) dev->dev_private;
 609        unsigned long irqflags;
 610
 611        if (!dev_priv->dsr_enable)
 612                return;
 613
 614        spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags);
 615
 616        mid_disable_pipe_event(dev_priv, pipe);
 617        psb_disable_pipestat(dev_priv, pipe, PIPE_TE_ENABLE);
 618
 619        spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags);
 620}
 621
 622/* Called from drm generic code, passed a 'crtc', which
 623 * we use as a pipe index
 624 */
 625u32 psb_get_vblank_counter(struct drm_device *dev, unsigned int pipe)
 626{
 627        uint32_t high_frame = PIPEAFRAMEHIGH;
 628        uint32_t low_frame = PIPEAFRAMEPIXEL;
 629        uint32_t pipeconf_reg = PIPEACONF;
 630        uint32_t reg_val = 0;
 631        uint32_t high1 = 0, high2 = 0, low = 0, count = 0;
 632
 633        switch (pipe) {
 634        case 0:
 635                break;
 636        case 1:
 637                high_frame = PIPEBFRAMEHIGH;
 638                low_frame = PIPEBFRAMEPIXEL;
 639                pipeconf_reg = PIPEBCONF;
 640                break;
 641        case 2:
 642                high_frame = PIPECFRAMEHIGH;
 643                low_frame = PIPECFRAMEPIXEL;
 644                pipeconf_reg = PIPECCONF;
 645                break;
 646        default:
 647                dev_err(dev->dev, "%s, invalid pipe.\n", __func__);
 648                return 0;
 649        }
 650
 651        if (!gma_power_begin(dev, false))
 652                return 0;
 653
 654        reg_val = REG_READ(pipeconf_reg);
 655
 656        if (!(reg_val & PIPEACONF_ENABLE)) {
 657                dev_err(dev->dev, "trying to get vblank count for disabled pipe %u\n",
 658                                                                pipe);
 659                goto psb_get_vblank_counter_exit;
 660        }
 661
 662        /*
 663         * High & low register fields aren't synchronized, so make sure
 664         * we get a low value that's stable across two reads of the high
 665         * register.
 666         */
 667        do {
 668                high1 = ((REG_READ(high_frame) & PIPE_FRAME_HIGH_MASK) >>
 669                         PIPE_FRAME_HIGH_SHIFT);
 670                low =  ((REG_READ(low_frame) & PIPE_FRAME_LOW_MASK) >>
 671                        PIPE_FRAME_LOW_SHIFT);
 672                high2 = ((REG_READ(high_frame) & PIPE_FRAME_HIGH_MASK) >>
 673                         PIPE_FRAME_HIGH_SHIFT);
 674        } while (high1 != high2);
 675
 676        count = (high1 << 8) | low;
 677
 678psb_get_vblank_counter_exit:
 679
 680        gma_power_end(dev);
 681
 682        return count;
 683}
 684
 685