From patchwork Thu Jul 16 12:20:34 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Hunter X-Patchwork-Id: 6806801 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 08013C05AD for ; Thu, 16 Jul 2015 12:21:17 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id E8B2D20742 for ; Thu, 16 Jul 2015 12:21:15 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id BF285206C7 for ; Thu, 16 Jul 2015 12:21:14 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 18D956E4AE; Thu, 16 Jul 2015 05:21:09 -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 6BE016E515 for ; Thu, 16 Jul 2015 05:21:07 -0700 (PDT) Received: from localhost.localdomain (unknown [59.108.92.109]) by mailfront03 (Coremail) with SMTP id 84FpogBnb2ewoadV+QOQAA--.16013S3; Thu, 16 Jul 2015 20:21:05 +0800 (CST) From: John Hunter To: dri-devel@lists.freedesktop.org Subject: [PATCH 1/8] drm/bochs: phase 1 - use the transitional helpers Date: Thu, 16 Jul 2015 20:20:34 +0800 Message-Id: <1437049241-11972-2-git-send-email-zhjwpku@gmail.com> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1437049241-11972-1-git-send-email-zhjwpku@gmail.com> References: <1437049241-11972-1-git-send-email-zhjwpku@gmail.com> X-CM-TRANSID: 84FpogBnb2ewoadV+QOQAA--.16013S3 X-Coremail-Antispam: 1UD129KBjvJXoW3WFW7KrW3KF17WF1UGF45Wrg_yoW3KrW7pr WDAFy3Kr40qFWUWFWDZrsFyF4fWw4fG342qF1kGwna9r17t345uF1FyrnruF13WrZrW3W5 GF47tFs5C3WUuF7anT9S1TB71UUUUUUqnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUU9Kb7Iv0xC_tr1lb4IE77IF4wAFF20E14v26r4j6ryUM7CY07I2 0VC2zVCF04k26cxKx2IYs7xG6rWj6s0DM7CIcVAFz4kK6r1j6r18M28IrcIa0xkI8VA2jI 8067AKxVWUGwA2048vs2IY020Ec7CjxVAFwI0_Jr4l8cAvFVAK0II2c7xJM28CjxkF64kE wVA0rcxSw2x7M28EF7xvwVC0I7IYx2IY67AKxVW7JVWDJwA2z4x0Y4vE2Ix0cI8IcVCY1x 0267AKxVW8Jr0_Cr1UM28EF7xvwVC2z280aVAFwI0_GcCE3s1l84ACjcxK6I8E87Iv6xkF 7I0E14v26rxl6s0DM2AIxVAIcxkEcVAq07x20xvEncxIr21l5I8CrVACY4xI64kE6c02F4 0Ex7xfMcIj6xIIjxv20xvE14v26r1j6r18McIj6I8E87Iv67AKxVWUJVW8JwAm72CE4IkC 6x0Yz7v_Jr0_Gr1lF7xvr2IYc2Ij64vIr41lc2xSY4AK67AK6ryUMxAIw28IcxkI7VAKI4 8JMxC20s026xCaFVCjc4AY6r1j6r4UMI8I3I0E5I8CrVAFwI0_Jr0_Jr4lx2IqxVCjr7xv wVAFwI0_JrI_JrWlx4CE17CEb7AF67AKxVWUAVWUtwCIc40Y0x0EwIxGrwCI42IY6xIIjx v20xvE14v26r1j6r1xMIIF0xvE2Ix0cI8IcVCY1x0267AKxVWUJVW8JwCI42IY6xAIw20E Y4v20xvaj40_Jr0_JF4lIxAIcVC2z280aVAFwI0_Jr0_Gr1lIxAIcVC2z280aVCY1x0267 AKxVWUJVW8JbIYCTnIWIevJa73UjIFyTuYvjxUcK9aDUUUU X-CM-SenderInfo: p2km411nx6wzxdlohudrp/ Cc: Daniel Vetter 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=-5.5 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 of drm_crtc_init -split ->mode_set into: 1. set the new hw mode 2. update the primary plane (This is done by ->set_base) -move what ->set_base do into ->atomic_update -the new atomic infrastructure needs the ->mode_set_nofb callback to update CRTC timings before setting any plane -since the ->cleanup_fb can't fail, set the interruptible argument of the ttm_bo_reserve to false, this make sure the ttm_bo_reserve can't fail v2: -add a few checks to plane's ->atomic_check, using drm_plane_helper_check_update v3: -polish the atomic_check, it does too much in v2, remove the ->disable_plane and ->set_config v4: -use plane->state instead of old_state in bochs_plane_atomic_update v5: -just return 0 in plane ->atomic_check, i.e. remove what we do in v2-v4 Cc: Maarten Lankhorst Cc: Daniel Vetter Signed-off-by: Zhao Junwang --- drivers/gpu/drm/bochs/bochs.h | 2 + drivers/gpu/drm/bochs/bochs_kms.c | 159 ++++++++++++++++++++++++------------- 2 files changed, 108 insertions(+), 53 deletions(-) diff --git a/drivers/gpu/drm/bochs/bochs.h b/drivers/gpu/drm/bochs/bochs.h index 71f2687..2f10480 100644 --- a/drivers/gpu/drm/bochs/bochs.h +++ b/drivers/gpu/drm/bochs/bochs.h @@ -5,6 +5,7 @@ #include #include #include +#include #include #include @@ -72,6 +73,7 @@ struct bochs_device { /* drm */ struct drm_device *dev; + struct drm_plane primary; struct drm_crtc crtc; struct drm_encoder encoder; struct drm_connector connector; diff --git a/drivers/gpu/drm/bochs/bochs_kms.c b/drivers/gpu/drm/bochs/bochs_kms.c index 26bcd03..1b66dd3 100644 --- a/drivers/gpu/drm/bochs/bochs_kms.c +++ b/drivers/gpu/drm/bochs/bochs_kms.c @@ -10,6 +10,11 @@ static int defx = 1024; static int defy = 768; +static u64 gpu_addr = 0; + +static const uint32_t bochs_primary_formats[] = { + DRM_FORMAT_XRGB8888, +}; module_param(defx, int, 0444); module_param(defy, int, 0444); @@ -37,59 +42,12 @@ static bool bochs_crtc_mode_fixup(struct drm_crtc *crtc, return true; } -static int bochs_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y, - struct drm_framebuffer *old_fb) +static void bochs_crtc_mode_set_nofb(struct drm_crtc *crtc) { struct bochs_device *bochs = container_of(crtc, struct bochs_device, crtc); - struct bochs_framebuffer *bochs_fb; - struct bochs_bo *bo; - u64 gpu_addr = 0; - int ret; - if (old_fb) { - bochs_fb = to_bochs_framebuffer(old_fb); - bo = gem_to_bochs_bo(bochs_fb->obj); - ret = ttm_bo_reserve(&bo->bo, true, false, false, NULL); - if (ret) { - DRM_ERROR("failed to reserve old_fb bo\n"); - } else { - bochs_bo_unpin(bo); - ttm_bo_unreserve(&bo->bo); - } - } - - if (WARN_ON(crtc->primary->fb == NULL)) - return -EINVAL; - - bochs_fb = to_bochs_framebuffer(crtc->primary->fb); - bo = gem_to_bochs_bo(bochs_fb->obj); - ret = ttm_bo_reserve(&bo->bo, true, false, false, NULL); - if (ret) - return ret; - - ret = bochs_bo_pin(bo, TTM_PL_FLAG_VRAM, &gpu_addr); - if (ret) { - ttm_bo_unreserve(&bo->bo); - return ret; - } - - ttm_bo_unreserve(&bo->bo); - bochs_hw_setbase(bochs, x, y, gpu_addr); - return 0; -} - -static int bochs_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) -{ - struct bochs_device *bochs = - container_of(crtc, struct bochs_device, crtc); - - bochs_hw_setmode(bochs, mode); - bochs_crtc_mode_set_base(crtc, x, y, old_fb); - return 0; + bochs_hw_setmode(bochs, &crtc->mode); } static void bochs_crtc_prepare(struct drm_crtc *crtc) @@ -116,7 +74,7 @@ static int bochs_crtc_page_flip(struct drm_crtc *crtc, unsigned long irqflags; crtc->primary->fb = fb; - bochs_crtc_mode_set_base(crtc, 0, 0, old_fb); + drm_helper_crtc_mode_set_base(crtc, 0, 0, old_fb); if (event) { spin_lock_irqsave(&bochs->dev->event_lock, irqflags); drm_send_vblank_event(bochs->dev, -1, event); @@ -136,8 +94,9 @@ static const struct drm_crtc_funcs bochs_crtc_funcs = { static const struct drm_crtc_helper_funcs bochs_helper_funcs = { .dpms = bochs_crtc_dpms, .mode_fixup = bochs_crtc_mode_fixup, - .mode_set = bochs_crtc_mode_set, - .mode_set_base = bochs_crtc_mode_set_base, + .mode_set = drm_helper_crtc_mode_set, + .mode_set_base = drm_helper_crtc_mode_set_base, + .mode_set_nofb = bochs_crtc_mode_set_nofb, .prepare = bochs_crtc_prepare, .commit = bochs_crtc_commit, }; @@ -146,12 +105,105 @@ static void bochs_crtc_init(struct drm_device *dev) { struct bochs_device *bochs = dev->dev_private; struct drm_crtc *crtc = &bochs->crtc; + struct drm_plane *primary = &bochs->primary; - drm_crtc_init(dev, crtc, &bochs_crtc_funcs); + drm_crtc_init_with_planes(dev, crtc, primary, NULL, &bochs_crtc_funcs); drm_mode_crtc_set_gamma_size(crtc, 256); drm_crtc_helper_add(crtc, &bochs_helper_funcs); } +static int bochs_plane_prepare_fb(struct drm_plane *plane, + struct drm_framebuffer *fb, + const struct drm_plane_state *new_state) +{ + struct bochs_framebuffer *bochs_fb; + struct bochs_bo *bo; + int ret; + + if (WARN_ON(plane->fb == NULL)) + return -EINVAL; + + bochs_fb = to_bochs_framebuffer(plane->fb); + bo = gem_to_bochs_bo(bochs_fb->obj); + ttm_bo_reserve(&bo->bo, true, false, false, NULL); + + ret = bochs_bo_pin(bo, TTM_PL_FLAG_VRAM, &gpu_addr); + if (ret) { + ttm_bo_unreserve(&bo->bo); + return ret; + } + + ttm_bo_unreserve(&bo->bo); + return 0; +} + +static void bochs_plane_cleanup_fb(struct drm_plane *plane, + struct drm_framebuffer *old_fb, + const struct drm_plane_state *old_state) +{ + struct bochs_framebuffer *bochs_fb; + struct bochs_bo *bo; + + bochs_fb = to_bochs_framebuffer(old_fb); + bo = gem_to_bochs_bo(bochs_fb->obj); + + /* + * Since cleanup can't fail, change the interruptible argument i.e. the + * second argument to false, this make sure ttm_bo_unpin can't fail. + */ + ttm_bo_reserve(&bo->bo, false, false, false, NULL); + bochs_bo_unpin(bo); + ttm_bo_unreserve(&bo->bo); +} + +static int bochs_plane_atomic_check(struct drm_plane *plane, + struct drm_plane_state *plane_state) +{ + return 0; +} + +static void bochs_plane_atomic_update(struct drm_plane *plane, + struct drm_plane_state *old_state) +{ + struct bochs_device *bochs = + container_of(plane, struct bochs_device, primary); + int x = plane->state->src_x >> 16; + int y = plane->state->src_y >> 16; + + bochs_hw_setbase(bochs, x, y, gpu_addr); +} + +static const struct drm_plane_funcs bochs_plane_funcs = { + .update_plane = drm_plane_helper_update, + .disable_plane = drm_plane_helper_disable, +}; + +static const struct drm_plane_helper_funcs bochs_plane_helper_funcs = { + .prepare_fb = bochs_plane_prepare_fb, + .cleanup_fb = bochs_plane_cleanup_fb, + .atomic_check = bochs_plane_atomic_check, + .atomic_update = bochs_plane_atomic_update, +}; + +static void bochs_plane_init(struct drm_device *dev) +{ + struct bochs_device *bochs = dev->dev_private; + struct drm_plane *primary = &bochs->primary; + int ret; + + ret = drm_universal_plane_init(dev, primary, 0, + &bochs_plane_funcs, + bochs_primary_formats, + ARRAY_SIZE(bochs_primary_formats), + DRM_PLANE_TYPE_PRIMARY); + if (ret) { + DRM_DEBUG_KMS("Failed to init primary plane init"); + return; + } + + drm_plane_helper_add(primary, &bochs_plane_helper_funcs); +} + static bool bochs_encoder_mode_fixup(struct drm_encoder *encoder, const struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) @@ -285,6 +337,7 @@ int bochs_kms_init(struct bochs_device *bochs) bochs->dev->mode_config.funcs = (void *)&bochs_mode_funcs; + bochs_plane_init(bochs->dev); bochs_crtc_init(bochs->dev); bochs_encoder_init(bochs->dev); bochs_connector_init(bochs->dev);