| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /************************************************************************** |
|---|
| 2 | 3 | * Copyright (c) 2007, Intel Corporation. |
|---|
| 3 | 4 | * 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 | 5 | * |
|---|
| 18 | 6 | * Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to |
|---|
| 19 | 7 | * develop this driver. |
|---|
| 20 | 8 | * |
|---|
| 21 | 9 | **************************************************************************/ |
|---|
| 22 | | -/* |
|---|
| 23 | | - */ |
|---|
| 24 | 10 | |
|---|
| 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" |
|---|
| 11 | +#include <drm/drm_vblank.h> |
|---|
| 12 | + |
|---|
| 31 | 13 | #include "mdfld_output.h" |
|---|
| 14 | +#include "power.h" |
|---|
| 15 | +#include "psb_drv.h" |
|---|
| 16 | +#include "psb_intel_reg.h" |
|---|
| 17 | +#include "psb_irq.h" |
|---|
| 18 | +#include "psb_reg.h" |
|---|
| 32 | 19 | |
|---|
| 33 | 20 | /* |
|---|
| 34 | 21 | * inline functions |
|---|
| .. | .. |
|---|
| 178 | 165 | "%s, can't clear status bits for pipe %d, its value = 0x%x.\n", |
|---|
| 179 | 166 | __func__, pipe, PSB_RVDC32(pipe_stat_reg)); |
|---|
| 180 | 167 | |
|---|
| 181 | | - if (pipe_stat_val & PIPE_VBLANK_STATUS) |
|---|
| 168 | + if (pipe_stat_val & PIPE_VBLANK_STATUS || |
|---|
| 169 | + (IS_MFLD(dev) && pipe_stat_val & PIPE_TE_STATUS)) { |
|---|
| 170 | + struct drm_crtc *crtc = drm_crtc_from_index(dev, pipe); |
|---|
| 171 | + struct gma_crtc *gma_crtc = to_gma_crtc(crtc); |
|---|
| 172 | + unsigned long flags; |
|---|
| 173 | + |
|---|
| 182 | 174 | drm_handle_vblank(dev, pipe); |
|---|
| 183 | 175 | |
|---|
| 184 | | - if (pipe_stat_val & PIPE_TE_STATUS) |
|---|
| 185 | | - drm_handle_vblank(dev, pipe); |
|---|
| 176 | + spin_lock_irqsave(&dev->event_lock, flags); |
|---|
| 177 | + if (gma_crtc->page_flip_event) { |
|---|
| 178 | + drm_crtc_send_vblank_event(crtc, |
|---|
| 179 | + gma_crtc->page_flip_event); |
|---|
| 180 | + gma_crtc->page_flip_event = NULL; |
|---|
| 181 | + drm_crtc_vblank_put(crtc); |
|---|
| 182 | + } |
|---|
| 183 | + spin_unlock_irqrestore(&dev->event_lock, flags); |
|---|
| 184 | + } |
|---|
| 186 | 185 | } |
|---|
| 187 | 186 | |
|---|
| 188 | 187 | /* |
|---|
| .. | .. |
|---|
| 207 | 206 | { |
|---|
| 208 | 207 | struct drm_psb_private *dev_priv = dev->dev_private; |
|---|
| 209 | 208 | u32 val, addr; |
|---|
| 210 | | - int error = false; |
|---|
| 211 | 209 | |
|---|
| 212 | 210 | if (stat_1 & _PSB_CE_TWOD_COMPLETE) |
|---|
| 213 | 211 | val = PSB_RSGX32(PSB_CR_2D_BLIT_STATUS); |
|---|
| .. | .. |
|---|
| 242 | 240 | |
|---|
| 243 | 241 | DRM_ERROR("\tMMU failing address is 0x%08x.\n", |
|---|
| 244 | 242 | (unsigned int)addr); |
|---|
| 245 | | - error = true; |
|---|
| 246 | 243 | } |
|---|
| 247 | 244 | } |
|---|
| 248 | 245 | |
|---|
| .. | .. |
|---|
| 463 | 460 | { |
|---|
| 464 | 461 | struct drm_psb_private *dev_priv = |
|---|
| 465 | 462 | (struct drm_psb_private *) dev->dev_private; |
|---|
| 466 | | - u32 hist_reg; |
|---|
| 467 | 463 | u32 pwm_reg; |
|---|
| 468 | 464 | |
|---|
| 469 | 465 | if (gma_power_begin(dev, false)) { |
|---|
| 470 | 466 | PSB_WVDC32(0x00000000, HISTOGRAM_INT_CONTROL); |
|---|
| 471 | | - hist_reg = PSB_RVDC32(HISTOGRAM_INT_CONTROL); |
|---|
| 467 | + PSB_RVDC32(HISTOGRAM_INT_CONTROL); |
|---|
| 472 | 468 | |
|---|
| 473 | 469 | psb_disable_pipestat(dev_priv, 0, PIPE_DPST_EVENT_ENABLE); |
|---|
| 474 | 470 | |
|---|
| .. | .. |
|---|
| 500 | 496 | /* |
|---|
| 501 | 497 | * It is used to enable VBLANK interrupt |
|---|
| 502 | 498 | */ |
|---|
| 503 | | -int psb_enable_vblank(struct drm_device *dev, unsigned int pipe) |
|---|
| 499 | +int psb_enable_vblank(struct drm_crtc *crtc) |
|---|
| 504 | 500 | { |
|---|
| 501 | + struct drm_device *dev = crtc->dev; |
|---|
| 502 | + unsigned int pipe = crtc->index; |
|---|
| 505 | 503 | struct drm_psb_private *dev_priv = dev->dev_private; |
|---|
| 506 | 504 | unsigned long irqflags; |
|---|
| 507 | 505 | uint32_t reg_val = 0; |
|---|
| .. | .. |
|---|
| 539 | 537 | /* |
|---|
| 540 | 538 | * It is used to disable VBLANK interrupt |
|---|
| 541 | 539 | */ |
|---|
| 542 | | -void psb_disable_vblank(struct drm_device *dev, unsigned int pipe) |
|---|
| 540 | +void psb_disable_vblank(struct drm_crtc *crtc) |
|---|
| 543 | 541 | { |
|---|
| 542 | + struct drm_device *dev = crtc->dev; |
|---|
| 543 | + unsigned int pipe = crtc->index; |
|---|
| 544 | 544 | struct drm_psb_private *dev_priv = dev->dev_private; |
|---|
| 545 | 545 | unsigned long irqflags; |
|---|
| 546 | 546 | |
|---|
| .. | .. |
|---|
| 612 | 612 | /* Called from drm generic code, passed a 'crtc', which |
|---|
| 613 | 613 | * we use as a pipe index |
|---|
| 614 | 614 | */ |
|---|
| 615 | | -u32 psb_get_vblank_counter(struct drm_device *dev, unsigned int pipe) |
|---|
| 615 | +u32 psb_get_vblank_counter(struct drm_crtc *crtc) |
|---|
| 616 | 616 | { |
|---|
| 617 | + struct drm_device *dev = crtc->dev; |
|---|
| 618 | + unsigned int pipe = crtc->index; |
|---|
| 617 | 619 | uint32_t high_frame = PIPEAFRAMEHIGH; |
|---|
| 618 | 620 | uint32_t low_frame = PIPEAFRAMEPIXEL; |
|---|
| 619 | 621 | uint32_t pipeconf_reg = PIPEACONF; |
|---|