From patchwork Mon Jan 17 23:22:51 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Micha=C5=82_Winiarski?= X-Patchwork-Id: 12715718 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5111EC433FE for ; Mon, 17 Jan 2022 23:24:18 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238509AbiAQXYR (ORCPT ); Mon, 17 Jan 2022 18:24:17 -0500 Received: from mga09.intel.com ([134.134.136.24]:63914 "EHLO mga09.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235370AbiAQXYR (ORCPT ); Mon, 17 Jan 2022 18:24:17 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1642461857; x=1673997857; h=from:to:cc:subject:date:message-id:in-reply-to: references:content-transfer-encoding:mime-version; bh=3hUWtiKXjg3cJE6CMKMTkwKwRYB2s1i3CV4QtKLxeyw=; b=Rv54X/cvosusqB7OftykPQn3PsYv5eMad9NOndyHmc8p0x88QJruEyPn iirWsHkY0N9599QRKyHeTH2naEWmmXFvUetILdaPUNeDxaMtBRF0LCH2I A26kNIk+a7nz43BW6rMDgO5DHREnXcyd4TdHMShmX1vARxLqNo9dpwcfP wgQw5c7PSxhTTjpP1Wieu2r84BoNm27Uf1iM2qIa9sML7XVdkTchX+Nag O64A54n0N12B0V6I44rw6t6GypFgAGz4joLjP/b/tmdX1MGwjJDpQiOqu W2MM1Gc2OPhRwMqdLBzvP2qGhbPxqv2iJg83mE4LRUKFq2SAXw8oIBtJG Q==; X-IronPort-AV: E=McAfee;i="6200,9189,10230"; a="244501822" X-IronPort-AV: E=Sophos;i="5.88,296,1635231600"; d="scan'208";a="244501822" Received: from orsmga003.jf.intel.com ([10.7.209.27]) by orsmga102.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 17 Jan 2022 15:24:16 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.88,296,1635231600"; d="scan'208";a="474580633" Received: from fmsmsx603.amr.corp.intel.com ([10.18.126.83]) by orsmga003.jf.intel.com with ESMTP; 17 Jan 2022 15:24:16 -0800 Received: from fmsmsx601.amr.corp.intel.com (10.18.126.81) by fmsmsx603.amr.corp.intel.com (10.18.126.83) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2308.20; Mon, 17 Jan 2022 15:24:16 -0800 Received: from fmsedg601.ED.cps.intel.com (10.1.192.135) by fmsmsx601.amr.corp.intel.com (10.18.126.81) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2308.20 via Frontend Transport; Mon, 17 Jan 2022 15:24:16 -0800 Received: from NAM10-BN7-obe.outbound.protection.outlook.com (104.47.70.105) by edgegateway.intel.com (192.55.55.70) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.1.2308.20; Mon, 17 Jan 2022 15:24:15 -0800 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=T3vll1c83sRjeoBdhEWuvzGjYVWjYIgnS1g5PpALLCcWSlsmHouL14VDcqF7AhbYQA2tajPajzTC/cfrDYq+uUw8PIM0obA3ijUdOIl7i/VUXyfKNbrm3IaOKAahtKQCXEDA0yd5XGnF9RhJzcKKzgAzPp8l11B++pjSZab3zpDIjjVvTWlbYUyhBtfqGYj52/++7UQ94MZLw3HSr54OMRUun+Zwl7VtF1on2MmFT6dci5/lRC+MBTEBkw/DwwaqIecxB2u34WgmaqFjLe2oE1TSjq5j7x78tRGpV0gZVDkcr4PnEWhH9GuJ3yLg7RRLmfVT3QC7j8Jgx6SuK5V95g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=ejnFkLnjeyaluKXsi+Sc4X3UbMwkT8iuOVvEia2FWvo=; b=RvW8NzDPSykHVjDhUcldnfYsxmwWaIVSqFjaCLpsS0RlolnM2bj4zOPOosZ96TLBC+OXMKR0CR+sbk0wWV4AEnFgHMNaNeNhxTeV5/GBJuDbQeQhNRuRyRKnJCX6gLvE3bQoqodYTDk+SnkpyPgbRFsyxOS0/BlKmmHAmRzUdvnsfs7pkQbwLjZzX1uDiD/EP4E8itMq5KsFw1q7Gs/LhZiSfOCIGvtH+CjaM4Vyp8ULPlTHO5lwDVOfhwRXAgLBhZfglujf1WTp14Uga12So2J+9FoFStZEAhikBuMF3XLinbucwongYmI/1GHodPb2TEbgtkDf8nPk52WxAXyHFA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=intel.com; dmarc=pass action=none header.from=intel.com; dkim=pass header.d=intel.com; arc=none Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=intel.com; Received: from DM4PR11MB5373.namprd11.prod.outlook.com (2603:10b6:5:394::7) by DM6PR11MB4140.namprd11.prod.outlook.com (2603:10b6:5:19f::11) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4888.11; Mon, 17 Jan 2022 23:24:11 +0000 Received: from DM4PR11MB5373.namprd11.prod.outlook.com ([fe80::fc15:bd26:128a:f5f5]) by DM4PR11MB5373.namprd11.prod.outlook.com ([fe80::fc15:bd26:128a:f5f5%8]) with mapi id 15.20.4888.014; Mon, 17 Jan 2022 23:24:11 +0000 From: =?utf-8?q?Micha=C5=82_Winiarski?= To: , CC: Brendan Higgins , Daniel Latypov , Daniel Vetter , David Airlie , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , Petri Latvala , Arkadiusz Hiler , =?utf-8?q?Micha=C5=82_Winiarski?= Subject: [RFC 02/10] drm: test-drm_plane_helper: Convert to KUnit Date: Tue, 18 Jan 2022 00:22:51 +0100 Message-ID: <20220117232259.180459-3-michal.winiarski@intel.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220117232259.180459-1-michal.winiarski@intel.com> References: <20220117232259.180459-1-michal.winiarski@intel.com> X-ClientProxiedBy: AS9PR06CA0014.eurprd06.prod.outlook.com (2603:10a6:20b:462::8) To DM4PR11MB5373.namprd11.prod.outlook.com (2603:10b6:5:394::7) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: bb2fc346-6551-4805-3bfb-08d9da1077ca X-MS-TrafficTypeDiagnostic: DM6PR11MB4140:EE_ X-LD-Processed: 46c98d88-e344-4ed4-8496-4ed7712e255d,ExtAddr X-Microsoft-Antispam-PRVS: X-MS-Oob-TLC-OOBClassifiers: OLM:8273; X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: eyEw58PhmdEnu4PRdmSwoiUtiiGNUOe5fBBjIodulWfISVWqvkCo6yzeaW07Q52BcMJgIFAbbBdfOVE8zadbDxuVQO6v1PpYlWA1ZujY9brvvSmOGEzd5vVGFLLDE8DqRRq1NkWdvCDG4YtZZv+PbjQYOSJ+62nyl7fq23Wvd+Yr1TWT+Ku90kdqlaTz/07HgFK2Bh2M38hO6oaay53JKSZAnX8pK+L5WmPt3sVp5u2vk9PZZiZs1QCFLUmncHFkwwzwxH5wlgjuYxngbBtNMwt43wuADtjOft+6409/AOWAEtQNfh0uKP4XGDVrjDPnenctLpHgOZHyipX0OkMu92uB6jsxdgv61YP/SxQK85HkDx9rqgcEkbjf3CVHPGr4RNa+RvmV2viOeEoNdBqxuYEWoNiTbm52bsV6BHl61iakU82JQ9A4HAgT+9+Q4xYdpHl6ZbJ2utbxqy0NBIl29URjZ34GnO7btAsT1RYNuqiUC8jz25+ByLjJTc2NC+9fgxgmSvuf83nZB4My9OX/jG3Jiag75xyfKiDlDHrI9uvpXwrBT0HYr1Uj0tc/qjhkpIO7sqwkarP0tDHE2+nb9jxFhYJOcyBBgbV7QAWePzShlEJe0RPB8XcmXDym0EyuX1Qa4gwyjRdF+DLGKwRzGQ== X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:DM4PR11MB5373.namprd11.prod.outlook.com;PTR:;CAT:NONE;SFS:(366004)(508600001)(7416002)(186003)(6506007)(82960400001)(86362001)(8676002)(6512007)(6666004)(83380400001)(38100700002)(8936002)(66556008)(30864003)(54906003)(5660300002)(2906002)(6486002)(316002)(36756003)(2616005)(66946007)(26005)(1076003)(4326008)(66476007);DIR:OUT;SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?utf-8?q?74dxfr8ENZanjDAVbQ/a+AMqEuF1?= =?utf-8?q?Fe74hXekR3eqPqAqkdBRq6DqXoXNJ4+PMQLCrmRF6uomRQIvcboGiTMZLqJbe00Pr?= =?utf-8?q?/KlGjhL9bWvGF/VwHb2WJgRApXKhJaAOA09RPEBWkUPkk34NBaKSEnV/StPSflJEt?= =?utf-8?q?TA3DCkoYnXqkWtNVhDjcAVHcXUmyTgnSeftl4N22+RBSnucTSj6F3uBnCzWDSROIT?= =?utf-8?q?Hsty1Myhp+KL1eTlunj6xJ7TL4yONE+dXXlU1wqeK6SoM5b3yzedtX5JNzYjJFOc1?= =?utf-8?q?wPb/GB7IsyZLXcLJ05Fl/1lbiEGw8TWAQWaSSas7RCvKL2B2lZ2lhsMmk7ZWFZA4h?= =?utf-8?q?6WGQccePzqrsHvxRhXFSRP2I9YrXigsugzYuMjCvXICq3ApNriBzVB0GUywTGSb2F?= =?utf-8?q?xALQ/BbyUzU9tgXBex7HjsGMx/7m+Cr4fn250j2MX3e+TJ+KVUUT8qahBsO/Egwpr?= =?utf-8?q?tegcONyLYdIssEN+idZLGwzP4WKBvGDY92eO9vM0C3Sub4tG5r8Ve1qHMuw7x8+06?= =?utf-8?q?E+dKuO8JHnzIELO0smltOLz0RHfnLxPzQS/4djP3KY+AKpCX18eObAAJi4i+65PPL?= =?utf-8?q?+szh+ziCbjnBvnEpkks3FX5vI4XREf7TyLNQRg0WOxp0zFMUYtyA5LuKcC4Ii6cRU?= =?utf-8?q?aAnO2F+btFzr7F2H2zgEzSMCMvAu0wTSilhCRJfyuWOL+ItkVtSWn0lOceyzfcSWR?= =?utf-8?q?oMbhr+SFyJWc/S7o945Gnau3b6m01VgNoiYkSfLeEdrjEnn++lLSxHc8ey3UNgb5T?= =?utf-8?q?HPJl/1ROSieaxLkwcu8WKAohjaNCCdUooR3/qMQspp3UHvqOldaP+jZ/dtBgCEXr2?= =?utf-8?q?AD+gdkl785dbGVOEg59r3cWLttT7CV2DoVv6N/CJ0Mu7Y7ZQtkO5P3jPMESMNQGpl?= =?utf-8?q?bFpLs6Hbo4gn/lAsrB0R/ecLP9otMR8vyJkLg6uny1f+2+zn9d2ijFIosTUq+ThX1?= =?utf-8?q?Ip86Se5sIc37hTaCB1SQxwdaGtW1Lzwb9K5HpK7seLWTruvfLp4vI1g1kjA/w41RK?= =?utf-8?q?11d/MOJ2E+A+c8p9abSAi3axnAnzv7D8f7byCKcQ4Xg47sv36i2/NwU3hlDZCR+ch?= =?utf-8?q?rKCSgA4Fm8dJtVUBPI8tBP4JmB4Ce2ubA/g5NWCyp0OWi4X9roBaEBeB2kOOdcQYI?= =?utf-8?q?0scyCRfi8iEeIEcSOLdgfsEa39WI28JQbWzfVf9PUBUXSfZ3JVrVZgj52fr1Rj1UE?= =?utf-8?q?HFTo4ADNDeDIwCTeBlPLlwOqYCV13zF7VO/GMjsuC1nHN392vF7oM7Gr3Q/sHwKsi?= =?utf-8?q?EKWv+bD/5Gk5I1UiZtXKOaqsKn1w6agjtcJ56ctMTiP14AQ0ZJm7AoJG476FpGSYr?= =?utf-8?q?EpQJF+ArSQp+k3TJPAok0NZL4Uf+nNZmr/JUljViVxVpu1BoTPqgsZX/BRFj7uIqf?= =?utf-8?q?wW+zilJFhAcxh7yrygyH9Y/f1U3IVFfNXRoe4v/MR9vmElDM4XnuLaiWn6mftTQaB?= =?utf-8?q?HAlIgQT/Bz80BhgSHMeBYgOfcV+tUo5fDgpGp/FTyB60rALqxjXaiKE2k4q9QoRb1?= =?utf-8?q?6vw7w1bVzugAmmVC/jZaEywvHoCpNy9DdaHTOsprFVhBaMyiXiLSGUFKu1PC2njhT?= =?utf-8?q?VhZ96iORKZT2anIif/Srho+elCpRMfumg=3D=3D?= X-MS-Exchange-CrossTenant-Network-Message-Id: bb2fc346-6551-4805-3bfb-08d9da1077ca X-MS-Exchange-CrossTenant-AuthSource: DM4PR11MB5373.namprd11.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 17 Jan 2022 23:24:11.5741 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 46c98d88-e344-4ed4-8496-4ed7712e255d X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: 1nYBgYqBITnPlsBI8YPsfkye92+RW18dVR0ZhyTDA+TZmXA4lbU0g47/BXs8sLqihIkCL4QjvO1Ee15izePK8+QTzIom4smq8mjPHtiZPXs= X-MS-Exchange-Transport-CrossTenantHeadersStamped: DM6PR11MB4140 X-OriginatorOrg: intel.com Precedence: bulk List-ID: X-Mailing-List: linux-kselftest@vger.kernel.org Tests were converted into parameterized test cases. Negative tests were separated. Mocking was moved to test->init(). No functional changes. Signed-off-by: MichaƂ Winiarski --- drivers/gpu/drm/Kconfig | 1 + drivers/gpu/drm/selftests/Makefile | 4 +- .../gpu/drm/selftests/drm_modeset_selftests.h | 1 - .../drm/selftests/test-drm_modeset_common.h | 1 - .../gpu/drm/selftests/test-drm_plane_helper.c | 483 +++++++++++------- 5 files changed, 289 insertions(+), 201 deletions(-) diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index 21e329f32997..89be0df7b0e9 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig @@ -83,6 +83,7 @@ config DRM_DEBUG_SELFTEST config DRM_KUNIT_TEST bool "DRM tests" if !KUNIT_ALL_TESTS depends on DRM=y && KUNIT=y + select DRM_KMS_HELPER default KUNIT_ALL_TESTS help Enables unit tests for DRM. Only useful for kernel devs running KUnit. diff --git a/drivers/gpu/drm/selftests/Makefile b/drivers/gpu/drm/selftests/Makefile index 6411c9a957b3..82e568665ace 100644 --- a/drivers/gpu/drm/selftests/Makefile +++ b/drivers/gpu/drm/selftests/Makefile @@ -1,6 +1,6 @@ # SPDX-License-Identifier: GPL-2.0-only test-drm_modeset-$(CONFIG_DRM_DEBUG_SELFTEST) := \ - test-drm_modeset_common.o test-drm_plane_helper.o \ + test-drm_modeset_common.o \ test-drm_format.o test-drm_framebuffer.o \ test-drm_damage_helper.o test-drm_dp_mst_helper.o \ test-drm_rect.o @@ -8,4 +8,4 @@ test-drm_modeset-$(CONFIG_DRM_DEBUG_SELFTEST) := \ obj-$(CONFIG_DRM_DEBUG_SELFTEST) += test-drm_mm.o test-drm_modeset.o obj-$(CONFIG_DRM_KUNIT_TEST) := \ - test-drm_cmdline_parser.o + test-drm_cmdline_parser.o test-drm_plane_helper.o diff --git a/drivers/gpu/drm/selftests/drm_modeset_selftests.h b/drivers/gpu/drm/selftests/drm_modeset_selftests.h index 782e285ca383..19d1142725c6 100644 --- a/drivers/gpu/drm/selftests/drm_modeset_selftests.h +++ b/drivers/gpu/drm/selftests/drm_modeset_selftests.h @@ -10,7 +10,6 @@ selftest(drm_rect_clip_scaled_div_by_zero, igt_drm_rect_clip_scaled_div_by_zero) selftest(drm_rect_clip_scaled_not_clipped, igt_drm_rect_clip_scaled_not_clipped) selftest(drm_rect_clip_scaled_clipped, igt_drm_rect_clip_scaled_clipped) selftest(drm_rect_clip_scaled_signed_vs_unsigned, igt_drm_rect_clip_scaled_signed_vs_unsigned) -selftest(check_plane_state, igt_check_plane_state) selftest(check_drm_format_block_width, igt_check_drm_format_block_width) selftest(check_drm_format_block_height, igt_check_drm_format_block_height) selftest(check_drm_format_min_pitch, igt_check_drm_format_min_pitch) diff --git a/drivers/gpu/drm/selftests/test-drm_modeset_common.h b/drivers/gpu/drm/selftests/test-drm_modeset_common.h index cfb51d8da2bc..8744fd840406 100644 --- a/drivers/gpu/drm/selftests/test-drm_modeset_common.h +++ b/drivers/gpu/drm/selftests/test-drm_modeset_common.h @@ -20,7 +20,6 @@ int igt_drm_rect_clip_scaled_div_by_zero(void *ignored); int igt_drm_rect_clip_scaled_not_clipped(void *ignored); int igt_drm_rect_clip_scaled_clipped(void *ignored); int igt_drm_rect_clip_scaled_signed_vs_unsigned(void *ignored); -int igt_check_plane_state(void *ignored); int igt_check_drm_format_block_width(void *ignored); int igt_check_drm_format_block_height(void *ignored); int igt_check_drm_format_min_pitch(void *ignored); diff --git a/drivers/gpu/drm/selftests/test-drm_plane_helper.c b/drivers/gpu/drm/selftests/test-drm_plane_helper.c index ceebeede55ea..f2c0cd37a949 100644 --- a/drivers/gpu/drm/selftests/test-drm_plane_helper.c +++ b/drivers/gpu/drm/selftests/test-drm_plane_helper.c @@ -3,221 +3,310 @@ * Test cases for the drm_plane_helper functions */ -#define pr_fmt(fmt) "drm_plane_helper: " fmt +#include #include #include #include -#include "test-drm_modeset_common.h" - -static void set_src(struct drm_plane_state *plane_state, - unsigned src_x, unsigned src_y, - unsigned src_w, unsigned src_h) +static void expect_src_eq(struct kunit *test, struct drm_plane_state *plane_state, + unsigned int src_x, unsigned int src_y, + unsigned int src_w, unsigned int src_h) { - plane_state->src_x = src_x; - plane_state->src_y = src_y; - plane_state->src_w = src_w; - plane_state->src_h = src_h; + KUNIT_EXPECT_GE_MSG(test, plane_state->src.x1, 0, + "src x coordinate %x should never be below 0, src: " DRM_RECT_FP_FMT, + plane_state->src.x1, DRM_RECT_FP_ARG(&plane_state->src)); + KUNIT_EXPECT_GE_MSG(test, plane_state->src.y1, 0, + "src y coordinate %x should never be below 0, src: " DRM_RECT_FP_FMT, + plane_state->src.y1, DRM_RECT_FP_ARG(&plane_state->src)); + + KUNIT_EXPECT_TRUE_MSG(test, + plane_state->src.x1 == src_x && + plane_state->src.y1 == src_y && + drm_rect_width(&plane_state->src) == src_w && + drm_rect_height(&plane_state->src) == src_h, + "src: " DRM_RECT_FP_FMT, DRM_RECT_FP_ARG(&plane_state->src)); } -static bool check_src_eq(struct drm_plane_state *plane_state, - unsigned src_x, unsigned src_y, - unsigned src_w, unsigned src_h) +static void expect_crtc_eq(struct kunit *test, struct drm_plane_state *plane_state, + int crtc_x, int crtc_y, + unsigned int crtc_w, unsigned int crtc_h) { - if (plane_state->src.x1 < 0) { - pr_err("src x coordinate %x should never be below 0.\n", plane_state->src.x1); - drm_rect_debug_print("src: ", &plane_state->src, true); - return false; - } - if (plane_state->src.y1 < 0) { - pr_err("src y coordinate %x should never be below 0.\n", plane_state->src.y1); - drm_rect_debug_print("src: ", &plane_state->src, true); - return false; - } - - if (plane_state->src.x1 != src_x || - plane_state->src.y1 != src_y || - drm_rect_width(&plane_state->src) != src_w || - drm_rect_height(&plane_state->src) != src_h) { - drm_rect_debug_print("src: ", &plane_state->src, true); - return false; - } - - return true; + KUNIT_EXPECT_TRUE_MSG(test, + plane_state->dst.x1 == crtc_x && + plane_state->dst.y1 == crtc_y && + drm_rect_width(&plane_state->dst) == crtc_w && + drm_rect_height(&plane_state->dst) == crtc_h, + "dst: " DRM_RECT_FMT, DRM_RECT_ARG(&plane_state->dst)); } -static void set_crtc(struct drm_plane_state *plane_state, - int crtc_x, int crtc_y, - unsigned crtc_w, unsigned crtc_h) +const struct drm_crtc_state crtc_state = { + .crtc = ZERO_SIZE_PTR, + .enable = true, + .active = true, + .mode = { + DRM_MODE("1024x768", 0, 65000, 1024, 1048, + 1184, 1344, 0, 768, 771, 777, 806, 0, + DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) + }, +}; + +struct drm_check_plane_state_test { + const char *name; + const char *msg; + struct { + unsigned int x; + unsigned int y; + unsigned int w; + unsigned int h; + } src, src_expected; + struct { + int x; + int y; + unsigned int w; + unsigned int h; + } crtc, crtc_expected; + unsigned int rotation; + int min_scale; + int max_scale; + bool can_position; +}; + +static int drm_plane_helper_init(struct kunit *test) { - plane_state->crtc_x = crtc_x; - plane_state->crtc_y = crtc_y; - plane_state->crtc_w = crtc_w; - plane_state->crtc_h = crtc_h; + const struct drm_check_plane_state_test *params = test->param_value; + struct drm_plane *plane; + struct drm_framebuffer *fb; + struct drm_plane_state *mock; + + plane = kunit_kzalloc(test, sizeof(*plane), GFP_KERNEL); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, plane); + + fb = kunit_kzalloc(test, sizeof(*fb), GFP_KERNEL); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, fb); + fb->width = 2048; + fb->height = 2048; + + mock = kunit_kzalloc(test, sizeof(*mock), GFP_KERNEL); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, mock); + mock->plane = plane; + mock->crtc = ZERO_SIZE_PTR; + mock->fb = fb; + mock->rotation = params->rotation; + mock->src_x = params->src.x; + mock->src_y = params->src.y; + mock->src_w = params->src.w; + mock->src_h = params->src.h; + mock->crtc_x = params->crtc.x; + mock->crtc_y = params->crtc.y; + mock->crtc_w = params->crtc.w; + mock->crtc_h = params->crtc.h; + + test->priv = mock; + + return 0; } -static bool check_crtc_eq(struct drm_plane_state *plane_state, - int crtc_x, int crtc_y, - unsigned crtc_w, unsigned crtc_h) +void drm_check_plane_state(struct kunit *test) { - if (plane_state->dst.x1 != crtc_x || - plane_state->dst.y1 != crtc_y || - drm_rect_width(&plane_state->dst) != crtc_w || - drm_rect_height(&plane_state->dst) != crtc_h) { - drm_rect_debug_print("dst: ", &plane_state->dst, false); - - return false; - } + const struct drm_check_plane_state_test *params = test->param_value; + struct drm_plane_state *plane_state = test->priv; - return true; + KUNIT_ASSERT_EQ_MSG(test, + drm_atomic_helper_check_plane_state(plane_state, &crtc_state, + params->min_scale, + params->max_scale, + params->can_position, false), + 0, params->msg); + KUNIT_EXPECT_TRUE(test, plane_state->visible); + expect_src_eq(test, plane_state, params->src_expected.x, params->src_expected.y, + params->src_expected.w, params->src_expected.h); + expect_crtc_eq(test, plane_state, params->crtc_expected.x, params->crtc_expected.y, + params->crtc_expected.w, params->crtc_expected.h); } -int igt_check_plane_state(void *ignored) +void drm_check_invalid_plane_state(struct kunit *test) { - int ret; - - const struct drm_crtc_state crtc_state = { - .crtc = ZERO_SIZE_PTR, - .enable = true, - .active = true, - .mode = { - DRM_MODE("1024x768", 0, 65000, 1024, 1048, - 1184, 1344, 0, 768, 771, 777, 806, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) - }, - }; - struct drm_plane plane = { - .dev = NULL - }; - struct drm_framebuffer fb = { - .width = 2048, - .height = 2048 - }; - struct drm_plane_state plane_state = { - .plane = &plane, - .crtc = ZERO_SIZE_PTR, - .fb = &fb, - .rotation = DRM_MODE_ROTATE_0 - }; - - /* Simple clipping, no scaling. */ - set_src(&plane_state, 0, 0, fb.width << 16, fb.height << 16); - set_crtc(&plane_state, 0, 0, fb.width, fb.height); - ret = drm_atomic_helper_check_plane_state(&plane_state, &crtc_state, - DRM_PLANE_HELPER_NO_SCALING, - DRM_PLANE_HELPER_NO_SCALING, - false, false); - FAIL(ret < 0, "Simple clipping check should pass\n"); - FAIL_ON(!plane_state.visible); - FAIL_ON(!check_src_eq(&plane_state, 0, 0, 1024 << 16, 768 << 16)); - FAIL_ON(!check_crtc_eq(&plane_state, 0, 0, 1024, 768)); - - /* Rotated clipping + reflection, no scaling. */ - plane_state.rotation = DRM_MODE_ROTATE_90 | DRM_MODE_REFLECT_X; - ret = drm_atomic_helper_check_plane_state(&plane_state, &crtc_state, - DRM_PLANE_HELPER_NO_SCALING, - DRM_PLANE_HELPER_NO_SCALING, - false, false); - FAIL(ret < 0, "Rotated clipping check should pass\n"); - FAIL_ON(!plane_state.visible); - FAIL_ON(!check_src_eq(&plane_state, 0, 0, 768 << 16, 1024 << 16)); - FAIL_ON(!check_crtc_eq(&plane_state, 0, 0, 1024, 768)); - plane_state.rotation = DRM_MODE_ROTATE_0; - - /* Check whether positioning works correctly. */ - set_src(&plane_state, 0, 0, 1023 << 16, 767 << 16); - set_crtc(&plane_state, 0, 0, 1023, 767); - ret = drm_atomic_helper_check_plane_state(&plane_state, &crtc_state, - DRM_PLANE_HELPER_NO_SCALING, - DRM_PLANE_HELPER_NO_SCALING, - false, false); - FAIL(!ret, "Should not be able to position on the crtc with can_position=false\n"); - - ret = drm_atomic_helper_check_plane_state(&plane_state, &crtc_state, - DRM_PLANE_HELPER_NO_SCALING, - DRM_PLANE_HELPER_NO_SCALING, - true, false); - FAIL(ret < 0, "Simple positioning should work\n"); - FAIL_ON(!plane_state.visible); - FAIL_ON(!check_src_eq(&plane_state, 0, 0, 1023 << 16, 767 << 16)); - FAIL_ON(!check_crtc_eq(&plane_state, 0, 0, 1023, 767)); - - /* Simple scaling tests. */ - set_src(&plane_state, 0, 0, 512 << 16, 384 << 16); - set_crtc(&plane_state, 0, 0, 1024, 768); - ret = drm_atomic_helper_check_plane_state(&plane_state, &crtc_state, - 0x8001, - DRM_PLANE_HELPER_NO_SCALING, - false, false); - FAIL(!ret, "Upscaling out of range should fail.\n"); - ret = drm_atomic_helper_check_plane_state(&plane_state, &crtc_state, - 0x8000, - DRM_PLANE_HELPER_NO_SCALING, - false, false); - FAIL(ret < 0, "Upscaling exactly 2x should work\n"); - FAIL_ON(!plane_state.visible); - FAIL_ON(!check_src_eq(&plane_state, 0, 0, 512 << 16, 384 << 16)); - FAIL_ON(!check_crtc_eq(&plane_state, 0, 0, 1024, 768)); - - set_src(&plane_state, 0, 0, 2048 << 16, 1536 << 16); - ret = drm_atomic_helper_check_plane_state(&plane_state, &crtc_state, - DRM_PLANE_HELPER_NO_SCALING, - 0x1ffff, false, false); - FAIL(!ret, "Downscaling out of range should fail.\n"); - ret = drm_atomic_helper_check_plane_state(&plane_state, &crtc_state, - DRM_PLANE_HELPER_NO_SCALING, - 0x20000, false, false); - FAIL(ret < 0, "Should succeed with exact scaling limit\n"); - FAIL_ON(!plane_state.visible); - FAIL_ON(!check_src_eq(&plane_state, 0, 0, 2048 << 16, 1536 << 16)); - FAIL_ON(!check_crtc_eq(&plane_state, 0, 0, 1024, 768)); - - /* Testing rounding errors. */ - set_src(&plane_state, 0, 0, 0x40001, 0x40001); - set_crtc(&plane_state, 1022, 766, 4, 4); - ret = drm_atomic_helper_check_plane_state(&plane_state, &crtc_state, - DRM_PLANE_HELPER_NO_SCALING, - 0x10001, - true, false); - FAIL(ret < 0, "Should succeed by clipping to exact multiple"); - FAIL_ON(!plane_state.visible); - FAIL_ON(!check_src_eq(&plane_state, 0, 0, 2 << 16, 2 << 16)); - FAIL_ON(!check_crtc_eq(&plane_state, 1022, 766, 2, 2)); - - set_src(&plane_state, 0x20001, 0x20001, 0x4040001, 0x3040001); - set_crtc(&plane_state, -2, -2, 1028, 772); - ret = drm_atomic_helper_check_plane_state(&plane_state, &crtc_state, - DRM_PLANE_HELPER_NO_SCALING, - 0x10001, - false, false); - FAIL(ret < 0, "Should succeed by clipping to exact multiple"); - FAIL_ON(!plane_state.visible); - FAIL_ON(!check_src_eq(&plane_state, 0x40002, 0x40002, 1024 << 16, 768 << 16)); - FAIL_ON(!check_crtc_eq(&plane_state, 0, 0, 1024, 768)); - - set_src(&plane_state, 0, 0, 0x3ffff, 0x3ffff); - set_crtc(&plane_state, 1022, 766, 4, 4); - ret = drm_atomic_helper_check_plane_state(&plane_state, &crtc_state, - 0xffff, - DRM_PLANE_HELPER_NO_SCALING, - true, false); - FAIL(ret < 0, "Should succeed by clipping to exact multiple"); - FAIL_ON(!plane_state.visible); - /* Should not be rounded to 0x20001, which would be upscaling. */ - FAIL_ON(!check_src_eq(&plane_state, 0, 0, 2 << 16, 2 << 16)); - FAIL_ON(!check_crtc_eq(&plane_state, 1022, 766, 2, 2)); - - set_src(&plane_state, 0x1ffff, 0x1ffff, 0x403ffff, 0x303ffff); - set_crtc(&plane_state, -2, -2, 1028, 772); - ret = drm_atomic_helper_check_plane_state(&plane_state, &crtc_state, - 0xffff, - DRM_PLANE_HELPER_NO_SCALING, - false, false); - FAIL(ret < 0, "Should succeed by clipping to exact multiple"); - FAIL_ON(!plane_state.visible); - FAIL_ON(!check_src_eq(&plane_state, 0x3fffe, 0x3fffe, 1024 << 16, 768 << 16)); - FAIL_ON(!check_crtc_eq(&plane_state, 0, 0, 1024, 768)); + const struct drm_check_plane_state_test *params = test->param_value; + struct drm_plane_state *plane_state = test->priv; - return 0; + KUNIT_ASSERT_LT_MSG(test, + drm_atomic_helper_check_plane_state(plane_state, &crtc_state, + params->min_scale, + params->max_scale, + params->can_position, false), + 0, params->msg); +} + +static const struct drm_check_plane_state_test drm_check_plane_state_tests[] = { + { + .name = "clipping_simple", + .msg = "Simple clipping check should pass", + .src = { 0, 0, + 2048 << 16, + 2048 << 16 }, + .crtc = { 0, 0, 2048, 2048 }, + .rotation = DRM_MODE_ROTATE_0, + .min_scale = DRM_PLANE_HELPER_NO_SCALING, + .max_scale = DRM_PLANE_HELPER_NO_SCALING, + .can_position = false, + .src_expected = { 0, 0, 1024 << 16, 768 << 16 }, + .crtc_expected = { 0, 0, 1024, 768 }, + }, + { + .name = "clipping_rotate_reflect", + .msg = "Rotated clipping check should pass", + .src = { 0, 0, + 2048 << 16, + 2048 << 16 }, + .crtc = { 0, 0, 2048, 2048 }, + .rotation = DRM_MODE_ROTATE_90 | DRM_MODE_REFLECT_X, + .min_scale = DRM_PLANE_HELPER_NO_SCALING, + .max_scale = DRM_PLANE_HELPER_NO_SCALING, + .can_position = false, + .src_expected = { 0, 0, 768 << 16, 1024 << 16 }, + .crtc_expected = { 0, 0, 1024, 768 }, + }, + { + .name = "positioning_simple", + .msg = "Simple positioning should work", + .src = { 0, 0, 1023 << 16, 767 << 16 }, + .crtc = { 0, 0, 1023, 767 }, + .rotation = DRM_MODE_ROTATE_0, + .min_scale = DRM_PLANE_HELPER_NO_SCALING, + .max_scale = DRM_PLANE_HELPER_NO_SCALING, + .can_position = true, + .src_expected = { 0, 0, 1023 << 16, 767 << 16 }, + .crtc_expected = { 0, 0, 1023, 767 }, + }, + { + .name = "upscaling", + .msg = "Upscaling exactly 2x should work", + .src = { 0, 0, 512 << 16, 384 << 16 }, + .crtc = { 0, 0, 1024, 768 }, + .rotation = DRM_MODE_ROTATE_0, + .min_scale = 0x8000, + .max_scale = DRM_PLANE_HELPER_NO_SCALING, + .can_position = false, + .src_expected = { 0, 0, 512 << 16, 384 << 16 }, + .crtc_expected = { 0, 0, 1024, 768 }, + }, + { + .name = "downscaling", + .msg = "Should succeed with exact scaling limit", + .src = { 0, 0, 2048 << 16, 1536 << 16 }, + .crtc = { 0, 0, 1024, 768 }, + .rotation = DRM_MODE_ROTATE_0, + .min_scale = DRM_PLANE_HELPER_NO_SCALING, + .max_scale = 0x20000, + .can_position = false, + .src_expected = { 0, 0, 2048 << 16, 1536 << 16 }, + .crtc_expected = { 0, 0, 1024, 768 }, + }, + { + .name = "rounding1", + .msg = "Should succeed by clipping to exact multiple", + .src = { 0, 0, 0x40001, 0x40001 }, + .crtc = { 1022, 766, 4, 4 }, + .rotation = DRM_MODE_ROTATE_0, + .min_scale = DRM_PLANE_HELPER_NO_SCALING, + .max_scale = 0x10001, + .can_position = true, + .src_expected = { 0, 0, 2 << 16, 2 << 16 }, + .crtc_expected = { 1022, 766, 2, 2 }, + }, + { + .name = "rounding2", + .msg = "Should succeed by clipping to exact multiple", + .src = { 0x20001, 0x20001, 0x4040001, 0x3040001 }, + .crtc = { -2, -2, 1028, 772 }, + .rotation = DRM_MODE_ROTATE_0, + .min_scale = DRM_PLANE_HELPER_NO_SCALING, + .max_scale = 0x10001, + .can_position = false, + .src_expected = { 0x40002, 0x40002, 1024 << 16, 768 << 16 }, + .crtc_expected = { 0, 0, 1024, 768 }, + }, + { + .name = "rounding3", + .msg = "Should succeed by clipping to exact multiple", + .src = { 0, 0, 0x3ffff, 0x3ffff }, + .crtc = { 1022, 766, 4, 4 }, + .rotation = DRM_MODE_ROTATE_0, + .min_scale = 0xffff, + .max_scale = DRM_PLANE_HELPER_NO_SCALING, + .can_position = true, + /* Should not be rounded to 0x20001, which would be upscaling. */ + .src_expected = { 0, 0, 2 << 16, 2 << 16 }, + .crtc_expected = { 1022, 766, 2, 2 }, + }, + { + .name = "rounding4", + .msg = "Should succeed by clipping to exact multiple", + .src = { 0x1ffff, 0x1ffff, 0x403ffff, 0x303ffff }, + .crtc = { -2, -2, 1028, 772 }, + .rotation = DRM_MODE_ROTATE_0, + .min_scale = 0xffff, + .max_scale = DRM_PLANE_HELPER_NO_SCALING, + .can_position = false, + .src_expected = { 0x3fffe, 0x3fffe, 1024 << 16, 768 << 16 }, + .crtc_expected = { 0, 0, 1024, 768 }, + }, +}; + +static const struct drm_check_plane_state_test drm_check_invalid_plane_state_tests[] = { + { + .name = "positioning_invalid", + .msg = "Should not be able to position on the crtc with can_position=false", + .src = { 0, 0, 1023 << 16, 767 << 16 }, + .crtc = { 0, 0, 1023, 767 }, + .rotation = DRM_MODE_ROTATE_0, + .min_scale = DRM_PLANE_HELPER_NO_SCALING, + .max_scale = DRM_PLANE_HELPER_NO_SCALING, + .can_position = false, + }, + { + .name = "upscaling_invalid", + .msg = "Upscaling out of range should fail", + .src = { 0, 0, 512 << 16, 384 << 16 }, + .crtc = { 0, 0, 1024, 768 }, + .rotation = DRM_MODE_ROTATE_0, + .min_scale = 0x8001, + .max_scale = DRM_PLANE_HELPER_NO_SCALING, + .can_position = false, + }, + { + .name = "downscaling_invalid", + .msg = "Downscaling out of range should fail", + .src = { 0, 0, 2048 << 16, 1536 << 16 }, + .crtc = { 0, 0, 1024, 768 }, + .rotation = DRM_MODE_ROTATE_0, + .min_scale = DRM_PLANE_HELPER_NO_SCALING, + .max_scale = 0x1ffff, + .can_position = false, + }, +}; + +static void drm_check_plane_state_desc(const struct drm_check_plane_state_test *t, + char *desc) +{ + sprintf(desc, "%s", t->name); } + +KUNIT_ARRAY_PARAM(drm_check_plane_state, drm_check_plane_state_tests, drm_check_plane_state_desc); +KUNIT_ARRAY_PARAM(drm_check_invalid_plane_state, drm_check_invalid_plane_state_tests, + drm_check_plane_state_desc); + +static struct kunit_case drm_plane_helper_tests[] = { + KUNIT_CASE_PARAM(drm_check_plane_state, drm_check_plane_state_gen_params), + KUNIT_CASE_PARAM(drm_check_invalid_plane_state, drm_check_invalid_plane_state_gen_params), + {} +}; + +static struct kunit_suite drm_plane_helper_test_suite = { + .name = "drm_plane_helper_tests", + .init = drm_plane_helper_init, + .test_cases = drm_plane_helper_tests, +}; + +kunit_test_suite(drm_plane_helper_test_suite);