From patchwork Tue May 24 10:10:50 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ying Liu X-Patchwork-Id: 9133397 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 39617607D5 for ; Tue, 24 May 2016 10:27:53 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 32B1B28233 for ; Tue, 24 May 2016 10:27:53 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 2767C28258; Tue, 24 May 2016 10:27:53 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.2 required=2.0 tests=BAD_ENC_HEADER,BAYES_00, DKIM_ADSP_CUSTOM_MED,FREEMAIL_FROM,RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 968ED28233 for ; Tue, 24 May 2016 10:27:51 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 618FD6E70A; Tue, 24 May 2016 10:27:45 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from na01-bn1-obe.outbound.protection.outlook.com (mail-bn1bn0100.outbound.protection.outlook.com [157.56.110.100]) by gabe.freedesktop.org (Postfix) with ESMTPS id 736A76E704 for ; Tue, 24 May 2016 10:26:49 +0000 (UTC) Received: from BLUPR0301CA0012.namprd03.prod.outlook.com (10.162.113.150) by BY2PR03MB476.namprd03.prod.outlook.com (10.141.141.153) with Microsoft SMTP Server (TLS) id 15.1.492.11; Tue, 24 May 2016 10:11:38 +0000 Received: from BL2FFO11FD033.protection.gbl (2a01:111:f400:7c09::156) by BLUPR0301CA0012.outlook.office365.com (2a01:111:e400:5259::22) with Microsoft SMTP Server (TLS) id 15.1.501.7 via Frontend Transport; Tue, 24 May 2016 10:11:37 +0000 Authentication-Results: spf=softfail (sender IP is 192.88.168.50) smtp.mailfrom=gmail.com; arm.linux.org.uk; dkim=none (message not signed) header.d=none; arm.linux.org.uk; dmarc=fail action=none header.from=gmail.com; Received-SPF: SoftFail (protection.outlook.com: domain of transitioning gmail.com discourages use of 192.88.168.50 as permitted sender) Received: from tx30smr01.am.freescale.net (192.88.168.50) by BL2FFO11FD033.mail.protection.outlook.com (10.173.161.129) with Microsoft SMTP Server (TLS) id 15.1.497.8 via Frontend Transport; Tue, 24 May 2016 10:11:37 +0000 Received: from victor.ap.freescale.net (victor.ap.freescale.net [10.192.241.62]) by tx30smr01.am.freescale.net (8.14.3/8.14.0) with ESMTP id u4OABCMA024148; Tue, 24 May 2016 03:11:35 -0700 From: Liu Ying To: Subject: [PATCH 11/14] drm/imx: atomic phase 3 step 2: Use atomic configuration Date: Tue, 24 May 2016 18:10:50 +0800 Message-ID: <1464084653-16684-12-git-send-email-gnuiyl@gmail.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1464084653-16684-1-git-send-email-gnuiyl@gmail.com> References: <1464084653-16684-1-git-send-email-gnuiyl@gmail.com> X-EOPAttributedMessage: 0 X-Matching-Connectors: 131085582976742094; (91ab9b29-cfa4-454e-5278-08d120cd25b8); () X-Forefront-Antispam-Report: CIP:192.88.168.50; IPV:NLI; CTRY:US; EFV:NLI; SFV:NSPM; SFS:(10009020)(6009001)(2980300002)(199003)(189002)(9170700003)(2950100001)(33646002)(87936001)(47776003)(92566002)(81166006)(8936002)(8676002)(575784001)(2906002)(104016004)(1220700001)(61266001)(86362001)(5890100001)(6806005)(77096005)(586003)(4326007)(50226002)(73972006)(5008740100001)(83322999)(76482005)(73392002)(87572001)(106466001)(105596002)(76176999)(50986999)(48376002)(50466002)(229853001)(82202001)(36756003)(2351001)(11100500001)(5003940100001)(19580395003)(19580405001)(110136002)(189998001)(81442002); DIR:OUT; SFP:1101; SCL:1; SRVR:BY2PR03MB476; H:tx30smr01.am.freescale.net; FPR:; SPF:SoftFail; MLV:sfv; A:1; MX:1; LANG:en; X-Microsoft-Exchange-Diagnostics: 1; BL2FFO11FD033; 1:v9fuq/hgas/N8K4/FOupJSxQGPUnqzO0VHrTS0ito9bDSvv95qazcS9xeIux2UC174TTKMd5IMsP3Z+fL/UOKbJQcHzJSxgtZScp5IrF6gyI7ocWbn51fKgZDJRBwKyfzVa9X8BvENVGnqGcteRdWreDCjqyMnglppuKiL9tMeG/VUJ7Oo6nt8gwbUO/X33zelXVacYn+T1lLA0BDgukLurE/V0gki232dIfF+J2sEBDmp+cp+8V0IugwqSMwYYE0483X/wobHGa3xITF2P6AnAtrahqHnomFRVEO1XizbEc2TSFKdV+C9R8PvGkpGwpZKUtpiUKib5C3ScUOHuQT7sv4ATgctghzhxT3JaJf8xMDPbz41lYFSlBmlhXTF+I4h8fObKRqWrKLjwxyS6VoYkMmz9kNSVeIkPFsk5zw97n+TvJTSCYcWUTW18Mdk0oR+JtFoHwsMDX/cvnuBF5xCD9VhK3FeGil/4h3F3TlsYU3kZHW1f0iXSqhud/7DCfN/7OYSd/243TBDODw7nj0gjZtckHcWK7o7CDFDsybReXjWkX63BIjcpE5AcPYfCQ MIME-Version: 1.0 X-MS-Office365-Filtering-Correlation-Id: 7ecc450e-570f-4534-8665-08d383bbcae2 X-Microsoft-Exchange-Diagnostics: 1; BY2PR03MB476; 2:nbehpPME9RtfSamVFvhLD6BvVdzKCCZrF9gi41qSDMMnA7fkseDxxuIZJAAMXSWLHwp+h6sp0eVfQaxp2Fpi3LXQzAIfvmmYXnZRux3bhhfriV0KAZc4iY6zENtgiidcPE1D+riEVPlOTQZKgDlOFfVH7WWbDFGlh3VAmSn8X/H56jkEODtRdX7R3p/bpmba; 3:bIGq/oo36XiXclFv3A+7ub1gQebIvgcj9DKqL2b73SZ0hINHbUwFbiNKTtR4L42yrj5A83x3WKNxZ0+Se3tSmCNRLTW4iWnGp8ELoNWs7GeuaV+AmdvB6SacYaOhaXBidkyyuoHnz9tBS7WcD+2VXUOSGdWIyNsvA70uzm/d8/Wgm0ptTN/oO4CpqVEDYi4cje7rwMEFbMxNYlEywQlw9fpUdY9E9k1o0cQKdyBbdLs= X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:BY2PR03MB476; X-Microsoft-Exchange-Diagnostics: 1; BY2PR03MB476; 25:O+fyyHpnOJlqP8vZM5ndCU+DRRq6GZftVZoIvX08IB8LVNM8fdQogJZFTtrQcTyA5fNJFo/wart7iZxo40bnQvs7aGMz4SL0qp2/ZTc3lCruTw4kt34hYCoohImNzljbsF2judXKJT8WS/W+uXQmUgBPBRCDSHr4cP5cn6i/A/mH46E9grGExH5EW6jmmJJg+Lf67eJ8iQidyn59KB1x4zQApvYJX98ElWx3q3DLubEFXMduq67z6TyHzpv06o0OX9a+bqaywkauiDO1zkuwEisIPMAWZDprZRtdpuCJ+TB4UkeXaWaZQMufenuetZ8fWno2grAN10MqPyIUH+Rc2ypEeJi/iT5rkSJgI41Q6817ILCu0qKesdKRCcljKmAGLag3N8bYppgA6xmXPuv1OzE13pRwcDnjl7uw0UmrlATUvPJJeHDuVhPOzpZVhXzY3m7CSIfcmCRevFkwweBHMgTd9XWoKpRCgbAVv6F84zLSWkl3yiv33TnbJp41SERC6XK+arO7+94k0XsEo5ea6DhisKVCtC8apNFfky3pSyKxkqPl9z7LQN8ioa9erlChAveVeqXgM8ry+MLgbf2SMCC9GB2UzqmSxP5ZsmKJr8KSw/Rbwo1SM96m1XzPEXksKJ1/M67AYsjH0Pwq7OL0zwYzLD10VF7N/X59mc6A7MqENmPl3gXYLP/nGlRQk+YSsZvZC5sh1PNsXWymA8otLtpxkcfVo052Xz6DwdXGWrggqREsnIJ8T9WEPE8xk7sgd6X8o7JiXu3A+deAFwYifg== X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:; X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(601004)(2401047)(13024025)(8121501046)(13015025)(13023025)(5005006)(13018025)(13017025)(3002001)(10201501046)(6055026); SRVR:BY2PR03MB476; BCL:0; PCL:0; RULEID:(400006); SRVR:BY2PR03MB476; X-Microsoft-Exchange-Diagnostics: 1; BY2PR03MB476; 4:bQ+Y4bfC52wHvaaqqR3xzkaQw/ad0nypW2vlEYFXnJzIimgW5DwssrZ0MLNbbbksIdFndot3KTuElgb8EALEt7RQUeqgDB4lxJuS4Yfu0JNg8c7JGDQqJdrdxsIGmig3w7cD6N62mjwz9appZNsAIKmyLYFWUeSffHUIBoKXRUPXSKIndaPzeONl6eh+ZkAY8lYAqdm0yMi1wSDTRgd2pNvOwNzUVGE1ouyDZuG3UYVSL4w2Hss9dPEaP22Ak7VpnEunkLA4QTQy+bf2GsxZqFdvfPR4hF1VXgehhkjKGKyIJrrA6zKNWDn80Wyj9jOS0a22HWLetbczvrvtI+tq6rKTyHGlzjNauZi+N4TdJ+Kepjz6gISxjMvmYhYfBKWy2zSIzFNvXKSljl9khVCwxcBnvRhfF8FgAbeqAhShzSJTHJm/jV6kYxA45m4O+LFC4CrdWluXurpB1UYup7Jd5y7Vrud8lsH8iw/uz/U/kYU= X-Forefront-PRVS: 09525C61DB X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; BY2PR03MB476; 23:PMQ00EZFR9GClOfB97a7vO/mo8MrvxZ7cu3aeEpg9s?= =?us-ascii?Q?Y1agfq3kSIzXmQNGMBy21RS+Em7pXmBaqeowUagM8qUaYuDeOSQKiCx7S25b?= =?us-ascii?Q?iM3MB0PKGpOkGMRqRnrbOGPHUbGw2pAcgdgicR/EPenI8yaKXejJvJIwZ1Qk?= =?us-ascii?Q?AE48dvW8u6bH1nx5mJUoYUD7aEuOl+tbTZg1BOpYPRSBkaGvTdh8LsFTepCF?= =?us-ascii?Q?iZZ6hINQEpF+s5KXZK/L2ioO7rOLOsZYw8DE/Jbo1ItogEzQo88NbAu6pZlj?= =?us-ascii?Q?xzuoEEHsUZA7wmUM6uUiHvkeSHb/fYTbIAZOgXMFvGtBwKUhXIabKik5F/V2?= =?us-ascii?Q?7wNw+MJq6U0JUG+RQWhnLKLG30b0JXqnEAZV+kKfBcpg4xyU7yjiDlZu/vk1?= =?us-ascii?Q?vlbU9G6cFUaSGXNK7gt7b0OURA4w9R4TstX5grwdHsDnhmYkGKSDQA+mLIGi?= =?us-ascii?Q?+POR9IH4gQFD3mF6wAIcGAeUYMKRG9qYEhfp9+Om3qwUB5xB6dRN0cu4CLYC?= =?us-ascii?Q?qIw1gDHhP2iZlmrar0q24Siq9FCxidR3irJcI77Y90Mlqc3nTcRULow5GxS/?= =?us-ascii?Q?yU8IJ/3lq7O6RLZ6G+GxiAuP/QEjClHdrMTXnkLJfwMfpEYIfkznYc27y2ZW?= =?us-ascii?Q?4wE2oqb+If3PHU+v1zvu23JgIzbP/9D3vqpRsSW2mPcAi/7KwgjlJZoH2h1r?= =?us-ascii?Q?aV16JMuwiClQbGFJ45NZMbX7F6voqfM4KbTqdR4HArtasJ3MMAs+K09O4G55?= =?us-ascii?Q?ZaDzKq63TNq4/G6mdORdqicG0SQAZZeR7rMosNO7auvaiWZkuzmo/ierwKaU?= =?us-ascii?Q?FuTtdKF4IRuBsi1+6wU9n4zJ0fllGk8hn65gn6U6Mb9HawgF7neUi3eeV0p/?= =?us-ascii?Q?RSn0GK7WtWxMf4hbcz2gq6p9Bp1D48J4oyp8FTB9ewcLCeRoEvH/doWoS/tf?= =?us-ascii?Q?A2dfvt/xspvbYD+KBa/Rsem1cuHXvOKolOH/gFyq+mwfKpLdwhCs63XYY9fR?= =?us-ascii?Q?6qCGFrKdbgBQh1XvZ3CihvxCggBb7YvAXhM+mDeMUxc9PtJo3f48JjFOvctG?= =?us-ascii?Q?O5TVgJbK70bOkvkSJqU4OFOKA/3mrpdIjMlOscyt/uZrphOSfY6DZkMaPvjr?= =?us-ascii?Q?11UFMbIFlsyOY1FPHIGoMeYolg5geGo9OUhrTnBNkkLl491pQkEN6qwUQdS7?= =?us-ascii?Q?JnoV6Y7LFtCGXr3/zSB8s9cD7BlwWRBnZRZd0xU6hy93888c63A6F8tg=3D?= =?us-ascii?Q?=3D?= X-Microsoft-Exchange-Diagnostics: 1; BY2PR03MB476; 5:0m/ZafeTBey5dTINBjWlYSMIsPiIeMJIxGDr1kOWss+3f9tMLGunIvbWX5u5nC1f325Us4wM7F4l7w0zEE7qeDb66PU9vxFZ8M9haWz0wjnpcGOs023x5KuEIIhIRbkNvt4wsUlvEjjV6XwAN5oox+QnybgrTWeT3j9nEXy8/b0=; 24:5Eak9t7fdXKBgWBvrUVmkqQi4xSg9ETO/Rg65/yWSffVreWMllih4isRIlVxJojpcimmauFvjbxP5Mm4mNcoy3EM1aoGQZtTOAjM3kfYOqs=; 7:UovZswN5rETqweXyUI7TsT65qjOAJ2AjQbYpBleZxBYM/OEhcLMkrpfLnGy16KkH+eFkhayxL8evhm0d6bJNazc9JTT1UXZaDI+TsUQ8HJbxr1HGF69/q133yuUxU2iuwOR3Kq4Xh/VXZ3UzmWpUipa4xi+H2B9TpsWNJHTcjxkMbCm/d0Z2PSIxmjK8QH0C SpamDiagnosticOutput: 1:23 SpamDiagnosticMetadata: NSPM X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 May 2016 10:11:37.2842 (UTC) X-MS-Exchange-CrossTenant-Id: 5afe0b00-7697-4969-b663-5eab37d5f47e X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=5afe0b00-7697-4969-b663-5eab37d5f47e; Ip=[192.88.168.50]; Helo=[tx30smr01.am.freescale.net] X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: BY2PR03MB476 Cc: Russell King 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: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP Replacing drm_crtc_helper_set_config() by drm_atomic_helper_set_config() and converting the suspend/resume operations to atomic makes us be able to use atomic configurations. All of these allows us to remove the crtc_funcs->mode_set callback as it is no longer used. Also, we may remove all the encoders' ->prepare callbacks as they can be replaced by ->disable. In consequence, the bus_format, di_vsync_pin and di_hsync_pin settings are moved from ->prepare to structure imx_encoder. Furthermore, switching to the pure atomic version of set_config callback means that we may implement CRTC/plane atomic checks by using the new CRTC/plane states instead of the legacy ones and we may remove the private ipu_crtc->enabled state which was left there for the transitional atomic helpers in phase 1. Signed-off-by: Liu Ying --- drivers/gpu/drm/imx/dw_hdmi-imx.c | 18 +++--- drivers/gpu/drm/imx/imx-drm-core.c | 49 ++++----------- drivers/gpu/drm/imx/imx-drm.h | 11 +++- drivers/gpu/drm/imx/imx-ldb.c | 109 +++++++++++++++------------------ drivers/gpu/drm/imx/imx-tve.c | 56 +++++++---------- drivers/gpu/drm/imx/ipuv3-crtc.c | 63 +++++-------------- drivers/gpu/drm/imx/ipuv3-plane.c | 23 +++---- drivers/gpu/drm/imx/parallel-display.c | 56 ++++++++--------- 8 files changed, 159 insertions(+), 226 deletions(-) diff --git a/drivers/gpu/drm/imx/dw_hdmi-imx.c b/drivers/gpu/drm/imx/dw_hdmi-imx.c index a24631fd..5f64674 100644 --- a/drivers/gpu/drm/imx/dw_hdmi-imx.c +++ b/drivers/gpu/drm/imx/dw_hdmi-imx.c @@ -22,9 +22,11 @@ #include "imx-drm.h" +#define imx_enc_to_imx_hdmi(x) container_of(x, struct imx_hdmi, imx_encoder) + struct imx_hdmi { struct device *dev; - struct drm_encoder encoder; + struct imx_drm_encoder imx_encoder; struct regmap *regmap; }; @@ -117,7 +119,8 @@ static void dw_hdmi_imx_encoder_mode_set(struct drm_encoder *encoder, static void dw_hdmi_imx_encoder_commit(struct drm_encoder *encoder) { - struct imx_hdmi *hdmi = container_of(encoder, struct imx_hdmi, encoder); + struct imx_drm_encoder *imx_encoder = enc_to_imx_enc(encoder); + struct imx_hdmi *hdmi = imx_enc_to_imx_hdmi(imx_encoder); int mux = drm_of_encoder_active_port_id(hdmi->dev->of_node, encoder); regmap_update_bits(hdmi->regmap, IOMUXC_GPR3, @@ -125,14 +128,8 @@ static void dw_hdmi_imx_encoder_commit(struct drm_encoder *encoder) mux << IMX6Q_GPR3_HDMI_MUX_CTL_SHIFT); } -static void dw_hdmi_imx_encoder_prepare(struct drm_encoder *encoder) -{ - imx_drm_set_bus_format(encoder, MEDIA_BUS_FMT_RGB888_1X24); -} - static const struct drm_encoder_helper_funcs dw_hdmi_imx_encoder_helper_funcs = { .mode_set = dw_hdmi_imx_encoder_mode_set, - .prepare = dw_hdmi_imx_encoder_prepare, .commit = dw_hdmi_imx_encoder_commit, .disable = dw_hdmi_imx_encoder_disable, }; @@ -215,7 +212,10 @@ static int dw_hdmi_imx_bind(struct device *dev, struct device *master, match = of_match_node(dw_hdmi_imx_dt_ids, pdev->dev.of_node); plat_data = match->data; hdmi->dev = &pdev->dev; - encoder = &hdmi->encoder; + encoder = &hdmi->imx_encoder.encoder; + hdmi->imx_encoder.bus_format = MEDIA_BUS_FMT_RGB888_1X24; + hdmi->imx_encoder.di_hsync_pin = 2; + hdmi->imx_encoder.di_vsync_pin = 3; irq = platform_get_irq(pdev, 0); if (irq < 0) diff --git a/drivers/gpu/drm/imx/imx-drm-core.c b/drivers/gpu/drm/imx/imx-drm-core.c index 7e058ea..2fa04a0 100644 --- a/drivers/gpu/drm/imx/imx-drm-core.c +++ b/drivers/gpu/drm/imx/imx-drm-core.c @@ -42,6 +42,7 @@ struct imx_drm_device { struct imx_drm_crtc *crtc[MAX_CRTC]; unsigned int pipes; struct drm_fbdev_cma *fbhelper; + struct drm_atomic_state *state; }; struct imx_drm_crtc { @@ -86,42 +87,6 @@ static int imx_drm_driver_unload(struct drm_device *drm) return 0; } -static struct imx_drm_crtc *imx_drm_find_crtc(struct drm_crtc *crtc) -{ - struct imx_drm_device *imxdrm = crtc->dev->dev_private; - unsigned i; - - for (i = 0; i < MAX_CRTC; i++) - if (imxdrm->crtc[i] && imxdrm->crtc[i]->crtc == crtc) - return imxdrm->crtc[i]; - - return NULL; -} - -int imx_drm_set_bus_format_pins(struct drm_encoder *encoder, u32 bus_format, - int hsync_pin, int vsync_pin) -{ - struct imx_drm_crtc_helper_funcs *helper; - struct imx_drm_crtc *imx_crtc; - - imx_crtc = imx_drm_find_crtc(encoder->crtc); - if (!imx_crtc) - return -EINVAL; - - helper = &imx_crtc->imx_drm_helper_funcs; - if (helper->set_interface_pix_fmt) - return helper->set_interface_pix_fmt(encoder->crtc, - bus_format, hsync_pin, vsync_pin); - return 0; -} -EXPORT_SYMBOL_GPL(imx_drm_set_bus_format_pins); - -int imx_drm_set_bus_format(struct drm_encoder *encoder, u32 bus_format) -{ - return imx_drm_set_bus_format_pins(encoder, bus_format, 2, 3); -} -EXPORT_SYMBOL_GPL(imx_drm_set_bus_format); - int imx_drm_crtc_vblank_get(struct imx_drm_crtc *imx_drm_crtc) { return drm_crtc_vblank_get(imx_drm_crtc->crtc); @@ -501,6 +466,7 @@ static int imx_drm_platform_remove(struct platform_device *pdev) static int imx_drm_suspend(struct device *dev) { struct drm_device *drm_dev = dev_get_drvdata(dev); + struct imx_drm_device *imxdrm; /* The drm_dev is NULL before .load hook is called */ if (drm_dev == NULL) @@ -508,17 +474,26 @@ static int imx_drm_suspend(struct device *dev) drm_kms_helper_poll_disable(drm_dev); + imxdrm = drm_dev->dev_private; + imxdrm->state = drm_atomic_helper_suspend(drm_dev); + if (IS_ERR(imxdrm->state)) { + drm_kms_helper_poll_enable(drm_dev); + return PTR_ERR(imxdrm->state); + } + return 0; } static int imx_drm_resume(struct device *dev) { struct drm_device *drm_dev = dev_get_drvdata(dev); + struct imx_drm_device *imx_drm; if (drm_dev == NULL) return 0; - drm_helper_resume_force_mode(drm_dev); + imx_drm = drm_dev->dev_private; + drm_atomic_helper_resume(drm_dev, imx_drm->state); drm_kms_helper_poll_enable(drm_dev); return 0; diff --git a/drivers/gpu/drm/imx/imx-drm.h b/drivers/gpu/drm/imx/imx-drm.h index b0241b9..5ecc1dd 100644 --- a/drivers/gpu/drm/imx/imx-drm.h +++ b/drivers/gpu/drm/imx/imx-drm.h @@ -15,11 +15,18 @@ struct platform_device; unsigned int imx_drm_crtc_id(struct imx_drm_crtc *crtc); +struct imx_drm_encoder { + struct drm_encoder encoder; + int bus_format; + int di_hsync_pin; + int di_vsync_pin; +}; + +#define enc_to_imx_enc(x) container_of(x, struct imx_drm_encoder, encoder) + struct imx_drm_crtc_helper_funcs { int (*enable_vblank)(struct drm_crtc *crtc); void (*disable_vblank)(struct drm_crtc *crtc); - int (*set_interface_pix_fmt)(struct drm_crtc *crtc, - u32 bus_format, int hsync_pin, int vsync_pin); const struct drm_crtc_helper_funcs *crtc_helper_funcs; const struct drm_crtc_funcs *crtc_funcs; }; diff --git a/drivers/gpu/drm/imx/imx-ldb.c b/drivers/gpu/drm/imx/imx-ldb.c index 8f17b64..d7d1e31 100644 --- a/drivers/gpu/drm/imx/imx-ldb.c +++ b/drivers/gpu/drm/imx/imx-ldb.c @@ -50,14 +50,15 @@ #define LDB_BGREF_RMODE_INT (1 << 15) #define con_to_imx_ldb_ch(x) container_of(x, struct imx_ldb_channel, connector) -#define enc_to_imx_ldb_ch(x) container_of(x, struct imx_ldb_channel, encoder) +#define imx_enc_to_imx_ldb_ch(x) \ + container_of(x, struct imx_ldb_channel, imx_encoder) struct imx_ldb; struct imx_ldb_channel { struct imx_ldb *ldb; struct drm_connector connector; - struct drm_encoder encoder; + struct imx_drm_encoder imx_encoder; struct drm_panel *panel; struct device_node *child; int chno; @@ -65,7 +66,6 @@ struct imx_ldb_channel { int edid_len; struct drm_display_mode mode; int mode_valid; - int bus_format; }; struct bus_mux { @@ -102,8 +102,8 @@ static int imx_ldb_connector_get_modes(struct drm_connector *connector) struct drm_display_info *di = &connector->display_info; num_modes = imx_ldb_ch->panel->funcs->get_modes(imx_ldb_ch->panel); - if (!imx_ldb_ch->bus_format && di->num_bus_formats) - imx_ldb_ch->bus_format = di->bus_formats[0]; + if (!imx_ldb_ch->imx_encoder.bus_format && di->num_bus_formats) + imx_ldb_ch->imx_encoder.bus_format = di->bus_formats[0]; if (num_modes > 0) return num_modes; } @@ -134,7 +134,7 @@ static struct drm_encoder *imx_ldb_connector_best_encoder( { struct imx_ldb_channel *imx_ldb_ch = con_to_imx_ldb_ch(connector); - return &imx_ldb_ch->encoder; + return &imx_ldb_ch->imx_encoder.encoder; } static void imx_ldb_encoder_dpms(struct drm_encoder *encoder, int mode) @@ -169,45 +169,10 @@ static void imx_ldb_set_clock(struct imx_ldb *ldb, int mux, int chno, chno); } -static void imx_ldb_encoder_prepare(struct drm_encoder *encoder) -{ - struct imx_ldb_channel *imx_ldb_ch = enc_to_imx_ldb_ch(encoder); - struct imx_ldb *ldb = imx_ldb_ch->ldb; - int dual = ldb->ldb_ctrl & LDB_SPLIT_MODE_EN; - u32 bus_format; - - switch (imx_ldb_ch->bus_format) { - default: - dev_warn(ldb->dev, - "could not determine data mapping, default to 18-bit \"spwg\"\n"); - /* fallthrough */ - case MEDIA_BUS_FMT_RGB666_1X7X3_SPWG: - bus_format = MEDIA_BUS_FMT_RGB666_1X18; - break; - case MEDIA_BUS_FMT_RGB888_1X7X4_SPWG: - bus_format = MEDIA_BUS_FMT_RGB888_1X24; - if (imx_ldb_ch->chno == 0 || dual) - ldb->ldb_ctrl |= LDB_DATA_WIDTH_CH0_24; - if (imx_ldb_ch->chno == 1 || dual) - ldb->ldb_ctrl |= LDB_DATA_WIDTH_CH1_24; - break; - case MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA: - bus_format = MEDIA_BUS_FMT_RGB888_1X24; - if (imx_ldb_ch->chno == 0 || dual) - ldb->ldb_ctrl |= LDB_DATA_WIDTH_CH0_24 | - LDB_BIT_MAP_CH0_JEIDA; - if (imx_ldb_ch->chno == 1 || dual) - ldb->ldb_ctrl |= LDB_DATA_WIDTH_CH1_24 | - LDB_BIT_MAP_CH1_JEIDA; - break; - } - - imx_drm_set_bus_format(encoder, bus_format); -} - static void imx_ldb_encoder_commit(struct drm_encoder *encoder) { - struct imx_ldb_channel *imx_ldb_ch = enc_to_imx_ldb_ch(encoder); + struct imx_drm_encoder *imx_encoder = enc_to_imx_enc(encoder); + struct imx_ldb_channel *imx_ldb_ch = imx_enc_to_imx_ldb_ch(imx_encoder); struct imx_ldb *ldb = imx_ldb_ch->ldb; int dual = ldb->ldb_ctrl & LDB_SPLIT_MODE_EN; int mux = drm_of_encoder_active_port_id(imx_ldb_ch->child, encoder); @@ -255,7 +220,8 @@ static void imx_ldb_encoder_mode_set(struct drm_encoder *encoder, struct drm_display_mode *orig_mode, struct drm_display_mode *mode) { - struct imx_ldb_channel *imx_ldb_ch = enc_to_imx_ldb_ch(encoder); + struct imx_drm_encoder *imx_encoder = enc_to_imx_enc(encoder); + struct imx_ldb_channel *imx_ldb_ch = imx_enc_to_imx_ldb_ch(imx_encoder); struct imx_ldb *ldb = imx_ldb_ch->ldb; int dual = ldb->ldb_ctrl & LDB_SPLIT_MODE_EN; unsigned long serial_clk; @@ -298,7 +264,8 @@ static void imx_ldb_encoder_mode_set(struct drm_encoder *encoder, static void imx_ldb_encoder_disable(struct drm_encoder *encoder) { - struct imx_ldb_channel *imx_ldb_ch = enc_to_imx_ldb_ch(encoder); + struct imx_drm_encoder *imx_encoder = enc_to_imx_enc(encoder); + struct imx_ldb_channel *imx_ldb_ch = imx_enc_to_imx_ldb_ch(imx_encoder); struct imx_ldb *ldb = imx_ldb_ch->ldb; int mux, ret; @@ -374,7 +341,6 @@ static const struct drm_encoder_funcs imx_ldb_encoder_funcs = { static const struct drm_encoder_helper_funcs imx_ldb_encoder_helper_funcs = { .dpms = imx_ldb_encoder_dpms, - .prepare = imx_ldb_encoder_prepare, .commit = imx_ldb_encoder_commit, .mode_set = imx_ldb_encoder_mode_set, .disable = imx_ldb_encoder_disable, @@ -401,7 +367,7 @@ static int imx_ldb_register(struct drm_device *drm, struct imx_ldb *ldb = imx_ldb_ch->ldb; int ret; - ret = imx_drm_encoder_parse_of(drm, &imx_ldb_ch->encoder, + ret = imx_drm_encoder_parse_of(drm, &imx_ldb_ch->imx_encoder.encoder, imx_ldb_ch->child); if (ret) return ret; @@ -416,10 +382,10 @@ static int imx_ldb_register(struct drm_device *drm, return ret; } - drm_encoder_helper_add(&imx_ldb_ch->encoder, + drm_encoder_helper_add(&imx_ldb_ch->imx_encoder.encoder, &imx_ldb_encoder_helper_funcs); - drm_encoder_init(drm, &imx_ldb_ch->encoder, &imx_ldb_encoder_funcs, - DRM_MODE_ENCODER_LVDS, NULL); + drm_encoder_init(drm, &imx_ldb_ch->imx_encoder.encoder, + &imx_ldb_encoder_funcs, DRM_MODE_ENCODER_LVDS, NULL); drm_connector_helper_add(&imx_ldb_ch->connector, &imx_ldb_connector_helper_funcs); @@ -430,7 +396,7 @@ static int imx_ldb_register(struct drm_device *drm, drm_panel_attach(imx_ldb_ch->panel, &imx_ldb_ch->connector); drm_mode_connector_attach_encoder(&imx_ldb_ch->connector, - &imx_ldb_ch->encoder); + &imx_ldb_ch->imx_encoder.encoder); return 0; } @@ -558,6 +524,7 @@ static int imx_ldb_bind(struct device *dev, struct device *master, void *data) for_each_child_of_node(np, child) { struct imx_ldb_channel *channel; struct device_node *port; + int bus_format; ret = of_property_read_u32(child, "reg", &i); if (ret || i < 0 || i > 1) @@ -609,21 +576,46 @@ static int imx_ldb_bind(struct device *dev, struct device *master, void *data) channel->mode_valid = 1; } - channel->bus_format = of_get_bus_format(dev, child); - if (channel->bus_format == -EINVAL) { + bus_format = of_get_bus_format(dev, child); + if (bus_format == -EINVAL) { /* * If no bus format was specified in the device tree, * we can still get it from the connected panel later. */ if (channel->panel && channel->panel->funcs && channel->panel->funcs->get_modes) - channel->bus_format = 0; + bus_format = 0; } - if (channel->bus_format < 0) { + if (bus_format < 0) { dev_err(dev, "could not determine data mapping: %d\n", - channel->bus_format); - return channel->bus_format; + bus_format); + return bus_format; } + switch (bus_format) { + case MEDIA_BUS_FMT_RGB666_1X7X3_SPWG: + bus_format = MEDIA_BUS_FMT_RGB666_1X18; + break; + case MEDIA_BUS_FMT_RGB888_1X7X4_SPWG: + bus_format = MEDIA_BUS_FMT_RGB888_1X24; + if (i == 0 || dual) + imx_ldb->ldb_ctrl |= LDB_DATA_WIDTH_CH0_24; + if (i == 1 || dual) + imx_ldb->ldb_ctrl |= LDB_DATA_WIDTH_CH1_24; + break; + case MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA: + bus_format = MEDIA_BUS_FMT_RGB888_1X24; + if (i == 0 || dual) + imx_ldb->ldb_ctrl |= LDB_DATA_WIDTH_CH0_24 | + LDB_BIT_MAP_CH0_JEIDA; + if (i == 1 || dual) + imx_ldb->ldb_ctrl |= LDB_DATA_WIDTH_CH1_24 | + LDB_BIT_MAP_CH1_JEIDA; + break; + } + channel->imx_encoder.bus_format = bus_format; + + channel->imx_encoder.di_hsync_pin = 2; + channel->imx_encoder.di_vsync_pin = 3; ret = imx_ldb_register(drm, channel); if (ret) @@ -648,7 +640,8 @@ static void imx_ldb_unbind(struct device *dev, struct device *master, continue; channel->connector.funcs->destroy(&channel->connector); - channel->encoder.funcs->destroy(&channel->encoder); + channel->imx_encoder.encoder.funcs->destroy( + &channel->imx_encoder.encoder); kfree(channel->edid); } diff --git a/drivers/gpu/drm/imx/imx-tve.c b/drivers/gpu/drm/imx/imx-tve.c index 9b45deb..82a1edd 100644 --- a/drivers/gpu/drm/imx/imx-tve.c +++ b/drivers/gpu/drm/imx/imx-tve.c @@ -99,7 +99,7 @@ #define TVE_TVDAC_TEST_MODE_MASK (0x7 << 0) #define con_to_tve(x) container_of(x, struct imx_tve, connector) -#define enc_to_tve(x) container_of(x, struct imx_tve, encoder) +#define imx_enc_to_tve(x) container_of(x, struct imx_tve, imx_encoder) enum { TVE_MODE_TVOUT, @@ -108,7 +108,7 @@ enum { struct imx_tve { struct drm_connector connector; - struct drm_encoder encoder; + struct imx_drm_encoder imx_encoder; struct device *dev; spinlock_t lock; /* register lock */ bool enabled; @@ -121,8 +121,6 @@ struct imx_tve { struct clk *di_sel_clk; struct clk_hw clk_hw_di; struct clk *di_clk; - int vsync_pin; - int hsync_pin; }; static void tve_lock(void *__tve) @@ -273,12 +271,13 @@ static struct drm_encoder *imx_tve_connector_best_encoder( { struct imx_tve *tve = con_to_tve(connector); - return &tve->encoder; + return &tve->imx_encoder.encoder; } static void imx_tve_encoder_dpms(struct drm_encoder *encoder, int mode) { - struct imx_tve *tve = enc_to_tve(encoder); + struct imx_drm_encoder *imx_encoder = enc_to_imx_enc(encoder); + struct imx_tve *tve = imx_enc_to_tve(imx_encoder); int ret; ret = regmap_update_bits(tve->regmap, TVE_COM_CONF_REG, @@ -287,28 +286,12 @@ static void imx_tve_encoder_dpms(struct drm_encoder *encoder, int mode) dev_err(tve->dev, "failed to disable TVOUT: %d\n", ret); } -static void imx_tve_encoder_prepare(struct drm_encoder *encoder) -{ - struct imx_tve *tve = enc_to_tve(encoder); - - tve_disable(tve); - - switch (tve->mode) { - case TVE_MODE_VGA: - imx_drm_set_bus_format_pins(encoder, MEDIA_BUS_FMT_GBR888_1X24, - tve->hsync_pin, tve->vsync_pin); - break; - case TVE_MODE_TVOUT: - imx_drm_set_bus_format(encoder, MEDIA_BUS_FMT_YUV8_1X24); - break; - } -} - static void imx_tve_encoder_mode_set(struct drm_encoder *encoder, struct drm_display_mode *orig_mode, struct drm_display_mode *mode) { - struct imx_tve *tve = enc_to_tve(encoder); + struct imx_drm_encoder *imx_encoder = enc_to_imx_enc(encoder); + struct imx_tve *tve = imx_enc_to_tve(imx_encoder); unsigned long rounded_rate; unsigned long rate; int div = 1; @@ -342,14 +325,16 @@ static void imx_tve_encoder_mode_set(struct drm_encoder *encoder, static void imx_tve_encoder_commit(struct drm_encoder *encoder) { - struct imx_tve *tve = enc_to_tve(encoder); + struct imx_drm_encoder *imx_encoder = enc_to_imx_enc(encoder); + struct imx_tve *tve = imx_enc_to_tve(imx_encoder); tve_enable(tve); } static void imx_tve_encoder_disable(struct drm_encoder *encoder) { - struct imx_tve *tve = enc_to_tve(encoder); + struct imx_drm_encoder *imx_encoder = enc_to_imx_enc(encoder); + struct imx_tve *tve = imx_enc_to_tve(imx_encoder); tve_disable(tve); } @@ -376,7 +361,6 @@ static const struct drm_encoder_funcs imx_tve_encoder_funcs = { static const struct drm_encoder_helper_funcs imx_tve_encoder_helper_funcs = { .dpms = imx_tve_encoder_dpms, - .prepare = imx_tve_encoder_prepare, .mode_set = imx_tve_encoder_mode_set, .commit = imx_tve_encoder_commit, .disable = imx_tve_encoder_disable, @@ -497,13 +481,14 @@ static int imx_tve_register(struct drm_device *drm, struct imx_tve *tve) encoder_type = tve->mode == TVE_MODE_VGA ? DRM_MODE_ENCODER_DAC : DRM_MODE_ENCODER_TVDAC; - ret = imx_drm_encoder_parse_of(drm, &tve->encoder, + ret = imx_drm_encoder_parse_of(drm, &tve->imx_encoder.encoder, tve->dev->of_node); if (ret) return ret; - drm_encoder_helper_add(&tve->encoder, &imx_tve_encoder_helper_funcs); - drm_encoder_init(drm, &tve->encoder, &imx_tve_encoder_funcs, + drm_encoder_helper_add(&tve->imx_encoder.encoder, + &imx_tve_encoder_helper_funcs); + drm_encoder_init(drm, &tve->imx_encoder.encoder, &imx_tve_encoder_funcs, encoder_type, NULL); drm_connector_helper_add(&tve->connector, @@ -511,7 +496,8 @@ static int imx_tve_register(struct drm_device *drm, struct imx_tve *tve) drm_connector_init(drm, &tve->connector, &imx_tve_connector_funcs, DRM_MODE_CONNECTOR_VGA); - drm_mode_connector_attach_encoder(&tve->connector, &tve->encoder); + drm_mode_connector_attach_encoder(&tve->connector, + &tve->imx_encoder.encoder); return 0; } @@ -589,7 +575,7 @@ static int imx_tve_bind(struct device *dev, struct device *master, void *data) if (tve->mode == TVE_MODE_VGA) { ret = of_property_read_u32(np, "fsl,hsync-pin", - &tve->hsync_pin); + &tve->imx_encoder.di_hsync_pin); if (ret < 0) { dev_err(dev, "failed to get vsync pin\n"); @@ -597,12 +583,14 @@ static int imx_tve_bind(struct device *dev, struct device *master, void *data) } ret |= of_property_read_u32(np, "fsl,vsync-pin", - &tve->vsync_pin); + &tve->imx_encoder.di_vsync_pin); if (ret < 0) { dev_err(dev, "failed to get vsync pin\n"); return ret; } + + tve->imx_encoder.bus_format = MEDIA_BUS_FMT_GBR888_1X24; } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); @@ -691,7 +679,7 @@ static void imx_tve_unbind(struct device *dev, struct device *master, struct imx_tve *tve = dev_get_drvdata(dev); tve->connector.funcs->destroy(&tve->connector); - tve->encoder.funcs->destroy(&tve->encoder); + tve->imx_encoder.encoder.funcs->destroy(&tve->imx_encoder.encoder); if (!IS_ERR(tve->dac_reg)) regulator_disable(tve->dac_reg); diff --git a/drivers/gpu/drm/imx/ipuv3-crtc.c b/drivers/gpu/drm/imx/ipuv3-crtc.c index 6ef6c96..3a3b67c 100644 --- a/drivers/gpu/drm/imx/ipuv3-crtc.c +++ b/drivers/gpu/drm/imx/ipuv3-crtc.c @@ -62,14 +62,10 @@ struct ipu_crtc { struct ipu_dc *dc; struct ipu_di *di; - int enabled; enum ipu_flip_status flip_state; struct workqueue_struct *flip_queue; struct ipu_flip_work *flip_work; int irq; - u32 bus_format; - int di_hsync_pin; - int di_vsync_pin; }; #define to_ipu_crtc(x) container_of(x, struct ipu_crtc, base) @@ -78,19 +74,10 @@ static void ipu_crtc_enable(struct ipu_crtc *ipu_crtc) { struct ipu_soc *ipu = dev_get_drvdata(ipu_crtc->dev->parent); - if (ipu_crtc->enabled) - return; - ipu_dc_enable(ipu); /* Start DC channel and DI after IDMAC */ ipu_dc_enable_channel(ipu_crtc->dc); ipu_di_enable(ipu_crtc->di); - ipu_crtc->enabled = 1; - - /* - * In order not to be warned on enabling vblank failure, - * we should call drm_crtc_vblank_on() after ->enabled is set to 1. - */ drm_crtc_vblank_on(&ipu_crtc->base); } @@ -98,15 +85,10 @@ static void ipu_crtc_disable(struct ipu_crtc *ipu_crtc) { struct ipu_soc *ipu = dev_get_drvdata(ipu_crtc->dev->parent); - if (!ipu_crtc->enabled) - return; - /* Stop DC channel and DI before IDMAC */ ipu_dc_disable_channel(ipu_crtc->dc); ipu_di_disable(ipu_crtc->di); ipu_dc_disable(ipu); - ipu_crtc->enabled = 0; - drm_crtc_vblank_off(&ipu_crtc->base); } @@ -235,7 +217,7 @@ put_vblank: } static const struct drm_crtc_funcs ipu_crtc_funcs = { - .set_config = drm_crtc_helper_set_config, + .set_config = drm_atomic_helper_set_config, .destroy = drm_crtc_cleanup, .page_flip = ipu_page_flip, .reset = drm_atomic_helper_crtc_reset, @@ -315,6 +297,11 @@ static void ipu_crtc_commit(struct drm_crtc *crtc) static int ipu_crtc_atomic_check(struct drm_crtc *crtc, struct drm_crtc_state *state) { + u32 primary_plane_mask = 1 << drm_plane_index(crtc->primary); + + if (state->active && (primary_plane_mask & state->plane_mask) == 0) + return -EINVAL; + return 0; } @@ -322,6 +309,7 @@ static void ipu_crtc_mode_set_nofb(struct drm_crtc *crtc) { struct drm_device *dev = crtc->dev; struct drm_encoder *encoder; + struct imx_drm_encoder *imx_encoder = NULL; struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc); struct drm_display_mode *mode = &crtc->state->adjusted_mode; struct ipu_di_signal_cfg sig_cfg = {}; @@ -332,9 +320,12 @@ static void ipu_crtc_mode_set_nofb(struct drm_crtc *crtc) dev_dbg(ipu_crtc->dev, "%s: mode->vdisplay: %d\n", __func__, mode->vdisplay); - list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) - if (encoder->crtc == crtc) + list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { + if (encoder->crtc == crtc) { encoder_types |= BIT(encoder->encoder_type); + imx_encoder = enc_to_imx_enc(encoder); + } + } dev_dbg(ipu_crtc->dev, "%s: attached to encoder types 0x%lx\n", __func__, encoder_types); @@ -354,23 +345,22 @@ static void ipu_crtc_mode_set_nofb(struct drm_crtc *crtc) sig_cfg.enable_pol = 1; sig_cfg.clk_pol = 0; - sig_cfg.bus_format = ipu_crtc->bus_format; + sig_cfg.bus_format = imx_encoder->bus_format; sig_cfg.v_to_h_sync = 0; - sig_cfg.hsync_pin = ipu_crtc->di_hsync_pin; - sig_cfg.vsync_pin = ipu_crtc->di_vsync_pin; + sig_cfg.hsync_pin = imx_encoder->di_hsync_pin; + sig_cfg.vsync_pin = imx_encoder->di_vsync_pin; drm_display_mode_to_videomode(mode, &sig_cfg.mode); ipu_dc_init_sync(ipu_crtc->dc, ipu_crtc->di, mode->flags & DRM_MODE_FLAG_INTERLACE, - ipu_crtc->bus_format, mode->hdisplay); + imx_encoder->bus_format, mode->hdisplay); ipu_di_init_sync_panel(ipu_crtc->di, &sig_cfg); } static const struct drm_crtc_helper_funcs ipu_helper_funcs = { .dpms = ipu_crtc_dpms, .mode_fixup = ipu_crtc_mode_fixup, - .mode_set = drm_helper_crtc_mode_set, .mode_set_nofb = ipu_crtc_mode_set_nofb, .prepare = ipu_crtc_prepare, .commit = ipu_crtc_commit, @@ -381,14 +371,6 @@ static int ipu_enable_vblank(struct drm_crtc *crtc) { struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc); - /* - * ->commit is done after ->mode_set in drm_crtc_helper_set_mode(), - * so waiting for vblank in drm_plane_helper_commit() will timeout. - * Check the state here to avoid the waiting. - */ - if (!ipu_crtc->enabled) - return -EINVAL; - enable_irq(ipu_crtc->irq); return 0; @@ -401,22 +383,9 @@ static void ipu_disable_vblank(struct drm_crtc *crtc) disable_irq_nosync(ipu_crtc->irq); } -static int ipu_set_interface_pix_fmt(struct drm_crtc *crtc, - u32 bus_format, int hsync_pin, int vsync_pin) -{ - struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc); - - ipu_crtc->bus_format = bus_format; - ipu_crtc->di_hsync_pin = hsync_pin; - ipu_crtc->di_vsync_pin = vsync_pin; - - return 0; -} - static const struct imx_drm_crtc_helper_funcs ipu_crtc_helper_funcs = { .enable_vblank = ipu_enable_vblank, .disable_vblank = ipu_disable_vblank, - .set_interface_pix_fmt = ipu_set_interface_pix_fmt, .crtc_funcs = &ipu_crtc_funcs, .crtc_helper_funcs = &ipu_helper_funcs, }; diff --git a/drivers/gpu/drm/imx/ipuv3-plane.c b/drivers/gpu/drm/imx/ipuv3-plane.c index 8419cc1..b2a413f 100644 --- a/drivers/gpu/drm/imx/ipuv3-plane.c +++ b/drivers/gpu/drm/imx/ipuv3-plane.c @@ -14,6 +14,7 @@ */ #include +#include #include #include #include @@ -374,31 +375,31 @@ static int ipu_plane_atomic_check(struct drm_plane *plane, struct drm_plane_state *old_state = plane->state; struct drm_crtc_state *crtc_state; struct device *dev = plane->dev->dev; - struct drm_crtc *crtc; struct drm_framebuffer *fb = state->fb; struct drm_framebuffer *old_fb = old_state->fb; unsigned long eba, ubo, vbo, old_ubo, old_vbo; /* Ok to disable */ if (!fb) - return old_fb ? 0 : -EINVAL; + return 0; + + if (!state->crtc) + return -EINVAL; + + crtc_state = + drm_atomic_get_existing_crtc_state(state->state, state->crtc); + if (WARN_ON(!crtc_state)) + return -EINVAL; /* CRTC should be enabled */ - drm_for_each_crtc(crtc, plane->dev) { - if (drm_crtc_mask(crtc) == plane->possible_crtcs) { - if (!crtc->enabled) - return -EINVAL; - break; - } - } + if (!crtc_state->enable) + return -EINVAL; /* no scaling */ if (state->src_w >> 16 != state->crtc_w || state->src_h >> 16 != state->crtc_h) return -EINVAL; - crtc_state = state->crtc->state; - switch (plane->type) { case DRM_PLANE_TYPE_PRIMARY: /* full plane doesn't support partial off screen */ diff --git a/drivers/gpu/drm/imx/parallel-display.c b/drivers/gpu/drm/imx/parallel-display.c index 252c0ea..2367f0a 100644 --- a/drivers/gpu/drm/imx/parallel-display.c +++ b/drivers/gpu/drm/imx/parallel-display.c @@ -27,15 +27,15 @@ #include "imx-drm.h" #define con_to_imxpd(x) container_of(x, struct imx_parallel_display, connector) -#define enc_to_imxpd(x) container_of(x, struct imx_parallel_display, encoder) +#define imx_enc_to_imxpd(x) \ + container_of(x, struct imx_parallel_display, imx_encoder) struct imx_parallel_display { struct drm_connector connector; - struct drm_encoder encoder; + struct imx_drm_encoder imx_encoder; struct device *dev; void *edid; int edid_len; - u32 bus_format; int mode_valid; struct drm_display_mode mode; struct drm_panel *panel; @@ -58,8 +58,8 @@ static int imx_pd_connector_get_modes(struct drm_connector *connector) struct drm_display_info *di = &connector->display_info; num_modes = imxpd->panel->funcs->get_modes(imxpd->panel); - if (!imxpd->bus_format && di->num_bus_formats) - imxpd->bus_format = di->bus_formats[0]; + if (!imxpd->imx_encoder.bus_format && di->num_bus_formats) + imxpd->imx_encoder.bus_format = di->bus_formats[0]; if (num_modes > 0) return num_modes; } @@ -100,12 +100,13 @@ static struct drm_encoder *imx_pd_connector_best_encoder( { struct imx_parallel_display *imxpd = con_to_imxpd(connector); - return &imxpd->encoder; + return &imxpd->imx_encoder.encoder; } static void imx_pd_encoder_dpms(struct drm_encoder *encoder, int mode) { - struct imx_parallel_display *imxpd = enc_to_imxpd(encoder); + struct imx_drm_encoder *imx_encoder = enc_to_imx_enc(encoder); + struct imx_parallel_display *imxpd = imx_enc_to_imxpd(imx_encoder); if (mode != DRM_MODE_DPMS_ON) drm_panel_disable(imxpd->panel); @@ -113,16 +114,10 @@ static void imx_pd_encoder_dpms(struct drm_encoder *encoder, int mode) drm_panel_enable(imxpd->panel); } -static void imx_pd_encoder_prepare(struct drm_encoder *encoder) -{ - struct imx_parallel_display *imxpd = enc_to_imxpd(encoder); - - imx_drm_set_bus_format(encoder, imxpd->bus_format); -} - static void imx_pd_encoder_commit(struct drm_encoder *encoder) { - struct imx_parallel_display *imxpd = enc_to_imxpd(encoder); + struct imx_drm_encoder *imx_encoder = enc_to_imx_enc(encoder); + struct imx_parallel_display *imxpd = imx_enc_to_imxpd(imx_encoder); drm_panel_prepare(imxpd->panel); drm_panel_enable(imxpd->panel); @@ -136,7 +131,8 @@ static void imx_pd_encoder_mode_set(struct drm_encoder *encoder, static void imx_pd_encoder_disable(struct drm_encoder *encoder) { - struct imx_parallel_display *imxpd = enc_to_imxpd(encoder); + struct imx_drm_encoder *imx_encoder = enc_to_imx_enc(encoder); + struct imx_parallel_display *imxpd = imx_enc_to_imxpd(imx_encoder); drm_panel_disable(imxpd->panel); drm_panel_unprepare(imxpd->panel); @@ -163,7 +159,6 @@ static const struct drm_encoder_funcs imx_pd_encoder_funcs = { static const struct drm_encoder_helper_funcs imx_pd_encoder_helper_funcs = { .dpms = imx_pd_encoder_dpms, - .prepare = imx_pd_encoder_prepare, .commit = imx_pd_encoder_commit, .mode_set = imx_pd_encoder_mode_set, .disable = imx_pd_encoder_disable, @@ -174,7 +169,7 @@ static int imx_pd_register(struct drm_device *drm, { int ret; - ret = imx_drm_encoder_parse_of(drm, &imxpd->encoder, + ret = imx_drm_encoder_parse_of(drm, &imxpd->imx_encoder.encoder, imxpd->dev->of_node); if (ret) return ret; @@ -186,9 +181,10 @@ static int imx_pd_register(struct drm_device *drm, */ imxpd->connector.dpms = DRM_MODE_DPMS_OFF; - drm_encoder_helper_add(&imxpd->encoder, &imx_pd_encoder_helper_funcs); - drm_encoder_init(drm, &imxpd->encoder, &imx_pd_encoder_funcs, - DRM_MODE_ENCODER_NONE, NULL); + drm_encoder_helper_add(&imxpd->imx_encoder.encoder, + &imx_pd_encoder_helper_funcs); + drm_encoder_init(drm, &imxpd->imx_encoder.encoder, + &imx_pd_encoder_funcs, DRM_MODE_ENCODER_NONE, NULL); drm_connector_helper_add(&imxpd->connector, &imx_pd_connector_helper_funcs); @@ -198,7 +194,8 @@ static int imx_pd_register(struct drm_device *drm, if (imxpd->panel) drm_panel_attach(imxpd->panel, &imxpd->connector); - drm_mode_connector_attach_encoder(&imxpd->connector, &imxpd->encoder); + drm_mode_connector_attach_encoder(&imxpd->connector, + &imxpd->imx_encoder.encoder); return 0; } @@ -210,7 +207,7 @@ static int imx_pd_bind(struct device *dev, struct device *master, void *data) struct device_node *port; const u8 *edidp; struct imx_parallel_display *imxpd; - int ret; + int ret, bus_format = 0; const char *fmt; imxpd = devm_kzalloc(dev, sizeof(*imxpd), GFP_KERNEL); @@ -224,14 +221,17 @@ static int imx_pd_bind(struct device *dev, struct device *master, void *data) ret = of_property_read_string(np, "interface-pix-fmt", &fmt); if (!ret) { if (!strcmp(fmt, "rgb24")) - imxpd->bus_format = MEDIA_BUS_FMT_RGB888_1X24; + bus_format = MEDIA_BUS_FMT_RGB888_1X24; else if (!strcmp(fmt, "rgb565")) - imxpd->bus_format = MEDIA_BUS_FMT_RGB565_1X16; + bus_format = MEDIA_BUS_FMT_RGB565_1X16; else if (!strcmp(fmt, "bgr666")) - imxpd->bus_format = MEDIA_BUS_FMT_RGB666_1X18; + bus_format = MEDIA_BUS_FMT_RGB666_1X18; else if (!strcmp(fmt, "lvds666")) - imxpd->bus_format = MEDIA_BUS_FMT_RGB666_1X24_CPADHI; + bus_format = MEDIA_BUS_FMT_RGB666_1X24_CPADHI; } + imxpd->imx_encoder.bus_format = bus_format; + imxpd->imx_encoder.di_hsync_pin = 2; + imxpd->imx_encoder.di_vsync_pin = 3; /* port@1 is the output port */ port = of_graph_get_port_by_id(np, 1); @@ -264,7 +264,7 @@ static void imx_pd_unbind(struct device *dev, struct device *master, { struct imx_parallel_display *imxpd = dev_get_drvdata(dev); - imxpd->encoder.funcs->destroy(&imxpd->encoder); + imxpd->imx_encoder.encoder.funcs->destroy(&imxpd->imx_encoder.encoder); imxpd->connector.funcs->destroy(&imxpd->connector); kfree(imxpd->edid);