Received: by 2002:a05:7412:f589:b0:e2:908c:2ebd with SMTP id eh9csp316256rdb; Tue, 31 Oct 2023 08:16:35 -0700 (PDT) X-Google-Smtp-Source: AGHT+IGMR/rdC2Tg94lZbh5lKBoQVt5cG7QiccXF3HLeWNI+Q06DMUZGEUPqZiSAWxwuLpL90yoj X-Received: by 2002:a05:6a20:2583:b0:17b:62ae:a8bf with SMTP id k3-20020a056a20258300b0017b62aea8bfmr3169978pzd.30.1698765394898; Tue, 31 Oct 2023 08:16:34 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1698765394; cv=pass; d=google.com; s=arc-20160816; b=GPOeGTHuH1/wuyAz567wHZQg0YtNTLi85W55ljNbvcPC2xyRmC1ydDvax/uPggHV1D imnxk+InWkUBuX6tDtFI0eyZsQHDSc1HxIGs111MjtpIRLVPDQdav48DBjJeLJiWELqQ vSJx3JhBBGD506uzP/fHB/R2NV/moEO2EhGA8t9ruuqDwBiLz1UgwPb/YvIW0Wyki/o3 s0Mr+V5CWgNbQd8I0NrFJ9RjJA0xnSVYeT7dekkoyAj84oMARToD0E6IQquE9UvrjxGM ymaVtJP3GjnHe80TNFh8ApayYgaQcKz614vvYFlX3RaRNLbZpV5JWHG40Jp/Ra0w7oP6 8eaA== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:mime-version:content-transfer-encoding :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature:dkim-signature; bh=bq1M3a6G+OB1G6B3NyueQbcxV6CRHcLbiucsVyjk1WY=; fh=uAcJMD9kKJiex5bNvA2VbDmFtBKN8W4O8bAfYtKCwBM=; b=fLOckh4HQ1sHvI/deb2uKQMLl9/2iUN2yCFfPRmVbFpTZvRSsBbEmWCp67JMmJvKqi 0j8h2SI3P6G6E4AdAcufL9CsyRr5DH1b1u/KfSoOYH45+QwuMpWD0EPX0j8ObUoqhier gQ+igFRgFVc/VMwH7mTU2CVDeFzZH9CblTYwtlQoc58l1aEVxHhVbfOyhmGU4Fo99i0p u1HG2Ke57upBaBz3BN6Cn2TI+6/MlakQT68EE0tJ821c1IshJjZnoZnZe/35JJ8VFN5I /sG91PAu69BNQBthBl26mzJIqvdzYJ79avBa5dDkcEJ2mChfvsAAlDDAFK71e1FBx1Fp iPxA== ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@imgtec.com header.s=dk201812 header.b=L0wKyu2c; dkim=pass header.i=@IMGTecCRM.onmicrosoft.com header.s=selector2-IMGTecCRM-onmicrosoft-com header.b=cXVLCj6x; arc=pass (i=1 spf=pass spfdomain=imgtec.com dkim=pass dkdomain=imgtec.com dmarc=pass fromdomain=imgtec.com); spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:4 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from howler.vger.email (howler.vger.email. [2620:137:e000::3:4]) by mx.google.com with ESMTPS id m189-20020a633fc6000000b0059cd78384fdsi1171905pga.222.2023.10.31.08.16.33 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 31 Oct 2023 08:16:34 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:4 as permitted sender) client-ip=2620:137:e000::3:4; Authentication-Results: mx.google.com; dkim=pass header.i=@imgtec.com header.s=dk201812 header.b=L0wKyu2c; dkim=pass header.i=@IMGTecCRM.onmicrosoft.com header.s=selector2-IMGTecCRM-onmicrosoft-com header.b=cXVLCj6x; arc=pass (i=1 spf=pass spfdomain=imgtec.com dkim=pass dkdomain=imgtec.com dmarc=pass fromdomain=imgtec.com); spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:4 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: from out1.vger.email (depot.vger.email [IPv6:2620:137:e000::3:0]) by howler.vger.email (Postfix) with ESMTP id F3E9C802D476; Tue, 31 Oct 2023 08:15:51 -0700 (PDT) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.10 at howler.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1344756AbjJaPOa (ORCPT + 99 others); Tue, 31 Oct 2023 11:14:30 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51852 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1344673AbjJaPOT (ORCPT ); Tue, 31 Oct 2023 11:14:19 -0400 Received: from mx08-00376f01.pphosted.com (mx08-00376f01.pphosted.com [91.207.212.86]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 81885EA; Tue, 31 Oct 2023 08:14:00 -0700 (PDT) Received: from pps.filterd (m0168888.ppops.net [127.0.0.1]) by mx08-00376f01.pphosted.com (8.17.1.22/8.17.1.22) with ESMTP id 39V7NESV029243; Tue, 31 Oct 2023 15:13:18 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=imgtec.com; h= from:to:cc:subject:date:message-id:in-reply-to:references :content-type:content-transfer-encoding:mime-version; s= dk201812; bh=bq1M3a6G+OB1G6B3NyueQbcxV6CRHcLbiucsVyjk1WY=; b=L0w Kyu2cIzHsHNQyabmdfOLJ1DCM4zVdv3B1XVzEBmOygXFCPBOjYBXa23fcCJuzSJl YnOJhHCf+QuEhS5rTXp8xXzwMTSxB22wf1N7Hfr3e8vamhWPpB/rDqPxtaw2rwhM cEWEkvbLAZ2aA6S6mpsHXD0w7PcL70Q3TsD1vR/1enHY7TI2R7q+Aa6pSC7dD6op 2DRcwJQJfExRue/QJLh9JdwN4Qa2I/xOygH6RptcMdOHQnkv6Z1gROh1cfkToDwr xBZyQyUbkSQA1hFiMjkjAcCSnznSkmCRZkjoh6dA9ox0bAImgul99oBgqYNxOzCq 7Tzny0V2ZkbErHZudNQ== Received: from hhmail05.hh.imgtec.org ([217.156.249.195]) by mx08-00376f01.pphosted.com (PPS) with ESMTPS id 3u0rjntf3w-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT); Tue, 31 Oct 2023 15:13:18 +0000 (GMT) Received: from HHMAIL04.hh.imgtec.org (10.100.10.119) by HHMAIL05.hh.imgtec.org (10.100.10.120) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.34; Tue, 31 Oct 2023 15:13:17 +0000 Received: from GBR01-LO2-obe.outbound.protection.outlook.com (104.47.21.50) by email.imgtec.com (10.100.10.121) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.34 via Frontend Transport; Tue, 31 Oct 2023 15:13:17 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=Z2zNhQ4QglW0k/v1aU4z4fAT1k9UsHIwCZH8Wom/gVOXyKXAV0ebqJXv4/GZoQrnt1vZb3GjbE9jshanBSI79yD83mKq19pbmd7TBlWiRWztQix/k9g/G2QggoceZfs2AKKv45WaXrcqnrSVAOCuANRpSYYcxR7A2egx1nFXEg7ROI58uMjLtfuwzp7TpbRrY1IAmv2Ulqer82fcX1YYRVGeR3idx93o0S1GmwTbi+DcCSyo78KDxb80eUEEOFUVPsbHxEW99/eNO1OterytP4MF2DYxQM6r2vnXvZAJ+HCoUNJhsaEAlZlyiFsyEyE0ZLHm865py7R1ASBas43pOg== 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=bq1M3a6G+OB1G6B3NyueQbcxV6CRHcLbiucsVyjk1WY=; b=a2MVkgYndFQyJqpTbJi7kCp1qapPuruTkWJQKjAfTIfcTAABYt0UV4WVEpm0UxW+DBzXNlffl2uftQS6n5UDiqNQR4gDUOR5CAw8srzQIDIu0bGu5ghl2j5sgrzhDlKh2MRNQGHHF8BRzCEOegv7HJNmyMFZrdO8BKY3ik4knvTPCNK+Xu7mDptEhtBZ1G1vuqNCT3orbNWasDWAXnPyczScE/C5YMQmTf1xqUAR1P5n+RVMITcEENnPxXnBgEjTI9nF0gpueOwDHf6ZnZlbUCBIcju4XxrmbzgYhVLRHNJu+k4FD9GYjk8KVS143ioKU1+Tq29A0iyHhMBEvKG8mA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=imgtec.com; dmarc=pass action=none header.from=imgtec.com; dkim=pass header.d=imgtec.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=IMGTecCRM.onmicrosoft.com; s=selector2-IMGTecCRM-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=bq1M3a6G+OB1G6B3NyueQbcxV6CRHcLbiucsVyjk1WY=; b=cXVLCj6xYU34ND9lvJp4e097VjeQzsf3muP+RD5lRZnpNb/+VBwT2kSanX3y3TAIApSeDjlv1Sp4LdGREFXHnYB7Jonj/s1NRkXkAM51TG5AIIhlsC3Quy2XMma9z40ZGOI0A9x6XAJUyDWs9cbuR4rTLrV9Gjh1LkiNSi0VQd4= Received: from CWLP265MB4817.GBRP265.PROD.OUTLOOK.COM (2603:10a6:400:170::9) by CWLP265MB2018.GBRP265.PROD.OUTLOOK.COM (2603:10a6:400:6a::10) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6933.25; Tue, 31 Oct 2023 15:13:15 +0000 Received: from CWLP265MB4817.GBRP265.PROD.OUTLOOK.COM ([fe80::eef1:bccc:508d:e086]) by CWLP265MB4817.GBRP265.PROD.OUTLOOK.COM ([fe80::eef1:bccc:508d:e086%5]) with mapi id 15.20.6933.029; Tue, 31 Oct 2023 15:13:15 +0000 From: Sarah Walker To: CC: , , , , , , , , , , , , , , , , , , , , , , Matt Coster Subject: [PATCH v8 05/20] drm/imagination: Add skeleton PowerVR driver Date: Tue, 31 Oct 2023 15:12:42 +0000 Message-Id: <20231031151257.90350-6-sarah.walker@imgtec.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20231031151257.90350-1-sarah.walker@imgtec.com> References: <20231031151257.90350-1-sarah.walker@imgtec.com> Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-ClientProxiedBy: LO4P123CA0301.GBRP123.PROD.OUTLOOK.COM (2603:10a6:600:196::18) To CWLP265MB4817.GBRP265.PROD.OUTLOOK.COM (2603:10a6:400:170::9) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: CWLP265MB4817:EE_|CWLP265MB2018:EE_ X-MS-Office365-Filtering-Correlation-Id: 7d0faf85-0907-48f3-629a-08dbda23e7fc X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: zNCNIunS6ynUitvPSA7HacdJVpkhQgNoh5RwJvlwRRROVaKA/cYUcnpZV1BD1+FT0VqJGZSQZgYvs0Ux9H9r/c28zwrU6v3cSra613+wmTEx8v8gwcQ2DTN9SgVeF2foe5gHdNgvM2tOiaykowN8SoMWkWeRmf4Hu2cPtnPdz0UhD/nPQ0xuWLPZy25GILupKajuttNrXAMqPlZy+nyYlOKYwGb0fw3NYaHFUKKG34v9/R4FGp2yiiIREboXuTZnMTxMTxloip5z6D4qf+O6qYomSIYHdFgwh915uI+lKtzaw/nUO/6g5Mk/U6ifZpN9nDbdJ3+2U+x3FsX7cJ2nQOPlKq21fG+0CKWtNyG23oF7mxG7TyVEL9ivWwMTPuN/YW22olzdSiiNavJ6np0RGkpj+RiyqtxDfDQsqgy3PFGyIQ2XphwBMVEXfcDf96iPMYB4XUagyYcws3E/W1SWtlwBclfWQVv0Ece+QIqR01aYoPUApyKQxXy/mGr9pqyJA3wRz0qdAHM6G6MfJwTGbkbyvUQ+Mlvbx5RqNjQno8zXCzEjkpHFSHgGER781NdGtu4g3Qeox0u3U26pfRwszAKi1k5U+yWYMQr/T57wSLnMv6CdYIoaFT2e2xNDLOTW X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:CWLP265MB4817.GBRP265.PROD.OUTLOOK.COM;PTR:;CAT:NONE;SFS:(13230031)(136003)(376002)(366004)(39850400004)(346002)(396003)(230922051799003)(64100799003)(1800799009)(186009)(451199024)(2906002)(30864003)(7416002)(41300700001)(5660300002)(44832011)(8676002)(4326008)(8936002)(38350700005)(36756003)(86362001)(38100700002)(107886003)(1076003)(316002)(6916009)(66946007)(66476007)(66556008)(2616005)(83380400001)(478600001)(6666004)(26005)(6512007)(6506007)(52116002)(6486002);DIR:OUT;SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?utf-8?B?VmpuSmhlYnVMNFhCZXhKa25lYTdWemk0amJ5UGtwMFYvQktmN0R4b3l6aGhz?= =?utf-8?B?WmZJMGpEckZYN2VsdmhQYXVWZSsySHFXdDkzN25iN3Q5dVpQM0ZsMlR3SDVZ?= =?utf-8?B?WFJRb1BrSTRWVnFZcU9KbW9yWC9QOFZZbzBESEFJWHBUK01DT0x6MXVTK3Yx?= =?utf-8?B?S0E5L0cwVGQ1ZVN3ajFyYkJhMElrSHNVOTVVMFpKaG40MTZhNThJRmpZV3Bl?= =?utf-8?B?VFlIamEvU1NGR1F1MjM0aXdycEZabG53ZkNhVTFBZVRub3VaWXVZTjIwdmdZ?= =?utf-8?B?TXdkencyT2ZLcUs0NFdYQ0wyVHlCRjhMQVIvZEpTV1UreXFseFhQVkx3c05u?= =?utf-8?B?amZSLzlrNkVZb1FrNGMwaEthcnpzek1FeG1PS21JbEt5VTlrN3NyckhzV2ZO?= =?utf-8?B?VmtSb1lKaUJaSHlhZExnQ0xvY1VuSUxQZDFmTHU3RWZpV1pHeXFjanQ0UGZB?= =?utf-8?B?Zno2SVJ1Yy9kUEIrYXNma2VSOWNBQUFpZFJnOUFCRUhpK2syU0FabjBoL1ZH?= =?utf-8?B?Y2g4RzRZTzN1TFlPd0paQ2Q2TlZwTjBpWkFvVEJ5d3NPV0ZYUC9Mb2syamtk?= =?utf-8?B?aEx4cFhlSlN3cWZhNjZNdU9IVkZlRUFzNUZ0cVlMWVJYL3BEenVocDdtalM1?= =?utf-8?B?bGhhU3FSOE1yMm42ZXBGT0FUMkF5MzBSOXNCWThISmdMcllQY0kvTEUwTGtE?= =?utf-8?B?Rnl6WXNyTjVpWDNuSS9xN2hGZFhsdWVqUWNxRFZKN3RxeVJjN0ZnbDNxcW95?= =?utf-8?B?cVNmRG5UN2FxOFZZU2Jnb0Q5OGt1MTJQbm9MdmgvSnpRaUp4dzFEbEdWQ1F0?= =?utf-8?B?UzNLVjIrWS9XV3VmRjdzbUp3T29SRlVUQmlWaGFZYytOLzIrNWFpVU1wRGtJ?= =?utf-8?B?ejBWTmZJQjFydnBJUlI0cndnazdDb1E4YmxINWlORklZZEd3RGpFanhYVkU0?= =?utf-8?B?MTNMNDZKY1lzSytkQklacDYzaE9uMEIyajhtcS9SMnc0S3BMdE43ZlpkNHkv?= =?utf-8?B?ZXlmS2NYc1NVSHUwU1Q0K0xZTWRKZ014M21KUm5xYlAyTVpGM1JzVGdTZXdK?= =?utf-8?B?YVJSSHJQWTA2bEl4c1dxZ0ZKVytNbGxFdkJoMXEycUZCeHR6RzdqcXVJaUNP?= =?utf-8?B?QVVPTlJlV1NGcGx4NFNpT1F1WmwzbS92MDhSS2trQ2IvRTg4VVp6WWtWcCtB?= =?utf-8?B?NUZRZEU2T20wZzhxeWtEbDMzcWJZaWx3ZldHVVVXaHR1aGJlbWxvVFV3aFpL?= =?utf-8?B?UHRkMDJFalNiaU9kajAvUUFYRnJsMDhzRlF5QmhLeE9DOU4zeXkxT2g4emRi?= =?utf-8?B?NVhCK2dUTzl4YVpoRDVVSG0wMmQza3NDcnQzU3piR2NocFdXTUxWcEcwNVlI?= =?utf-8?B?K2M5VERDc1BOUUIvOFc4YlFEUm1ReUptSFI4R1Uyd29TVnptMUFNRGZxeTdn?= =?utf-8?B?Vm55L0VzMUp5dTUvSzE3UGg3eUNpYml2VUdjcStPN3ZCU3kzVGJKWDBEUXNz?= =?utf-8?B?T0VXT2sxdkVHUDBYbUVuVjQ4RHhWT0t6T3dQR2IwVGxULzJQNVplVER2U0ZN?= =?utf-8?B?cHpLeVR5UkZtbFNBdGVvNHJ2OHBZTGkxQ05Wa0RzL0ppVTJ3Vy9Db2hUYk1y?= =?utf-8?B?WHFSUUZOVXBoWkY4QXRsa1cvb05jUU40cnZOS09YVGtseTk3T0NHRHRVV1J3?= =?utf-8?B?TjAyMUxGckZUZDljWUFFNHZsQVVycnZtQld4MENWcWM1dDQ2ckxhOUNmN1RS?= =?utf-8?B?NkVjMlpSaFAxZG9sRUdlcGNkMW1EVWVTOStFaDFWRmxWc1JHNDhNRjRGU3Rl?= =?utf-8?B?WGVIY2Y0MExqOTRpYXR4WW11dDFFWktFTzFWc0RKUnI4K2ptWk9Nc0I4bFdu?= =?utf-8?B?MDRjd1ppZDZQa0FQTXJLamNyeEx0cG5KMjE5SXVnVTRQRWtidFRManZ4TWtF?= =?utf-8?B?OENtRkRFWjNYakE1b3VOU1F0dE9DQ2ZYblNpSVVYZEZSUjlIMWJ0MWc3VmNk?= =?utf-8?B?TVJrWG1hM2VkUE9RSXRTSHVGZElpV0owbW9hREpnN3FzTHV1bTRmM2xYU0Iw?= =?utf-8?B?RXdMclhTa0gxU3dQYXdGRlNoVzhCcFNsUlFIRnVwd285c3hyamVZUUYxSVBV?= =?utf-8?B?VjIrZm9xQWVPbUNUemlFTXJXaXhyOGpVV3I0RmladGZadWpQa0FUUkZ6TGY1?= =?utf-8?B?enc9PQ==?= X-MS-Exchange-CrossTenant-Network-Message-Id: 7d0faf85-0907-48f3-629a-08dbda23e7fc X-MS-Exchange-CrossTenant-AuthSource: CWLP265MB4817.GBRP265.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 31 Oct 2023 15:13:15.5336 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 0d5fd8bb-e8c2-4e0a-8dd5-2c264f7140fe X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: 9fLF4+EcFRTJbkyqyh+8P03KIef9J7S7vr867pSsHqjF/Zpl+K3qaB4Dkqh0BKRCaalLKfFzgi/lVRiwRRc+/A== X-MS-Exchange-Transport-CrossTenantHeadersStamped: CWLP265MB2018 X-OriginatorOrg: imgtec.com X-EXCLAIMER-MD-CONFIG: 15a78312-3e47-46eb-9010-2e54d84a9631 X-Proofpoint-GUID: D_VDEiUXIRVq6gFjnoB5BKQQ5amWgdug X-Proofpoint-ORIG-GUID: D_VDEiUXIRVq6gFjnoB5BKQQ5amWgdug X-Spam-Status: No, score=-0.9 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI, SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on howler.vger.email Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (howler.vger.email [0.0.0.0]); Tue, 31 Oct 2023 08:15:52 -0700 (PDT) This adds the basic skeleton of the driver. The driver registers itself with DRM on probe. Ioctl handlers are currently implemented as stubs. Changes since v5: - Update compatible string & description to match marketing name - Checkpatch fixes in to/from_pvr_device/file macros Changes since v3: - Clarify supported GPU generations in driver description - Use drm_dev_unplug() when removing device - Change from_* and to_* functions to macros - Fix IS_PTR/PTR_ERR confusion in pvr_probe() - Remove err_out labels in favour of direct returning - Remove specific am62 compatible match string - Drop MODULE_FIRMWARE() Co-developed-by: Frank Binns Signed-off-by: Frank Binns Co-developed-by: Matt Coster Signed-off-by: Matt Coster Signed-off-by: Sarah Walker Reviewed-by: Maxime Ripard --- MAINTAINERS | 1 + drivers/gpu/drm/Kconfig | 2 + drivers/gpu/drm/Makefile | 1 + drivers/gpu/drm/imagination/Kconfig | 15 + drivers/gpu/drm/imagination/Makefile | 9 + drivers/gpu/drm/imagination/pvr_device.h | 153 +++++++ drivers/gpu/drm/imagination/pvr_drv.c | 509 +++++++++++++++++++++++ drivers/gpu/drm/imagination/pvr_drv.h | 22 + 8 files changed, 712 insertions(+) create mode 100644 drivers/gpu/drm/imagination/Kconfig create mode 100644 drivers/gpu/drm/imagination/Makefile create mode 100644 drivers/gpu/drm/imagination/pvr_device.h create mode 100644 drivers/gpu/drm/imagination/pvr_drv.c create mode 100644 drivers/gpu/drm/imagination/pvr_drv.h diff --git a/MAINTAINERS b/MAINTAINERS index bef1ac7ed647..8166ffd4349e 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -10265,6 +10265,7 @@ M: Frank Binns M: Donald Robson S: Supported F: Documentation/devicetree/bindings/gpu/img,powervr.yaml +F: drivers/gpu/drm/imagination/ F: include/uapi/drm/pvr_drm.h IMON SOUNDGRAPH USB IR RECEIVER diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index 3eee8636f847..7fc72d994782 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig @@ -394,6 +394,8 @@ source "drivers/gpu/drm/solomon/Kconfig" source "drivers/gpu/drm/sprd/Kconfig" +source "drivers/gpu/drm/imagination/Kconfig" + config DRM_HYPERV tristate "DRM Support for Hyper-V synthetic video device" depends on DRM && PCI && MMU && HYPERV diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile index 8e1bde059170..d236103e3361 100644 --- a/drivers/gpu/drm/Makefile +++ b/drivers/gpu/drm/Makefile @@ -198,3 +198,4 @@ obj-$(CONFIG_DRM_HYPERV) += hyperv/ obj-y += solomon/ obj-$(CONFIG_DRM_SPRD) += sprd/ obj-$(CONFIG_DRM_LOONGSON) += loongson/ +obj-$(CONFIG_DRM_POWERVR) += imagination/ diff --git a/drivers/gpu/drm/imagination/Kconfig b/drivers/gpu/drm/imagination/Kconfig new file mode 100644 index 000000000000..e9aaa5313485 --- /dev/null +++ b/drivers/gpu/drm/imagination/Kconfig @@ -0,0 +1,15 @@ +# SPDX-License-Identifier: GPL-2.0 OR MIT +# Copyright (c) 2023 Imagination Technologies Ltd. + +config DRM_POWERVR + tristate "Imagination Technologies PowerVR (Series 6 and later) & IMG Graphics" + depends on ARM64 + depends on DRM + select DRM_GEM_SHMEM_HELPER + select DRM_SCHED + select FW_LOADER + help + Choose this option if you have a system that has an Imagination + Technologies PowerVR (Series 6 or later) or IMG GPU. + + If "M" is selected, the module will be called powervr. diff --git a/drivers/gpu/drm/imagination/Makefile b/drivers/gpu/drm/imagination/Makefile new file mode 100644 index 000000000000..19b40c2d7356 --- /dev/null +++ b/drivers/gpu/drm/imagination/Makefile @@ -0,0 +1,9 @@ +# SPDX-License-Identifier: GPL-2.0 OR MIT +# Copyright (c) 2023 Imagination Technologies Ltd. + +subdir-ccflags-y := -I$(srctree)/$(src) + +powervr-y := \ + pvr_drv.o \ + +obj-$(CONFIG_DRM_POWERVR) += powervr.o diff --git a/drivers/gpu/drm/imagination/pvr_device.h b/drivers/gpu/drm/imagination/pvr_device.h new file mode 100644 index 000000000000..53b1cdb5a6a6 --- /dev/null +++ b/drivers/gpu/drm/imagination/pvr_device.h @@ -0,0 +1,153 @@ +/* SPDX-License-Identifier: GPL-2.0 OR MIT */ +/* Copyright (c) 2023 Imagination Technologies Ltd. */ + +#ifndef PVR_DEVICE_H +#define PVR_DEVICE_H + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +/** + * struct pvr_device - powervr-specific wrapper for &struct drm_device + */ +struct pvr_device { + /** + * @base: The underlying &struct drm_device. + * + * Do not access this member directly, instead call + * from_pvr_device(). + */ + struct drm_device base; +}; + +/** + * struct pvr_file - powervr-specific data to be assigned to &struct + * drm_file.driver_priv + */ +struct pvr_file { + /** + * @file: A reference to the parent &struct drm_file. + * + * Do not access this member directly, instead call from_pvr_file(). + */ + struct drm_file *file; + + /** + * @pvr_dev: A reference to the powervr-specific wrapper for the + * associated device. Saves on repeated calls to + * to_pvr_device(). + */ + struct pvr_device *pvr_dev; +}; + +#define from_pvr_device(pvr_dev) (&(pvr_dev)->base) + +#define to_pvr_device(drm_dev) container_of_const(drm_dev, struct pvr_device, base) + +#define from_pvr_file(pvr_file) ((pvr_file)->file) + +#define to_pvr_file(file) ((file)->driver_priv) + +/** + * DOC: IOCTL validation helpers + * + * To validate the constraints imposed on IOCTL argument structs, a collection + * of macros and helper functions exist in ``pvr_device.h``. + * + * Of the current helpers, it should only be necessary to call + * PVR_IOCTL_UNION_PADDING_CHECK() directly. This macro should be used once in + * every code path which extracts a union member from a struct passed from + * userspace. + */ + +/** + * pvr_ioctl_union_padding_check() - Validate that the implicit padding between + * the end of a union member and the end of the union itself is zeroed. + * @instance: Pointer to the instance of the struct to validate. + * @union_offset: Offset into the type of @instance of the target union. Must + * be 64-bit aligned. + * @union_size: Size of the target union in the type of @instance. Must be + * 64-bit aligned. + * @member_size: Size of the target member in the target union specified by + * @union_offset and @union_size. It is assumed that the offset of the target + * member is zero relative to @union_offset. Must be 64-bit aligned. + * + * You probably want to use PVR_IOCTL_UNION_PADDING_CHECK() instead of calling + * this function directly, since that macro abstracts away much of the setup, + * and also provides some static validation. See its docs for details. + * + * Return: + * * %true if every byte between the end of the used member of the union and + * the end of that union is zeroed, or + * * %false otherwise. + */ +static __always_inline bool +pvr_ioctl_union_padding_check(void *instance, size_t union_offset, + size_t union_size, size_t member_size) +{ + /* + * void pointer arithmetic is technically illegal - cast to a byte + * pointer so this addition works safely. + */ + void *padding_start = ((u8 *)instance) + union_offset + member_size; + size_t padding_size = union_size - member_size; + + return !memchr_inv(padding_start, 0, padding_size); +} + +/** + * PVR_STATIC_ASSERT_64BIT_ALIGNED() - Inline assertion for 64-bit alignment. + * @static_expr_: Target expression to evaluate. + * + * If @static_expr_ does not evaluate to a constant integer which would be a + * 64-bit aligned address (i.e. a multiple of 8), compilation will fail. + * + * Return: + * The value of @static_expr_. + */ +#define PVR_STATIC_ASSERT_64BIT_ALIGNED(static_expr_) \ + ({ \ + static_assert(((static_expr_) & (sizeof(u64) - 1)) == 0); \ + (static_expr_); \ + }) + +/** + * PVR_IOCTL_UNION_PADDING_CHECK() - Validate that the implicit padding between + * the end of a union member and the end of the union itself is zeroed. + * @struct_instance_: An expression which evaluates to a pointer to a UAPI data + * struct. + * @union_: The name of the union member of @struct_instance_ to check. If the + * union member is nested within the type of @struct_instance_, this may + * contain the member access operator ("."). + * @member_: The name of the member of @union_ to assess. + * + * This is a wrapper around pvr_ioctl_union_padding_check() which performs + * alignment checks and simplifies things for the caller. + * + * Return: + * * %true if every byte in @struct_instance_ between the end of @member_ and + * the end of @union_ is zeroed, or + * * %false otherwise. + */ +#define PVR_IOCTL_UNION_PADDING_CHECK(struct_instance_, union_, member_) \ + ({ \ + typeof(struct_instance_) __instance = (struct_instance_); \ + size_t __union_offset = PVR_STATIC_ASSERT_64BIT_ALIGNED( \ + offsetof(typeof(*__instance), union_)); \ + size_t __union_size = PVR_STATIC_ASSERT_64BIT_ALIGNED( \ + sizeof(__instance->union_)); \ + size_t __member_size = PVR_STATIC_ASSERT_64BIT_ALIGNED( \ + sizeof(__instance->union_.member_)); \ + pvr_ioctl_union_padding_check(__instance, __union_offset, \ + __union_size, __member_size); \ + }) + +#endif /* PVR_DEVICE_H */ diff --git a/drivers/gpu/drm/imagination/pvr_drv.c b/drivers/gpu/drm/imagination/pvr_drv.c new file mode 100644 index 000000000000..a23bef62b52b --- /dev/null +++ b/drivers/gpu/drm/imagination/pvr_drv.c @@ -0,0 +1,509 @@ +// SPDX-License-Identifier: GPL-2.0 OR MIT +/* Copyright (c) 2023 Imagination Technologies Ltd. */ + +#include "pvr_device.h" +#include "pvr_drv.h" + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/** + * DOC: PowerVR (Series 6 and later) and IMG Graphics Driver + * + * This driver supports the following PowerVR/IMG graphics cores from Imagination Technologies: + * + * * AXE-1-16M (found in Texas Instruments AM62) + */ + +/** + * pvr_ioctl_create_bo() - IOCTL to create a GEM buffer object. + * @drm_dev: [IN] Target DRM device. + * @raw_args: [IN/OUT] Arguments passed to this IOCTL. This must be of type + * &struct drm_pvr_ioctl_create_bo_args. + * @file: [IN] DRM file-private data. + * + * Called from userspace with %DRM_IOCTL_PVR_CREATE_BO. + * + * Return: + * * 0 on success, + * * -%EINVAL if the value of &drm_pvr_ioctl_create_bo_args.size is zero + * or wider than &typedef size_t, + * * -%EINVAL if any bits in &drm_pvr_ioctl_create_bo_args.flags that are + * reserved or undefined are set, + * * -%EINVAL if any padding fields in &drm_pvr_ioctl_create_bo_args are not + * zero, + * * Any error encountered while creating the object (see + * pvr_gem_object_create()), or + * * Any error encountered while transferring ownership of the object into a + * userspace-accessible handle (see pvr_gem_object_into_handle()). + */ +static int +pvr_ioctl_create_bo(struct drm_device *drm_dev, void *raw_args, + struct drm_file *file) +{ + return -ENOTTY; +} + +/** + * pvr_ioctl_get_bo_mmap_offset() - IOCTL to generate a "fake" offset to be + * used when calling mmap() from userspace to map the given GEM buffer object + * @drm_dev: [IN] DRM device (unused). + * @raw_args: [IN/OUT] Arguments passed to this IOCTL. This must be of type + * &struct drm_pvr_ioctl_get_bo_mmap_offset_args. + * @file: [IN] DRM file private data. + * + * Called from userspace with %DRM_IOCTL_PVR_GET_BO_MMAP_OFFSET. + * + * This IOCTL does *not* perform an mmap. See the docs on + * &struct drm_pvr_ioctl_get_bo_mmap_offset_args for details. + * + * Return: + * * 0 on success, + * * -%ENOENT if the handle does not reference a valid GEM buffer object, + * * -%EINVAL if any padding fields in &struct + * drm_pvr_ioctl_get_bo_mmap_offset_args are not zero, or + * * Any error returned by drm_gem_create_mmap_offset(). + */ +static int +pvr_ioctl_get_bo_mmap_offset(struct drm_device *drm_dev, void *raw_args, + struct drm_file *file) +{ + return -ENOTTY; +} + +/** + * pvr_ioctl_dev_query() - IOCTL to copy information about a device + * @drm_dev: [IN] DRM device. + * @raw_args: [IN/OUT] Arguments passed to this IOCTL. This must be of type + * &struct drm_pvr_ioctl_dev_query_args. + * @file: [IN] DRM file private data. + * + * Called from userspace with %DRM_IOCTL_PVR_DEV_QUERY. + * If the given receiving struct pointer is NULL, or the indicated size is too + * small, the expected size of the struct type will be returned in the size + * argument field. + * + * Return: + * * 0 on success or when fetching the size with args->pointer == NULL, or + * * -%E2BIG if the indicated size of the receiving struct is less than is + * required to contain the copied data, or + * * -%EINVAL if the indicated struct type is unknown, or + * * -%ENOMEM if local memory could not be allocated, or + * * -%EFAULT if local memory could not be copied to userspace. + */ +static int +pvr_ioctl_dev_query(struct drm_device *drm_dev, void *raw_args, + struct drm_file *file) +{ + return -ENOTTY; +} + +/** + * pvr_ioctl_create_context() - IOCTL to create a context + * @drm_dev: [IN] DRM device. + * @raw_args: [IN/OUT] Arguments passed to this IOCTL. This must be of type + * &struct drm_pvr_ioctl_create_context_args. + * @file: [IN] DRM file private data. + * + * Called from userspace with %DRM_IOCTL_PVR_CREATE_CONTEXT. + * + * Return: + * * 0 on success, or + * * -%EINVAL if provided arguments are invalid, or + * * -%EFAULT if arguments can't be copied from userspace, or + * * Any error returned by pvr_create_render_context(). + */ +static int +pvr_ioctl_create_context(struct drm_device *drm_dev, void *raw_args, + struct drm_file *file) +{ + return -ENOTTY; +} + +/** + * pvr_ioctl_destroy_context() - IOCTL to destroy a context + * @drm_dev: [IN] DRM device. + * @raw_args: [IN/OUT] Arguments passed to this IOCTL. This must be of type + * &struct drm_pvr_ioctl_destroy_context_args. + * @file: [IN] DRM file private data. + * + * Called from userspace with %DRM_IOCTL_PVR_DESTROY_CONTEXT. + * + * Return: + * * 0 on success, or + * * -%EINVAL if context not in context list. + */ +static int +pvr_ioctl_destroy_context(struct drm_device *drm_dev, void *raw_args, + struct drm_file *file) +{ + return -ENOTTY; +} + +/** + * pvr_ioctl_create_free_list() - IOCTL to create a free list + * @drm_dev: [IN] DRM device. + * @raw_args: [IN/OUT] Arguments passed to this IOCTL. This must be of type + * &struct drm_pvr_ioctl_create_free_list_args. + * @file: [IN] DRM file private data. + * + * Called from userspace with %DRM_IOCTL_PVR_CREATE_FREE_LIST. + * + * Return: + * * 0 on success, or + * * Any error returned by pvr_free_list_create(). + */ +static int +pvr_ioctl_create_free_list(struct drm_device *drm_dev, void *raw_args, + struct drm_file *file) +{ + return -ENOTTY; +} + +/** + * pvr_ioctl_destroy_free_list() - IOCTL to destroy a free list + * @drm_dev: [IN] DRM device. + * @raw_args: [IN] Arguments passed to this IOCTL. This must be of type + * &struct drm_pvr_ioctl_destroy_free_list_args. + * @file: [IN] DRM file private data. + * + * Called from userspace with %DRM_IOCTL_PVR_DESTROY_FREE_LIST. + * + * Return: + * * 0 on success, or + * * -%EINVAL if free list not in object list. + */ +static int +pvr_ioctl_destroy_free_list(struct drm_device *drm_dev, void *raw_args, + struct drm_file *file) +{ + return -ENOTTY; +} + +/** + * pvr_ioctl_create_hwrt_dataset() - IOCTL to create a HWRT dataset + * @drm_dev: [IN] DRM device. + * @raw_args: [IN/OUT] Arguments passed to this IOCTL. This must be of type + * &struct drm_pvr_ioctl_create_hwrt_dataset_args. + * @file: [IN] DRM file private data. + * + * Called from userspace with %DRM_IOCTL_PVR_CREATE_HWRT_DATASET. + * + * Return: + * * 0 on success, or + * * Any error returned by pvr_hwrt_dataset_create(). + */ +static int +pvr_ioctl_create_hwrt_dataset(struct drm_device *drm_dev, void *raw_args, + struct drm_file *file) +{ + return -ENOTTY; +} + +/** + * pvr_ioctl_destroy_hwrt_dataset() - IOCTL to destroy a HWRT dataset + * @drm_dev: [IN] DRM device. + * @raw_args: [IN] Arguments passed to this IOCTL. This must be of type + * &struct drm_pvr_ioctl_destroy_hwrt_dataset_args. + * @file: [IN] DRM file private data. + * + * Called from userspace with %DRM_IOCTL_PVR_DESTROY_HWRT_DATASET. + * + * Return: + * * 0 on success, or + * * -%EINVAL if HWRT dataset not in object list. + */ +static int +pvr_ioctl_destroy_hwrt_dataset(struct drm_device *drm_dev, void *raw_args, + struct drm_file *file) +{ + return -ENOTTY; +} + +/** + * pvr_ioctl_create_vm_context() - IOCTL to create a VM context + * @drm_dev: [IN] DRM device. + * @raw_args: [IN/OUT] Arguments passed to this IOCTL. This must be of type + * &struct drm_pvr_ioctl_create_vm_context_args. + * @file: [IN] DRM file private data. + * + * Called from userspace with %DRM_IOCTL_PVR_CREATE_VM_CONTEXT. + * + * Return: + * * 0 on success, or + * * Any error returned by pvr_vm_create_context(). + */ +static int +pvr_ioctl_create_vm_context(struct drm_device *drm_dev, void *raw_args, + struct drm_file *file) +{ + return -ENOTTY; +} + +/** + * pvr_ioctl_destroy_vm_context() - IOCTL to destroy a VM context +* @drm_dev: [IN] DRM device. +* @raw_args: [IN] Arguments passed to this IOCTL. This must be of type +* &struct drm_pvr_ioctl_destroy_vm_context_args. +* @file: [IN] DRM file private data. +* +* Called from userspace with %DRM_IOCTL_PVR_DESTROY_VM_CONTEXT. +* +* Return: +* * 0 on success, or +* * -%EINVAL if object not in object list. + */ +static int +pvr_ioctl_destroy_vm_context(struct drm_device *drm_dev, void *raw_args, + struct drm_file *file) +{ + return -ENOTTY; +} + +/** + * pvr_ioctl_vm_map() - IOCTL to map buffer to GPU address space. + * @drm_dev: [IN] DRM device. + * @raw_args: [IN] Arguments passed to this IOCTL. This must be of type + * &struct drm_pvr_ioctl_vm_map_args. + * @file: [IN] DRM file private data. + * + * Called from userspace with %DRM_IOCTL_PVR_VM_MAP. + * + * Return: + * * 0 on success, + * * -%EINVAL if &drm_pvr_ioctl_vm_op_map_args.flags is not zero, + * * -%EINVAL if the bounds specified by &drm_pvr_ioctl_vm_op_map_args.offset + * and &drm_pvr_ioctl_vm_op_map_args.size are not valid or do not fall + * within the buffer object specified by + * &drm_pvr_ioctl_vm_op_map_args.handle, + * * -%EINVAL if the bounds specified by + * &drm_pvr_ioctl_vm_op_map_args.device_addr and + * &drm_pvr_ioctl_vm_op_map_args.size do not form a valid device-virtual + * address range which falls entirely within a single heap, or + * * -%ENOENT if &drm_pvr_ioctl_vm_op_map_args.handle does not refer to a + * valid PowerVR buffer object. + */ +static int +pvr_ioctl_vm_map(struct drm_device *drm_dev, void *raw_args, + struct drm_file *file) +{ + return -ENOTTY; +} + +/** + * pvr_ioctl_vm_unmap() - IOCTL to unmap buffer from GPU address space. + * @drm_dev: [IN] DRM device. + * @raw_args: [IN] Arguments passed to this IOCTL. This must be of type + * &struct drm_pvr_ioctl_vm_unmap_args. + * @file: [IN] DRM file private data. + * + * Called from userspace with %DRM_IOCTL_PVR_VM_UNMAP. + * + * Return: + * * 0 on success, + * * -%EINVAL if &drm_pvr_ioctl_vm_op_unmap_args.device_addr is not a valid + * device page-aligned device-virtual address, or + * * -%ENOENT if there is currently no PowerVR buffer object mapped at + * &drm_pvr_ioctl_vm_op_unmap_args.device_addr. + */ +static int +pvr_ioctl_vm_unmap(struct drm_device *drm_dev, void *raw_args, + struct drm_file *file) +{ + return -ENOTTY; +} + +/* + * pvr_ioctl_submit_job() - IOCTL to submit a job to the GPU + * @drm_dev: [IN] DRM device. + * @raw_args: [IN] Arguments passed to this IOCTL. This must be of type + * &struct drm_pvr_ioctl_submit_job_args. + * @file: [IN] DRM file private data. + * + * Called from userspace with %DRM_IOCTL_PVR_SUBMIT_JOB. + * + * Return: + * * 0 on success, or + * * -%EINVAL if arguments are invalid. + */ +static int +pvr_ioctl_submit_jobs(struct drm_device *drm_dev, void *raw_args, + struct drm_file *file) +{ + return -ENOTTY; +} + +#define DRM_PVR_IOCTL(_name, _func, _flags) \ + DRM_IOCTL_DEF_DRV(PVR_##_name, pvr_ioctl_##_func, _flags) + +/* clang-format off */ + +static const struct drm_ioctl_desc pvr_drm_driver_ioctls[] = { + DRM_PVR_IOCTL(DEV_QUERY, dev_query, DRM_RENDER_ALLOW), + DRM_PVR_IOCTL(CREATE_BO, create_bo, DRM_RENDER_ALLOW), + DRM_PVR_IOCTL(GET_BO_MMAP_OFFSET, get_bo_mmap_offset, DRM_RENDER_ALLOW), + DRM_PVR_IOCTL(CREATE_VM_CONTEXT, create_vm_context, DRM_RENDER_ALLOW), + DRM_PVR_IOCTL(DESTROY_VM_CONTEXT, destroy_vm_context, DRM_RENDER_ALLOW), + DRM_PVR_IOCTL(VM_MAP, vm_map, DRM_RENDER_ALLOW), + DRM_PVR_IOCTL(VM_UNMAP, vm_unmap, DRM_RENDER_ALLOW), + DRM_PVR_IOCTL(CREATE_CONTEXT, create_context, DRM_RENDER_ALLOW), + DRM_PVR_IOCTL(DESTROY_CONTEXT, destroy_context, DRM_RENDER_ALLOW), + DRM_PVR_IOCTL(CREATE_FREE_LIST, create_free_list, DRM_RENDER_ALLOW), + DRM_PVR_IOCTL(DESTROY_FREE_LIST, destroy_free_list, DRM_RENDER_ALLOW), + DRM_PVR_IOCTL(CREATE_HWRT_DATASET, create_hwrt_dataset, DRM_RENDER_ALLOW), + DRM_PVR_IOCTL(DESTROY_HWRT_DATASET, destroy_hwrt_dataset, DRM_RENDER_ALLOW), + DRM_PVR_IOCTL(SUBMIT_JOBS, submit_jobs, DRM_RENDER_ALLOW), +}; + +/* clang-format on */ + +#undef DRM_PVR_IOCTL + +/** + * pvr_drm_driver_open() - Driver callback when a new &struct drm_file is opened + * @drm_dev: [IN] DRM device. + * @file: [IN] DRM file private data. + * + * Allocates powervr-specific file private data (&struct pvr_file). + * + * Registered in &pvr_drm_driver. + * + * Return: + * * 0 on success, + * * -%ENOMEM if the allocation of a &struct ipvr_file fails, or + * * Any error returned by pvr_memory_context_init(). + */ +static int +pvr_drm_driver_open(struct drm_device *drm_dev, struct drm_file *file) +{ + struct pvr_device *pvr_dev = to_pvr_device(drm_dev); + struct pvr_file *pvr_file; + + pvr_file = kzalloc(sizeof(*pvr_file), GFP_KERNEL); + if (!pvr_file) + return -ENOMEM; + + /* + * Store reference to base DRM file private data for use by + * from_pvr_file. + */ + pvr_file->file = file; + + /* + * Store reference to powervr-specific outer device struct in file + * private data for convenient access. + */ + pvr_file->pvr_dev = pvr_dev; + + /* + * Store reference to powervr-specific file private data in DRM file + * private data. + */ + file->driver_priv = pvr_file; + + return 0; +} + +/** + * pvr_drm_driver_postclose() - One of the driver callbacks when a &struct + * drm_file is closed. + * @drm_dev: [IN] DRM device (unused). + * @file: [IN] DRM file private data. + * + * Frees powervr-specific file private data (&struct pvr_file). + * + * Registered in &pvr_drm_driver. + */ +static void +pvr_drm_driver_postclose(__always_unused struct drm_device *drm_dev, + struct drm_file *file) +{ + struct pvr_file *pvr_file = to_pvr_file(file); + + kfree(pvr_file); + file->driver_priv = NULL; +} + +DEFINE_DRM_GEM_FOPS(pvr_drm_driver_fops); + +static struct drm_driver pvr_drm_driver = { + .driver_features = DRIVER_RENDER, + .open = pvr_drm_driver_open, + .postclose = pvr_drm_driver_postclose, + .ioctls = pvr_drm_driver_ioctls, + .num_ioctls = ARRAY_SIZE(pvr_drm_driver_ioctls), + .fops = &pvr_drm_driver_fops, + + .name = PVR_DRIVER_NAME, + .desc = PVR_DRIVER_DESC, + .date = PVR_DRIVER_DATE, + .major = PVR_DRIVER_MAJOR, + .minor = PVR_DRIVER_MINOR, + .patchlevel = PVR_DRIVER_PATCHLEVEL, + +}; + +static int +pvr_probe(struct platform_device *plat_dev) +{ + struct pvr_device *pvr_dev; + struct drm_device *drm_dev; + + pvr_dev = devm_drm_dev_alloc(&plat_dev->dev, &pvr_drm_driver, + struct pvr_device, base); + if (IS_ERR(pvr_dev)) + return PTR_ERR(pvr_dev); + + drm_dev = &pvr_dev->base; + + platform_set_drvdata(plat_dev, drm_dev); + + return drm_dev_register(drm_dev, 0); +} + +static int +pvr_remove(struct platform_device *plat_dev) +{ + struct drm_device *drm_dev = platform_get_drvdata(plat_dev); + + drm_dev_unplug(drm_dev); + + return 0; +} + +static const struct of_device_id dt_match[] = { + { .compatible = "img,img-axe", .data = NULL }, + {} +}; +MODULE_DEVICE_TABLE(of, dt_match); + +static struct platform_driver pvr_driver = { + .probe = pvr_probe, + .remove = pvr_remove, + .driver = { + .name = PVR_DRIVER_NAME, + .of_match_table = dt_match, + }, +}; +module_platform_driver(pvr_driver); + +MODULE_AUTHOR("Imagination Technologies Ltd."); +MODULE_DESCRIPTION(PVR_DRIVER_DESC); +MODULE_LICENSE("Dual MIT/GPL"); +MODULE_IMPORT_NS(DMA_BUF); diff --git a/drivers/gpu/drm/imagination/pvr_drv.h b/drivers/gpu/drm/imagination/pvr_drv.h new file mode 100644 index 000000000000..ecd8f6011ae9 --- /dev/null +++ b/drivers/gpu/drm/imagination/pvr_drv.h @@ -0,0 +1,22 @@ +/* SPDX-License-Identifier: GPL-2.0 OR MIT */ +/* Copyright (c) 2023 Imagination Technologies Ltd. */ + +#ifndef PVR_DRV_H +#define PVR_DRV_H + +#include "linux/compiler_attributes.h" +#include + +#define PVR_DRIVER_NAME "powervr" +#define PVR_DRIVER_DESC "Imagination PowerVR (Series 6 and later) & IMG Graphics" +#define PVR_DRIVER_DATE "20230904" + +/* + * Driver interface version: + * - 1.0: Initial interface + */ +#define PVR_DRIVER_MAJOR 1 +#define PVR_DRIVER_MINOR 0 +#define PVR_DRIVER_PATCHLEVEL 0 + +#endif /* PVR_DRV_H */ -- 2.42.0