Received: by 2002:a25:ef43:0:0:0:0:0 with SMTP id w3csp951513ybm; Wed, 27 May 2020 12:01:20 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxhu61TRXSzvj++L7CZORpPLhHVKPSZ5WbwVoEqPXKbJ5F9p8trIW90+/PeqREMuIhSq+iX X-Received: by 2002:a50:f094:: with SMTP id v20mr7049091edl.77.1590606080185; Wed, 27 May 2020 12:01:20 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1590606080; cv=none; d=google.com; s=arc-20160816; b=vpIK5PbSIZCuBt8QZlv/yOQyQXeJe+zGNENHLVwthtW/0pZttOimiQyoY/WXwGr6R6 U09buYy6D9hAhmSlsAbFOLjRAgGKJ+dum/fXO/QGBNR1+2zGVNoPl0ZDOqZMFuDwDRUq 8k7UC5JugrWMhYoqTE1U0LfKcefWU4fx5BTtE1cJgquiFIjADn7BNYSpKQcTkH0vm5dZ PaUQ0103DrBDXiiwapZiRHIAinBBgdpNC2UtvBTPe3blDzPB+OuQ9cWMFvnQYUMMd2XZ gtT0zRdt8YlA/WgnguW/RJh2dol5gvBtX7Fwl9FeqMorQkt9OGX129ljmzQv5P36nKgw D8sg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature:dkim-signature; bh=phMcnikxY9YemNSUM3gM7sfHRLZYeHD44iyBhWJvsEU=; b=Z+FHFlzNpdogDGBQH8FZf9p/LMByb2u7CPfZndgBTXCMgAJA79Xg3CeSgENYwC73NY vZaahlkLYAec+fOY09rsw7ze8Ne8fLIB4YTJXTFmuLA95dPqjETgJ5cvE7TTxgyJI/Cv wKc33lm2ipbK8seQiINF+HqUZ7zAF2bsfN5Nxzg0F+97HPRHIepq52+XbG4FSZas9wca O969R8tq63mh6Vuh3GRnSrJWq/Q3rCqkJMqjtJb1eMz0mHbzkemXnv96gqiaLqqiazp5 Xl9yQnzgsBDyMcqdYTutRYd7zJReFmgq6BmlsT/8d6Ztpc2wNM0oHyWcZZiBOHf820/t Z4jA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@cerno.tech header.s=fm2 header.b=v+WZhmNo; dkim=pass header.i=@messagingengine.com header.s=fm2 header.b=BNFUvXeH; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=cerno.tech Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id n17si2405683ejd.437.2020.05.27.12.00.56; Wed, 27 May 2020 12:01:20 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@cerno.tech header.s=fm2 header.b=v+WZhmNo; dkim=pass header.i=@messagingengine.com header.s=fm2 header.b=BNFUvXeH; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=cerno.tech Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2390345AbgE0Pvx (ORCPT + 98 others); Wed, 27 May 2020 11:51:53 -0400 Received: from new1-smtp.messagingengine.com ([66.111.4.221]:40697 "EHLO new1-smtp.messagingengine.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2390239AbgE0PvE (ORCPT ); Wed, 27 May 2020 11:51:04 -0400 Received: from compute4.internal (compute4.nyi.internal [10.202.2.44]) by mailnew.nyi.internal (Postfix) with ESMTP id 179F75820E5; Wed, 27 May 2020 11:51:02 -0400 (EDT) Received: from mailfrontend1 ([10.202.2.162]) by compute4.internal (MEProxy); Wed, 27 May 2020 11:51:02 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cerno.tech; h= from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; s=fm2; bh=phMcnikxY9Yem NSUM3gM7sfHRLZYeHD44iyBhWJvsEU=; b=v+WZhmNoPJp1wKWwaEN0+MRZ3er31 zhxI7jnpvEAsKYHhkH6rqHB3PNMmjN5752qdlzzoBHb4SKrJ7hbk2SXQEXdgv3mR zZQGAstOsi3WSnY1d4YIdSsovsHw66zIrsC6QIkob5FCj0QHgqBBrTPZVPvqdtw2 YDxdlULYs/pvRE/URkAlR0G6o5EHlsAUtZMIdXDM5waKDi539iNN6ro6c1kSi1Cd zm/W/1l0T1fxtHQbP0x4LZcS64kQkG8UxFmieSLYl0phf5TQjO2yUOFFrGfZcoNI Z3+42lm1sS/HEZCkkI94tcAdpYIiBplkDFVfYtJezlDOJph4X+rebCT9Q== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-transfer-encoding:date:from :in-reply-to:message-id:mime-version:references:subject:to :x-me-proxy:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s= fm2; bh=phMcnikxY9YemNSUM3gM7sfHRLZYeHD44iyBhWJvsEU=; b=BNFUvXeH +lnWxIbwguw/FxyCu+U/4ab/zuj8YAfCLY2iei1QLh/MM5mjhv6+CCow2G4bFlp5 ysHveEUoC6TXhJbpgYMdtKrexSc37Oyq12G0uhcTyIQ8KHT8ZU6YH06/FVDHCcaw LBohcaoa73p2giBXzfq9yVmpoN1+ditp3Osxbrk4mFSFxA9FQSdiTAuwWbZto7CE M2siYUOXaSLCUFWR7xVnBLx7BzYYD8iEzwmq/g+BAZefHlE/sa4lMmFKJ2D6/Alk MhSff17tgREfh93Zovrqwd8FMHuNCp88zPIDUkFAuth6CQ8MyxGJRuysjriKCOWS INIx5I2f3hZ4Tw== X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeduhedruddvgedgkeegucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddmne cujfgurhephffvufffkffojghfggfgsedtkeertdertddtnecuhfhrohhmpeforgigihhm vgcutfhiphgrrhguuceomhgrgihimhgvsegtvghrnhhordhtvggthheqnecuggftrfgrth htvghrnhepjeelvdetvddugeeiffetffektdfggfduheeulefgveehgeefgeejvdffueeu fefgnecuffhomhgrihhnpehmrghrghhinhhsrdhtohhpnecukfhppeeltddrkeelrdeike drjeeinecuvehluhhsthgvrhfuihiivgeptdenucfrrghrrghmpehmrghilhhfrhhomhep mhgrgihimhgvsegtvghrnhhordhtvggthh X-ME-Proxy: Received: from localhost (lfbn-tou-1-1502-76.w90-89.abo.wanadoo.fr [90.89.68.76]) by mail.messagingengine.com (Postfix) with ESMTPA id C03CC3280063; Wed, 27 May 2020 11:51:01 -0400 (EDT) From: Maxime Ripard To: Nicolas Saenz Julienne , Eric Anholt Cc: dri-devel@lists.freedesktop.org, linux-rpi-kernel@lists.infradead.org, bcm-kernel-feedback-list@broadcom.com, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, Dave Stevenson , Tim Gover , Phil Elwell , Maxime Ripard Subject: [PATCH v3 066/105] drm/vc4: txp: Turn the TXP into a CRTC of its own Date: Wed, 27 May 2020 17:48:36 +0200 Message-Id: X-Mailer: git-send-email 2.26.2 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The TXP so far has been leveraging the PixelValve infrastructure in the driver, that was really two things: the interaction with DRM's CRTC concept, the setup of the underlying pixelvalve and the setup of the shared HVS, the pixelvalve part being irrelevant to the TXP since it accesses the HVS directly. Now that we have a clear separation between the three parts, we can represent the TXP as a CRTC of its own, leveraging the common CRTC and HVS code, but leaving aside the pixelvalve setup. Signed-off-by: Maxime Ripard --- drivers/gpu/drm/vc4/vc4_crtc.c | 19 +------ drivers/gpu/drm/vc4/vc4_txp.c | 100 +++++++++++++++++++++++++++++++++- 2 files changed, 99 insertions(+), 20 deletions(-) diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c index fbddd38ba6a9..d6eca130644d 100644 --- a/drivers/gpu/drm/vc4/vc4_crtc.c +++ b/drivers/gpu/drm/vc4/vc4_crtc.c @@ -583,17 +583,6 @@ static int vc4_crtc_atomic_check(struct drm_crtc *crtc, if (conn_state->crtc != crtc) continue; - /* The writeback connector is implemented using the transposer - * block which is directly taking its data from the HVS FIFO. - */ - if (conn->connector_type == DRM_MODE_CONNECTOR_WRITEBACK) { - state->no_vblank = true; - vc4_state->feed_txp = true; - } else { - state->no_vblank = false; - vc4_state->feed_txp = false; - } - vc4_state->margins.left = conn_state->tv.margins.left; vc4_state->margins.right = conn_state->tv.margins.right; vc4_state->margins.top = conn_state->tv.margins.top; @@ -1017,7 +1006,6 @@ static void vc4_set_crtc_possible_masks(struct drm_device *drm, struct drm_crtc *crtc) { struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc); - const struct vc4_crtc_data *crtc_data = vc4_crtc_to_vc4_crtc_data(vc4_crtc); const struct vc4_pv_data *pv_data = vc4_crtc_to_vc4_pv_data(vc4_crtc); const enum vc4_encoder_type *encoder_types = pv_data->encoder_types; struct drm_encoder *encoder; @@ -1026,13 +1014,6 @@ static void vc4_set_crtc_possible_masks(struct drm_device *drm, struct vc4_encoder *vc4_encoder; int i; - /* HVS FIFO2 can feed the TXP IP. */ - if (crtc_data->hvs_output == 2 && - encoder->encoder_type == DRM_MODE_ENCODER_VIRTUAL) { - encoder->possible_crtcs |= drm_crtc_mask(crtc); - continue; - } - vc4_encoder = to_vc4_encoder(encoder); for (i = 0; i < ARRAY_SIZE(pv_data->encoder_types); i++) { if (vc4_encoder->type == encoder_types[i]) { diff --git a/drivers/gpu/drm/vc4/vc4_txp.c b/drivers/gpu/drm/vc4/vc4_txp.c index d9a8ab87ad25..849dcafbfff1 100644 --- a/drivers/gpu/drm/vc4/vc4_txp.c +++ b/drivers/gpu/drm/vc4/vc4_txp.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include "vc4_drv.h" @@ -145,6 +146,8 @@ #define TXP_WRITE(offset, val) writel(val, txp->regs + (offset)) struct vc4_txp { + struct vc4_crtc base; + struct platform_device *pdev; struct drm_writeback_connector connector; @@ -362,23 +365,105 @@ static const struct drm_encoder_helper_funcs vc4_txp_encoder_helper_funcs = { .disable = vc4_txp_encoder_disable, }; +static int vc4_txp_enable_vblank(struct drm_crtc *crtc) +{ + return 0; +} + +static void vc4_txp_disable_vblank(struct drm_crtc *crtc) {} + +static const struct drm_crtc_funcs vc4_txp_crtc_funcs = { + .set_config = drm_atomic_helper_set_config, + .destroy = vc4_crtc_destroy, + .page_flip = vc4_page_flip, + .reset = vc4_crtc_reset, + .atomic_duplicate_state = vc4_crtc_duplicate_state, + .atomic_destroy_state = vc4_crtc_destroy_state, + .gamma_set = drm_atomic_helper_legacy_gamma_set, + .enable_vblank = vc4_txp_enable_vblank, + .disable_vblank = vc4_txp_disable_vblank, +}; + +static int vc4_txp_atomic_check(struct drm_crtc *crtc, + struct drm_crtc_state *state) +{ + struct vc4_crtc_state *vc4_state = to_vc4_crtc_state(state); + int ret; + + ret = vc4_hvs_atomic_check(crtc, state); + if (ret) + return ret; + + state->no_vblank = true; + vc4_state->feed_txp = true; + + return 0; +} + +static void vc4_txp_atomic_enable(struct drm_crtc *crtc, + struct drm_crtc_state *old_state) +{ + drm_crtc_vblank_on(crtc); + vc4_hvs_atomic_enable(crtc, old_state); +} + +static void vc4_txp_atomic_disable(struct drm_crtc *crtc, + struct drm_crtc_state *old_state) +{ + struct drm_device *dev = crtc->dev; + + /* Disable vblank irq handling before crtc is disabled. */ + drm_crtc_vblank_off(crtc); + + vc4_hvs_atomic_disable(crtc, old_state); + + /* + * Make sure we issue a vblank event after disabling the CRTC if + * someone was waiting it. + */ + if (crtc->state->event) { + unsigned long flags; + + spin_lock_irqsave(&dev->event_lock, flags); + drm_crtc_send_vblank_event(crtc, crtc->state->event); + crtc->state->event = NULL; + spin_unlock_irqrestore(&dev->event_lock, flags); + } +} + +static const struct drm_crtc_helper_funcs vc4_txp_crtc_helper_funcs = { + .atomic_check = vc4_txp_atomic_check, + .atomic_flush = vc4_hvs_atomic_flush, + .atomic_enable = vc4_txp_atomic_enable, + .atomic_disable = vc4_txp_atomic_disable, +}; + static irqreturn_t vc4_txp_interrupt(int irq, void *data) { struct vc4_txp *txp = data; + struct vc4_crtc *vc4_crtc = &txp->base; TXP_WRITE(TXP_DST_CTRL, TXP_READ(TXP_DST_CTRL) & ~TXP_EI); - vc4_crtc_handle_vblank(to_vc4_crtc(txp->connector.base.state->crtc)); + vc4_crtc_handle_vblank(vc4_crtc); drm_writeback_signal_completion(&txp->connector, 0); return IRQ_HANDLED; } +static const struct vc4_crtc_data vc4_txp_crtc_data = { + .hvs_available_channels = BIT(2), + .hvs_output = 2, +}; + static int vc4_txp_bind(struct device *dev, struct device *master, void *data) { struct platform_device *pdev = to_platform_device(dev); struct drm_device *drm = dev_get_drvdata(master); struct vc4_dev *vc4 = to_vc4_dev(drm); + struct vc4_crtc *vc4_crtc; struct vc4_txp *txp; + struct drm_crtc *crtc; + struct drm_encoder *encoder; int ret, irq; irq = platform_get_irq(pdev, 0); @@ -388,6 +473,11 @@ static int vc4_txp_bind(struct device *dev, struct device *master, void *data) txp = devm_kzalloc(dev, sizeof(*txp), GFP_KERNEL); if (!txp) return -ENOMEM; + vc4_crtc = &txp->base; + crtc = &vc4_crtc->base; + + vc4_crtc->pdev = pdev; + vc4_crtc->data = &vc4_txp_crtc_data; txp->pdev = pdev; @@ -407,6 +497,14 @@ static int vc4_txp_bind(struct device *dev, struct device *master, void *data) if (ret) return ret; + ret = vc4_crtc_init(drm, vc4_crtc, + &vc4_txp_crtc_funcs, &vc4_txp_crtc_helper_funcs); + if (ret) + return ret; + + encoder = &txp->connector.encoder; + encoder->possible_crtcs |= drm_crtc_mask(crtc); + ret = devm_request_irq(dev, irq, vc4_txp_interrupt, 0, dev_name(dev), txp); if (ret) -- git-series 0.9.1