From patchwork Thu Sep 12 06:42:28 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thomas Zimmermann X-Patchwork-Id: 11142407 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 9AFD61599 for ; Thu, 12 Sep 2019 06:42:45 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 7F2A7206CD for ; Thu, 12 Sep 2019 06:42:45 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 7F2A7206CD Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=suse.de Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=dri-devel-bounces@lists.freedesktop.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id BC4546EB59; Thu, 12 Sep 2019 06:42:43 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mx1.suse.de (mx2.suse.de [195.135.220.15]) by gabe.freedesktop.org (Postfix) with ESMTPS id 799DA6EA4C for ; Thu, 12 Sep 2019 06:42:38 +0000 (UTC) X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id BABD9AE6F; Thu, 12 Sep 2019 06:42:36 +0000 (UTC) From: Thomas Zimmermann To: daniel@ffwll.ch, airlied@redhat.com, noralf@tronnes.org, rong.a.chen@intel.com, feng.tang@intel.com, ying.huang@intel.com, kraxel@redhat.com, ville.syrjala@linux.intel.com Subject: [PATCH v2 1/3] drm/fb-helper: Synchronize dirty worker with vblank Date: Thu, 12 Sep 2019 08:42:28 +0200 Message-Id: <20190912064230.27972-2-tzimmermann@suse.de> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20190912064230.27972-1-tzimmermann@suse.de> References: <20190912064230.27972-1-tzimmermann@suse.de> MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Thomas Zimmermann , dri-devel@lists.freedesktop.org Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" Before updating the display from the console's shadow buffer, the dirty worker now waits for vblank. This allows several screen updates to pile up and acts as a rate limiter. v2: * don't hold helper->lock while waiting for vblank Signed-off-by: Thomas Zimmermann Reviewed-by: Gerd Hoffmann --- drivers/gpu/drm/drm_fb_helper.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index a7ba5b4902d6..d0cb1fa4f909 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -402,8 +402,18 @@ static void drm_fb_helper_dirty_work(struct work_struct *work) dirty_work); struct drm_clip_rect *clip = &helper->dirty_clip; struct drm_clip_rect clip_copy; + struct drm_crtc *crtc; unsigned long flags; void *vaddr; + int ret; + + /* rate-limit update frequency */ + crtc = helper->client.modesets[0].crtc; + ret = drm_crtc_vblank_get(crtc); + if (!ret) { + drm_crtc_wait_one_vblank(crtc); + drm_crtc_vblank_put(crtc); + } spin_lock_irqsave(&helper->dirty_lock, flags); clip_copy = *clip; From patchwork Thu Sep 12 06:42:29 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thomas Zimmermann X-Patchwork-Id: 11142403 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 84E1514ED for ; Thu, 12 Sep 2019 06:42:41 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 6C771206CD for ; Thu, 12 Sep 2019 06:42:41 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 6C771206CD Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=suse.de Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=dri-devel-bounces@lists.freedesktop.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 30CDD6EA4C; Thu, 12 Sep 2019 06:42:40 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mx1.suse.de (mx2.suse.de [195.135.220.15]) by gabe.freedesktop.org (Postfix) with ESMTPS id 7FAD76EB57 for ; Thu, 12 Sep 2019 06:42:38 +0000 (UTC) X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id 19F42AD4B; Thu, 12 Sep 2019 06:42:37 +0000 (UTC) From: Thomas Zimmermann To: daniel@ffwll.ch, airlied@redhat.com, noralf@tronnes.org, rong.a.chen@intel.com, feng.tang@intel.com, ying.huang@intel.com, kraxel@redhat.com, ville.syrjala@linux.intel.com Subject: [PATCH v2 2/3] drm/mgag200: Rename constant MGAREG_Status to MGAREG_STATUS Date: Thu, 12 Sep 2019 08:42:29 +0200 Message-Id: <20190912064230.27972-3-tzimmermann@suse.de> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20190912064230.27972-1-tzimmermann@suse.de> References: <20190912064230.27972-1-tzimmermann@suse.de> MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Thomas Zimmermann , dri-devel@lists.freedesktop.org Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" Register constants are upper case. Fix MGAREG_Status accordingly. Signed-off-by: Thomas Zimmermann Reviewed-by: Gerd Hoffmann --- drivers/gpu/drm/mgag200/mgag200_mode.c | 6 +++--- drivers/gpu/drm/mgag200/mgag200_reg.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/mgag200/mgag200_mode.c b/drivers/gpu/drm/mgag200/mgag200_mode.c index 5e778b5f1a10..302ba40eb033 100644 --- a/drivers/gpu/drm/mgag200/mgag200_mode.c +++ b/drivers/gpu/drm/mgag200/mgag200_mode.c @@ -79,12 +79,12 @@ static inline void mga_wait_vsync(struct mga_device *mdev) unsigned int status = 0; do { - status = RREG32(MGAREG_Status); + status = RREG32(MGAREG_STATUS); } while ((status & 0x08) && time_before(jiffies, timeout)); timeout = jiffies + HZ/10; status = 0; do { - status = RREG32(MGAREG_Status); + status = RREG32(MGAREG_STATUS); } while (!(status & 0x08) && time_before(jiffies, timeout)); } @@ -93,7 +93,7 @@ static inline void mga_wait_busy(struct mga_device *mdev) unsigned long timeout = jiffies + HZ; unsigned int status = 0; do { - status = RREG8(MGAREG_Status + 2); + status = RREG8(MGAREG_STATUS + 2); } while ((status & 0x01) && time_before(jiffies, timeout)); } diff --git a/drivers/gpu/drm/mgag200/mgag200_reg.h b/drivers/gpu/drm/mgag200/mgag200_reg.h index c096a9d6bcbc..6c460d9a2143 100644 --- a/drivers/gpu/drm/mgag200/mgag200_reg.h +++ b/drivers/gpu/drm/mgag200/mgag200_reg.h @@ -101,7 +101,7 @@ #define MGAREG_EXEC 0x0100 #define MGAREG_FIFOSTATUS 0x1e10 -#define MGAREG_Status 0x1e14 +#define MGAREG_STATUS 0x1e14 #define MGAREG_CACHEFLUSH 0x1fff #define MGAREG_ICLEAR 0x1e18 #define MGAREG_IEN 0x1e1c From patchwork Thu Sep 12 06:42:30 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thomas Zimmermann X-Patchwork-Id: 11142409 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 868CD1599 for ; Thu, 12 Sep 2019 06:42:47 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 6E95A206CD for ; Thu, 12 Sep 2019 06:42:47 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 6E95A206CD Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=suse.de Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=dri-devel-bounces@lists.freedesktop.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 547A26EB5B; Thu, 12 Sep 2019 06:42:46 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mx1.suse.de (mx2.suse.de [195.135.220.15]) by gabe.freedesktop.org (Postfix) with ESMTPS id D82F86EA4C for ; Thu, 12 Sep 2019 06:42:38 +0000 (UTC) X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id 6F504AE4D; Thu, 12 Sep 2019 06:42:37 +0000 (UTC) From: Thomas Zimmermann To: daniel@ffwll.ch, airlied@redhat.com, noralf@tronnes.org, rong.a.chen@intel.com, feng.tang@intel.com, ying.huang@intel.com, kraxel@redhat.com, ville.syrjala@linux.intel.com Subject: [PATCH v2 3/3] drm/mgag200: Add vblank support Date: Thu, 12 Sep 2019 08:42:30 +0200 Message-Id: <20190912064230.27972-4-tzimmermann@suse.de> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20190912064230.27972-1-tzimmermann@suse.de> References: <20190912064230.27972-1-tzimmermann@suse.de> MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Thomas Zimmermann , dri-devel@lists.freedesktop.org Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" There's no VBLANK interrupt on Matrox chipsets. The workaround that is being used here and in other free Matrox drivers is to program to the value of and enable the VLINE interrupt. This triggers an interrupt at the time when VBLANK begins. VLINE uses separate registers for enabling and clearing pending interrupts. No extra syncronization between irq handler and the rest of the driver is required. Signed-off-by: Thomas Zimmermann v2: * only signal vblank on CRTC 0 * use constants for registers and fields * set VLINECLR before enabling interrupt * test against STATUS and IEN in irq handler * coding-style fixes Acked-by: Gerd Hoffmann --- drivers/gpu/drm/mgag200/mgag200_drv.c | 1 + drivers/gpu/drm/mgag200/mgag200_drv.h | 1 + drivers/gpu/drm/mgag200/mgag200_main.c | 40 ++++++++++++++++++++++ drivers/gpu/drm/mgag200/mgag200_mode.c | 47 +++++++++++++++++++++++--- drivers/gpu/drm/mgag200/mgag200_reg.h | 5 +++ 5 files changed, 90 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.c b/drivers/gpu/drm/mgag200/mgag200_drv.c index 4f9df3b93598..cff265973154 100644 --- a/drivers/gpu/drm/mgag200/mgag200_drv.c +++ b/drivers/gpu/drm/mgag200/mgag200_drv.c @@ -67,6 +67,7 @@ static struct drm_driver driver = { .driver_features = DRIVER_GEM | DRIVER_MODESET, .load = mgag200_driver_load, .unload = mgag200_driver_unload, + .irq_handler = mgag200_irq_handler, .fops = &mgag200_driver_fops, .name = DRIVER_NAME, .desc = DRIVER_DESC, diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.h b/drivers/gpu/drm/mgag200/mgag200_drv.h index 1c93f8dc08c7..88cf256d135f 100644 --- a/drivers/gpu/drm/mgag200/mgag200_drv.h +++ b/drivers/gpu/drm/mgag200/mgag200_drv.h @@ -195,6 +195,7 @@ void mgag200_modeset_fini(struct mga_device *mdev); /* mgag200_main.c */ int mgag200_driver_load(struct drm_device *dev, unsigned long flags); void mgag200_driver_unload(struct drm_device *dev); +irqreturn_t mgag200_irq_handler(int irq, void *arg); /* mgag200_i2c.c */ struct mga_i2c_chan *mgag200_i2c_create(struct drm_device *dev); diff --git a/drivers/gpu/drm/mgag200/mgag200_main.c b/drivers/gpu/drm/mgag200/mgag200_main.c index a9773334dedf..44273a66f5a5 100644 --- a/drivers/gpu/drm/mgag200/mgag200_main.c +++ b/drivers/gpu/drm/mgag200/mgag200_main.c @@ -10,7 +10,9 @@ #include #include +#include #include +#include #include "mgag200_drv.h" @@ -186,10 +188,18 @@ int mgag200_driver_load(struct drm_device *dev, unsigned long flags) } mdev->cursor.pixels_current = NULL; + r = drm_vblank_init(dev, 1); + if (r) + goto err_modeset; + r = drm_fbdev_generic_setup(mdev->dev, 0); if (r) goto err_modeset; + r = drm_irq_install(dev, dev->pdev->irq); + if (r) + goto err_modeset; + return 0; err_modeset: @@ -207,8 +217,38 @@ void mgag200_driver_unload(struct drm_device *dev) if (mdev == NULL) return; + drm_irq_uninstall(dev); mgag200_modeset_fini(mdev); drm_mode_config_cleanup(dev); mgag200_mm_fini(mdev); dev->dev_private = NULL; } + +irqreturn_t mgag200_irq_handler(int irq, void *arg) +{ + struct drm_device *dev = arg; + struct mga_device *mdev = dev->dev_private; + struct drm_crtc *crtc; + u32 status, ien, iclear; + + status = RREG32(MGAREG_STATUS); + + if (status & MGA_VLINEPEN) { + ien = RREG32(MGAREG_IEN); + if (!(ien & MGA_VLINEIEN)) + goto out; + + crtc = drm_crtc_from_index(dev, 0); + if (WARN_ON_ONCE(!crtc)) + goto out; + drm_crtc_handle_vblank(crtc); + + iclear = RREG32(MGAREG_ICLEAR); + iclear |= MGA_VLINECLR; + WREG32(MGAREG_ICLEAR, iclear); + return IRQ_HANDLED; + } + +out: + return IRQ_NONE; +}; diff --git a/drivers/gpu/drm/mgag200/mgag200_mode.c b/drivers/gpu/drm/mgag200/mgag200_mode.c index 302ba40eb033..e13c3244fea9 100644 --- a/drivers/gpu/drm/mgag200/mgag200_mode.c +++ b/drivers/gpu/drm/mgag200/mgag200_mode.c @@ -905,6 +905,7 @@ static int mga_crtc_mode_set(struct drm_crtc *crtc, const struct drm_framebuffer *fb = crtc->primary->fb; int hdisplay, hsyncstart, hsyncend, htotal; int vdisplay, vsyncstart, vsyncend, vtotal; + int linecomp; int pitch; int option = 0, option2 = 0; int i; @@ -1042,6 +1043,14 @@ static int mga_crtc_mode_set(struct drm_crtc *crtc, vsyncend = mode->vsync_end - 1; vtotal = mode->vtotal - 2; + /* + * There's no VBLANK interrupt on Matrox chipsets, so we have to + * use the VLINE interrupt instead. It triggers when the current + * linecomp has been reached. Therefore keep in + * sync with . + */ + linecomp = vdisplay; + WREG_GFX(0, 0); WREG_GFX(1, 0); WREG_GFX(2, 0); @@ -1063,12 +1072,12 @@ static int mga_crtc_mode_set(struct drm_crtc *crtc, ((vdisplay & 0x100) >> 7) | ((vsyncstart & 0x100) >> 6) | ((vdisplay & 0x100) >> 5) | - ((vdisplay & 0x100) >> 4) | /* linecomp */ + ((linecomp & 0x100) >> 4) | ((vtotal & 0x200) >> 4)| ((vdisplay & 0x200) >> 3) | ((vsyncstart & 0x200) >> 2)); WREG_CRT(9, ((vdisplay & 0x200) >> 4) | - ((vdisplay & 0x200) >> 3)); + ((linecomp & 0x200) >> 3)); WREG_CRT(10, 0); WREG_CRT(11, 0); WREG_CRT(12, 0); @@ -1083,7 +1092,7 @@ static int mga_crtc_mode_set(struct drm_crtc *crtc, WREG_CRT(21, vdisplay & 0xFF); WREG_CRT(22, (vtotal + 1) & 0xFF); WREG_CRT(23, 0xc3); - WREG_CRT(24, vdisplay & 0xFF); + WREG_CRT(24, linecomp & 0xff); ext_vga[0] = 0; ext_vga[5] = 0; @@ -1099,7 +1108,7 @@ static int mga_crtc_mode_set(struct drm_crtc *crtc, ((vdisplay & 0x400) >> 8) | ((vdisplay & 0xc00) >> 7) | ((vsyncstart & 0xc00) >> 5) | - ((vdisplay & 0x400) >> 3); + ((linecomp & 0x400) >> 3); if (fb->format->cpp[0] * 8 == 24) ext_vga[3] = (((1 << bppshift) * 3) - 1) | 0x80; else @@ -1411,6 +1420,34 @@ static void mga_crtc_disable(struct drm_crtc *crtc) crtc->primary->fb = NULL; } +static int mga_crtc_enable_vblank(struct drm_crtc *crtc) +{ + struct drm_device *dev = crtc->dev; + struct mga_device *mdev = dev->dev_private; + u32 iclear, ien; + + iclear = RREG32(MGAREG_ICLEAR); + iclear |= MGA_VLINECLR; + WREG32(MGAREG_ICLEAR, iclear); + + ien = RREG32(MGAREG_IEN); + ien |= MGA_VLINEIEN; + WREG32(MGAREG_IEN, ien); + + return 0; +} + +static void mga_crtc_disable_vblank(struct drm_crtc *crtc) +{ + struct drm_device *dev = crtc->dev; + struct mga_device *mdev = dev->dev_private; + u32 ien; + + ien = RREG32(MGAREG_IEN); + ien &= ~(MGA_VLINEIEN); + WREG32(MGAREG_IEN, ien); +} + /* These provide the minimum set of functions required to handle a CRTC */ static const struct drm_crtc_funcs mga_crtc_funcs = { .cursor_set = mga_crtc_cursor_set, @@ -1418,6 +1455,8 @@ static const struct drm_crtc_funcs mga_crtc_funcs = { .gamma_set = mga_crtc_gamma_set, .set_config = drm_crtc_helper_set_config, .destroy = mga_crtc_destroy, + .enable_vblank = mga_crtc_enable_vblank, + .disable_vblank = mga_crtc_disable_vblank, }; static const struct drm_crtc_helper_funcs mga_helper_funcs = { diff --git a/drivers/gpu/drm/mgag200/mgag200_reg.h b/drivers/gpu/drm/mgag200/mgag200_reg.h index 6c460d9a2143..44db1d8279fa 100644 --- a/drivers/gpu/drm/mgag200/mgag200_reg.h +++ b/drivers/gpu/drm/mgag200/mgag200_reg.h @@ -122,6 +122,11 @@ #define MGAREG_MEMCTL 0x2e08 +/* Interrupt fields */ +#define MGA_VLINEPEN (0x01 << 5) +#define MGA_VLINECLR (0x01 << 5) +#define MGA_VLINEIEN (0x01 << 5) + /* OPMODE register additives */ #define MGAOPM_DMA_GENERAL (0x00 << 2)