From patchwork Wed Aug 5 07:22:50 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Hunter X-Patchwork-Id: 6946751 Return-Path: X-Original-To: patchwork-dri-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 294D9C05AD for ; Wed, 5 Aug 2015 07:23:04 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id DD18120443 for ; Wed, 5 Aug 2015 07:23:02 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id 6BEEB20489 for ; Wed, 5 Aug 2015 07:23:01 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id E9B4D6E8E1; Wed, 5 Aug 2015 00:22:57 -0700 (PDT) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from pku.edu.cn (mx13.pku.edu.cn [162.105.129.176]) by gabe.freedesktop.org (Postfix) with ESMTP id 4693F72093 for ; Wed, 5 Aug 2015 00:22:55 -0700 (PDT) Received: from debian.localdomain (unknown [59.108.92.109]) by mailfront03 (Coremail) with SMTP id 84FpogD3qGXKucFVsbTDAA--.56129S3; Wed, 05 Aug 2015 15:22:51 +0800 (CST) From: John Hunter To: dri-devel@lists.freedesktop.org Subject: [PATCH 1/7] drm/cirrus: phase 1 - use the transitional helpers Date: Wed, 5 Aug 2015 15:22:50 +0800 Message-Id: <1438759376-4509-2-git-send-email-zhjwpku@gmail.com> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1438759376-4509-1-git-send-email-zhjwpku@gmail.com> References: <1438759376-4509-1-git-send-email-zhjwpku@gmail.com> X-CM-TRANSID: 84FpogD3qGXKucFVsbTDAA--.56129S3 X-Coremail-Antispam: 1UD129KBjvJXoWfGF4UGw15ArWxKr4DWF13XFb_yoWDZr4rpr 4DAFy5KrWUKF4UWrW8C39YyF4aka4Yg3W7KryxCwna9r1DtrW5WFy8Aay3ury5Z3y7Wr13 tF45try8C3WjkaUanT9S1TB71UUUUUUqnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUU9Eb7Iv0xC_Kw4lb4IE77IF4wAFF20E14v26r4j6ryUM7CY07I2 0VC2zVCF04k26cxKx2IYs7xG6rWj6s0DM7CIcVAFz4kK6r1j6r18M28IrcIa0xkI8VA2jI 8067AKxVWUGwA2048vs2IY020Ec7CjxVAFwI0_Jr4l8cAvFVAK0II2c7xJM28CjxkF64kE wVA0rcxSw2x7M28EF7xvwVC0I7IYx2IY67AKxVWDJVCq3wA2z4x0Y4vE2Ix0cI8IcVCY1x 0267AKxVW8Jr0_Cr1UM28EF7xvwVC2z280aVAFwI0_GcCE3s1l84ACjcxK6I8E87Iv6xkF 7I0E14v26rxl6s0DM2AIxVAIcxkEcVAq07x20xvEncxIr21l5I8CrVACY4xI64kE6c02F4 0Ex7xfMcIj6xIIjxv20xvE14v26r106r15McIj6I8E87Iv67AKxVWUJVW8JwAm72CE4IkC 6x0Yz7v_Jr0_Gr1lF7xvr2IYc2Ij64vIr41lc2xSY4AK67AK6r4xMxAIw28IcxkI7VAKI4 8JMxC20s026xCaFVCjc4AY6r1j6r4UMI8I3I0E5I8CrVAFwI0_Jr0_Jr4lx2IqxVCjr7xv wVAFwI0_JrI_JrWlx4CE17CEb7AF67AKxVWUAVWUtwCIc40Y0x0EwIxGrwCI42IY6xIIjx v20xvE14v26r1j6r1xMIIF0xvE2Ix0cI8IcVCY1x0267AKxVW8JVWxJwCI42IY6xAIw20E Y4v20xvaj40_Jr0_JF4lIxAIcVC2z280aVAFwI0_Jr0_Gr1lIxAIcVC2z280aVCY1x0267 AKxVW8JVW8JrUvcSsGvfC2KfnxnUUI43ZEXa7IU5fcTJUUUUU== X-CM-SenderInfo: p2km411nx6wzxdlohudrp/ Cc: Daniel Vetter , Matthew Garrett , Dave Airlie X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Spam-Status: No, score=-4.3 required=5.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, FREEMAIL_FROM,RCVD_IN_DNSWL_MED,RP_MATCHES_RCVD,UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Zhao Junwang -register driver's own primary plane -use drm_crtc_init_with_planes instead drm_crtc_init -the new atomic_infrastructure needs ->mode_set_nofb callback Cc: Daniel Vetter Cc: Gerd Hoffmann Cc: Matthew Garrett Cc: Dave Airlie Signed-off-by: Zhao Junwang --- drivers/gpu/drm/cirrus/cirrus_drv.c | 1 - drivers/gpu/drm/cirrus/cirrus_drv.h | 3 +- drivers/gpu/drm/cirrus/cirrus_main.c | 2 +- drivers/gpu/drm/cirrus/cirrus_mode.c | 201 +++++++++++++++++++++------------- 4 files changed, 129 insertions(+), 78 deletions(-) diff --git a/drivers/gpu/drm/cirrus/cirrus_drv.c b/drivers/gpu/drm/cirrus/cirrus_drv.c index 08bd176..80f1cd2 100644 --- a/drivers/gpu/drm/cirrus/cirrus_drv.c +++ b/drivers/gpu/drm/cirrus/cirrus_drv.c @@ -40,7 +40,6 @@ static const struct pci_device_id pciidlist[] = { {0,} }; - static int cirrus_kick_out_firmware_fb(struct pci_dev *pdev) { struct apertures_struct *ap; diff --git a/drivers/gpu/drm/cirrus/cirrus_drv.h b/drivers/gpu/drm/cirrus/cirrus_drv.h index 7050615..bd1ff51 100644 --- a/drivers/gpu/drm/cirrus/cirrus_drv.h +++ b/drivers/gpu/drm/cirrus/cirrus_drv.h @@ -135,8 +135,9 @@ struct cirrus_device { resource_size_t rmmio_size; void __iomem *rmmio; - struct cirrus_mc mc; + struct cirrus_mc mc; struct cirrus_mode_info mode_info; + struct drm_plane primary; int num_crtc; int fb_mtrr; diff --git a/drivers/gpu/drm/cirrus/cirrus_main.c b/drivers/gpu/drm/cirrus/cirrus_main.c index e4b9766..d95de34 100644 --- a/drivers/gpu/drm/cirrus/cirrus_main.c +++ b/drivers/gpu/drm/cirrus/cirrus_main.c @@ -308,10 +308,10 @@ cirrus_dumb_mmap_offset(struct drm_file *file, drm_gem_object_unreference(obj); ret = 0; + out_unlock: mutex_unlock(&dev->struct_mutex); return ret; - } bool cirrus_check_framebuffer(struct cirrus_device *cdev, int width, int height, diff --git a/drivers/gpu/drm/cirrus/cirrus_mode.c b/drivers/gpu/drm/cirrus/cirrus_mode.c index 61385f2..7a7c874 100644 --- a/drivers/gpu/drm/cirrus/cirrus_mode.c +++ b/drivers/gpu/drm/cirrus/cirrus_mode.c @@ -27,6 +27,10 @@ #define PALETTE_INDEX 0x8 #define PALETTE_DATA 0x9 +static const uint32_t cirrus_primary_formats[] = { + DRM_FORMAT_RGB888, +}; + /* * This file contains setup code for the CRTC. */ @@ -126,77 +130,11 @@ static void cirrus_set_start_address(struct drm_crtc *crtc, unsigned offset) WREG_CRT(0x1d, tmp); } -/* cirrus is different - we will force move buffers out of VRAM */ -static int cirrus_crtc_do_set_base(struct drm_crtc *crtc, - struct drm_framebuffer *fb, - int x, int y, int atomic) -{ - struct cirrus_device *cdev = crtc->dev->dev_private; - struct drm_gem_object *obj; - struct cirrus_framebuffer *cirrus_fb; - struct cirrus_bo *bo; - int ret; - u64 gpu_addr; - - /* push the previous fb to system ram */ - if (!atomic && fb) { - cirrus_fb = to_cirrus_framebuffer(fb); - obj = cirrus_fb->obj; - bo = gem_to_cirrus_bo(obj); - ret = cirrus_bo_reserve(bo, false); - if (ret) - return ret; - cirrus_bo_push_sysram(bo); - cirrus_bo_unreserve(bo); - } - - cirrus_fb = to_cirrus_framebuffer(crtc->primary->fb); - obj = cirrus_fb->obj; - bo = gem_to_cirrus_bo(obj); - - ret = cirrus_bo_reserve(bo, false); - if (ret) - return ret; - - ret = cirrus_bo_pin(bo, TTM_PL_FLAG_VRAM, &gpu_addr); - if (ret) { - cirrus_bo_unreserve(bo); - return ret; - } - - if (&cdev->mode_info.gfbdev->gfb == cirrus_fb) { - /* if pushing console in kmap it */ - ret = ttm_bo_kmap(&bo->bo, 0, bo->bo.num_pages, &bo->kmap); - if (ret) - DRM_ERROR("failed to kmap fbcon\n"); - } - cirrus_bo_unreserve(bo); - - cirrus_set_start_address(crtc, (u32)gpu_addr); - return 0; -} - -static int cirrus_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y, - struct drm_framebuffer *old_fb) -{ - return cirrus_crtc_do_set_base(crtc, old_fb, x, y, 0); -} - -/* - * The meat of this driver. The core passes us a mode and we have to program - * it. The modesetting here is the bare minimum required to satisfy the qemu - * emulation of this hardware, and running this against a real device is - * likely to result in an inadequately programmed mode. We've already had - * the opportunity to modify the mode, so whatever we receive here should - * be something that can be correctly programmed and displayed - */ -static int cirrus_crtc_mode_set(struct drm_crtc *crtc, - struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode, - int x, int y, struct drm_framebuffer *old_fb) +static void cirrus_crtc_mode_set_nofb(struct drm_crtc *crtc) { struct drm_device *dev = crtc->dev; struct cirrus_device *cdev = dev->dev_private; + struct drm_display_mode *mode = &crtc->mode; int hsyncstart, hsyncend, htotal, hdispend; int vtotal, vdispend; int tmp; @@ -286,7 +224,7 @@ static int cirrus_crtc_mode_set(struct drm_crtc *crtc, hdr = 0xc5; break; default: - return -1; + return; } WREG_SEQ(0x7, sr07); @@ -308,11 +246,9 @@ static int cirrus_crtc_mode_set(struct drm_crtc *crtc, WREG_GFX(VGA_GFX_MISC, 0x01); WREG_HDR(hdr); - cirrus_crtc_do_set_base(crtc, old_fb, x, y, 0); /* Unblank (needed on S3 resume, vgabios doesn't do it then) */ outb(0x20, 0x3c0); - return 0; } /* @@ -373,8 +309,9 @@ static const struct drm_crtc_funcs cirrus_crtc_funcs = { static const struct drm_crtc_helper_funcs cirrus_helper_funcs = { .dpms = cirrus_crtc_dpms, .mode_fixup = cirrus_crtc_mode_fixup, - .mode_set = cirrus_crtc_mode_set, - .mode_set_base = cirrus_crtc_mode_set_base, + .mode_set = drm_helper_crtc_mode_set, + .mode_set_base = drm_helper_crtc_mode_set_base, + .mode_set_nofb = cirrus_crtc_mode_set_nofb, .prepare = cirrus_crtc_prepare, .commit = cirrus_crtc_commit, .load_lut = cirrus_crtc_load_lut, @@ -394,7 +331,8 @@ static void cirrus_crtc_init(struct drm_device *dev) if (cirrus_crtc == NULL) return; - drm_crtc_init(dev, &cirrus_crtc->base, &cirrus_crtc_funcs); + drm_crtc_init_with_planes(dev, &cirrus_crtc->base, &cdev->primary, + NULL, &cirrus_crtc_funcs); drm_mode_crtc_set_gamma_size(&cirrus_crtc->base, CIRRUS_LUT_SIZE); cdev->mode_info.crtc = cirrus_crtc; @@ -408,6 +346,119 @@ static void cirrus_crtc_init(struct drm_device *dev) drm_crtc_helper_add(&cirrus_crtc->base, &cirrus_helper_funcs); } +static int cirrus_plane_prepare_fb(struct drm_plane *plane, + struct drm_framebuffer *fb, + const struct drm_plane_state *new_state) +{ + struct cirrus_device *cdev = + container_of(plane, struct cirrus_device, primary); + struct cirrus_framebuffer *cirrus_fb; + struct drm_gem_object *obj; + struct cirrus_bo *bo; + int ret; + + cirrus_fb = to_cirrus_framebuffer(fb); + obj = cirrus_fb->obj; + bo = gem_to_cirrus_bo(obj); + + ret = cirrus_bo_reserve(bo, false); + if (ret) + return ret; + + ret = cirrus_bo_pin(bo, TTM_PL_FLAG_VRAM, NULL); + if (ret) { + cirrus_bo_unreserve(bo); + return ret; + } + + if (&cdev->mode_info.gfbdev->gfb == cirrus_fb) { + /* if pushing console in kmap it */ + ret = ttm_bo_kmap(&bo->bo, 0, bo->bo.num_pages, &bo->kmap); + if (ret) + DRM_ERROR("failed to kmap fbcon\n"); + } + cirrus_bo_unreserve(bo); + + return 0; +} + +static void cirrus_plane_cleanup_fb(struct drm_plane *plane, + struct drm_framebuffer *old_fb, + const struct drm_plane_state *old_state) +{ + struct cirrus_framebuffer *cirrus_fb; + struct drm_gem_object *obj; + struct cirrus_bo *bo; + + cirrus_fb = to_cirrus_framebuffer(old_fb); + obj = cirrus_fb->obj; + bo = gem_to_cirrus_bo(obj); + + cirrus_bo_reserve(bo, false); + cirrus_bo_push_sysram(bo); + cirrus_bo_unreserve(bo); +} + +static int cirrus_plane_atomic_check(struct drm_plane *plane, + struct drm_plane_state *plane_state) +{ + return 0; +} + +static void cirrus_plane_atomic_update(struct drm_plane *plane, + struct drm_plane_state *old_state) +{ + struct cirrus_framebuffer *cirrus_fb; + struct drm_gem_object *obj; + struct cirrus_bo *bo; + u64 gpu_addr; + + cirrus_fb = to_cirrus_framebuffer(plane->state->fb); + obj = cirrus_fb->obj; + bo = gem_to_cirrus_bo(obj); + gpu_addr = bo->bo.offset; + + cirrus_set_start_address(plane->state->crtc, (u32)gpu_addr); +} + +static void cirrus_plane_atomic_disable(struct drm_plane *plane, + struct drm_plane_state *old_state) +{ +} + +static const struct drm_plane_funcs cirrus_plane_funcs = { + .update_plane = drm_plane_helper_update, + .disable_plane = drm_plane_helper_disable, +}; + +static const struct drm_plane_helper_funcs cirrus_plane_helper_funcs = { + .prepare_fb = cirrus_plane_prepare_fb, + .cleanup_fb = cirrus_plane_cleanup_fb, + .atomic_check = cirrus_plane_atomic_check, + .atomic_update = cirrus_plane_atomic_update, + .atomic_disable = cirrus_plane_atomic_disable, +}; + +static void cirrus_plane_init(struct drm_device *dev) +{ + struct cirrus_device *cirrus = dev->dev_private; + struct drm_plane *primary = &cirrus->primary; + int r; + + r = drm_universal_plane_init(dev, primary, 0, + &cirrus_plane_funcs, + cirrus_primary_formats, + ARRAY_SIZE(cirrus_primary_formats), + DRM_PLANE_TYPE_PRIMARY); + + if (r) { + DRM_DEBUG_KMS("Failed to init primary plane.\n"); + return; + } + + drm_plane_helper_add(primary, &cirrus_plane_helper_funcs); +} + /** Sets the color ramps on behalf of fbcon */ void cirrus_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green, u16 blue, int regno) @@ -430,7 +481,6 @@ void cirrus_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green, *blue = cirrus_crtc->lut_b[regno]; } - static bool cirrus_encoder_mode_fixup(struct drm_encoder *encoder, const struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) @@ -583,6 +633,7 @@ int cirrus_modeset_init(struct cirrus_device *cdev) /* don't prefer a shadow on virt GPU */ cdev->dev->mode_config.prefer_shadow = 0; + cirrus_plane_init(cdev->dev); cirrus_crtc_init(cdev->dev); encoder = cirrus_encoder_init(cdev->dev);