From mboxrd@z Thu Jan 1 00:00:00 1970 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 gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id B82A1C433EF for ; Tue, 19 Jul 2022 15:29:20 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id F35418D776; Tue, 19 Jul 2022 15:29:19 +0000 (UTC) Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) by gabe.freedesktop.org (Postfix) with ESMTPS id 18A7B8D760; Tue, 19 Jul 2022 15:29:19 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1658244559; x=1689780559; h=message-id:date:subject:to:cc:references:from: in-reply-to:content-transfer-encoding:mime-version; bh=odEy2pYJNYC14JjaqHI1HfFyAjyaXO+9I9iomVhEh7A=; b=U9N4AfnxdQJmDCFsTY3XGSBMQQqSuMzE6sTs5uOUu+WGIpSPZHKF3ZON tlx6gXJzgXkQYEIRHWqLMcMWi/jnkGgBDahSvV1doUxdcgSxDPWHeGhpm 1lHmhelYEGOMZXGKDblpcq9MkD93BEOFL6svW9oNcRLUkeYQu2l57nBbA QG66idOs2kpEEnNc3huc5vktcKaq9na4cBuM61OO01v0Hz2R2ypWphtRe Hi0itdSo+k7N1ytMAIbYEtGXdGuyIU6MVOGCBOktP8UpxCRuE9pRMxYuq BtuMNAp6QLXqf7gCdv7TakKwq78rIg98iQiyUqIaukh8DgsBTIomMlXA7 w==; X-IronPort-AV: E=McAfee;i="6400,9594,10413"; a="286532693" X-IronPort-AV: E=Sophos;i="5.92,284,1650956400"; d="scan'208";a="286532693" Received: from orsmga005.jf.intel.com ([10.7.209.41]) by fmsmga103.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 19 Jul 2022 08:29:18 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.92,284,1650956400"; d="scan'208";a="774166121" Received: from orsmsx605.amr.corp.intel.com ([10.22.229.18]) by orsmga005.jf.intel.com with ESMTP; 19 Jul 2022 08:29:17 -0700 Received: from orsmsx609.amr.corp.intel.com (10.22.229.22) by ORSMSX605.amr.corp.intel.com (10.22.229.18) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.28; Tue, 19 Jul 2022 08:29:17 -0700 Received: from orsedg603.ED.cps.intel.com (10.7.248.4) by orsmsx609.amr.corp.intel.com (10.22.229.22) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2308.27 via Frontend Transport; Tue, 19 Jul 2022 08:29:17 -0700 Received: from NAM12-BN8-obe.outbound.protection.outlook.com (104.47.55.174) by edgegateway.intel.com (134.134.137.100) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.1.2308.27; Tue, 19 Jul 2022 08:29:16 -0700 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=UUBZd2mIJs5PR3Ab+WDgt6b33v1a9lpxZx3ioZx9t7qbtOSr+yIfdAAQqF4XgBVYOk5M73RGkeeqgYur6nqQ693l+edQIGcJRT7HP08mo4YALTSFTvxrviuHXOg0FERO6iyw1PDpwCFZoKPetUnxUukBVEZnJYIcfCaXFzQ+45GKoUX1ZnJVYW8zA0y823BJ25jaXykw8wHo41tw7fvWKYs9KzS10O+XJb7KmHsltjgJ16FAvpq2ZcyeHXS+nJCQxQaGlTyJJT6lWgsGRzXcxqtzm0eTKQh6k9k3CtwuzphWfpDtP6TLEERcogpWQJeOeveuHP2q90/sGMfDf6ItBA== 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=3mZ+UwZ36W4Kx3uTnhpn2q2nM7R/wQ987ALy2js8IwU=; b=HICGeWP0LvG/3QO/E7tANdSdX1h4zJsis3lyVnNYoAopjwB0dvgPPt1ynRioUoRHv3lYrATAHIckWCk5/XsLNW4tuBl5l23nAVXtdplOcQjCetPFh6QAtj+58jGLcDz9lwdzP9E0O/DOi2jFQbAsQOpo+O0YfEL4H23EBWqD8ada51vXQqFW6nofIE7wBBXgPfG1NFO4wga99B/4iBKNggDCP6x1eFDSUr0Ly31phuZ5u/TCvcLkmzwoowtx4JvokBcL6SeNonLsVMDyitQ4SFbjuxUvUYC6JnbK3ICCgp3OafUnjf/VxWfTdlCeFsRcPi57piLGymfFdHdmATWPSQ== 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 DM4PR11MB5488.namprd11.prod.outlook.com (2603:10b6:5:39d::5) by BL1PR11MB5415.namprd11.prod.outlook.com (2603:10b6:208:315::14) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5438.14; Tue, 19 Jul 2022 15:29:14 +0000 Received: from DM4PR11MB5488.namprd11.prod.outlook.com ([fe80::e8a1:cb8a:5124:2848]) by DM4PR11MB5488.namprd11.prod.outlook.com ([fe80::e8a1:cb8a:5124:2848%6]) with mapi id 15.20.5438.024; Tue, 19 Jul 2022 15:29:14 +0000 Message-ID: Date: Tue, 19 Jul 2022 08:29:11 -0700 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:91.0) Gecko/20100101 Thunderbird/91.10.0 Content-Language: en-US To: Tvrtko Ursulin , References: <20220715225451.1294354-1-daniele.ceraolospurio@intel.com> <8b782ef1-89ca-b66f-c8ee-1466b26ce6b9@linux.intel.com> <1651bac8-f88f-7166-3037-40889537e166@intel.com> From: "Ceraolo Spurio, Daniele" In-Reply-To: Content-Type: text/plain; charset="UTF-8"; format=flowed Content-Transfer-Encoding: 8bit X-ClientProxiedBy: BY5PR04CA0013.namprd04.prod.outlook.com (2603:10b6:a03:1d0::23) To DM4PR11MB5488.namprd11.prod.outlook.com (2603:10b6:5:39d::5) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 48bc7ce5-07db-4b04-81ed-08da699b6f73 X-MS-TrafficTypeDiagnostic: BL1PR11MB5415:EE_ X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: wWpUEJMPCyP1Et6NRns3BiuzP+b9/GKVO3xiScAmIaDPJ3FjlKOV4iUoiS0YrwWncz4BIpV9gv4/MBeH6wknxRfrYq9iNZF3DEo55pp6Wb28/FVFFwAuupraJOBaFLsDskROmVoiSY1mrPal3J5jxdeCRETM+otgnllFfxwnnnJRWGU14LfUirgv8TgLIYKctqlHJO+yMPBEs73EhUkuxCSiv5a8Wb/uHiNDa0evWmePRSowp7tQYqT638sxh66NbtYANFN4MlN6yLYn4XfOpbyhsW/a7q7RcycUFPFjoSeUzrmz9lw6ktRXbPURFV8IX2kpGoVkDROw2M7a03B6XAo+HWlBoJ+Ro20M3vAhQMV89sbo1hqP1RkPDtZKccE5K/Qx1+vu2ukxIG26jHxHqQWP0pSogQP63WkkR9v98/rQadrjrW9KqGHbynk8ZGvPliYYFOPJCHBv7GLmVkTaopehQ4CXcaliKSJBPXdI7OoJR/Pu58htobEpRQztbIHT9ScrPLHdv39/H8w65Tis0YgYbCYJG3uEQcvdTXj5kt5IzOum3LtFsF6TQYeIqC2y8TzZAFK4P1uFkjwOeor4U4Xia4AWH17nCXgL81iWFn2Pr2PFHRVSs8O9iRiHOFXiyaCpsDA1pHqEeIiTFYeeENdNSPhQZm9+h1cCCvfZQ4i5BFImsUFpW4+CPcFteo902TIbMW1ZJ9tKOH7DRRjeMyzP1Ayd9HEvvcLNqLQk6+dlzwZfEfrAj0+IfWua+3sQSVKUI/uiWxdjO9N3psiZdvICSDPFb5Yq8/S7XMMz/PjYmaRPVaNIKXX8ABpmdnXu8XYXrEPKMqRoZmgMfNXHphj55heIRwx5wBNbmAhcP1EFQjOAnaiQaI7TwOsYs0ptEfw+D2y7fBFS8dDn6CzxDg== X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:DM4PR11MB5488.namprd11.prod.outlook.com; PTR:; CAT:NONE; SFS:(13230016)(366004)(376002)(39860400002)(396003)(346002)(136003)(31696002)(966005)(6486002)(478600001)(2616005)(6506007)(186003)(53546011)(41300700001)(82960400001)(6512007)(38100700002)(26005)(6666004)(83380400001)(8676002)(2906002)(30864003)(8936002)(5660300002)(316002)(36756003)(86362001)(66556008)(66476007)(4326008)(31686004)(66946007)(334744004)(45980500001)(43740500002)(579004); DIR:OUT; SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?utf-8?B?TmxCTysvbE40b3VtZkIyMUEwdGlaVU85QUxJVks2bEo5UHByeUkzSDVFUFRt?= =?utf-8?B?REhJNnc5VWp1OGJLd0haM3N3WUtoS3E1TXlNZjA4eExubFl1RFdYK1V5VXln?= =?utf-8?B?QktpZG4wVW9TaGNrVUJJbTNGZkJZaXhYbUYxOGU2UmtFOVpWYXZ0c3c2cWg4?= =?utf-8?B?VjNPbitKRnVBc0RPVVZLU1pGaEFlV1c1T0R6dDdKdVdqbEE5RjFWZjBhRDF0?= =?utf-8?B?VUt1Z0piQTFrRmNKWHpNQ1BvMnZhWlpZdXdkMzFibGlsOTl1UnU5RUl3dWY5?= =?utf-8?B?VENWZTlodWFTUXdycTVOalpob2ljZ21SKzVsajMvYW80TTBYcHBmenlzZUdY?= =?utf-8?B?cGJSTUVZcU1nRkp1bjRwOG5tNzVxV1BFM1VTUkRuc0dyRUU0VE53NzIwaVhh?= =?utf-8?B?RHJYWTFHRXVDSzhiVUFzVjZDMWpPZkZ1dTlDeXdob010QnZsR0Zzc01RWmdv?= =?utf-8?B?QVowT3NxdGh6Wk8xM01vRWNBemk1K1pPK09zWGVhN0VHSEVmTUtPMDZvSXdF?= =?utf-8?B?UElaZGxWK3VDWElFKzc0eWNzdHVrdmpqeEVPYVUvdVdtR1cyMnIxYlZkVVRC?= =?utf-8?B?aGs2WVhPZ3BQdkxaNTFjdWFDVVlUVTJPUlRVcjBtbFNJTnorR2MwZkgwK2g4?= =?utf-8?B?VnZHVzJxeTlwRXZMeG10VzBkYkd3THJrR0tPS3BFVVBMcDUwdEFtN2tEUGcx?= =?utf-8?B?c0ZDTmFtRlVVbzFEV3BpSW9WVDJxL0VaOXVyVno3M0k3dzMvcGI1MVBYV3Q3?= =?utf-8?B?RlVKczNhS0doa1V3VUFjMDBXSjRVVFJuYlRBOCtlYmNJT1hPK21yZHhFYlBz?= =?utf-8?B?dHBvWGpZeFFtb2xJZ29raGlXVjJpZW1hbDB3bmxvTjNFdUlBSDUwTVZJMEFM?= =?utf-8?B?QUo2c1RaOGNDY0J2N01pZGdvZzc4Mmg2RG9Jd1JPbWVFZU94WnRCNFVoQ3pZ?= =?utf-8?B?MVo2QVlEY1pxMUhqdjNyMUtHZW9Hb1ZkUEVYOVBxdmZlTWdrenZsRlFORi9k?= =?utf-8?B?N3FsU1ZnRUlUU1Bmb2h4R1JQY1o5YWNpL1VpcW8yTm4vNUFKQ3FTdjZEZTZU?= =?utf-8?B?OStRQmd6YWZMc3E4L1YxRDFQV05zM0hqaFVzS2hHYWZMbmJSTXVncTdHY3RF?= =?utf-8?B?UTZESUJoQUsyMXlLMTdiRjV4SVFuNzdsRUx5UjcvK1ZYeWJodmNYbmQxc3c4?= =?utf-8?B?aWRtbElrMHpCOGtZTW9UQW1OZWtyR3NnRktPWWNUT0Nka0Yrdlp3ODRzNXhM?= =?utf-8?B?S1VaVkp6Y0hHQ3ZMQVFQMUo2VVlwQmJmTXdaK3h3VnNFdXVEUWdkWk0yRTNT?= =?utf-8?B?Z1lURzNQSHpMRnJ3cjhZRGJsdi8rMkNjWjJPdGg1VEpOSE9CMU05dzYvV3J0?= =?utf-8?B?czlFODY0YWNhcUFOQ012YXFpNGdQV2lBMkR1dk43Z3FZdHN5aUlkdnQ3SWlv?= =?utf-8?B?NnVPbjNka3A0bGhEUTRVbXk5SzVDa2JycExSZnVQMWVJS0VWT0gwVmY5dUpt?= =?utf-8?B?cjZzcHB2SXJjRTkza1R6Rkd2dDUrcGRDZ1hNMlNlQzhUSS81WUhPdDU0Q1FK?= =?utf-8?B?eWJON0sxNEd1aG5lNk1WUjhLNlJsUVcwYnVSUXhUN1p0N0ZhYlRuaEMrWU9o?= =?utf-8?B?VFlWUjY1S2ZFbkdqTVR6UVdVdGRCYU5sYTE2TnFINmFoTzYxTHRiVTQzMlc3?= =?utf-8?B?RjF4MVpYY25YM1pZMmowZ3E2YjRjMGI5d2hwalp1RmdNci95NjVBcHhTc3JC?= =?utf-8?B?NEJmWFVjeFBEQ3puZmZIZDJBUURGZzBRVnZwY3dLV2N2bHJuVTg1c0RtL1RV?= =?utf-8?B?UFE1dnJLbWtXQWFiNWJpUU0waU1lSG5OUEhCSnJGRlNkNTN0RUI2ZmZBZXds?= =?utf-8?B?bVZrU3QrTUF6ZGhzaXVzRkU3STdYRWh4VGtQb3BtV2kxQ2MzQllITmRZeXlI?= =?utf-8?B?SDhHTEpJeWE2NDFOL2VvZU9hYW9ZMzJZalBWRDJRN1NudCt4aGR4WHp1OGx6?= =?utf-8?B?OEhtTVJXajhRMGswWDNsbGxPNW9vVDRZYlNiTWx5WnoreFRMMlVKazFRRDFh?= =?utf-8?B?Z2N0NXdPK0VqdlJWS1ZJRGMydWJ1R05sS2hVNDJNRWFKYzljY3NmNXgwSmJL?= =?utf-8?B?WkVGZEZuTGtXaVp0dDhBZ1l2S0hzeFlyWExVRXM1MFc4THlUQWhFZmdLT2lZ?= =?utf-8?Q?dzTC4AkQt6qdaQnNPcVvPJ4=3D?= X-MS-Exchange-CrossTenant-Network-Message-Id: 48bc7ce5-07db-4b04-81ed-08da699b6f73 X-MS-Exchange-CrossTenant-AuthSource: DM4PR11MB5488.namprd11.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 19 Jul 2022 15:29:14.1262 (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: uDza32m3rJBmsA7VswfzYXzVdOXj69aVvF1C9XEelml9IL0e2bJ+ZsdJ2aFJpVSf7uUnncf9EQmIaMkvIxbqGaubJmUS/t7l5iDKuqGYrGw= X-MS-Exchange-Transport-CrossTenantHeadersStamped: BL1PR11MB5415 X-OriginatorOrg: intel.com Subject: Re: [Intel-gfx] [PATCH] drm/i915/guc: support v69 in parallel to v70 X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Dave Airlie , dri-devel@lists.freedesktop.org Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" On 7/19/2022 12:34 AM, Tvrtko Ursulin wrote: > > On 18/07/2022 17:41, Ceraolo Spurio, Daniele wrote: >> On 7/18/2022 3:02 AM, Tvrtko Ursulin wrote: >>> >>> Hi, >>> >>> On 15/07/2022 23:54, Daniele Ceraolo Spurio wrote: >>>> This patch re-introduces support for GuC v69 in parallel to v70. As >>>> this >>>> is a quick fix, v69 has been re-introduced as the single "fallback" >>>> guc >>>> version in case v70 is not available on disk. All v69 specific code >>>> has >>>> been labeled as such for easy identification, and the same was done >>>> for >>>> all v70 functions for which there is a separate v69 version, to avoid >>>> accidentally calling the wrong version via the unlabeled name. >>>> >>>> When the fallback mode kicks in, a drm_warn message is printed in >>>> dmesg >>>> to warn the user of the required update. >>>> >>>> The plan is to follow this up with a more complex rework to allow for >>>> multiple different GuC versions to be supported at the same time. >>>> >>>> Fixes: 2584b3549f4c ("drm/i915/guc: Update to GuC version 70.1.1") >>> >>> Please check if I got this right: >>> >>>  * ADL-P was out of "force probe" starting from 5.17. >>>  * GuC fw got bumped from v62 to v69 in 5.18. >>> >>> Does this mean you would also need to handle v62 to avoid regressing >>> ADL-P from 5.17 to 5.18? I couldn't figure out when ADL-P switched >>> from execlists to GuC due a bit convoluted supported/wanted/needed >>> macros etc, so not entirely sure. >>> >> >> I haven't checked about previous GuC versions because the report from >> Dave was on the 69->70 transition and about re-introducing v69 >> support, so I just focused on that. Let me dig on the versions and on >> what would be needed to support all 3 revs (if it is required). >> >>> Secondly, my concern with the approach like in this patch is that it >>> would grow the i915 code base *if* there is no incentive to keep the >>> compatiblity breaking firware updates in check. >>> >> >> The grow of the i915 code is inevitable. Even without changes to >> existing platforms, new features for new platforms will require new >> GuC interfaces. Sometimes the GuC team also refactors an existing >> interface so that it can include a new aspect of an existing feature. >> We'll have to discuss with them how to minimize breakages in such >> scenarios. >> >>> To think about in tandem with this is the question of whether many >>> more fallback versions need to be handled, even for platforms which >>> only use GuC to load HuC? Those would also regress in the media >>> encoding side of things, even if they don't use GuC submission, right? >>> >> >> The only HuC-only platform is ADL-S and that went out of force probe >> when we were on GuC 62, so definitely nothing older than that will be >> needed. > > I was referring to platforms where HuC is used for some encoding > types. List on > https://github.com/intel/media-driver/blob/master/docs/media_features.md#media-features-summary. > It is not entirely clear to me from that list - you are saying the HuC > is actually used only on ADL-S? I was going by the existence of HuC > firmware files only so might be wrong just as well. > Like GuC, HuC can be enabled via modparam on anything gen11+, but it is only enabled by default on a subset of platforms, which are all the platforms for which we enable GuC submission, plus ADL-S. Of those, the only ones out of force probe are the ADL variants and their derivatives, so they're the only ones we need to guarantee backwards compatibility for. See uc_expand_default_options() in intel_uc.c for further details. Daniele > Regards, > > Tvrtko > >>> If this is so, the approach from this patch would feel rushed in my >>> view. >> >> It totally is, no argument there. As mentioned in the commit message, >> the plan is to replace the whole thing with a more flexible and >> cleaner mechanism, but we do need something for the upcoming 5.19 >> release so there is no time to do this properly from the get-go. >> >>> >>> There is also the question of being able to automatically load the >>> latest _compatible_ (same major version) GuC fw found on disk. Aka >>> allowing a bugfix firmware update which does not require a kernel >>> update. In theory should be possible but we don't have that >>> implemented either, right? >> >> We do not. Something like this was actually shot down when GuC first >> came around. We used to have simlinks for the GuC binary to be able >> to drop in a replacement like you said, but there were concerns about >> how to validate all the possible kernel:fw combinations this could >> cause, hence why in the end we went with the exact match model. Note >> that at the time we didn't have a patch number for bugfix tracking in >> GuC, so the decision made more sense back then than it does now. >> We've already restarted the discussion internally. >> >> Daniele >> >>> >>> Regards, >>> >>> Tvrtko >>> >>>> Link: >>>> https://lists.freedesktop.org/archives/intel-gfx/2022-July/301640.html >>>> Signed-off-by: Daniele Ceraolo Spurio >>>> >>>> Cc: John Harrison >>>> Cc: Matthew Brost >>>> Cc: Matt Roper >>>> Cc: Dave Airlie >>>> --- >>>>   drivers/gpu/drm/i915/gt/intel_context_types.h |  11 +- >>>>   .../gpu/drm/i915/gt/uc/abi/guc_actions_abi.h  |   3 + >>>>   drivers/gpu/drm/i915/gt/uc/intel_guc.h        |   5 + >>>>   drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h   |  45 +++ >>>>   .../gpu/drm/i915/gt/uc/intel_guc_submission.c | 348 >>>> +++++++++++++++--- >>>>   drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c      |  57 ++- >>>>   drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h      |   7 + >>>>   7 files changed, 419 insertions(+), 57 deletions(-) >>>> >>>> diff --git a/drivers/gpu/drm/i915/gt/intel_context_types.h >>>> b/drivers/gpu/drm/i915/gt/intel_context_types.h >>>> index d2d75d9c0c8d..04eacae1aca5 100644 >>>> --- a/drivers/gpu/drm/i915/gt/intel_context_types.h >>>> +++ b/drivers/gpu/drm/i915/gt/intel_context_types.h >>>> @@ -275,10 +275,17 @@ struct intel_context { >>>>           u8 child_index; >>>>           /** @guc: GuC specific members for parallel submission */ >>>>           struct { >>>> -            /** @wqi_head: head pointer in work queue */ >>>> +            /** @wqi_head: cached head pointer in work queue */ >>>>               u16 wqi_head; >>>> -            /** @wqi_tail: tail pointer in work queue */ >>>> +            /** @wqi_tail: cached tail pointer in work queue */ >>>>               u16 wqi_tail; >>>> +            /** @wq_head: pointer to the actual head in work queue */ >>>> +            u32 *wq_head; >>>> +            /** @wq_tail: pointer to the actual head in work queue */ >>>> +            u32 *wq_tail; >>>> +            /** @wq_status: pointer to the status in work queue */ >>>> +            u32 *wq_status; >>>> + >>>>               /** >>>>                * @parent_page: page in context state (ce->state) used >>>>                * by parent for work queue, process descriptor >>>> diff --git a/drivers/gpu/drm/i915/gt/uc/abi/guc_actions_abi.h >>>> b/drivers/gpu/drm/i915/gt/uc/abi/guc_actions_abi.h >>>> index 4ef9990ed7f8..29ef8afc8c2e 100644 >>>> --- a/drivers/gpu/drm/i915/gt/uc/abi/guc_actions_abi.h >>>> +++ b/drivers/gpu/drm/i915/gt/uc/abi/guc_actions_abi.h >>>> @@ -122,6 +122,9 @@ enum intel_guc_action { >>>>       INTEL_GUC_ACTION_SCHED_CONTEXT_MODE_DONE = 0x1002, >>>>       INTEL_GUC_ACTION_SCHED_ENGINE_MODE_SET = 0x1003, >>>>       INTEL_GUC_ACTION_SCHED_ENGINE_MODE_DONE = 0x1004, >>>> +    INTEL_GUC_ACTION_V69_SET_CONTEXT_PRIORITY = 0x1005, >>>> +    INTEL_GUC_ACTION_V69_SET_CONTEXT_EXECUTION_QUANTUM = 0x1006, >>>> +    INTEL_GUC_ACTION_V69_SET_CONTEXT_PREEMPTION_TIMEOUT = 0x1007, >>>>       INTEL_GUC_ACTION_CONTEXT_RESET_NOTIFICATION = 0x1008, >>>>       INTEL_GUC_ACTION_ENGINE_FAILURE_NOTIFICATION = 0x1009, >>>>       INTEL_GUC_ACTION_HOST2GUC_UPDATE_CONTEXT_POLICIES = 0x100B, >>>> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc.h >>>> b/drivers/gpu/drm/i915/gt/uc/intel_guc.h >>>> index d0d99f178f2d..a7acffbf15d1 100644 >>>> --- a/drivers/gpu/drm/i915/gt/uc/intel_guc.h >>>> +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc.h >>>> @@ -170,6 +170,11 @@ struct intel_guc { >>>>       /** @ads_engine_usage_size: size of engine usage in the ADS */ >>>>       u32 ads_engine_usage_size; >>>>   +    /** @lrc_desc_pool_v69: object allocated to hold the GuC LRC >>>> descriptor pool */ >>>> +    struct i915_vma *lrc_desc_pool_v69; >>>> +    /** @lrc_desc_pool_vaddr_v69: contents of the GuC LRC >>>> descriptor pool */ >>>> +    void *lrc_desc_pool_vaddr_v69; >>>> + >>>>       /** >>>>        * @context_lookup: used to resolve intel_context from >>>> guc_id, if a >>>>        * context is present in this structure it is registered with >>>> the GuC >>>> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h >>>> b/drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h >>>> index b3c9a9327f76..323b055e5db9 100644 >>>> --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h >>>> +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h >>>> @@ -204,6 +204,20 @@ struct guc_wq_item { >>>>       u32 fence_id; >>>>   } __packed; >>>>   +struct guc_process_desc_v69 { >>>> +    u32 stage_id; >>>> +    u64 db_base_addr; >>>> +    u32 head; >>>> +    u32 tail; >>>> +    u32 error_offset; >>>> +    u64 wq_base_addr; >>>> +    u32 wq_size_bytes; >>>> +    u32 wq_status; >>>> +    u32 engine_presence; >>>> +    u32 priority; >>>> +    u32 reserved[36]; >>>> +} __packed; >>>> + >>>>   struct guc_sched_wq_desc { >>>>       u32 head; >>>>       u32 tail; >>>> @@ -228,6 +242,37 @@ struct guc_ctxt_registration_info { >>>>   }; >>>>   #define CONTEXT_REGISTRATION_FLAG_KMD    BIT(0) >>>>   +/* Preempt to idle on quantum expiry */ >>>> +#define CONTEXT_POLICY_FLAG_PREEMPT_TO_IDLE_V69    BIT(0) >>>> + >>>> +/* >>>> + * GuC Context registration descriptor. >>>> + * FIXME: This is only required to exist during context registration. >>>> + * The current 1:1 between guc_lrc_desc and LRCs for the lifetime >>>> of the LRC >>>> + * is not required. >>>> + */ >>>> +struct guc_lrc_desc_v69 { >>>> +    u32 hw_context_desc; >>>> +    u32 slpm_perf_mode_hint;    /* SPLC v1 only */ >>>> +    u32 slpm_freq_hint; >>>> +    u32 engine_submit_mask;        /* In logical space */ >>>> +    u8 engine_class; >>>> +    u8 reserved0[3]; >>>> +    u32 priority; >>>> +    u32 process_desc; >>>> +    u32 wq_addr; >>>> +    u32 wq_size; >>>> +    u32 context_flags;        /* CONTEXT_REGISTRATION_* */ >>>> +    /* Time for one workload to execute. (in micro seconds) */ >>>> +    u32 execution_quantum; >>>> +    /* Time to wait for a preemption request to complete before >>>> issuing a >>>> +     * reset. (in micro seconds). >>>> +     */ >>>> +    u32 preemption_timeout; >>>> +    u32 policy_flags;        /* CONTEXT_POLICY_* */ >>>> +    u32 reserved1[19]; >>>> +} __packed; >>>> + >>>>   /* 32-bit KLV structure as used by policy updates and others */ >>>>   struct guc_klv_generic_dw_t { >>>>       u32 kl; >>>> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c >>>> b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c >>>> index 40f726c61e95..aa10db25cc06 100644 >>>> --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c >>>> +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c >>>> @@ -414,12 +414,15 @@ struct sync_semaphore { >>>>   }; >>>>     struct parent_scratch { >>>> -    struct guc_sched_wq_desc wq_desc; >>>> +    union guc_descs { >>>> +        struct guc_sched_wq_desc wq_desc; >>>> +        struct guc_process_desc_v69 pdesc; >>>> +    } descs; >>>>         struct sync_semaphore go; >>>>       struct sync_semaphore join[MAX_ENGINE_INSTANCE + 1]; >>>>   -    u8 unused[WQ_OFFSET - sizeof(struct guc_sched_wq_desc) - >>>> +    u8 unused[WQ_OFFSET - sizeof(union guc_descs) - >>>>           sizeof(struct sync_semaphore) * (MAX_ENGINE_INSTANCE + 2)]; >>>>         u32 wq[WQ_SIZE / sizeof(u32)]; >>>> @@ -456,17 +459,23 @@ __get_parent_scratch(struct intel_context *ce) >>>>              LRC_STATE_OFFSET) / sizeof(u32))); >>>>   } >>>>   +static struct guc_process_desc_v69 * >>>> +__get_process_desc_v69(struct intel_context *ce) >>>> +{ >>>> +    struct parent_scratch *ps = __get_parent_scratch(ce); >>>> + >>>> +    return &ps->descs.pdesc; >>>> +} >>>> + >>>>   static struct guc_sched_wq_desc * >>>> -__get_wq_desc(struct intel_context *ce) >>>> +__get_wq_desc_v70(struct intel_context *ce) >>>>   { >>>>       struct parent_scratch *ps = __get_parent_scratch(ce); >>>>   -    return &ps->wq_desc; >>>> +    return &ps->descs.wq_desc; >>>>   } >>>>   -static u32 *get_wq_pointer(struct guc_sched_wq_desc *wq_desc, >>>> -               struct intel_context *ce, >>>> -               u32 wqi_size) >>>> +static u32 *get_wq_pointer(struct intel_context *ce, u32 wqi_size) >>>>   { >>>>       /* >>>>        * Check for space in work queue. Caching a value of head >>>> pointer in >>>> @@ -476,7 +485,7 @@ static u32 *get_wq_pointer(struct >>>> guc_sched_wq_desc *wq_desc, >>>>   #define AVAILABLE_SPACE    \ >>>>       CIRC_SPACE(ce->parallel.guc.wqi_tail, >>>> ce->parallel.guc.wqi_head, WQ_SIZE) >>>>       if (wqi_size > AVAILABLE_SPACE) { >>>> -        ce->parallel.guc.wqi_head = READ_ONCE(wq_desc->head); >>>> +        ce->parallel.guc.wqi_head = >>>> READ_ONCE(*ce->parallel.guc.wq_head); >>>>             if (wqi_size > AVAILABLE_SPACE) >>>>               return NULL; >>>> @@ -495,11 +504,55 @@ static inline struct intel_context >>>> *__get_context(struct intel_guc *guc, u32 id) >>>>       return ce; >>>>   } >>>>   +static struct guc_lrc_desc_v69 *__get_lrc_desc_v69(struct >>>> intel_guc *guc, u32 index) >>>> +{ >>>> +    struct guc_lrc_desc_v69 *base = guc->lrc_desc_pool_vaddr_v69; >>>> + >>>> +    if (!base) >>>> +        return NULL; >>>> + >>>> +    GEM_BUG_ON(index >= GUC_MAX_CONTEXT_ID); >>>> + >>>> +    return &base[index]; >>>> +} >>>> + >>>> +static int guc_lrc_desc_pool_create_v69(struct intel_guc *guc) >>>> +{ >>>> +    u32 size; >>>> +    int ret; >>>> + >>>> +    size = PAGE_ALIGN(sizeof(struct guc_lrc_desc_v69) * >>>> +              GUC_MAX_CONTEXT_ID); >>>> +    ret = intel_guc_allocate_and_map_vma(guc, size, >>>> &guc->lrc_desc_pool_v69, >>>> +                         (void **)&guc->lrc_desc_pool_vaddr_v69); >>>> +    if (ret) >>>> +        return ret; >>>> + >>>> +    return 0; >>>> +} >>>> + >>>> +static void guc_lrc_desc_pool_destroy_v69(struct intel_guc *guc) >>>> +{ >>>> +    if (!guc->lrc_desc_pool_vaddr_v69) >>>> +        return; >>>> + >>>> +    guc->lrc_desc_pool_vaddr_v69 = NULL; >>>> + i915_vma_unpin_and_release(&guc->lrc_desc_pool_v69, >>>> I915_VMA_RELEASE_MAP); >>>> +} >>>> + >>>>   static inline bool guc_submission_initialized(struct intel_guc *guc) >>>>   { >>>>       return guc->submission_initialized; >>>>   } >>>>   +static inline void _reset_lrc_desc_v69(struct intel_guc *guc, >>>> u32 id) >>>> +{ >>>> +    struct guc_lrc_desc_v69 *desc = __get_lrc_desc_v69(guc, id); >>>> + >>>> +    if (desc) >>>> +        memset(desc, 0, sizeof(*desc)); >>>> +} >>>> + >>>>   static inline bool ctx_id_mapped(struct intel_guc *guc, u32 id) >>>>   { >>>>       return __get_context(guc, id); >>>> @@ -526,6 +579,8 @@ static inline void clr_ctx_id_mapping(struct >>>> intel_guc *guc, u32 id) >>>>       if (unlikely(!guc_submission_initialized(guc))) >>>>           return; >>>>   +    _reset_lrc_desc_v69(guc, id); >>>> + >>>>       /* >>>>        * xarray API doesn't have xa_erase_irqsave wrapper, so calling >>>>        * the lower level functions directly. >>>> @@ -611,7 +666,7 @@ int intel_guc_wait_for_idle(struct intel_guc >>>> *guc, long timeout) >>>>                             true, timeout); >>>>   } >>>>   -static int guc_context_policy_init(struct intel_context *ce, >>>> bool loop); >>>> +static int guc_context_policy_init_v70(struct intel_context *ce, >>>> bool loop); >>>>   static int try_context_registration(struct intel_context *ce, >>>> bool loop); >>>>     static int __guc_add_request(struct intel_guc *guc, struct >>>> i915_request *rq) >>>> @@ -639,7 +694,7 @@ static int __guc_add_request(struct intel_guc >>>> *guc, struct i915_request *rq) >>>>       GEM_BUG_ON(context_guc_id_invalid(ce)); >>>>         if (context_policy_required(ce)) { >>>> -        err = guc_context_policy_init(ce, false); >>>> +        err = guc_context_policy_init_v70(ce, false); >>>>           if (err) >>>>               return err; >>>>       } >>>> @@ -737,9 +792,7 @@ static u32 wq_space_until_wrap(struct >>>> intel_context *ce) >>>>       return (WQ_SIZE - ce->parallel.guc.wqi_tail); >>>>   } >>>>   -static void write_wqi(struct guc_sched_wq_desc *wq_desc, >>>> -              struct intel_context *ce, >>>> -              u32 wqi_size) >>>> +static void write_wqi(struct intel_context *ce, u32 wqi_size) >>>>   { >>>>       BUILD_BUG_ON(!is_power_of_2(WQ_SIZE)); >>>>   @@ -750,13 +803,12 @@ static void write_wqi(struct >>>> guc_sched_wq_desc *wq_desc, >>>>         ce->parallel.guc.wqi_tail = (ce->parallel.guc.wqi_tail + >>>> wqi_size) & >>>>           (WQ_SIZE - 1); >>>> -    WRITE_ONCE(wq_desc->tail, ce->parallel.guc.wqi_tail); >>>> +    WRITE_ONCE(*ce->parallel.guc.wq_tail, ce->parallel.guc.wqi_tail); >>>>   } >>>>     static int guc_wq_noop_append(struct intel_context *ce) >>>>   { >>>> -    struct guc_sched_wq_desc *wq_desc = __get_wq_desc(ce); >>>> -    u32 *wqi = get_wq_pointer(wq_desc, ce, wq_space_until_wrap(ce)); >>>> +    u32 *wqi = get_wq_pointer(ce, wq_space_until_wrap(ce)); >>>>       u32 len_dw = wq_space_until_wrap(ce) / sizeof(u32) - 1; >>>>         if (!wqi) >>>> @@ -775,7 +827,6 @@ static int __guc_wq_item_append(struct >>>> i915_request *rq) >>>>   { >>>>       struct intel_context *ce = request_to_scheduling_context(rq); >>>>       struct intel_context *child; >>>> -    struct guc_sched_wq_desc *wq_desc = __get_wq_desc(ce); >>>>       unsigned int wqi_size = (ce->parallel.number_children + 4) * >>>>           sizeof(u32); >>>>       u32 *wqi; >>>> @@ -795,7 +846,7 @@ static int __guc_wq_item_append(struct >>>> i915_request *rq) >>>>               return ret; >>>>       } >>>>   -    wqi = get_wq_pointer(wq_desc, ce, wqi_size); >>>> +    wqi = get_wq_pointer(ce, wqi_size); >>>>       if (!wqi) >>>>           return -EBUSY; >>>>   @@ -810,7 +861,7 @@ static int __guc_wq_item_append(struct >>>> i915_request *rq) >>>>       for_each_child(ce, child) >>>>           *wqi++ = child->ring->tail / sizeof(u64); >>>>   -    write_wqi(wq_desc, ce, wqi_size); >>>> +    write_wqi(ce, wqi_size); >>>>         return 0; >>>>   } >>>> @@ -1812,20 +1863,34 @@ static void reset_fail_worker_func(struct >>>> work_struct *w); >>>>   int intel_guc_submission_init(struct intel_guc *guc) >>>>   { >>>>       struct intel_gt *gt = guc_to_gt(guc); >>>> +    int ret; >>>>         if (guc->submission_initialized) >>>>           return 0; >>>>   +    if (guc->fw.major_ver_found < 70) { >>>> +        ret = guc_lrc_desc_pool_create_v69(guc); >>>> +        if (ret) >>>> +            return ret; >>>> +    } >>>> + >>>>       guc->submission_state.guc_ids_bitmap = >>>>           bitmap_zalloc(NUMBER_MULTI_LRC_GUC_ID(guc), GFP_KERNEL); >>>> -    if (!guc->submission_state.guc_ids_bitmap) >>>> -        return -ENOMEM; >>>> +    if (!guc->submission_state.guc_ids_bitmap) { >>>> +        ret = -ENOMEM; >>>> +        goto destroy_pool; >>>> +    } >>>>         guc->timestamp.ping_delay = (POLL_TIME_CLKS / >>>> gt->clock_frequency + 1) * HZ; >>>>       guc->timestamp.shift = gpm_timestamp_shift(gt); >>>>       guc->submission_initialized = true; >>>>         return 0; >>>> + >>>> +destroy_pool: >>>> +    guc_lrc_desc_pool_destroy_v69(guc); >>>> + >>>> +    return ret; >>>>   } >>>>     void intel_guc_submission_fini(struct intel_guc *guc) >>>> @@ -1834,6 +1899,7 @@ void intel_guc_submission_fini(struct >>>> intel_guc *guc) >>>>           return; >>>>         guc_flush_destroyed_contexts(guc); >>>> +    guc_lrc_desc_pool_destroy_v69(guc); >>>>       i915_sched_engine_put(guc->sched_engine); >>>>       bitmap_free(guc->submission_state.guc_ids_bitmap); >>>>       guc->submission_initialized = false; >>>> @@ -2091,10 +2157,34 @@ static void unpin_guc_id(struct intel_guc >>>> *guc, struct intel_context *ce) >>>> spin_unlock_irqrestore(&guc->submission_state.lock, flags); >>>>   } >>>>   -static int __guc_action_register_multi_lrc(struct intel_guc *guc, >>>> +static int __guc_action_register_multi_lrc_v69(struct intel_guc *guc, >>>>                          struct intel_context *ce, >>>> -                       struct guc_ctxt_registration_info *info, >>>> +                       u32 guc_id, >>>> +                       u32 offset, >>>>                          bool loop) >>>> +{ >>>> +    struct intel_context *child; >>>> +    u32 action[4 + MAX_ENGINE_INSTANCE]; >>>> +    int len = 0; >>>> + >>>> +    GEM_BUG_ON(ce->parallel.number_children > MAX_ENGINE_INSTANCE); >>>> + >>>> +    action[len++] = INTEL_GUC_ACTION_REGISTER_CONTEXT_MULTI_LRC; >>>> +    action[len++] = guc_id; >>>> +    action[len++] = ce->parallel.number_children + 1; >>>> +    action[len++] = offset; >>>> +    for_each_child(ce, child) { >>>> +        offset += sizeof(struct guc_lrc_desc_v69); >>>> +        action[len++] = offset; >>>> +    } >>>> + >>>> +    return guc_submission_send_busy_loop(guc, action, len, 0, loop); >>>> +} >>>> + >>>> +static int __guc_action_register_multi_lrc_v70(struct intel_guc *guc, >>>> +                           struct intel_context *ce, >>>> +                           struct guc_ctxt_registration_info *info, >>>> +                           bool loop) >>>>   { >>>>       struct intel_context *child; >>>>       u32 action[13 + (MAX_ENGINE_INSTANCE * 2)]; >>>> @@ -2134,9 +2224,24 @@ static int >>>> __guc_action_register_multi_lrc(struct intel_guc *guc, >>>>       return guc_submission_send_busy_loop(guc, action, len, 0, loop); >>>>   } >>>>   -static int __guc_action_register_context(struct intel_guc *guc, >>>> -                     struct guc_ctxt_registration_info *info, >>>> -                     bool loop) >>>> +static int __guc_action_register_context_v69(struct intel_guc *guc, >>>> +                         u32 guc_id, >>>> +                         u32 offset, >>>> +                         bool loop) >>>> +{ >>>> +    u32 action[] = { >>>> +        INTEL_GUC_ACTION_REGISTER_CONTEXT, >>>> +        guc_id, >>>> +        offset, >>>> +    }; >>>> + >>>> +    return guc_submission_send_busy_loop(guc, action, >>>> ARRAY_SIZE(action), >>>> +                         0, loop); >>>> +} >>>> + >>>> +static int __guc_action_register_context_v70(struct intel_guc *guc, >>>> +                         struct guc_ctxt_registration_info *info, >>>> +                         bool loop) >>>>   { >>>>       u32 action[] = { >>>>           INTEL_GUC_ACTION_REGISTER_CONTEXT, >>>> @@ -2157,24 +2262,52 @@ static int >>>> __guc_action_register_context(struct intel_guc *guc, >>>>                            0, loop); >>>>   } >>>>   -static void prepare_context_registration_info(struct >>>> intel_context *ce, >>>> -                          struct guc_ctxt_registration_info *info); >>>> +static void prepare_context_registration_info_v69(struct >>>> intel_context *ce); >>>> +static void prepare_context_registration_info_v70(struct >>>> intel_context *ce, >>>> +                          struct guc_ctxt_registration_info *info); >>>>   -static int register_context(struct intel_context *ce, bool loop) >>>> +static int >>>> +register_context_v69(struct intel_guc *guc, struct intel_context >>>> *ce, bool loop) >>>> +{ >>>> +    u32 offset = intel_guc_ggtt_offset(guc, guc->lrc_desc_pool_v69) + >>>> +        ce->guc_id.id * sizeof(struct guc_lrc_desc_v69); >>>> + >>>> +    prepare_context_registration_info_v69(ce); >>>> + >>>> +    if (intel_context_is_parent(ce)) >>>> +        return __guc_action_register_multi_lrc_v69(guc, ce, >>>> ce->guc_id.id, >>>> +                               offset, loop); >>>> +    else >>>> +        return __guc_action_register_context_v69(guc, ce->guc_id.id, >>>> +                             offset, loop); >>>> +} >>>> + >>>> +static int >>>> +register_context_v70(struct intel_guc *guc, struct intel_context >>>> *ce, bool loop) >>>>   { >>>>       struct guc_ctxt_registration_info info; >>>> + >>>> +    prepare_context_registration_info_v70(ce, &info); >>>> + >>>> +    if (intel_context_is_parent(ce)) >>>> +        return __guc_action_register_multi_lrc_v70(guc, ce, &info, >>>> loop); >>>> +    else >>>> +        return __guc_action_register_context_v70(guc, &info, loop); >>>> +} >>>> + >>>> +static int register_context(struct intel_context *ce, bool loop) >>>> +{ >>>>       struct intel_guc *guc = ce_to_guc(ce); >>>>       int ret; >>>>         GEM_BUG_ON(intel_context_is_child(ce)); >>>>       trace_intel_context_register(ce); >>>>   -    prepare_context_registration_info(ce, &info); >>>> - >>>> -    if (intel_context_is_parent(ce)) >>>> -        ret = __guc_action_register_multi_lrc(guc, ce, &info, loop); >>>> +    if (guc->fw.major_ver_found >= 70) >>>> +        ret = register_context_v70(guc, ce, loop); >>>>       else >>>> -        ret = __guc_action_register_context(guc, &info, loop); >>>> +        ret = register_context_v69(guc, ce, loop); >>>> + >>>>       if (likely(!ret)) { >>>>           unsigned long flags; >>>>   @@ -2182,7 +2315,8 @@ static int register_context(struct >>>> intel_context *ce, bool loop) >>>>           set_context_registered(ce); >>>>           spin_unlock_irqrestore(&ce->guc_state.lock, flags); >>>>   -        guc_context_policy_init(ce, loop); >>>> +        if (guc->fw.major_ver_found >= 70) >>>> +            guc_context_policy_init_v70(ce, loop); >>>>       } >>>>         return ret; >>>> @@ -2279,7 +2413,7 @@ static int >>>> __guc_context_set_context_policies(struct intel_guc *guc, >>>>                       0, loop); >>>>   } >>>>   -static int guc_context_policy_init(struct intel_context *ce, >>>> bool loop) >>>> +static int guc_context_policy_init_v70(struct intel_context *ce, >>>> bool loop) >>>>   { >>>>       struct intel_engine_cs *engine = ce->engine; >>>>       struct intel_guc *guc = &engine->gt->uc.guc; >>>> @@ -2338,6 +2472,19 @@ static int guc_context_policy_init(struct >>>> intel_context *ce, bool loop) >>>>       return ret; >>>>   } >>>>   +static void guc_context_policy_init_v69(struct intel_engine_cs >>>> *engine, >>>> +                    struct guc_lrc_desc_v69 *desc) >>>> +{ >>>> +    desc->policy_flags = 0; >>>> + >>>> +    if (engine->flags & I915_ENGINE_WANT_FORCED_PREEMPTION) >>>> +        desc->policy_flags |= >>>> CONTEXT_POLICY_FLAG_PREEMPT_TO_IDLE_V69; >>>> + >>>> +    /* NB: For both of these, zero means disabled. */ >>>> +    desc->execution_quantum = engine->props.timeslice_duration_ms >>>> * 1000; >>>> +    desc->preemption_timeout = engine->props.preempt_timeout_ms * >>>> 1000; >>>> +} >>>> + >>>>   static u32 map_guc_prio_to_lrc_desc_prio(u8 prio) >>>>   { >>>>       /* >>>> @@ -2358,8 +2505,75 @@ static u32 map_guc_prio_to_lrc_desc_prio(u8 >>>> prio) >>>>       } >>>>   } >>>>   -static void prepare_context_registration_info(struct >>>> intel_context *ce, >>>> -                          struct guc_ctxt_registration_info *info) >>>> +static void prepare_context_registration_info_v69(struct >>>> intel_context *ce) >>>> +{ >>>> +    struct intel_engine_cs *engine = ce->engine; >>>> +    struct intel_guc *guc = &engine->gt->uc.guc; >>>> +    u32 ctx_id = ce->guc_id.id; >>>> +    struct guc_lrc_desc_v69 *desc; >>>> +    struct intel_context *child; >>>> + >>>> +    GEM_BUG_ON(!engine->mask); >>>> + >>>> +    /* >>>> +     * Ensure LRC + CT vmas are is same region as write barrier is >>>> done >>>> +     * based on CT vma region. >>>> +     */ >>>> + GEM_BUG_ON(i915_gem_object_is_lmem(guc->ct.vma->obj) != >>>> + i915_gem_object_is_lmem(ce->ring->vma->obj)); >>>> + >>>> +    desc = __get_lrc_desc_v69(guc, ctx_id); >>>> +    desc->engine_class = engine_class_to_guc_class(engine->class); >>>> +    desc->engine_submit_mask = engine->logical_mask; >>>> +    desc->hw_context_desc = ce->lrc.lrca; >>>> +    desc->priority = ce->guc_state.prio; >>>> +    desc->context_flags = CONTEXT_REGISTRATION_FLAG_KMD; >>>> +    guc_context_policy_init_v69(engine, desc); >>>> + >>>> +    /* >>>> +     * If context is a parent, we need to register a process >>>> descriptor >>>> +     * describing a work queue and register all child contexts. >>>> +     */ >>>> +    if (intel_context_is_parent(ce)) { >>>> +        struct guc_process_desc_v69 *pdesc; >>>> + >>>> +        ce->parallel.guc.wqi_tail = 0; >>>> +        ce->parallel.guc.wqi_head = 0; >>>> + >>>> +        desc->process_desc = i915_ggtt_offset(ce->state) + >>>> +            __get_parent_scratch_offset(ce); >>>> +        desc->wq_addr = i915_ggtt_offset(ce->state) + >>>> +            __get_wq_offset(ce); >>>> +        desc->wq_size = WQ_SIZE; >>>> + >>>> +        pdesc = __get_process_desc_v69(ce); >>>> +        memset(pdesc, 0, sizeof(*(pdesc))); >>>> +        pdesc->stage_id = ce->guc_id.id; >>>> +        pdesc->wq_base_addr = desc->wq_addr; >>>> +        pdesc->wq_size_bytes = desc->wq_size; >>>> +        pdesc->wq_status = WQ_STATUS_ACTIVE; >>>> + >>>> +        ce->parallel.guc.wq_head = &pdesc->head; >>>> +        ce->parallel.guc.wq_tail = &pdesc->tail; >>>> +        ce->parallel.guc.wq_status = &pdesc->wq_status; >>>> + >>>> +        for_each_child(ce, child) { >>>> +            desc = __get_lrc_desc_v69(guc, child->guc_id.id); >>>> + >>>> +            desc->engine_class = >>>> + engine_class_to_guc_class(engine->class); >>>> +            desc->hw_context_desc = child->lrc.lrca; >>>> +            desc->priority = ce->guc_state.prio; >>>> +            desc->context_flags = CONTEXT_REGISTRATION_FLAG_KMD; >>>> +            guc_context_policy_init_v69(engine, desc); >>>> +        } >>>> + >>>> +        clear_children_join_go_memory(ce); >>>> +    } >>>> +} >>>> + >>>> +static void prepare_context_registration_info_v70(struct >>>> intel_context *ce, >>>> +                          struct guc_ctxt_registration_info *info) >>>>   { >>>>       struct intel_engine_cs *engine = ce->engine; >>>>       struct intel_guc *guc = &engine->gt->uc.guc; >>>> @@ -2409,10 +2623,14 @@ static void >>>> prepare_context_registration_info(struct intel_context *ce, >>>>           info->wq_base_hi = upper_32_bits(wq_base_offset); >>>>           info->wq_size = WQ_SIZE; >>>>   -        wq_desc = __get_wq_desc(ce); >>>> +        wq_desc = __get_wq_desc_v70(ce); >>>>           memset(wq_desc, 0, sizeof(*wq_desc)); >>>>      ��    wq_desc->wq_status = WQ_STATUS_ACTIVE; >>>>   +        ce->parallel.guc.wq_head = &wq_desc->head; >>>> +        ce->parallel.guc.wq_tail = &wq_desc->tail; >>>> +        ce->parallel.guc.wq_status = &wq_desc->wq_status; >>>> + >>>>           clear_children_join_go_memory(ce); >>>>       } >>>>   } >>>> @@ -2727,11 +2945,21 @@ static void >>>> __guc_context_set_preemption_timeout(struct intel_guc *guc, >>>>                            u16 guc_id, >>>>                            u32 preemption_timeout) >>>>   { >>>> -    struct context_policy policy; >>>> +    if (guc->fw.major_ver_found >= 70) { >>>> +        struct context_policy policy; >>>>   -    __guc_context_policy_start_klv(&policy, guc_id); >>>> - __guc_context_policy_add_preemption_timeout(&policy, >>>> preemption_timeout); >>>> -    __guc_context_set_context_policies(guc, &policy, true); >>>> +        __guc_context_policy_start_klv(&policy, guc_id); >>>> + __guc_context_policy_add_preemption_timeout(&policy, >>>> preemption_timeout); >>>> +        __guc_context_set_context_policies(guc, &policy, true); >>>> +    } else { >>>> +        u32 action[] = { >>>> + INTEL_GUC_ACTION_V69_SET_CONTEXT_PREEMPTION_TIMEOUT, >>>> +            guc_id, >>>> +            preemption_timeout >>>> +        }; >>>> + >>>> +        intel_guc_send_busy_loop(guc, action, ARRAY_SIZE(action), >>>> 0, true); >>>> +    } >>>>   } >>>>     static void >>>> @@ -2982,11 +3210,21 @@ static int guc_context_alloc(struct >>>> intel_context *ce) >>>>   static void __guc_context_set_prio(struct intel_guc *guc, >>>>                      struct intel_context *ce) >>>>   { >>>> -    struct context_policy policy; >>>> +    if (guc->fw.major_ver_found >= 70) { >>>> +        struct context_policy policy; >>>>   -    __guc_context_policy_start_klv(&policy, ce->guc_id.id); >>>> -    __guc_context_policy_add_priority(&policy, ce->guc_state.prio); >>>> -    __guc_context_set_context_policies(guc, &policy, true); >>>> +        __guc_context_policy_start_klv(&policy, ce->guc_id.id); >>>> +        __guc_context_policy_add_priority(&policy, >>>> ce->guc_state.prio); >>>> +        __guc_context_set_context_policies(guc, &policy, true); >>>> +    } else { >>>> +        u32 action[] = { >>>> +            INTEL_GUC_ACTION_V69_SET_CONTEXT_PRIORITY, >>>> +            ce->guc_id.id, >>>> +            ce->guc_state.prio, >>>> +        }; >>>> + >>>> +        guc_submission_send_busy_loop(guc, action, >>>> ARRAY_SIZE(action), 0, true); >>>> +    } >>>>   } >>>>     static void guc_context_set_prio(struct intel_guc *guc, >>>> @@ -4496,17 +4734,19 @@ void >>>> intel_guc_submission_print_context_info(struct intel_guc *guc, >>>>           guc_log_context_priority(p, ce); >>>>             if (intel_context_is_parent(ce)) { >>>> -            struct guc_sched_wq_desc *wq_desc = __get_wq_desc(ce); >>>>               struct intel_context *child; >>>>                 drm_printf(p, "\t\tNumber children: %u\n", >>>>                      ce->parallel.number_children); >>>> -            drm_printf(p, "\t\tWQI Head: %u\n", >>>> -                   READ_ONCE(wq_desc->head)); >>>> -            drm_printf(p, "\t\tWQI Tail: %u\n", >>>> -                   READ_ONCE(wq_desc->tail)); >>>> -            drm_printf(p, "\t\tWQI Status: %u\n\n", >>>> -                   READ_ONCE(wq_desc->wq_status)); >>>> + >>>> +            if (ce->parallel.guc.wq_status) { >>>> +                drm_printf(p, "\t\tWQI Head: %u\n", >>>> + READ_ONCE(*ce->parallel.guc.wq_head)); >>>> +                drm_printf(p, "\t\tWQI Tail: %u\n", >>>> + READ_ONCE(*ce->parallel.guc.wq_tail)); >>>> +                drm_printf(p, "\t\tWQI Status: %u\n\n", >>>> + READ_ONCE(*ce->parallel.guc.wq_status)); >>>> +            } >>>>                 if (ce->engine->emit_bb_start == >>>>                   emit_bb_start_parent_no_preempt_mid_batch) { >>>> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c >>>> b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c >>>> index 27363091e1af..210c84411406 100644 >>>> --- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c >>>> +++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.c >>>> @@ -70,6 +70,23 @@ void intel_uc_fw_change_status(struct >>>> intel_uc_fw *uc_fw, >>>>       fw_def(BROXTON,      0, guc_def(bxt,  70, 1, 1)) \ >>>>       fw_def(SKYLAKE,      0, guc_def(skl,  70, 1, 1)) >>>>   +#define INTEL_GUC_FIRMWARE_DEFS_FALLBACK(fw_def, guc_def) \ >>>> +    fw_def(ALDERLAKE_P,  0, guc_def(adlp, 69, 0, 3)) \ >>>> +    fw_def(ALDERLAKE_S,  0, guc_def(tgl,  69, 0, 3)) \ >>>> +    fw_def(DG1,          0, guc_def(dg1,  69, 0, 3)) \ >>>> +    fw_def(ROCKETLAKE,   0, guc_def(tgl,  69, 0, 3)) \ >>>> +    fw_def(TIGERLAKE,    0, guc_def(tgl,  69, 0, 3)) \ >>>> +    fw_def(JASPERLAKE,   0, guc_def(ehl,  69, 0, 3)) \ >>>> +    fw_def(ELKHARTLAKE,  0, guc_def(ehl,  69, 0, 3)) \ >>>> +    fw_def(ICELAKE,      0, guc_def(icl,  69, 0, 3)) \ >>>> +    fw_def(COMETLAKE,    5, guc_def(cml,  69, 0, 3)) \ >>>> +    fw_def(COMETLAKE,    0, guc_def(kbl,  69, 0, 3)) \ >>>> +    fw_def(COFFEELAKE,   0, guc_def(kbl,  69, 0, 3)) \ >>>> +    fw_def(GEMINILAKE,   0, guc_def(glk,  69, 0, 3)) \ >>>> +    fw_def(KABYLAKE,     0, guc_def(kbl,  69, 0, 3)) \ >>>> +    fw_def(BROXTON,      0, guc_def(bxt,  69, 0, 3)) \ >>>> +    fw_def(SKYLAKE,      0, guc_def(skl,  69, 0, 3)) >>>> + >>>>   #define INTEL_HUC_FIRMWARE_DEFS(fw_def, huc_def) \ >>>>       fw_def(ALDERLAKE_P,  0, huc_def(tgl,  7, 9, 3)) \ >>>>       fw_def(ALDERLAKE_S,  0, huc_def(tgl,  7, 9, 3)) \ >>>> @@ -105,6 +122,7 @@ void intel_uc_fw_change_status(struct >>>> intel_uc_fw *uc_fw, >>>>       MODULE_FIRMWARE(uc_); >>>>     INTEL_GUC_FIRMWARE_DEFS(INTEL_UC_MODULE_FW, MAKE_GUC_FW_PATH) >>>> +INTEL_GUC_FIRMWARE_DEFS_FALLBACK(INTEL_UC_MODULE_FW, >>>> MAKE_GUC_FW_PATH) >>>>   INTEL_HUC_FIRMWARE_DEFS(INTEL_UC_MODULE_FW, MAKE_HUC_FW_PATH) >>>>     /* The below structs and macros are used to iterate across the >>>> list of blobs */ >>>> @@ -149,6 +167,9 @@ __uc_fw_auto_select(struct drm_i915_private >>>> *i915, struct intel_uc_fw *uc_fw) >>>>       static const struct uc_fw_platform_requirement blobs_guc[] = { >>>>           INTEL_GUC_FIRMWARE_DEFS(MAKE_FW_LIST, GUC_FW_BLOB) >>>>       }; >>>> +    static const struct uc_fw_platform_requirement >>>> blobs_guc_fallback[] = { >>>> +        INTEL_GUC_FIRMWARE_DEFS_FALLBACK(MAKE_FW_LIST, GUC_FW_BLOB) >>>> +    }; >>>>       static const struct uc_fw_platform_requirement blobs_huc[] = { >>>>           INTEL_HUC_FIRMWARE_DEFS(MAKE_FW_LIST, HUC_FW_BLOB) >>>>       }; >>>> @@ -179,12 +200,28 @@ __uc_fw_auto_select(struct drm_i915_private >>>> *i915, struct intel_uc_fw *uc_fw) >>>>           if (p == fw_blobs[i].p && rev >= fw_blobs[i].rev) { >>>>               const struct uc_fw_blob *blob = &fw_blobs[i].blob; >>>>               uc_fw->path = blob->path; >>>> +            uc_fw->wanted_path = blob->path; >>>>               uc_fw->major_ver_wanted = blob->major; >>>>               uc_fw->minor_ver_wanted = blob->minor; >>>>               break; >>>>           } >>>>       } >>>>   +    if (uc_fw->type == INTEL_UC_FW_TYPE_GUC) { >>>> +        const struct uc_fw_platform_requirement *blobs = >>>> blobs_guc_fallback; >>>> +        u32 count = ARRAY_SIZE(blobs_guc_fallback); >>>> + >>>> +        for (i = 0; i < count && p <= blobs[i].p; i++) { >>>> +            if (p == blobs[i].p && rev >= blobs[i].rev) { >>>> +                const struct uc_fw_blob *blob = &blobs[i].blob; >>>> +                uc_fw->fallback.path = blob->path; >>>> +                uc_fw->fallback.major_ver = blob->major; >>>> +                uc_fw->fallback.minor_ver = blob->minor; >>>> +                break; >>>> +            } >>>> +        } >>>> +    } >>>> + >>>>       /* make sure the list is ordered as expected */ >>>>       if (IS_ENABLED(CONFIG_DRM_I915_SELFTEST)) { >>>>           for (i = 1; i < fw_count; i++) { >>>> @@ -413,6 +450,18 @@ int intel_uc_fw_fetch(struct intel_uc_fw *uc_fw) >>>>       __force_fw_fetch_failures(uc_fw, -ESTALE); >>>>         err = request_firmware(&fw, uc_fw->path, dev); >>>> +    if (err && !intel_uc_fw_is_overridden(uc_fw) && >>>> uc_fw->fallback.path) { >>>> +        err = request_firmware(&fw, uc_fw->fallback.path, dev); >>>> +        if (!err) { >>>> +            drm_warn(&i915->drm, "%s firmware %s not found, >>>> falling back to %s\n", >>>> + intel_uc_fw_type_repr(uc_fw->type), >>>> +                         uc_fw->wanted_path, >>>> +                         uc_fw->fallback.path); >>>> +            uc_fw->path = uc_fw->fallback.path; >>>> +            uc_fw->major_ver_wanted = uc_fw->fallback.major_ver; >>>> +            uc_fw->minor_ver_wanted = uc_fw->fallback.minor_ver; >>>> +        } >>>> +    } >>>>       if (err) >>>>           goto fail; >>>>   @@ -822,7 +871,13 @@ size_t intel_uc_fw_copy_rsa(struct >>>> intel_uc_fw *uc_fw, void *dst, u32 max_len) >>>>   void intel_uc_fw_dump(const struct intel_uc_fw *uc_fw, struct >>>> drm_printer *p) >>>>   { >>>>       drm_printf(p, "%s firmware: %s\n", >>>> -           intel_uc_fw_type_repr(uc_fw->type), uc_fw->path); >>>> +           intel_uc_fw_type_repr(uc_fw->type), uc_fw->wanted_path); >>>> +    if (uc_fw->fallback.path) { >>>> +        drm_printf(p, "%s firmware fallback: %s\n", >>>> +               intel_uc_fw_type_repr(uc_fw->type), >>>> uc_fw->fallback.path); >>>> +        drm_printf(p, "fallback selected: %s\n", >>>> +               str_yes_no(uc_fw->path == uc_fw->fallback.path)); >>>> +    } >>>>       drm_printf(p, "\tstatus: %s\n", >>>>              intel_uc_fw_status_repr(uc_fw->status)); >>>>       drm_printf(p, "\tversion: wanted %u.%u, found %u.%u\n", >>>> diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h >>>> b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h >>>> index 4f169035f504..7aa2644400b9 100644 >>>> --- a/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h >>>> +++ b/drivers/gpu/drm/i915/gt/uc/intel_uc_fw.h >>>> @@ -74,6 +74,7 @@ struct intel_uc_fw { >>>>           const enum intel_uc_fw_status status; >>>>           enum intel_uc_fw_status __status; /* no accidental >>>> overwrites */ >>>>       }; >>>> +    const char *wanted_path; >>>>       const char *path; >>>>       bool user_overridden; >>>>       size_t size; >>>> @@ -98,6 +99,12 @@ struct intel_uc_fw { >>>>       u16 major_ver_found; >>>>       u16 minor_ver_found; >>>>   +    struct { >>>> +        const char *path; >>>> +        u16 major_ver; >>>> +        u16 minor_ver; >>>> +    } fallback; >>>> + >>>>       u32 rsa_size; >>>>       u32 ucode_size; >>