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 phobos.denx.de (phobos.denx.de [85.214.62.61]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 8BDAECD342F for ; Fri, 8 May 2026 05:48:22 +0000 (UTC) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id C605283CF5; Fri, 8 May 2026 07:48:20 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=reject dis=none) header.from=altera.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (2048-bit key; unprotected) header.d=altera.com header.i=@altera.com header.b="VigXCYZx"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id D5CC284BBD; Fri, 8 May 2026 07:48:19 +0200 (CEST) Received: from CH1PR05CU001.outbound.protection.outlook.com (mail-northcentralusazlp170100001.outbound.protection.outlook.com [IPv6:2a01:111:f403:c105::1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id B9B6F803C6 for ; Fri, 8 May 2026 07:48:14 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=reject dis=none) header.from=altera.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=tien.fong.chee@altera.com ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=JeKePn4cUCEtKj0pLV2OpsGosxNTvLm76akNRzKOHs9TObnBvxbiV03hR6H0COboW0yviawzLKmCQZRB7OSClLmxK8c9iPruRfTmgFTq1LUzonlqvUNhCK+zfLhbSKrCYmWHlT2cEP08dc5RYh9gt8UGine5+v+Fc8WzGcwfPSfN2rQTCIorxCP+HIXH7EsPrEgwe1sx1VTJeJ2yxXYXKT/7wrnlUvX1m/MDgmbNJBwT6wg0rX2tx4TRZhDQ9wHfNmm54HICH16DbYvU2d8cs22fwDQXAEEGYQRjxo347zF2Qb7YR0zwGQr2DyVubcYs1bcKyTgCtrFT3mxXwOAMFA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; 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=+BN2SD8XEDGP1rNqd/RvPtbKsVnDR0BcLjhYO9pJNJI=; b=L0+ZMbOYPsJ6Capekwntze9e5ordprTcYnQlnTlpPg3AE0CUCjjd159zIwSWvr+zr5I3OKKf/+COp759zYNpi85MHajIKddAR5JcFyyCC82ovN3VbYxl5ZA0woW+Z23WmPVUju+H0g09B8WyLogujpunr8Z5cxRE0sd6gBtg6nc9HEOIelhoyiBnbM5cOnEWjZFZUddHfu7vwq7Yu3oM//LeDUlWrjpRub4PbVkj6EcR5XcaPSaGprWKghMA+1C+HnoJhqwyIs2IJoU5jdspbUzLJive0O5lp+w65yzJtumq4ypZDL3oKU/HNrvKf6wmxNjWNenG3/kL9LXl8SEbgg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=altera.com; dmarc=pass action=none header.from=altera.com; dkim=pass header.d=altera.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=altera.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=+BN2SD8XEDGP1rNqd/RvPtbKsVnDR0BcLjhYO9pJNJI=; b=VigXCYZx66th+8HsCB+YseJ5NoM8G2Idm54J6ldjeuHP3Eq50t4oo9ygwcJZNHU/ud17G2Iwm1ACBfQJ2j1gClwaIO2gXUHekb4Wk4kx63WSnJdlYzUlRTzm5iAUtIHKeXh7lHRQXUkrPZP5Em2kArWOtR1QQkDVJjlfQ1RZG74SKTuhwB5iLQR9wlddeMcNJ3biCx2z08669VA+j6lfED/2VUbXmyc2kDBjTg4mrp9iUNI3ZMR0avezMp1+Hp1ulRMgxiA7OeuReZuVbTroPJklDlEuYqN1/eYTGOeE6UpmzsLdoMHc+PoL17ZFPFQhNRb6T7i25WEqsPbNVlBtLg== Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=altera.com; Received: from LV8PR03MB8137.namprd03.prod.outlook.com (2603:10b6:408:295::8) by IA3PR03MB8431.namprd03.prod.outlook.com (2603:10b6:208:540::9) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9891.17; Fri, 8 May 2026 05:48:11 +0000 Received: from LV8PR03MB8137.namprd03.prod.outlook.com ([fe80::efa9:4b97:3b4a:8235]) by LV8PR03MB8137.namprd03.prod.outlook.com ([fe80::efa9:4b97:3b4a:8235%4]) with mapi id 15.20.9891.019; Fri, 8 May 2026 05:48:11 +0000 Message-ID: Date: Fri, 8 May 2026 13:48:00 +0800 User-Agent: Mozilla Thunderbird Subject: Re: [PATCH v2 7/9] clk: s10: Refactor S10 clock driver To: alif.zakuan.yuslaimi@altera.com, u-boot@lists.denx.de Cc: Tom Rini , Marek Vasut , Simon Goldschmidt , Lukasz Majewski , Peng Fan , Jaehoon Chung , Simon Glass , Neil Armstrong , Kory Maincent , Yao Zi References: <20260428034822.23756-1-alif.zakuan.yuslaimi@altera.com> <20260428034822.23756-8-alif.zakuan.yuslaimi@altera.com> Content-Language: en-US From: "Chee, Tien Fong" In-Reply-To: <20260428034822.23756-8-alif.zakuan.yuslaimi@altera.com> Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit X-ClientProxiedBy: SI2PR06CA0001.apcprd06.prod.outlook.com (2603:1096:4:186::21) To LV8PR03MB8137.namprd03.prod.outlook.com (2603:10b6:408:295::8) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: LV8PR03MB8137:EE_|IA3PR03MB8431:EE_ X-MS-Office365-Filtering-Correlation-Id: 674c4738-7002-42d2-299b-08deacc562ee X-MS-Exchange-AtpMessageProperties: SA X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; ARA:13230040|376014|7416014|1800799024|366016|13003099007|3023799003|56012099003|18002099003|22082099003|55112099003; X-Microsoft-Antispam-Message-Info: 2TyzUcZnPdqJpN32jLpKwsEJsyrF8AvGSwNj4uyZTpCV/+na4nDKzFirZeJg7OTpcRTuggfhnTBJxBgC04sv2KNFPoOle2jwO9PI7zJM0KXllrOY2mDJwS2HgQJPLKhJV7sI5qCVF9xEXUyjs6K5ZXFZi+x0lVEVDHt2zhBNggHVte7I+zL0AlEPw2Hcdza+3JUd8hM9b42/r5osqcSr9TVtCCivpcfLTX5gn0ngJ6rjckc0qaOaB51709/PiogQ61LyUrOp80S4+YerPH1UcA4LKGSbO2OKYuRIJAVA9GBcSYcmwdzNio+Y1EBEzggpRkO1QLjdInRCP+n4RJhKPek7qHOvDUUFScGmXymXUhHny5O8Yt8QdqpQmwZoZiyprrz9gcgo7CtWhYID6BJAyKlKpmadMABKDn1pFN3cD3NaFFEz7FXbqDLMK8tZeyuMjCWNC6oDNk/zByRPYz9hbP6esycTb/1TSfbRyOnJsNEa5iyr2LcryKbRrwoBY4DOygnJqGFl4GRJZ0DY6YCaLlPSvd8+IqRg/foJZaZhNLLLRHn6Of9ZDx3ehFyzIqheI6BKQUPFAHeoeaqJ6ziG7DdUC9HJeaRMj5CWmi4QYej3PyV+M3zVfch7tdfFNbbohWqKDDcHioRRo1Vcbt2KqQ== X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:LV8PR03MB8137.namprd03.prod.outlook.com; PTR:; CAT:NONE; SFS:(13230040)(376014)(7416014)(1800799024)(366016)(13003099007)(3023799003)(56012099003)(18002099003)(22082099003)(55112099003); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?utf-8?B?SzZZZmg4RlVJMEsya1JjRVhwTlEvTThDald0UjUxbDZrekVkQUt2YVlGM1d3?= =?utf-8?B?U05qbmhMQWl1NTlMc0xIM3RJTGttUCtDaW1MMEJEcjd0bDlqQTV6OHpnNTRY?= =?utf-8?B?K2c0WnllcTBodExCc2swS3BwaFN2N1ljdi9OVlA5QkVkUThGQVRtVGFqeXpR?= =?utf-8?B?TTFYakxNNjhZWXVGd3UxbjhaQTdheTJpKzRqc1RQdlJ1d0RwNFRxdUxxY09h?= =?utf-8?B?eTNzOEoySGtDVFFUQU8xMkFvc3d4dVM3enFGVk9DTFJteEVYSGNTYkJYb1I3?= =?utf-8?B?QXJWZzd3VE9udm8yOXJYc3ZaZXliT2JqWmRkbldMRUhNNEFhdEhkcWxDQTFX?= =?utf-8?B?RWphUTViOG5DTUhQVEphcmp0UkZmQnlHTzNuTkpUUTBBL012VWdRdDE5a3R6?= =?utf-8?B?VDZRVmRtY2dsNXplVlc4bTRUaHMwOFFSZDZSb3JjUDMrWE94WDQralVYcFJB?= =?utf-8?B?OWhzb05CdmVzRWp4c2dmSkFRRmJGcTBwNVNqcHRhUFQ4dkR4a3FFL3BOaDBj?= =?utf-8?B?NUVlS29jemtVMEh1dWNiVS9aL24xQU9FKy90T3k1TVpURFQwcWcyaVV3Ny9q?= =?utf-8?B?SXJuNGxxbFc0blJNYmN2WWJCbEowZHVPamhWTDFTQi8vL1JCdXhLbVlTK29Q?= =?utf-8?B?Z21OUTI1SCtKZUkveUljZ0dMQTU3czMyaHFtNWJzLzNnbjlnYVZIS1hmaWRE?= =?utf-8?B?cmkrNFhoSG5yMzlkbFdoVjRZQ2NGRDJqeWd4SjRhdGw5Rm0wOHUyUnVCZ0Va?= =?utf-8?B?aGlpcmpLZGR3MnlwbmkyVFYzZWw0L3Z2YTVUbkZkWHMzMTRCRHFsYnplaHd4?= =?utf-8?B?ZjZjSjVrQ2RObHlXaWFSRUIySVNydU40YXpBMk1KMndNanBCS21Nc0FwTHpE?= =?utf-8?B?cCsxbkpCalhQb2FYNkVUNHNEYUo5dDM3OURjczRRaWNiYW9rYXlxS2ViZDBF?= =?utf-8?B?TlNOeXhvdC9Td1VDcDBwWkd5L0VWMnRlSDhobTJNYzhtKzB2TlNZWFRicWN5?= =?utf-8?B?L1BTTEdYNm44a2M2b0ZrT1M1WjZYcDAySHBTOVlYWVdxTkZJRHBUY1I1Si9l?= =?utf-8?B?dHF3M3RaamswOW84alE0YUVHM1Y4WXl2S1VVUXFsQWFkUXI5VDh2SVF1NmZk?= =?utf-8?B?QUJWclREODM4SFVWaHRYK2RITkJiZTBUa1dHYWlKelpsK29YM0J3UEZlSVVo?= =?utf-8?B?cURoV2RKSUpiR3AwbmhTMy9EaHB1ajg5bmhCK2tOWFJmenJRak4ram1mc0w1?= =?utf-8?B?Ry80OW0zblo0SWJUanh4Vkh2Q240dnoybWFEMC9iaGdDdW43R2l4SFlTQjdF?= =?utf-8?B?TitreFYvNVFycWRVOFpMaWxacytOcTJJY0ZsZzFkUTl2S1lwOGQ1dmlYMXAw?= =?utf-8?B?VXlnV3dFUGgwcFF6VXl1Q3NENDd1S0pBTVMyNkxBNXFTdVVTanFVL2Q4dmJP?= =?utf-8?B?d0ttUHVZVkU5REg3emtzY1VNdnBraTZQSDdyT0hpTzVvM0pBRDRMa09PdHBa?= =?utf-8?B?TGswVVFQY0g5SFk3VmFFaFZiOGt4b0V2WGNEU21nSjVZY1AycE5vcGpJUUJ6?= =?utf-8?B?ZzdNczVYU1Jvbk1YMW9IUm9KSG15ZGE5TDExaXpVei80QjNwckdCNDFlSmxk?= =?utf-8?B?WkJuNWZJcER2KzkxMFpCOVR5djVGQTVIMUc2SlVHdE9vazJCMHc1eGp6VEM2?= =?utf-8?B?NlI5N0s5YXU1aHp5TWo0ZHI2M1RLWjNGM2lqTDlFRWJtR1B4NTB5SzRFLzhu?= =?utf-8?B?THc1YnE0NmFKUnlKZWxhZWpid2pzazhLaGN0ZW11TnU2aloraWh5ejRwRFNW?= =?utf-8?B?dmlPdU1oN3IyUzQvY2RhVXJjc3pQUFR2cEVYSEdHL2NvVHRzRmMrM1pNak1Q?= =?utf-8?B?dWlBOTlxcXgwbnpSRTVPbDBGVXJNc3lpZEpnRzJDZHgxRHVWcnNqZFVUNU0x?= =?utf-8?B?ZERvdTJVNDEwRlcxMTZKR0hDL2luRWlSUXVRVnRjRUdzN1hSWnFXZjVMekdj?= =?utf-8?B?alh5aCsvV0Z6K2V2czk5S3k0UklCWEhKQUlvdzJxY1pDbjAxMHlLcFBNYVVW?= =?utf-8?B?QjdOaVhkRzZHb1pEdDk1ZlM3NzR1TW5ZOW42ZU5ydGM4Y2NTdGNtY3dKdzVX?= =?utf-8?B?QWYrS2FmSFFrakRwbkhQTkZCd3VVcTE5N1JDa2JxbVF3YWk4eEIrelZVRHVM?= =?utf-8?B?cHJlSFN3RXVkaXNEVGVPTytNOWc3dXRkVWlvTWxOWlBXSXZVOGV3eFI1Ykhv?= =?utf-8?B?ZUREUEMrdUhjcDZBOHFBSVorUWxOQXA1WDJIMXRCaUVYVlZvdTc2OFZJckVq?= =?utf-8?B?aFAxMjRIMDRtMDR0Y1FhR3VUb0c3eGVCSG82RXl1bGpTSDh4MnQ5TXhvRmk5?= =?utf-8?Q?ripMC4Xye9pqgrFk=3D?= X-OriginatorOrg: altera.com X-MS-Exchange-CrossTenant-Network-Message-Id: 674c4738-7002-42d2-299b-08deacc562ee X-MS-Exchange-CrossTenant-AuthSource: LV8PR03MB8137.namprd03.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 08 May 2026 05:48:10.8871 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: fbd72e03-d4a5-4110-adce-614d51f2077a X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: loWAkoqgNJMXzhJG2ktAyzBOKXXZFViGqoRfRcw+hd8Oue+1+eLd9F+jBP4oyq3ITLNx2dNYmC61SmQEEsmjzYp+NYKNSHZ9usesDomLhHs= X-MS-Exchange-Transport-CrossTenantHeadersStamped: IA3PR03MB8431 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.8 at phobos.denx.de X-Virus-Status: Clean Hi Alif, On 28/4/2026 11:48 am, alif.zakuan.yuslaimi@altera.com wrote: > From: Alif Zakuan Yuslaimi > > Refactor Stratix10 clock manager driver to support driver model, following > Agilex clock driver. > > Create a new clock driver, clk-s10.c, for Stratix10 which supports the > driver model. This allows several APIs such as enable/disable clock, and > get clock rate to be supported. > > This driver will be initialized during SPL to bring up the clock as early > as possible. The clock initialization process are refactored into this new > driver from clock_manager_s10.c during clock driver probe. > > Excluding Stratix10 from legacy method of obtaining clkmgr base address in > mach-socfpga/misc.c as the base address is already obtained during clock > driver probe during SPL initialization. > > Signed-off-by: Alif Zakuan Yuslaimi > --- > MAINTAINERS | 1 + > arch/arm/mach-socfpga/Kconfig | 2 + > arch/arm/mach-socfpga/clock_manager_s10.c | 449 ++----------- > .../include/mach/clock_manager_s10.h | 176 +---- > arch/arm/mach-socfpga/misc.c | 3 +- > arch/arm/mach-socfpga/spl_s10.c | 7 +- > drivers/clk/altera/Makefile | 1 + > drivers/clk/altera/clk-s10.c | 603 ++++++++++++++++++ > drivers/clk/altera/clk-s10.h | 202 ++++++ > 9 files changed, 873 insertions(+), 571 deletions(-) > create mode 100644 drivers/clk/altera/clk-s10.c > create mode 100644 drivers/clk/altera/clk-s10.h > > diff --git a/MAINTAINERS b/MAINTAINERS > index d1173126fc6..032f0ee97fc 100644 > --- a/MAINTAINERS > +++ b/MAINTAINERS > @@ -159,6 +159,7 @@ F: arch/arm/mach-socfpga/ > F: board/altera/stratix10-socdk/ > F: board/intel/agilex-socdk/ > F: configs/socfpga_* > +F: drivers/clk/altera/ > F: drivers/ddr/altera/ > F: drivers/power/domain/altr-pmgr-agilex5.c > F: drivers/sysreset/sysreset_socfpga* > diff --git a/arch/arm/mach-socfpga/Kconfig b/arch/arm/mach-socfpga/Kconfig > index fb98b647442..aa1f3e761cd 100644 > --- a/arch/arm/mach-socfpga/Kconfig > +++ b/arch/arm/mach-socfpga/Kconfig > @@ -146,8 +146,10 @@ config ARCH_SOCFPGA_STRATIX10 > select ARMV8_MULTIENTRY > select ARMV8_SET_SMPEN > select BINMAN if SPL_ATF > + select CLK > select FPGA_INTEL_SDM_MAILBOX > select GICV2 > + select SPL_CLK if SPL > select ARCH_SOCFPGA_SOC64 > > choice > diff --git a/arch/arm/mach-socfpga/clock_manager_s10.c b/arch/arm/mach-socfpga/clock_manager_s10.c > index fd27470f967..df636f14f93 100644 > --- a/arch/arm/mach-socfpga/clock_manager_s10.c > +++ b/arch/arm/mach-socfpga/clock_manager_s10.c > @@ -1,425 +1,78 @@ > // SPDX-License-Identifier: GPL-2.0 > /* > - * Copyright (C) 2016-2023 Intel Corporation all prior copyright notices to be retained > + * Copyright (C) 2026 Altera Corporation > * > */ > > -#include > -#include > -#include > -#include > +#include > +#include > +#include > +#include > #include > -#include > #include > +#include > +#include > > -/* > - * function to write the bypass register which requires a poll of the > - * busy bit > - */ > -static void cm_write_bypass_mainpll(u32 val) > -{ > - writel(val, socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_BYPASS); > - cm_wait_for_fsm(); > -} > - > -static void cm_write_bypass_perpll(u32 val) > -{ > - writel(val, socfpga_get_clkmgr_addr() + CLKMGR_S10_PERPLL_BYPASS); > - cm_wait_for_fsm(); > -} > - > -/* function to write the ctrl register which requires a poll of the busy bit */ > -static void cm_write_ctrl(u32 val) > -{ > - writel(val, socfpga_get_clkmgr_addr() + CLKMGR_S10_CTRL); > - cm_wait_for_fsm(); > -} > - > -/* > - * Setup clocks while making no assumptions about previous state of the clocks. > - */ > -void cm_basic_init(const struct cm_config * const cfg) > -{ > - u32 mdiv, refclkdiv, mscnt, hscnt, vcocalib; > - > - if (cfg == 0) > - return; > - > - /* Put all plls in bypass */ > - cm_write_bypass_mainpll(CLKMGR_BYPASS_MAINPLL_ALL); > - cm_write_bypass_perpll(CLKMGR_BYPASS_PERPLL_ALL); > - > - /* setup main PLL dividers where calculate the vcocalib value */ > - mdiv = (cfg->main_pll_fdbck >> CLKMGR_FDBCK_MDIV_OFFSET) & > - CLKMGR_FDBCK_MDIV_MASK; > - refclkdiv = (cfg->main_pll_pllglob >> CLKMGR_PLLGLOB_REFCLKDIV_OFFSET) & > - CLKMGR_PLLGLOB_REFCLKDIV_MASK; > - mscnt = CLKMGR_MSCNT_CONST / (CLKMGR_MDIV_CONST + mdiv) / refclkdiv; > - hscnt = (mdiv + CLKMGR_MDIV_CONST) * mscnt / refclkdiv - > - CLKMGR_HSCNT_CONST; > - vcocalib = (hscnt & CLKMGR_VCOCALIB_HSCNT_MASK) | > - ((mscnt & CLKMGR_VCOCALIB_MSCNT_MASK) << > - CLKMGR_VCOCALIB_MSCNT_OFFSET); > - > - writel((cfg->main_pll_pllglob & ~CLKMGR_PLLGLOB_PD_MASK & > - ~CLKMGR_PLLGLOB_RST_MASK), > - socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_PLLGLOB); > - writel(cfg->main_pll_fdbck, > - socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_FDBCK); > - writel(vcocalib, > - socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_VCOCALIB); > - writel(cfg->main_pll_pllc0, > - socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_PLLC0); > - writel(cfg->main_pll_pllc1, > - socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_PLLC1); > - writel(cfg->main_pll_nocdiv, > - socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_NOCDIV); > - > - /* setup peripheral PLL dividers */ > - /* calculate the vcocalib value */ > - mdiv = (cfg->per_pll_fdbck >> CLKMGR_FDBCK_MDIV_OFFSET) & > - CLKMGR_FDBCK_MDIV_MASK; > - refclkdiv = (cfg->per_pll_pllglob >> CLKMGR_PLLGLOB_REFCLKDIV_OFFSET) & > - CLKMGR_PLLGLOB_REFCLKDIV_MASK; > - mscnt = CLKMGR_MSCNT_CONST / (CLKMGR_MDIV_CONST + mdiv) / refclkdiv; > - hscnt = (mdiv + CLKMGR_MDIV_CONST) * mscnt / refclkdiv - > - CLKMGR_HSCNT_CONST; > - vcocalib = (hscnt & CLKMGR_VCOCALIB_HSCNT_MASK) | > - ((mscnt & CLKMGR_VCOCALIB_MSCNT_MASK) << > - CLKMGR_VCOCALIB_MSCNT_OFFSET); > - > - writel((cfg->per_pll_pllglob & ~CLKMGR_PLLGLOB_PD_MASK & > - ~CLKMGR_PLLGLOB_RST_MASK), > - socfpga_get_clkmgr_addr() + CLKMGR_S10_PERPLL_PLLGLOB); > - writel(cfg->per_pll_fdbck, > - socfpga_get_clkmgr_addr() + CLKMGR_S10_PERPLL_FDBCK); > - writel(vcocalib, > - socfpga_get_clkmgr_addr() + CLKMGR_S10_PERPLL_VCOCALIB); > - writel(cfg->per_pll_pllc0, > - socfpga_get_clkmgr_addr() + CLKMGR_S10_PERPLL_PLLC0); > - writel(cfg->per_pll_pllc1, > - socfpga_get_clkmgr_addr() + CLKMGR_S10_PERPLL_PLLC1); > - writel(cfg->per_pll_emacctl, > - socfpga_get_clkmgr_addr() + CLKMGR_S10_PERPLL_EMACCTL); > - writel(cfg->per_pll_gpiodiv, > - socfpga_get_clkmgr_addr() + CLKMGR_S10_PERPLL_GPIODIV); > - > - /* Take both PLL out of reset and power up */ > - setbits_le32(socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_PLLGLOB, > - CLKMGR_PLLGLOB_PD_MASK | CLKMGR_PLLGLOB_RST_MASK); > - setbits_le32(socfpga_get_clkmgr_addr() + CLKMGR_S10_PERPLL_PLLGLOB, > - CLKMGR_PLLGLOB_PD_MASK | CLKMGR_PLLGLOB_RST_MASK); > - > -#define LOCKED_MASK \ > - (CLKMGR_STAT_MAINPLL_LOCKED | \ > - CLKMGR_STAT_PERPLL_LOCKED) > - > - cm_wait_for_lock(LOCKED_MASK); > - > - /* > - * Dividers for C2 to C9 only init after PLLs are lock. As dividers > - * only take effect upon value change, we shall set a maximum value as > - * default value. > - */ > - writel(0xff, socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_MPUCLK); > - writel(0xff, socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_NOCCLK); > - writel(0xff, socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_CNTR2CLK); > - writel(0xff, socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_CNTR3CLK); > - writel(0xff, socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_CNTR4CLK); > - writel(0xff, socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_CNTR5CLK); > - writel(0xff, socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_CNTR6CLK); > - writel(0xff, socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_CNTR7CLK); > - writel(0xff, socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_CNTR8CLK); > - writel(0xff, socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_CNTR9CLK); > - writel(0xff, socfpga_get_clkmgr_addr() + CLKMGR_S10_PERPLL_CNTR2CLK); > - writel(0xff, socfpga_get_clkmgr_addr() + CLKMGR_S10_PERPLL_CNTR3CLK); > - writel(0xff, socfpga_get_clkmgr_addr() + CLKMGR_S10_PERPLL_CNTR4CLK); > - writel(0xff, socfpga_get_clkmgr_addr() + CLKMGR_S10_PERPLL_CNTR5CLK); > - writel(0xff, socfpga_get_clkmgr_addr() + CLKMGR_S10_PERPLL_CNTR6CLK); > - writel(0xff, socfpga_get_clkmgr_addr() + CLKMGR_S10_PERPLL_CNTR7CLK); > - writel(0xff, socfpga_get_clkmgr_addr() + CLKMGR_S10_PERPLL_CNTR8CLK); > - writel(0xff, socfpga_get_clkmgr_addr() + CLKMGR_S10_PERPLL_CNTR9CLK); > - > - writel(cfg->main_pll_mpuclk, > - socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_MPUCLK); > - writel(cfg->main_pll_nocclk, > - socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_NOCCLK); > - writel(cfg->main_pll_cntr2clk, > - socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_CNTR2CLK); > - writel(cfg->main_pll_cntr3clk, > - socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_CNTR3CLK); > - writel(cfg->main_pll_cntr4clk, > - socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_CNTR4CLK); > - writel(cfg->main_pll_cntr5clk, > - socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_CNTR5CLK); > - writel(cfg->main_pll_cntr6clk, > - socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_CNTR6CLK); > - writel(cfg->main_pll_cntr7clk, > - socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_CNTR7CLK); > - writel(cfg->main_pll_cntr8clk, > - socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_CNTR8CLK); > - writel(cfg->main_pll_cntr9clk, > - socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_CNTR9CLK); > - writel(cfg->per_pll_cntr2clk, > - socfpga_get_clkmgr_addr() + CLKMGR_S10_PERPLL_CNTR2CLK); > - writel(cfg->per_pll_cntr3clk, > - socfpga_get_clkmgr_addr() + CLKMGR_S10_PERPLL_CNTR3CLK); > - writel(cfg->per_pll_cntr4clk, > - socfpga_get_clkmgr_addr() + CLKMGR_S10_PERPLL_CNTR4CLK); > - writel(cfg->per_pll_cntr5clk, > - socfpga_get_clkmgr_addr() + CLKMGR_S10_PERPLL_CNTR5CLK); > - writel(cfg->per_pll_cntr6clk, > - socfpga_get_clkmgr_addr() + CLKMGR_S10_PERPLL_CNTR6CLK); > - writel(cfg->per_pll_cntr7clk, > - socfpga_get_clkmgr_addr() + CLKMGR_S10_PERPLL_CNTR7CLK); > - writel(cfg->per_pll_cntr8clk, > - socfpga_get_clkmgr_addr() + CLKMGR_S10_PERPLL_CNTR8CLK); > - writel(cfg->per_pll_cntr9clk, > - socfpga_get_clkmgr_addr() + CLKMGR_S10_PERPLL_CNTR9CLK); > - > - /* Take all PLLs out of bypass */ > - cm_write_bypass_mainpll(0); > - cm_write_bypass_perpll(0); > - > - /* clear safe mode / out of boot mode */ > - cm_write_ctrl(readl(socfpga_get_clkmgr_addr() + CLKMGR_S10_CTRL) & > - ~(CLKMGR_CTRL_SAFEMODE)); > - > - /* Now ungate non-hw-managed clocks */ > - writel(~0, socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_EN); > - writel(~0, socfpga_get_clkmgr_addr() + CLKMGR_S10_PERPLL_EN); > - > - /* Clear the loss of lock bits (write 1 to clear) */ > - writel(CLKMGR_INTER_PERPLLLOST_MASK | > - CLKMGR_INTER_MAINPLLLOST_MASK, > - socfpga_get_clkmgr_addr() + CLKMGR_S10_INTRCLR); > -} > - > -static unsigned long cm_get_main_vco_clk_hz(void) > +static ulong cm_get_rate_dm(u32 id) > { > - unsigned long fref, refdiv, mdiv, reg, vco; > - > - reg = readl(socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_PLLGLOB); > - > - fref = (reg >> CLKMGR_PLLGLOB_VCO_PSRC_OFFSET) & > - CLKMGR_PLLGLOB_VCO_PSRC_MASK; > - switch (fref) { > - case CLKMGR_VCO_PSRC_EOSC1: > - fref = cm_get_osc_clk_hz(); > - break; > - case CLKMGR_VCO_PSRC_INTOSC: > - fref = cm_get_intosc_clk_hz(); > - break; > - case CLKMGR_VCO_PSRC_F2S: > - fref = cm_get_fpga_clk_hz(); > - break; > + struct udevice *dev; > + struct clk clk; > + ulong rate; > + int ret; > + > + ret = uclass_get_device_by_driver(UCLASS_CLK, > + DM_DRIVER_GET(socfpga_s10_clk), > + &dev); > + if (ret) > + return 0; > + > + clk.id = id; > + ret = clk_request(dev, &clk); > + if (ret < 0) > + return 0; > + > + rate = clk_get_rate(&clk); > + > + if ((rate == (unsigned long)-ENOSYS) || > + (rate == (unsigned long)-ENXIO) || > + (rate == (unsigned long)-EIO)) { > + debug("%s id %u: clk_get_rate err: %ld\n", > + __func__, id, rate); > + return 0; > } > > - refdiv = (reg >> CLKMGR_PLLGLOB_REFCLKDIV_OFFSET) & > - CLKMGR_PLLGLOB_REFCLKDIV_MASK; > - > - reg = readl(socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_FDBCK); > - mdiv = (reg >> CLKMGR_FDBCK_MDIV_OFFSET) & CLKMGR_FDBCK_MDIV_MASK; > - > - vco = fref / refdiv; > - vco = vco * (CLKMGR_MDIV_CONST + mdiv); > - return vco; > + return rate; > } > > -static unsigned long cm_get_per_vco_clk_hz(void) > +static u32 cm_get_rate_dm_khz(u32 id) > { > - unsigned long fref, refdiv, mdiv, reg, vco; > - > - reg = readl(socfpga_get_clkmgr_addr() + CLKMGR_S10_PERPLL_PLLGLOB); > - > - fref = (reg >> CLKMGR_PLLGLOB_VCO_PSRC_OFFSET) & > - CLKMGR_PLLGLOB_VCO_PSRC_MASK; > - switch (fref) { > - case CLKMGR_VCO_PSRC_EOSC1: > - fref = cm_get_osc_clk_hz(); > - break; > - case CLKMGR_VCO_PSRC_INTOSC: > - fref = cm_get_intosc_clk_hz(); > - break; > - case CLKMGR_VCO_PSRC_F2S: > - fref = cm_get_fpga_clk_hz(); > - break; > - } > - > - refdiv = (reg >> CLKMGR_PLLGLOB_REFCLKDIV_OFFSET) & > - CLKMGR_PLLGLOB_REFCLKDIV_MASK; > - > - reg = readl(socfpga_get_clkmgr_addr() + CLKMGR_S10_PERPLL_FDBCK); > - mdiv = (reg >> CLKMGR_FDBCK_MDIV_OFFSET) & CLKMGR_FDBCK_MDIV_MASK; > - > - vco = fref / refdiv; > - vco = vco * (CLKMGR_MDIV_CONST + mdiv); > - return vco; > + return cm_get_rate_dm(id) / 1000; > } > > unsigned long cm_get_mpu_clk_hz(void) > { > - unsigned long clock = readl(socfpga_get_clkmgr_addr() + > - CLKMGR_S10_MAINPLL_MPUCLK); > - > - clock = (clock >> CLKMGR_CLKSRC_OFFSET) & CLKMGR_CLKSRC_MASK; > - > - switch (clock) { > - case CLKMGR_CLKSRC_MAIN: > - clock = cm_get_main_vco_clk_hz(); > - clock /= (readl(socfpga_get_clkmgr_addr() + > - CLKMGR_S10_MAINPLL_PLLC0) & > - CLKMGR_PLLC0_DIV_MASK); > - break; > - > - case CLKMGR_CLKSRC_PER: > - clock = cm_get_per_vco_clk_hz(); > - clock /= (readl(socfpga_get_clkmgr_addr() + > - CLKMGR_S10_PERPLL_PLLC0) & > - CLKMGR_CLKCNT_MSK); > - break; > - > - case CLKMGR_CLKSRC_OSC1: > - clock = cm_get_osc_clk_hz(); > - break; > - > - case CLKMGR_CLKSRC_INTOSC: > - clock = cm_get_intosc_clk_hz(); > - break; > - > - case CLKMGR_CLKSRC_FPGA: > - clock = cm_get_fpga_clk_hz(); > - break; > - } > - > - clock /= 1 + (readl(socfpga_get_clkmgr_addr() + > - CLKMGR_S10_MAINPLL_MPUCLK) & CLKMGR_CLKCNT_MSK); > - return clock; > -} > - > -unsigned int cm_get_l3_main_clk_hz(void) > -{ > - u32 clock = readl(socfpga_get_clkmgr_addr() + > - CLKMGR_S10_MAINPLL_NOCCLK); > - > - clock = (clock >> CLKMGR_CLKSRC_OFFSET) & CLKMGR_CLKSRC_MASK; > - > - switch (clock) { > - case CLKMGR_CLKSRC_MAIN: > - clock = cm_get_main_vco_clk_hz(); > - clock /= (readl(socfpga_get_clkmgr_addr() + > - CLKMGR_S10_MAINPLL_PLLC1) & > - CLKMGR_PLLC0_DIV_MASK); > - break; > - > - case CLKMGR_CLKSRC_PER: > - clock = cm_get_per_vco_clk_hz(); > - clock /= (readl(socfpga_get_clkmgr_addr() + > - CLKMGR_S10_PERPLL_PLLC1) & CLKMGR_CLKCNT_MSK); > - break; > - > - case CLKMGR_CLKSRC_OSC1: > - clock = cm_get_osc_clk_hz(); > - break; > - > - case CLKMGR_CLKSRC_INTOSC: > - clock = cm_get_intosc_clk_hz(); > - break; > - > - case CLKMGR_CLKSRC_FPGA: > - clock = cm_get_fpga_clk_hz(); > - break; > - } > - > - clock /= 1 + (readl(socfpga_get_clkmgr_addr() + > - CLKMGR_S10_MAINPLL_NOCCLK) & CLKMGR_CLKCNT_MSK); > - return clock; > -} > - > -unsigned int cm_get_mmc_controller_clk_hz(void) > -{ > - u32 clock = readl(socfpga_get_clkmgr_addr() + > - CLKMGR_S10_PERPLL_CNTR6CLK); > - > - clock = (clock >> CLKMGR_CLKSRC_OFFSET) & CLKMGR_CLKSRC_MASK; > - > - switch (clock) { > - case CLKMGR_CLKSRC_MAIN: > - clock = cm_get_l3_main_clk_hz(); > - clock /= 1 + (readl(socfpga_get_clkmgr_addr() + > - CLKMGR_S10_MAINPLL_CNTR6CLK) & > - CLKMGR_CLKCNT_MSK); > - break; > - > - case CLKMGR_CLKSRC_PER: > - clock = cm_get_l3_main_clk_hz(); > - clock /= 1 + (readl(socfpga_get_clkmgr_addr() + > - CLKMGR_S10_PERPLL_CNTR6CLK) & > - CLKMGR_CLKCNT_MSK); > - break; > - > - case CLKMGR_CLKSRC_OSC1: > - clock = cm_get_osc_clk_hz(); > - break; > - > - case CLKMGR_CLKSRC_INTOSC: > - clock = cm_get_intosc_clk_hz(); > - break; > - > - case CLKMGR_CLKSRC_FPGA: > - clock = cm_get_fpga_clk_hz(); > - break; > - } > - return clock / 4; > -} > - > -unsigned int cm_get_l4_sp_clk_hz(void) > -{ > - u32 clock = cm_get_l3_main_clk_hz(); > - > - clock /= (1 << ((readl(socfpga_get_clkmgr_addr() + > - CLKMGR_S10_MAINPLL_NOCDIV) >> > - CLKMGR_NOCDIV_L4SPCLK_OFFSET) & CLKMGR_CLKCNT_MSK)); > - return clock; > -} > - > -unsigned int cm_get_spi_controller_clk_hz(void) > -{ > - u32 clock = cm_get_l3_main_clk_hz(); > - > - clock /= (1 << ((readl(socfpga_get_clkmgr_addr() + > - CLKMGR_S10_MAINPLL_NOCDIV) >> > - CLKMGR_NOCDIV_L4MAIN_OFFSET) & CLKMGR_CLKCNT_MSK)); > - return clock; > + return cm_get_rate_dm(STRATIX10_MPU_CLK); > } > > unsigned int cm_get_l4_sys_free_clk_hz(void) > { > - return cm_get_l3_main_clk_hz() / 4; > -} > - > -/* > - * Override weak dw_spi_get_clk implementation in designware_spi.c driver > - */ > - > -int dw_spi_get_clk(struct udevice *bus, ulong *rate) > -{ > - *rate = cm_get_spi_controller_clk_hz(); > - if (!*rate) { > - printf("SPI: clock rate is zero"); > - return -EINVAL; > - } > - > - return 0; The dw_spi_get_clk() removal and the missing STRATIX10_L4_MAIN_CLK(from upstream dts) in socfpga_clk_get_rate() have impacted the use case where someone enables spi@ffda4000 or spi@ffda5000 in a board DTS for a general-purpose SPI peripheral (not the use case spi0 = &qspi alias) > + return cm_get_rate_dm(STRATIX10_L4_SYS_FREE_CLK); > } > > void cm_print_clock_quick_summary(void) > { > - printf("MPU %d kHz\n", (u32)(cm_get_mpu_clk_hz() / 1000)); > - printf("L3 main %d kHz\n", cm_get_l3_main_clk_hz() / 1000); > - printf("Main VCO %d kHz\n", (u32)(cm_get_main_vco_clk_hz() / 1000)); > - printf("Per VCO %d kHz\n", (u32)(cm_get_per_vco_clk_hz() / 1000)); > - printf("EOSC1 %d kHz\n", cm_get_osc_clk_hz() / 1000); > - printf("HPS MMC %d kHz\n", cm_get_mmc_controller_clk_hz() / 1000); > - printf("UART %d kHz\n", cm_get_l4_sp_clk_hz() / 1000); > + printf("MPU %d kHz\n", > + cm_get_rate_dm_khz(STRATIX10_MPU_CLK)); > + printf("L3 main %d kHz\n", > + cm_get_rate_dm_khz(STRATIX10_NOC_CLK)); > + printf("Main VCO %d kHz\n", > + cm_get_rate_dm_khz(STRATIX10_MAIN_PLL_CLK)); > + printf("Per VCO %d kHz\n", > + cm_get_rate_dm_khz(STRATIX10_PERIPH_PLL_CLK)); > + printf("EOSC1 %d kHz\n", > + cm_get_rate_dm_khz(STRATIX10_OSC1)); > + printf("HPS MMC %d kHz\n", > + cm_get_rate_dm_khz(STRATIX10_SDMMC_CLK)); > + printf("UART %d kHz\n", > + cm_get_rate_dm_khz(STRATIX10_L4_SP_CLK)); > } > diff --git a/arch/arm/mach-socfpga/include/mach/clock_manager_s10.h b/arch/arm/mach-socfpga/include/mach/clock_manager_s10.h > index 5dcbda9473e..e5ff0648b86 100644 > --- a/arch/arm/mach-socfpga/include/mach/clock_manager_s10.h > +++ b/arch/arm/mach-socfpga/include/mach/clock_manager_s10.h > @@ -1,177 +1,13 @@ > -/* SPDX-License-Identifier: GPL-2.0 > - * > - * Copyright (C) 2016-2019 Intel Corporation all prior copyright notices to be retained > +/* SPDX-License-Identifier: GPL-2.0 */ > +/* > + * Copyright (C) 2026 Altera Corporation > * > */ > > -#ifndef _CLOCK_MANAGER_S10_ > -#define _CLOCK_MANAGER_S10_ > +#ifndef _CLOCK_MANAGER_S10_ > +#define _CLOCK_MANAGER_S10_ > > #include > -#include > - > -/* Clock speed accessors */ > -unsigned long cm_get_sdram_clk_hz(void); > -unsigned int cm_get_l4_sp_clk_hz(void); > -unsigned int cm_get_mmc_controller_clk_hz(void); > -unsigned int cm_get_spi_controller_clk_hz(void); > - > -struct cm_config { > - /* main group */ > - u32 main_pll_mpuclk; > - u32 main_pll_nocclk; > - u32 main_pll_cntr2clk; > - u32 main_pll_cntr3clk; > - u32 main_pll_cntr4clk; > - u32 main_pll_cntr5clk; > - u32 main_pll_cntr6clk; > - u32 main_pll_cntr7clk; > - u32 main_pll_cntr8clk; > - u32 main_pll_cntr9clk; > - u32 main_pll_nocdiv; > - u32 main_pll_pllglob; > - u32 main_pll_fdbck; > - u32 main_pll_pllc0; > - u32 main_pll_pllc1; > - u32 spare; > - > - /* peripheral group */ > - u32 per_pll_cntr2clk; > - u32 per_pll_cntr3clk; > - u32 per_pll_cntr4clk; > - u32 per_pll_cntr5clk; > - u32 per_pll_cntr6clk; > - u32 per_pll_cntr7clk; > - u32 per_pll_cntr8clk; > - u32 per_pll_cntr9clk; > - u32 per_pll_emacctl; > - u32 per_pll_gpiodiv; > - u32 per_pll_pllglob; > - u32 per_pll_fdbck; > - u32 per_pll_pllc0; > - u32 per_pll_pllc1; > - > - /* incoming clock */ > - u32 hps_osc_clk_hz; > - u32 fpga_clk_hz; > -}; > - > -void cm_basic_init(const struct cm_config * const cfg); > - > -/* Control status */ > -#define CLKMGR_S10_CTRL 0x00 > -#define CLKMGR_S10_STAT 0x04 > -#define CLKMGR_S10_INTRCLR 0x14 > -/* Mainpll group */ > -#define CLKMGR_S10_MAINPLL_EN 0x30 > -#define CLKMGR_S10_MAINPLL_BYPASS 0x3c > -#define CLKMGR_S10_MAINPLL_MPUCLK 0x48 > -#define CLKMGR_S10_MAINPLL_NOCCLK 0x4c > -#define CLKMGR_S10_MAINPLL_CNTR2CLK 0x50 > -#define CLKMGR_S10_MAINPLL_CNTR3CLK 0x54 > -#define CLKMGR_S10_MAINPLL_CNTR4CLK 0x58 > -#define CLKMGR_S10_MAINPLL_CNTR5CLK 0x5c > -#define CLKMGR_S10_MAINPLL_CNTR6CLK 0x60 > -#define CLKMGR_S10_MAINPLL_CNTR7CLK 0x64 > -#define CLKMGR_S10_MAINPLL_CNTR8CLK 0x68 > -#define CLKMGR_S10_MAINPLL_CNTR9CLK 0x6c > -#define CLKMGR_S10_MAINPLL_NOCDIV 0x70 > -#define CLKMGR_S10_MAINPLL_PLLGLOB 0x74 > -#define CLKMGR_S10_MAINPLL_FDBCK 0x78 > -#define CLKMGR_S10_MAINPLL_MEMSTAT 0x80 > -#define CLKMGR_S10_MAINPLL_PLLC0 0x84 > -#define CLKMGR_S10_MAINPLL_PLLC1 0x88 > -#define CLKMGR_S10_MAINPLL_VCOCALIB 0x8c > -/* Periphpll group */ > -#define CLKMGR_S10_PERPLL_EN 0xa4 > -#define CLKMGR_S10_PERPLL_BYPASS 0xb0 > -#define CLKMGR_S10_PERPLL_CNTR2CLK 0xbc > -#define CLKMGR_S10_PERPLL_CNTR3CLK 0xc0 > -#define CLKMGR_S10_PERPLL_CNTR4CLK 0xc4 > -#define CLKMGR_S10_PERPLL_CNTR5CLK 0xc8 > -#define CLKMGR_S10_PERPLL_CNTR6CLK 0xcc > -#define CLKMGR_S10_PERPLL_CNTR7CLK 0xd0 > -#define CLKMGR_S10_PERPLL_CNTR8CLK 0xd4 > -#define CLKMGR_S10_PERPLL_CNTR9CLK 0xd8 > -#define CLKMGR_S10_PERPLL_EMACCTL 0xdc > -#define CLKMGR_S10_PERPLL_GPIODIV 0xe0 > -#define CLKMGR_S10_PERPLL_PLLGLOB 0xe4 > -#define CLKMGR_S10_PERPLL_FDBCK 0xe8 > -#define CLKMGR_S10_PERPLL_MEMSTAT 0xf0 > -#define CLKMGR_S10_PERPLL_PLLC0 0xf4 > -#define CLKMGR_S10_PERPLL_PLLC1 0xf8 > -#define CLKMGR_S10_PERPLL_VCOCALIB 0xfc > - > -#define CLKMGR_STAT CLKMGR_S10_STAT > -#define CLKMGR_INTER CLKMGR_S10_INTER > -#define CLKMGR_PERPLL_EN CLKMGR_S10_PERPLL_EN > - > -#define CLKMGR_CTRL_SAFEMODE BIT(0) > -#define CLKMGR_BYPASS_MAINPLL_ALL 0x00000007 > -#define CLKMGR_BYPASS_PERPLL_ALL 0x0000007f > - > -#define CLKMGR_INTER_MAINPLLLOCKED_MASK 0x00000001 > -#define CLKMGR_INTER_PERPLLLOCKED_MASK 0x00000002 > -#define CLKMGR_INTER_MAINPLLLOST_MASK 0x00000004 > -#define CLKMGR_INTER_PERPLLLOST_MASK 0x00000008 > -#define CLKMGR_STAT_BUSY BIT(0) > -#define CLKMGR_STAT_MAINPLL_LOCKED BIT(8) > -#define CLKMGR_STAT_PERPLL_LOCKED BIT(9) > - > -#define CLKMGR_PLLGLOB_PD_MASK 0x00000001 > -#define CLKMGR_PLLGLOB_RST_MASK 0x00000002 > -#define CLKMGR_PLLGLOB_VCO_PSRC_MASK 0x3 > -#define CLKMGR_PLLGLOB_VCO_PSRC_OFFSET 16 > -#define CLKMGR_VCO_PSRC_EOSC1 0 > -#define CLKMGR_VCO_PSRC_INTOSC 1 > -#define CLKMGR_VCO_PSRC_F2S 2 > -#define CLKMGR_PLLGLOB_REFCLKDIV_MASK 0x3f > -#define CLKMGR_PLLGLOB_REFCLKDIV_OFFSET 8 > - > -#define CLKMGR_CLKSRC_MASK 0x7 > -#define CLKMGR_CLKSRC_OFFSET 16 > -#define CLKMGR_CLKSRC_MAIN 0 > -#define CLKMGR_CLKSRC_PER 1 > -#define CLKMGR_CLKSRC_OSC1 2 > -#define CLKMGR_CLKSRC_INTOSC 3 > -#define CLKMGR_CLKSRC_FPGA 4 > -#define CLKMGR_CLKCNT_MSK 0x7ff > - > -#define CLKMGR_FDBCK_MDIV_MASK 0xff > -#define CLKMGR_FDBCK_MDIV_OFFSET 24 > - > -#define CLKMGR_PLLC0_DIV_MASK 0xff > -#define CLKMGR_PLLC1_DIV_MASK 0xff > -#define CLKMGR_PLLC0_EN_OFFSET 27 > -#define CLKMGR_PLLC1_EN_OFFSET 24 > - > -#define CLKMGR_NOCDIV_L4MAIN_OFFSET 0 > -#define CLKMGR_NOCDIV_L4MPCLK_OFFSET 8 > -#define CLKMGR_NOCDIV_L4SPCLK_OFFSET 16 > -#define CLKMGR_NOCDIV_CSATCLK_OFFSET 24 > -#define CLKMGR_NOCDIV_CSTRACECLK_OFFSET 26 > -#define CLKMGR_NOCDIV_CSPDBGCLK_OFFSET 28 > - > -#define CLKMGR_NOCDIV_L4SPCLK_MASK 0x3 > -#define CLKMGR_NOCDIV_DIV1 0 > -#define CLKMGR_NOCDIV_DIV2 1 > -#define CLKMGR_NOCDIV_DIV4 2 > -#define CLKMGR_NOCDIV_DIV8 3 > -#define CLKMGR_CSPDBGCLK_DIV1 0 > -#define CLKMGR_CSPDBGCLK_DIV4 1 > - > -#define CLKMGR_MSCNT_CONST 200 > -#define CLKMGR_MDIV_CONST 6 > -#define CLKMGR_HSCNT_CONST 9 > - > -#define CLKMGR_VCOCALIB_MSCNT_MASK 0xff > -#define CLKMGR_VCOCALIB_MSCNT_OFFSET 9 > -#define CLKMGR_VCOCALIB_HSCNT_MASK 0xff > - > -#define CLKMGR_EMACCTL_EMAC0SEL_OFFSET 26 > -#define CLKMGR_EMACCTL_EMAC1SEL_OFFSET 27 > -#define CLKMGR_EMACCTL_EMAC2SEL_OFFSET 28 > - > -#define CLKMGR_PERPLLGRP_EN_SDMMCCLK_MASK 0x00000020 > +#include "../../../../../drivers/clk/altera/clk-s10.h" > > #endif /* _CLOCK_MANAGER_S10_ */ > diff --git a/arch/arm/mach-socfpga/misc.c b/arch/arm/mach-socfpga/misc.c > index 418d7dfb572..6d7128c77be 100644 > --- a/arch/arm/mach-socfpga/misc.c > +++ b/arch/arm/mach-socfpga/misc.c > @@ -276,7 +276,8 @@ void socfpga_get_managers_addr(void) > &socfpga_clkmgr_base); > else if (!IS_ENABLED(CONFIG_ARCH_SOCFPGA_AGILEX) && > !IS_ENABLED(CONFIG_ARCH_SOCFPGA_AGILEX7M) && > - !IS_ENABLED(CONFIG_ARCH_SOCFPGA_AGILEX5)) > + !IS_ENABLED(CONFIG_ARCH_SOCFPGA_AGILEX5) && > + !IS_ENABLED(CONFIG_ARCH_SOCFPGA_STRATIX10)) > ret = socfpga_get_base_addr("altr,clk-mgr", > &socfpga_clkmgr_base); > > diff --git a/arch/arm/mach-socfpga/spl_s10.c b/arch/arm/mach-socfpga/spl_s10.c > index b05bec2cbc1..ace029557f3 100644 > --- a/arch/arm/mach-socfpga/spl_s10.c > +++ b/arch/arm/mach-socfpga/spl_s10.c > @@ -37,7 +37,6 @@ u32 reset_flag(void) > > void board_init_f(ulong dummy) > { > - const struct cm_config *cm_default_cfg = cm_get_default_config(); > int ret; > struct udevice *dev; > > @@ -75,7 +74,11 @@ void board_init_f(ulong dummy) > sysmgr_pinmux_init(); > > /* configuring the HPS clocks */ > - cm_basic_init(cm_default_cfg); > + ret = uclass_get_device(UCLASS_CLK, 0, &dev); > + if (ret) { > + debug("Clock init failed: %d\n", ret); > + hang(); > + } > > #ifdef CONFIG_DEBUG_UART > socfpga_per_reset(SOCFPGA_RESET(UART0), 0); > diff --git a/drivers/clk/altera/Makefile b/drivers/clk/altera/Makefile > index 693446b3d89..e961d059820 100644 > --- a/drivers/clk/altera/Makefile > +++ b/drivers/clk/altera/Makefile > @@ -9,3 +9,4 @@ obj-$(CONFIG_ARCH_SOCFPGA_ARRIA10) += clk-arria10.o > obj-$(CONFIG_ARCH_SOCFPGA_N5X) += clk-n5x.o > obj-$(CONFIG_ARCH_SOCFPGA_N5X) += clk-mem-n5x.o > obj-$(CONFIG_ARCH_SOCFPGA_AGILEX5) += clk-agilex5.o > +obj-$(CONFIG_ARCH_SOCFPGA_STRATIX10) += clk-s10.o > diff --git a/drivers/clk/altera/clk-s10.c b/drivers/clk/altera/clk-s10.c > new file mode 100644 > index 00000000000..c6492e0cb43 > --- /dev/null > +++ b/drivers/clk/altera/clk-s10.c > @@ -0,0 +1,603 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* NEW FILE, but derived from Intel code Copyright (C) 2016-2023 Intel Corporation ← must add (code origin) > + * Copyright (C) 2026 Altera Corporation > + * > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +struct socfpga_clk_plat { > + void __iomem *regs; > + int pllgrp; > + int bitmask; > +}; > + > +/* > + * function to write the bypass register which requires a poll of the > + * busy bit > + */ > +static void clk_write_bypass_mainpll(struct socfpga_clk_plat *plat, u32 val) > +{ > + void __iomem *base = plat->regs; > + > + CM_REG_WRITEL(plat, val, CLKMGR_MAINPLL_BYPASS); > + > + wait_for_bit_le32(base + CLKMGR_STAT, > + CLKMGR_STAT_BUSY, false, 20000, false); > +} > + > +static void clk_write_bypass_perpll(struct socfpga_clk_plat *plat, u32 val) > +{ > + void __iomem *base = plat->regs; > + > + CM_REG_WRITEL(plat, val, CLKMGR_PERPLL_BYPASS); > + > + wait_for_bit_le32(base + CLKMGR_STAT, > + CLKMGR_STAT_BUSY, false, 20000, false); > +} > + > +/* function to write the ctrl register which requires a poll of the busy bit */ > +static void clk_write_ctrl(struct socfpga_clk_plat *plat, u32 val) > +{ > + void __iomem *base = plat->regs; > + > + CM_REG_WRITEL(plat, val, CLKMGR_CTRL); > + > + wait_for_bit_le32(base + CLKMGR_STAT, > + CLKMGR_STAT_BUSY, false, 20000, false); > +} > + > +/* > + * Setup clocks while making no assumptions about previous state of the clocks. > + */ > +static void clk_basic_init(struct udevice *dev, > + const struct cm_config * const cfg) > +{ > + struct socfpga_clk_plat *plat = dev_get_plat(dev); > + u32 mdiv, refclkdiv, mscnt, hscnt, vcocalib; > + uintptr_t base_addr = (uintptr_t)plat->regs; > + > + if (!cfg) > + return; > + > + /* Put all plls in bypass */ > + clk_write_bypass_mainpll(plat, CLKMGR_BYPASS_MAINPLL_ALL); > + clk_write_bypass_perpll(plat, CLKMGR_BYPASS_PERPLL_ALL); > + > + /* setup main PLL dividers where calculate the vcocalib value */ > + mdiv = (cfg->main_pll_fdbck >> CLKMGR_FDBCK_MDIV_OFFSET) & > + CLKMGR_FDBCK_MDIV_MASK; > + refclkdiv = (cfg->main_pll_pllglob >> CLKMGR_PLLGLOB_REFCLKDIV_OFFSET) & > + CLKMGR_PLLGLOB_REFCLKDIV_MASK; > + mscnt = CLKMGR_MSCNT_CONST / (CLKMGR_MDIV_CONST + mdiv) / refclkdiv; > + hscnt = (mdiv + CLKMGR_MDIV_CONST) * mscnt / refclkdiv - > + CLKMGR_HSCNT_CONST; > + vcocalib = (hscnt & CLKMGR_VCOCALIB_HSCNT_MASK) | > + ((mscnt & CLKMGR_VCOCALIB_MSCNT_MASK) << > + CLKMGR_VCOCALIB_MSCNT_OFFSET); > + > + writel((cfg->main_pll_pllglob & ~CLKMGR_PLLGLOB_PD_MASK & > + ~CLKMGR_PLLGLOB_RST_MASK), > + base_addr + CLKMGR_MAINPLL_PLLGLOB); > + writel(cfg->main_pll_fdbck, > + base_addr + CLKMGR_MAINPLL_FDBCK); > + writel(vcocalib, > + base_addr + CLKMGR_MAINPLL_VCOCALIB); > + writel(cfg->main_pll_pllc0, > + base_addr + CLKMGR_MAINPLL_PLLC0); > + writel(cfg->main_pll_pllc1, > + base_addr + CLKMGR_MAINPLL_PLLC1); > + writel(cfg->main_pll_nocdiv, > + base_addr + CLKMGR_MAINPLL_NOCDIV); > + > + /* setup peripheral PLL dividers */ > + /* calculate the vcocalib value */ > + mdiv = (cfg->per_pll_fdbck >> CLKMGR_FDBCK_MDIV_OFFSET) & > + CLKMGR_FDBCK_MDIV_MASK; > + refclkdiv = (cfg->per_pll_pllglob >> CLKMGR_PLLGLOB_REFCLKDIV_OFFSET) & > + CLKMGR_PLLGLOB_REFCLKDIV_MASK; > + mscnt = CLKMGR_MSCNT_CONST / (CLKMGR_MDIV_CONST + mdiv) / refclkdiv; > + hscnt = (mdiv + CLKMGR_MDIV_CONST) * mscnt / refclkdiv - > + CLKMGR_HSCNT_CONST; > + vcocalib = (hscnt & CLKMGR_VCOCALIB_HSCNT_MASK) | > + ((mscnt & CLKMGR_VCOCALIB_MSCNT_MASK) << > + CLKMGR_VCOCALIB_MSCNT_OFFSET); > + > + writel((cfg->per_pll_pllglob & ~CLKMGR_PLLGLOB_PD_MASK & > + ~CLKMGR_PLLGLOB_RST_MASK), > + base_addr + CLKMGR_PERPLL_PLLGLOB); > + writel(cfg->per_pll_fdbck, > + base_addr + CLKMGR_PERPLL_FDBCK); > + writel(vcocalib, > + base_addr + CLKMGR_PERPLL_VCOCALIB); > + writel(cfg->per_pll_pllc0, > + base_addr + CLKMGR_PERPLL_PLLC0); > + writel(cfg->per_pll_pllc1, > + base_addr + CLKMGR_PERPLL_PLLC1); > + writel(cfg->per_pll_emacctl, > + base_addr + CLKMGR_PERPLL_EMACCTL); > + writel(cfg->per_pll_gpiodiv, > + base_addr + CLKMGR_PERPLL_GPIODIV); > + > + /* Take both PLL out of reset and power up */ > + setbits_le32(base_addr + CLKMGR_MAINPLL_PLLGLOB, > + CLKMGR_PLLGLOB_PD_MASK | CLKMGR_PLLGLOB_RST_MASK); > + setbits_le32(base_addr + CLKMGR_PERPLL_PLLGLOB, > + CLKMGR_PLLGLOB_PD_MASK | CLKMGR_PLLGLOB_RST_MASK); > + > + wait_for_bit_le32((const void *)(base_addr + CLKMGR_STAT), > + CLKMGR_STAT_ALLPLL_LOCKED_MASK, true, 20000, false); > + > + /* > + * Dividers for C2 to C9 only init after PLLs are lock. As dividers > + * only take effect upon value change, we shall set a maximum value as > + * default value. > + */ > + writel(0xff, base_addr + CLKMGR_MAINPLL_MPUCLK); > + writel(0xff, base_addr + CLKMGR_MAINPLL_NOCCLK); > + writel(0xff, base_addr + CLKMGR_MAINPLL_CNTR2CLK); > + writel(0xff, base_addr + CLKMGR_MAINPLL_CNTR3CLK); > + writel(0xff, base_addr + CLKMGR_MAINPLL_CNTR4CLK); > + writel(0xff, base_addr + CLKMGR_MAINPLL_CNTR5CLK); > + writel(0xff, base_addr + CLKMGR_MAINPLL_CNTR6CLK); > + writel(0xff, base_addr + CLKMGR_MAINPLL_CNTR7CLK); > + writel(0xff, base_addr + CLKMGR_MAINPLL_CNTR8CLK); > + writel(0xff, base_addr + CLKMGR_MAINPLL_CNTR9CLK); > + writel(0xff, base_addr + CLKMGR_PERPLL_CNTR2CLK); > + writel(0xff, base_addr + CLKMGR_PERPLL_CNTR3CLK); > + writel(0xff, base_addr + CLKMGR_PERPLL_CNTR4CLK); > + writel(0xff, base_addr + CLKMGR_PERPLL_CNTR5CLK); > + writel(0xff, base_addr + CLKMGR_PERPLL_CNTR6CLK); > + writel(0xff, base_addr + CLKMGR_PERPLL_CNTR7CLK); > + writel(0xff, base_addr + CLKMGR_PERPLL_CNTR8CLK); > + writel(0xff, base_addr + CLKMGR_PERPLL_CNTR9CLK); > + > + writel(cfg->main_pll_mpuclk, > + base_addr + CLKMGR_MAINPLL_MPUCLK); > + writel(cfg->main_pll_nocclk, > + base_addr + CLKMGR_MAINPLL_NOCCLK); > + writel(cfg->main_pll_cntr2clk, > + base_addr + CLKMGR_MAINPLL_CNTR2CLK); > + writel(cfg->main_pll_cntr3clk, > + base_addr + CLKMGR_MAINPLL_CNTR3CLK); > + writel(cfg->main_pll_cntr4clk, > + base_addr + CLKMGR_MAINPLL_CNTR4CLK); > + writel(cfg->main_pll_cntr5clk, > + base_addr + CLKMGR_MAINPLL_CNTR5CLK); > + writel(cfg->main_pll_cntr6clk, > + base_addr + CLKMGR_MAINPLL_CNTR6CLK); > + writel(cfg->main_pll_cntr7clk, > + base_addr + CLKMGR_MAINPLL_CNTR7CLK); > + writel(cfg->main_pll_cntr8clk, > + base_addr + CLKMGR_MAINPLL_CNTR8CLK); > + writel(cfg->main_pll_cntr9clk, > + base_addr + CLKMGR_MAINPLL_CNTR9CLK); > + writel(cfg->per_pll_cntr2clk, > + base_addr + CLKMGR_PERPLL_CNTR2CLK); > + writel(cfg->per_pll_cntr3clk, > + base_addr + CLKMGR_PERPLL_CNTR3CLK); > + writel(cfg->per_pll_cntr4clk, > + base_addr + CLKMGR_PERPLL_CNTR4CLK); > + writel(cfg->per_pll_cntr5clk, > + base_addr + CLKMGR_PERPLL_CNTR5CLK); > + writel(cfg->per_pll_cntr6clk, > + base_addr + CLKMGR_PERPLL_CNTR6CLK); > + writel(cfg->per_pll_cntr7clk, > + base_addr + CLKMGR_PERPLL_CNTR7CLK); > + writel(cfg->per_pll_cntr8clk, > + base_addr + CLKMGR_PERPLL_CNTR8CLK); > + writel(cfg->per_pll_cntr9clk, > + base_addr + CLKMGR_PERPLL_CNTR9CLK); > + > + /* Take all PLLs out of bypass */ > + clk_write_bypass_mainpll(plat, 0); > + clk_write_bypass_perpll(plat, 0); > + > +#ifdef COUNTER_FREQUENCY_REAL > + u32 cntfrq = COUNTER_FREQUENCY_REAL; > + u32 counter_freq = 0; > + > + /* Update with accurate clock frequency */ > + if (current_el() == 3) { > + asm volatile("msr cntfrq_el0, %0" : : "r" (cntfrq) : "memory"); > + asm volatile("mrs %0, cntfrq_el0" : "=r" (counter_freq)); > + debug("Counter freq = 0x%x\n", counter_freq); > + } > +#endif > + > + /* clear safe mode / out of boot mode */ > + clk_write_ctrl(plat, readl(base_addr + CLKMGR_CTRL) & > + ~(CLKMGR_CTRL_SAFEMODE)); > + > + /* Now ungate non-hw-managed clocks */ > + writel(~0, base_addr + CLKMGR_MAINPLL_EN); > + writel(~0, base_addr + CLKMGR_PERPLL_EN); > + > + /* Clear the loss of lock bits (write 1 to clear) */ > + writel(CLKMGR_INTER_PERPLLLOST_MASK | > + CLKMGR_INTER_MAINPLLLOST_MASK, > + base_addr + CLKMGR_INTRCLR); > +} > + > +static u64 clk_get_vco_clk_hz(struct socfpga_clk_plat *plat, > + u32 pllglob_reg, u32 fdbck_reg) > +{ > + u64 fref, refdiv, mdiv, reg, vco; > + > + reg = CM_REG_READL(plat, pllglob_reg); > + > + fref = (reg >> CLKMGR_PLLGLOB_VCO_PSRC_OFFSET) & > + CLKMGR_PLLGLOB_VCO_PSRC_MASK; > + > + switch (fref) { > + case CLKMGR_VCO_PSRC_EOSC1: > + fref = cm_get_osc_clk_hz(); > + break; > + case CLKMGR_VCO_PSRC_INTOSC: > + fref = cm_get_intosc_clk_hz(); > + break; > + case CLKMGR_VCO_PSRC_F2S: > + fref = cm_get_fpga_clk_hz(); > + break; > + } > + > + refdiv = (reg >> CLKMGR_PLLGLOB_REFCLKDIV_OFFSET) & > + CLKMGR_PLLGLOB_REFCLKDIV_MASK; > + > + reg = CM_REG_READL(plat, fdbck_reg); > + mdiv = (reg >> CLKMGR_FDBCK_MDIV_OFFSET) & CLKMGR_FDBCK_MDIV_MASK; > + > + vco = fref / refdiv; > + vco = vco * (CLKMGR_MDIV_CONST + mdiv); > + > + return vco; > +} > + > +static u64 clk_get_main_vco_clk_hz(struct socfpga_clk_plat *plat) > +{ > + return clk_get_vco_clk_hz(plat, CLKMGR_MAINPLL_PLLGLOB, > + CLKMGR_MAINPLL_FDBCK); > +} > + > +static u64 clk_get_per_vco_clk_hz(struct socfpga_clk_plat *plat) > +{ > + return clk_get_vco_clk_hz(plat, CLKMGR_PERPLL_PLLGLOB, > + CLKMGR_PERPLL_FDBCK); > +} > + > +static u32 clk_get_5_1_clk_src(struct socfpga_clk_plat *plat, u64 reg) > +{ > + u32 clksrc = CM_REG_READL(plat, reg); > + > + return (clksrc >> CLKMGR_CLKSRC_OFFSET) & CLKMGR_CLKSRC_MASK; > +} > + > +static u64 clk_get_mpu_clk_hz(struct socfpga_clk_plat *plat) > +{ > + u64 clock; > + u32 clklsrc = clk_get_5_1_clk_src(plat, CLKMGR_MAINPLL_MPUCLK); > + > + switch (clklsrc) { > + case CLKMGR_CLKSRC_MAIN: > + clock = clk_get_main_vco_clk_hz(plat); > + clock /= (CM_REG_READL(plat, CLKMGR_MAINPLL_PLLC0) & > + CLKMGR_PLLC0_DIV_MASK); > + break; > + case CLKMGR_CLKSRC_PER: > + clock = clk_get_per_vco_clk_hz(plat); > + clock /= (CM_REG_READL(plat, CLKMGR_PERPLL_PLLC0) & > + CLKMGR_CLKCNT_MSK); > + break; > + case CLKMGR_CLKSRC_OSC1: > + clock = cm_get_osc_clk_hz(); > + break; > + case CLKMGR_CLKSRC_INTOSC: > + clock = cm_get_intosc_clk_hz(); > + break; > + case CLKMGR_CLKSRC_FPGA: > + clock = cm_get_fpga_clk_hz(); > + break; > + default: > + return 0; > + } > + > + clock /= 1 + (CM_REG_READL(plat, CLKMGR_MAINPLL_MPUCLK) & > + CLKMGR_CLKCNT_MSK); > + > + return clock; > +} > + > +static u32 clk_get_l3_main_clk_hz(struct socfpga_clk_plat *plat) > +{ > + u64 clock; > + u32 clklsrc = clk_get_5_1_clk_src(plat, CLKMGR_MAINPLL_NOCCLK); > + > + switch (clklsrc) { > + case CLKMGR_CLKSRC_MAIN: > + clock = clk_get_main_vco_clk_hz(plat); > + clock /= (CM_REG_READL(plat, CLKMGR_MAINPLL_PLLC1) & > + CLKMGR_PLLC0_DIV_MASK); > + break; > + case CLKMGR_CLKSRC_PER: > + clock = clk_get_per_vco_clk_hz(plat); > + clock /= (CM_REG_READL(plat, CLKMGR_PERPLL_PLLC1) & > + CLKMGR_CLKCNT_MSK); > + break; > + case CLKMGR_CLKSRC_OSC1: > + clock = cm_get_osc_clk_hz(); > + break; > + case CLKMGR_CLKSRC_INTOSC: > + clock = cm_get_intosc_clk_hz(); > + break; > + case CLKMGR_CLKSRC_FPGA: > + clock = cm_get_fpga_clk_hz(); > + break; > + default: > + return 0; > + } > + > + clock /= 1 + (CM_REG_READL(plat, CLKMGR_MAINPLL_NOCCLK) & > + CLKMGR_CLKCNT_MSK); > + > + return clock; > +} > + > +static u32 clk_get_sdmmc_clk_hz(struct socfpga_clk_plat *plat) > +{ > + u32 clock; > + u32 clklsrc = clk_get_5_1_clk_src(plat, CLKMGR_PERPLL_CNTR6CLK); > + > + switch (clklsrc) { > + case CLKMGR_CLKSRC_MAIN: > + clock = clk_get_l3_main_clk_hz(plat); > + clock /= 1 + (CM_REG_READL(plat, CLKMGR_MAINPLL_CNTR6CLK) & CLKMGR_CLKCNT_MSK); > + break; > + case CLKMGR_CLKSRC_PER: > + clock = clk_get_l3_main_clk_hz(plat); > + clock /= 1 + (CM_REG_READL(plat, CLKMGR_PERPLL_CNTR6CLK) & CLKMGR_CLKCNT_MSK); > + break; > + case CLKMGR_CLKSRC_OSC1: > + clock = cm_get_osc_clk_hz(); > + break; > + case CLKMGR_CLKSRC_INTOSC: > + clock = cm_get_intosc_clk_hz(); > + break; > + case CLKMGR_CLKSRC_FPGA: > + clock = cm_get_fpga_clk_hz(); > + break; > + default: > + return 0; > + } > + > + return clock / 4; > +} > + > +static u32 clk_get_l4_sp_clk_hz(struct socfpga_clk_plat *plat) > +{ > + u64 clock = clk_get_l3_main_clk_hz(plat); > + > + clock /= BIT((CM_REG_READL(plat, CLKMGR_MAINPLL_NOCDIV) >> > + CLKMGR_NOCDIV_L4SPCLK_OFFSET) & > + CLKMGR_CLKCNT_MSK); > + > + return clock; > +} > + > +static u32 clk_get_l4_sys_free_clk_hz(struct socfpga_clk_plat *plat) > +{ > + if (CM_REG_READL(plat, CLKMGR_STAT) & CLKMGR_STAT_BOOTMODE) > + return clk_get_l3_main_clk_hz(plat) / 2; > + > + return clk_get_l3_main_clk_hz(plat) / 4; > +} > + > +static ulong socfpga_clk_get_rate(struct clk *clk) > +{ > + struct socfpga_clk_plat *plat = dev_get_plat(clk->dev); > + > + switch (clk->id) { > + case STRATIX10_MPU_CLK: > + return clk_get_mpu_clk_hz(plat); > + case STRATIX10_NOC_CLK: > + return clk_get_l3_main_clk_hz(plat); > + case STRATIX10_MAIN_PLL_CLK: > + return clk_get_main_vco_clk_hz(plat); > + case STRATIX10_PERIPH_PLL_CLK: > + return clk_get_per_vco_clk_hz(plat); > + case STRATIX10_OSC1: > + return cm_get_osc_clk_hz(); > + case STRATIX10_SDMMC_CLK: > + return clk_get_sdmmc_clk_hz(plat); > + case STRATIX10_L4_SP_CLK: > + return clk_get_l4_sp_clk_hz(plat); > + case STRATIX10_L4_SYS_FREE_CLK: > + return clk_get_l4_sys_free_clk_hz(plat); missing STRATIX10_L4_MAIN_CLK(from upstream dts for spi0/1), please check whether is name diff between U-Boot & Linux, or missing. > + default: > + return -ENXIO; > + } > +} > + > +static int bitmask_from_clk_id(struct clk *clk) > +{ > + struct socfpga_clk_plat *plat = dev_get_plat(clk->dev); > + > + switch (clk->id) { > + case STRATIX10_MPU_CLK: > + plat->pllgrp = CLKMGR_MAINPLL_EN; > + plat->bitmask = CLKMGR_MAINPLLGRP_EN_MPUCLK_MASK; > + break; > + case STRATIX10_L4_MAIN_CLK: > + plat->pllgrp = CLKMGR_MAINPLL_EN; > + plat->bitmask = CLKMGR_MAINPLLGRP_EN_L4MAINCLK_MASK; > + break; > + case STRATIX10_L4_MP_CLK: > + case STRATIX10_NAND_X_CLK: > + plat->pllgrp = CLKMGR_MAINPLL_EN; > + plat->bitmask = CLKMGR_MAINPLLGRP_EN_L4MPCLK_MASK; > + break; > + case STRATIX10_L4_SP_CLK: > + plat->pllgrp = CLKMGR_MAINPLL_EN; > + plat->bitmask = CLKMGR_MAINPLLGRP_EN_L4SPCLK_MASK; > + break; > + case STRATIX10_CS_AT_CLK: > + plat->pllgrp = CLKMGR_MAINPLL_EN; > + plat->bitmask = CLKMGR_MAINPLLGRP_EN_CSCLK_MASK; > + break; > + case STRATIX10_CS_TRACE_CLK: > + plat->pllgrp = CLKMGR_MAINPLL_EN; > + plat->bitmask = CLKMGR_MAINPLLGRP_EN_CSCLK_MASK; > + break; > + case STRATIX10_CS_PDBG_CLK: > + plat->pllgrp = CLKMGR_MAINPLL_EN; > + plat->bitmask = CLKMGR_MAINPLLGRP_EN_CSCLK_MASK; > + break; > + case STRATIX10_CS_TIMER_CLK: > + plat->pllgrp = CLKMGR_MAINPLL_EN; > + plat->bitmask = CLKMGR_MAINPLLGRP_EN_CSTIMERCLK_MASK; > + break; > + case STRATIX10_S2F_USER0_CLK: > + plat->pllgrp = CLKMGR_MAINPLL_EN; > + plat->bitmask = CLKMGR_MAINPLLGRP_EN_S2FUSER0CLK_MASK; > + break; > + case STRATIX10_EMAC0_CLK: > + plat->pllgrp = CLKMGR_PERPLL_EN; > + plat->bitmask = CLKMGR_PERPLLGRP_EN_EMAC0CLK_MASK; > + break; > + case STRATIX10_EMAC1_CLK: > + plat->pllgrp = CLKMGR_PERPLL_EN; > + plat->bitmask = CLKMGR_PERPLLGRP_EN_EMAC1CLK_MASK; > + break; > + case STRATIX10_EMAC2_CLK: > + plat->pllgrp = CLKMGR_PERPLL_EN; > + plat->bitmask = CLKMGR_PERPLLGRP_EN_EMAC2CLK_MASK; > + break; > + case STRATIX10_EMAC_PTP_CLK: > + plat->pllgrp = CLKMGR_PERPLL_EN; > + plat->bitmask = CLKMGR_PERPLLGRP_EN_EMACPTPCLK_MASK; > + break; > + case STRATIX10_GPIO_DB_CLK: > + plat->pllgrp = CLKMGR_PERPLL_EN; > + plat->bitmask = CLKMGR_PERPLLGRP_EN_GPIODBCLK_MASK; > + break; > + case STRATIX10_SDMMC_CLK: > + plat->pllgrp = CLKMGR_PERPLL_EN; > + plat->bitmask = CLKMGR_PERPLLGRP_EN_SDMMCCLK_MASK; > + break; > + case STRATIX10_S2F_USER1_CLK: > + plat->pllgrp = CLKMGR_PERPLL_EN; > + plat->bitmask = CLKMGR_PERPLLGRP_EN_S2FUSER1CLK_MASK; > + break; > + case STRATIX10_PSI_REF_CLK: > + plat->pllgrp = CLKMGR_PERPLL_EN; > + plat->bitmask = CLKMGR_PERPLLGRP_EN_PSIREFCLK_MASK; > + break; > + case STRATIX10_USB_CLK: > + plat->pllgrp = CLKMGR_PERPLL_EN; > + plat->bitmask = CLKMGR_PERPLLGRP_EN_USBCLK_MASK; > + break; > + case STRATIX10_SPI_M_CLK: > + plat->pllgrp = CLKMGR_PERPLL_EN; > + plat->bitmask = CLKMGR_PERPLLGRP_EN_SPIMCLK_MASK; > + break; > + case STRATIX10_NAND_CLK: > + plat->pllgrp = CLKMGR_PERPLL_EN; > + plat->bitmask = CLKMGR_PERPLLGRP_EN_NANDCLK_MASK; > + break; > + case STRATIX10_L4_SYS_FREE_CLK: > + return -EOPNOTSUPP; > + default: > + return -ENXIO; > + } > + > + return 0; > +} > + > +static int socfpga_clk_enable(struct clk *clk) > +{ > + struct socfpga_clk_plat *plat = dev_get_plat(clk->dev); > + uintptr_t base_addr = (uintptr_t)plat->regs; > + int ret; > + > + ret = bitmask_from_clk_id(clk); > + if (ret == -EOPNOTSUPP) > + return 0; > + > + if (ret) > + return ret; > + > + setbits_le32(base_addr + plat->pllgrp, plat->bitmask); > + > + return 0; > +} > + > +static int socfpga_clk_disable(struct clk *clk) > +{ > + struct socfpga_clk_plat *plat = dev_get_plat(clk->dev); > + uintptr_t base_addr = (uintptr_t)plat->regs; > + int ret; > + > + ret = bitmask_from_clk_id(clk); > + if (ret == -EOPNOTSUPP) > + return 0; > + > + if (ret) > + return ret; > + > + clrbits_le32(base_addr + plat->pllgrp, plat->bitmask); > + > + return 0; > +} > + > +static int socfpga_clk_probe(struct udevice *dev) > +{ > + const struct cm_config *cm_default_cfg = cm_get_default_config(); > + > + clk_basic_init(dev, cm_default_cfg); > + > + return 0; > +} > + > +static int socfpga_clk_of_to_plat(struct udevice *dev) > +{ > + struct socfpga_clk_plat *plat = dev_get_plat(dev); > + fdt_addr_t addr; > + > + addr = dev_read_addr(dev); > + if (addr == FDT_ADDR_T_NONE) > + return -EINVAL; > + plat->regs = (void __iomem *)addr; > + > + return 0; > +} > + > +static struct clk_ops socfpga_clk_ops = { > + .enable = socfpga_clk_enable, > + .disable = socfpga_clk_disable, > + .get_rate = socfpga_clk_get_rate, > +}; > + > +static const struct udevice_id socfpga_clk_match[] = { > + { .compatible = "intel,stratix10-clkmgr" }, > + {} > +}; > + > +U_BOOT_DRIVER(socfpga_s10_clk) = { > + .name = "clk-s10", > + .id = UCLASS_CLK, > + .of_match = socfpga_clk_match, > + .ops = &socfpga_clk_ops, > + .probe = socfpga_clk_probe, > + .of_to_plat = socfpga_clk_of_to_plat, > + .plat_auto = sizeof(struct socfpga_clk_plat), > +}; > diff --git a/drivers/clk/altera/clk-s10.h b/drivers/clk/altera/clk-s10.h > new file mode 100644 > index 00000000000..f5be1e68500 > --- /dev/null > +++ b/drivers/clk/altera/clk-s10.h > @@ -0,0 +1,202 @@ > +/* SPDX-License-Identifier: GPL-2.0 > + * NEW FILE, but derived from Intel code Copyright (C) 2016-2023 Intel Corporation   ← must add (code origin) > + * Copyright (C) 2026 Altera Corporation > + * > + */ > + > +#ifndef _CLK_S10_ > +#define _CLK_S10_ > + Best regards, Tien Fong