From patchwork Tue Aug 9 12:59:51 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ralph Siemsen X-Patchwork-Id: 596220 Delivered-To: patch@linaro.org Received: by 2002:a05:7000:b345:0:0:0:0 with SMTP id w5csp4151541maz; Tue, 9 Aug 2022 06:01:01 -0700 (PDT) X-Google-Smtp-Source: AA6agR7If9h1npaPL/5+msMogcmxn8tuqs4IgAVr+S6oyy0vPZ5A+op9yrnwV+eanI3ERDkokizC X-Received: by 2002:a05:6602:1407:b0:67b:c2ca:f8ef with SMTP id t7-20020a056602140700b0067bc2caf8efmr9547413iov.38.1660050061093; Tue, 09 Aug 2022 06:01:01 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1660050061; cv=none; d=google.com; s=arc-20160816; b=Fa6YAnIw0w7/ZiQRdgLZ5f6eSRMUMykZOEkdR0D11g/pzvbyBYQLZ6BcSV7mKNAGS/ oCjrdYE7PDtOhYlQQ8sUvBFiWU2NWS0O/e4SCNLArE3V1UuvFDzngT8M2J+Bw27yET/g sBp7gdBI5GPqfNf89Q4AVkPIUzgTgBaP4X+23qxRqplpxc8VVDb6dbdp165ur91Zm+fO eeaLfU3wktBApdp7kJ4Cy27OBCPgSFlB9YOG6zPXnmV/ZF3JvRD+ZRTx2Uob4GATU5V6 Mk1fqGrjactICZaurRjYnG7NMX2nxKU+DMT6FUO5vf14AGUKIBLwd9K6AP+O7nevf3Nk NhNg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=nOqdHIFkECrf32zS4bTd/xG/b7sjI0chYma1yIlyktw=; b=X+KBIRx5Jfc/LHUsSCTGwHRVMfP+XZIpbXrp+IeEk5HJXUrLqw1VYdnO+rmeMWkOTP eWT/gnfJj2xGd/r4vMsafwEuF8vf0W3wGiruH4xLyiyQXW8WQ9xHzGmNx6kVL/ANWsGi QnsexGOugCzJY+BD5tkC2nguzfFrgXfvUCEpijxLILER2TCV2a8P60Fg9scQyITatqr9 aX+BamPv7Zz6Fh4sVJsnVhSQ3MCqy302PeJpiCUanZF5LaMjfjyTxjxt74WvK18n/0aT bTGq9Xh3CCSNXDPVnGJ4iAA3c8SayIGBMOMLXCYrgzemZF2I48UEhBtBYoyf9qgkHvXz UHGA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=x9BIs5s7; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 2a01:238:438b:c500:173d:9f52:ddab:ee01 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from phobos.denx.de (phobos.denx.de. [2a01:238:438b:c500:173d:9f52:ddab:ee01]) by mx.google.com with ESMTPS id q125-20020a6b2a83000000b0067c18179c1csi1305070ioq.101.2022.08.09.06.01.00 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 09 Aug 2022 06:01:01 -0700 (PDT) Received-SPF: pass (google.com: domain of u-boot-bounces@lists.denx.de designates 2a01:238:438b:c500:173d:9f52:ddab:ee01 as permitted sender) client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=x9BIs5s7; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 2a01:238:438b:c500:173d:9f52:ddab:ee01 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 2473F84A25; Tue, 9 Aug 2022 15:00:45 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org 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=linaro.org header.i=@linaro.org header.b="x9BIs5s7"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id C289D84A1A; Tue, 9 Aug 2022 15:00:27 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_NONE,SPF_PASS, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-io1-xd33.google.com (mail-io1-xd33.google.com [IPv6:2607:f8b0:4864:20::d33]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 3BC2E84A04 for ; Tue, 9 Aug 2022 15:00:19 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=ralph.siemsen@linaro.org Received: by mail-io1-xd33.google.com with SMTP id d187so2713697iof.4 for ; Tue, 09 Aug 2022 06:00:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc; bh=nOqdHIFkECrf32zS4bTd/xG/b7sjI0chYma1yIlyktw=; b=x9BIs5s7GwLoj/uCdpAhjV4rK9ESYxVUaak+heI0BiZnbmeA/isfSqQD3eaEV2LM/O YBfmmR93i2TnSAYb1hyL6E4l8NujBE2Wgsr6pnWTzPUH347JBWVqtyEjmCB+UMiWNxFq DnMZTploTQC15aRG8s87YEWm6B1tesISqX3XXolycYz6WWG0rMzwnKQd8X077CfRSgsR xhG74kRtKEx+XR5EAVcU6WdtWJKI5sU3YinOgul1rcanMO3OJvBeN2Za6eUx4JvNQG3d hUzm9V/zfxc9HUfSKvrdjNy/JiQ1FFSacU3D/Xd+KJ6mNXq2OmjfyunfXSo4hNP1PZ4L QvDw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc; bh=nOqdHIFkECrf32zS4bTd/xG/b7sjI0chYma1yIlyktw=; b=Ch+4vY9LcA27tyCkRVEZ7qIA7ytQCk6C4tkeOs2v1AboSrMjhcpB6EL3+U7QDWsiD9 2TzpU+INRS7a0/oFBzK153m3m8XdP0jP3LOjXGxCGL2BVD/4jZL8UyTR3vFyzibOcJDo fM+QzieCrYF7ZMMe4tZvrlbiTPVSRS5XW1zQ5vjYg7/Tm5X8P11hAnrQG4u2z1aDP7yC 28rnIoabSyZ/0w5cQmX1nmHXo5WqElmO5irJdoLuGupTkxOw+JqW82wEQOWo+Mn7XNIN o69lDynPLxz7ZOtIbNhs0rJqLJ6HK3KlXqaiv2AHksoWYMkz+rUt2iXK5n8RVqdkWwJY JKuQ== X-Gm-Message-State: ACgBeo3NA9E6TZsF/Eq+JnMFLbm+B01RskFwbYKOBMHITaoCCOPhMRMe 8hqc/t4E+Rr/eHjm6/ENVldvCRwaPLs1ftiQ X-Received: by 2002:a05:6602:2c0c:b0:669:c1a9:245c with SMTP id w12-20020a0566022c0c00b00669c1a9245cmr9489709iov.218.1660050018839; Tue, 09 Aug 2022 06:00:18 -0700 (PDT) Received: from maple.netwinder.org (rfs.netwinder.org. [206.248.184.2]) by smtp.gmail.com with ESMTPSA id g12-20020a056e021a2c00b002dea1e18a94sm1022197ile.47.2022.08.09.06.00.18 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 09 Aug 2022 06:00:18 -0700 (PDT) From: Ralph Siemsen To: u-boot@lists.denx.de Cc: Ralph Siemsen , Andre Przywara Subject: [RFC PATCH v1 1/9] ARM: armv7: add non-SPL enable for Cortex SMPEN Date: Tue, 9 Aug 2022 08:59:51 -0400 Message-Id: <20220809125959.217333-2-ralph.siemsen@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220809125959.217333-1-ralph.siemsen@linaro.org> References: <20220809125959.217333-1-ralph.siemsen@linaro.org> MIME-Version: 1.0 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.6 at phobos.denx.de X-Virus-Status: Clean Commit 2564fce7eea3 ("sunxi: move Cortex SMPEN setting into start.S") added SPL_ARMV7_SET_CORTEX_SMPEN to enable setting SMP bit. For platforms not using SPL boot, add the corresponding non-SPL config, so that CONFIG_IS_ENABLED(ARMV7_SET_CORTEX_SMPEN) works as expected. Signed-off-by: Ralph Siemsen --- This will be used by the following commit that adds ARCH_RZN1. arch/arm/cpu/armv7/Kconfig | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/arm/cpu/armv7/Kconfig b/arch/arm/cpu/armv7/Kconfig index f1e4e26b8f..e33e53636a 100644 --- a/arch/arm/cpu/armv7/Kconfig +++ b/arch/arm/cpu/armv7/Kconfig @@ -107,6 +107,11 @@ config ARMV7_LPAE Say Y here to use the long descriptor page table format. This is required if U-Boot runs in HYP mode. +config ARMV7_SET_CORTEX_SMPEN + bool + help + Enable the ARM Cortex ACTLR.SMP enable bit in U-boot. + config SPL_ARMV7_SET_CORTEX_SMPEN bool help From patchwork Tue Aug 9 12:59:52 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ralph Siemsen X-Patchwork-Id: 596221 Delivered-To: patch@linaro.org Received: by 2002:a05:7000:b345:0:0:0:0 with SMTP id w5csp4151808maz; Tue, 9 Aug 2022 06:01:15 -0700 (PDT) X-Google-Smtp-Source: AA6agR5qJqvQ6Ygi92MWuXSJcy54+l/11VDGX1Pdjuz6/ft5MgppuPXUKpJV+42PCHmjoYVSewyW X-Received: by 2002:a05:6638:1641:b0:342:81be:ed1d with SMTP id a1-20020a056638164100b0034281beed1dmr11010752jat.262.1660050075775; Tue, 09 Aug 2022 06:01:15 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1660050075; cv=none; d=google.com; s=arc-20160816; b=cWNAcJdc2xM0HnAtesFXAZ0xxlN/afgT1d7V0QrnnaaPo/6EIyBzMkDKnq5NwFPv67 OJe1AS4dkPLOE0t6h0IW48J8KvVvFmAwf+wy4wqbUdz7/2lKcCEhrVvHKAReHMzrF2zj bjhy14f7TdtGmimuQmjYsxHd6plSVWwDr8xCR6vBh9DA0SyI3jWh6cDUtDR7FEJoZa2+ SajUQ99MedPwYNmI1E1ThNSvssArC6RZXgHT4aq3JeZOfZ7bwt1smWEez821+KAa4I3G vl2K92KIvRlNJQgMjWjNBZ0ZbTjgV2auPjSBhggmPWuZjc7fKIuKZ9tduYUze6BoJuDY r2rA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=N11XMr9JuNk7JEqk/bX0BJgxBcA1T9LGs8Po6mZuNaU=; b=az+MG+bdWQP2GLMANZsUzWYlEE+XrEbSK8xpYSr45ONdpxzH+W4QZVxJPLsUiR8PnC /nKS3KEj5Z7bqmcKrqROKTNpt/Osn8JbbCuh301SIzwcYe9mexL5V6cGYngQxaJyulTs QPerC1TgJWGKO7+Jqfv0q1KWojBcNxlrYh3uST9i8aDG6ZsQVXPIXIHKpj1hySdfcT4m NgexBgT63HRjIaatSCWCmEMEsPZ5C8H+oeItq13qUpuVIyCUcGCzIM83YWRp0eQu8t+t kFLB3bepf8rxnk/pl6cWPrb5iLe9qQW3WOh+RWG8Fq3Cj38iH/IlVm4Lv9PjXLfbHF7B jtqw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=p1IkkxJr; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from phobos.denx.de (phobos.denx.de. [85.214.62.61]) by mx.google.com with ESMTPS id o8-20020a027408000000b00342d3d9bc62si823419jac.28.2022.08.09.06.01.14 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 09 Aug 2022 06:01:15 -0700 (PDT) Received-SPF: pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 as permitted sender) client-ip=85.214.62.61; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=p1IkkxJr; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 1AD6A84A1E; Tue, 9 Aug 2022 15:00:56 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org 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=linaro.org header.i=@linaro.org header.b="p1IkkxJr"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 0ED3584A14; Tue, 9 Aug 2022 15:00:38 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_NONE,SPF_PASS, T_SCC_BODY_TEXT_LINE autolearn=unavailable autolearn_force=no version=3.4.2 Received: from mail-io1-xd33.google.com (mail-io1-xd33.google.com [IPv6:2607:f8b0:4864:20::d33]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 98DDF849EA for ; Tue, 9 Aug 2022 15:00:25 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=ralph.siemsen@linaro.org Received: by mail-io1-xd33.google.com with SMTP id e69so9478986iof.5 for ; Tue, 09 Aug 2022 06:00:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc; bh=N11XMr9JuNk7JEqk/bX0BJgxBcA1T9LGs8Po6mZuNaU=; b=p1IkkxJr40nyOc/wxVaHrwcNentukzGKdQHPZ1DKDIe0qcLohWWsf0v5FJwGa0nAa6 wjwTwCmc6pdpxzwAn4zEZyBOivciaxM75TYHAeHDzEd4C0m+NjS4Xcqk7MVxhZqJ3O7j mnvImE/NtDgL2fPUhvuOS/xdrubaXMda1nEDcaLthZ4aXgCMziXpAQVjp2l4MXPPNqJ2 jL/9XhEHCUyh3bmZsXotQnugq+mUr8RAyw1ymei3b/C9Jn5HMRNsgqjePVoH20TVDsWu 4hyOVe32RZ9iDM9306WkVS8SzCRCV93cbitRX+QKrtu4olgJu2Z4FDerdrs1Wrd7ZyVm vLjA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc; bh=N11XMr9JuNk7JEqk/bX0BJgxBcA1T9LGs8Po6mZuNaU=; b=dXpCWr6mm3iJaPdcjJK99kCaa/4S2yLGlUCdWbepHzCauhpqyUWsgqSmp0Ij4sK2xL Igh1joo/kOIm4yEwdUCtcNQ2hkNA6b/dsGXYucO4lUpn306NhGFWNXooXeWOhJ92NNbz zIV9bS8owosYmS+ioN33Qk2KoB8XRALy7xgiHmz+ClxMyvY6MzX3OnHMhguJTvyEdT6D +Hzu9tvlNsV0m8TIF9f5Uy3oJ2+W5BzwtvW2WE+2gFOVlo5rFJhW5qhBYcujrllko95u 0otnrnDAKOuMwl8MVN7zH0bTnzeOzfl/yDMNnaDX3+xMI9bKs8KYd2mgIRh5pMtPemH0 qX+w== X-Gm-Message-State: ACgBeo1WCyi3pipcIsmFF1Qh09naDBLoFLr3EnIeS1gQiZ2VNPHbEfGz qdjqpFu1HokwLM0E+ft/4hSUtll9jQiTarWm X-Received: by 2002:a05:6638:44c:b0:342:b431:50d0 with SMTP id r12-20020a056638044c00b00342b43150d0mr9002569jap.253.1660050023725; Tue, 09 Aug 2022 06:00:23 -0700 (PDT) Received: from maple.netwinder.org (rfs.netwinder.org. [206.248.184.2]) by smtp.gmail.com with ESMTPSA id g12-20020a056e021a2c00b002dea1e18a94sm1022197ile.47.2022.08.09.06.00.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 09 Aug 2022 06:00:23 -0700 (PDT) From: Ralph Siemsen To: u-boot@lists.denx.de Cc: Ralph Siemsen , Lukasz Majewski , Sean Anderson Subject: [RFC PATCH v1 2/9] clk: renesas: prepare for non-RCAR clock drivers Date: Tue, 9 Aug 2022 08:59:52 -0400 Message-Id: <20220809125959.217333-3-ralph.siemsen@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220809125959.217333-1-ralph.siemsen@linaro.org> References: <20220809125959.217333-1-ralph.siemsen@linaro.org> MIME-Version: 1.0 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.6 at phobos.denx.de X-Virus-Status: Clean Allow CONFIG_CLK_RENESAS to be set without bringing in RCAR-GEN2/3 code. CONFIG_RENESAS is used in drivers/clk/Makefile to control recursion into the drivers/clk/renesas subdirectory. It also controls compilation of renesas-cpg-mssr.c support code for the RCAR-GEN2 and RCAR-GEN3 devices. The support code contains platform specific hardware access (TMU_BASE), and it is not needed for other Renesas devices such as RZ/N1. Therefore, alter Makefile to build renesas-cpg-mssr.c only for RCAR-GEN2 and RCAR-GEN3. Signed-off-by: Ralph Siemsen Reviewed-by: Sean Anderson --- drivers/clk/renesas/Kconfig | 2 +- drivers/clk/renesas/Makefile | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/clk/renesas/Kconfig b/drivers/clk/renesas/Kconfig index f4d6ef9f93..c53ff3ce01 100644 --- a/drivers/clk/renesas/Kconfig +++ b/drivers/clk/renesas/Kconfig @@ -1,6 +1,6 @@ config CLK_RENESAS bool "Renesas clock drivers" - depends on CLK && ARCH_RMOBILE + depends on CLK && (ARCH_RMOBILE || ARCH_RZN1) help Enable support for clock present on Renesas RCar SoCs. diff --git a/drivers/clk/renesas/Makefile b/drivers/clk/renesas/Makefile index 36a5ca65f4..2cd2c69f68 100644 --- a/drivers/clk/renesas/Makefile +++ b/drivers/clk/renesas/Makefile @@ -1,5 +1,4 @@ -obj-$(CONFIG_CLK_RENESAS) += renesas-cpg-mssr.o -obj-$(CONFIG_CLK_RCAR_GEN2) += clk-rcar-gen2.o +obj-$(CONFIG_CLK_RCAR_GEN2) += clk-rcar-gen2.o renesas-cpg-mssr.o obj-$(CONFIG_CLK_R8A774A1) += r8a774a1-cpg-mssr.o obj-$(CONFIG_CLK_R8A774B1) += r8a774b1-cpg-mssr.o obj-$(CONFIG_CLK_R8A774C0) += r8a774c0-cpg-mssr.o @@ -9,7 +8,7 @@ obj-$(CONFIG_CLK_R8A7791) += r8a7791-cpg-mssr.o obj-$(CONFIG_CLK_R8A7792) += r8a7792-cpg-mssr.o obj-$(CONFIG_CLK_R8A7793) += r8a7791-cpg-mssr.o obj-$(CONFIG_CLK_R8A7794) += r8a7794-cpg-mssr.o -obj-$(CONFIG_CLK_RCAR_GEN3) += clk-rcar-gen3.o +obj-$(CONFIG_CLK_RCAR_GEN3) += clk-rcar-gen3.o renesas-cpg-mssr.o obj-$(CONFIG_CLK_R8A7795) += r8a7795-cpg-mssr.o obj-$(CONFIG_CLK_R8A7796) += r8a7796-cpg-mssr.o obj-$(CONFIG_CLK_R8A77965) += r8a77965-cpg-mssr.o From patchwork Tue Aug 9 12:59:53 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ralph Siemsen X-Patchwork-Id: 596222 Delivered-To: patch@linaro.org Received: by 2002:a05:7000:b345:0:0:0:0 with SMTP id w5csp4152031maz; Tue, 9 Aug 2022 06:01:28 -0700 (PDT) X-Google-Smtp-Source: AA6agR6RaAC8sk0SzN5uxKlIkXYU3p5WV+nrUQLoWPOQeGeRb/9ahikQg95kEtt9SrVCptFXUHYC X-Received: by 2002:a05:6e02:1685:b0:2df:2dd5:80f3 with SMTP id f5-20020a056e02168500b002df2dd580f3mr10389357ila.17.1660050088777; Tue, 09 Aug 2022 06:01:28 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1660050088; cv=none; d=google.com; s=arc-20160816; b=emGE4rL1z/0vCTffSRZmv0ofNvvgC4FX/a4HZEqpYs2jcY1V/MvyAQ98KFQnUf3fdd 7y3+wGfqX/TLpAlXzUCkzq+TrcjyqbHFR4taHq83iWnncT68K3ZzeQbx5vkpd1wIjqZg bXrQXYpuuU6kfIczPN9sw1UuO7qxwB/3g3V645lHkUS2p9p/aGUMGz03SyA7ZRM8MF21 vPm1IQctnaZ52rHUvdaP6a7ARTgvf0mW9cH8AaSswkhrUrKGvZju3drAvBIiBirvfJ8w 64ngyfXXdcrvxdf2I2JU9D1GNp3wDeVSbh4mMQ74sxcLjCUQ3IApR//TcL1lL+qv1B2W H0Eg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=pBm/8hDXmxwpdMyeuvejfg2Zixzt8nMlRUY1VhPhEq8=; b=f79VBzkurHV2BveJfPvQ+1ZgREFCiGkuRC7OoK4/v/rJQJFkmihJojTYEAa2I+5bO6 +CwmOSB/T+luy9zKIjzfmJGC73MxUfaavqUPJIMvqsdfQ84fjH/CR/wj1AMpu+sRKSbw N9Lzq+sUQS0lxRDRyU4shxPNs0/r57YwRQ3faTndSJihIry/D8C1gc7NKy88rpgvboUZ bZywDuXCpfb5NmvbdXXm9jD3Sr6H6sNx5Y/ARkczLwSCcma/h7NYrTr5RQ3zv5PWAlrV kY43sZ5hazqQVsvicRIcYLEkZ+iAIriXsZ9zCDGO1wuHA36Iw6eb5T0ti3rVyKEQcGRm heng== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=NOxj+3x2; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 2a01:238:438b:c500:173d:9f52:ddab:ee01 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from phobos.denx.de (phobos.denx.de. [2a01:238:438b:c500:173d:9f52:ddab:ee01]) by mx.google.com with ESMTPS id g1-20020a056602150100b0067c42b980fcsi2137270iow.23.2022.08.09.06.01.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 09 Aug 2022 06:01:28 -0700 (PDT) Received-SPF: pass (google.com: domain of u-boot-bounces@lists.denx.de designates 2a01:238:438b:c500:173d:9f52:ddab:ee01 as permitted sender) client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=NOxj+3x2; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 2a01:238:438b:c500:173d:9f52:ddab:ee01 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 5CD3684A42; Tue, 9 Aug 2022 15:01:07 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org 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=linaro.org header.i=@linaro.org header.b="NOxj+3x2"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 77C1484A47; Tue, 9 Aug 2022 15:00:52 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_NONE,SPF_PASS, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-io1-xd2a.google.com (mail-io1-xd2a.google.com [IPv6:2607:f8b0:4864:20::d2a]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id BA8B584A04 for ; Tue, 9 Aug 2022 15:00:28 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=ralph.siemsen@linaro.org Received: by mail-io1-xd2a.google.com with SMTP id g15so2973513iob.0 for ; Tue, 09 Aug 2022 06:00:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc; bh=pBm/8hDXmxwpdMyeuvejfg2Zixzt8nMlRUY1VhPhEq8=; b=NOxj+3x2LsFNq1+kfVLjCEVjDV/h/C1acrp1f9jtXgRNPAY2DduQvKcCu1YU3tnB3s Aq7Hw2f/E7+ju+UIGViXmPXZmuB9Wfi4OW0U66d5kUAMY4MAeK51JSapL2mz+VP+13OU g+2Ur3V6Mh4fnTVs79z+LLbLU0xltDkxNPz8mFrYKcBGNR00PbfmTton33zg8fKrg0ds ANh+5lqpjx+/xzGNiUPXGokNZRUgxwFCvBlTWX7Hb3GmFnIwMiCeSw1xElNQZlHRklFm z+gP6Ph/hOzxftLemlHN0Z2qm7my3wi5GFNOLLhR3swGAVSM8VRyBb2tqxfAZA7ZJ2S5 1goQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc; bh=pBm/8hDXmxwpdMyeuvejfg2Zixzt8nMlRUY1VhPhEq8=; b=vX1GWzcMpKY3cOt1EZA0FBDlEMwv9WqaG8QjmpkxDTk8ci8md7ZU5I5IwiNH/Jk4Zb hLzD4BSo8XFgs1p6u27c/SCPT230oU/FLTC0cNiBJGStoe+XvL2Dd8FFx5WBsmNOzX+3 cptPdjOWQEHFsSkgfqEqt7+CLnW3lGQwZehqYbfrHvcCIR/94GAM2B20NIZQJtDEjFJQ Gf80knEBGR63sDcZRY02c/f1llvX0WJ44Ts4+rD2do8Qj6+xQavS8xmv/P4zCe2KTUK+ B2wMxGF/0e0bMR2tYXn/DWqn7sCbp3DwWlzu1hxiMqklnBtR2MufRRBPlAC4NTjK04TY jp9w== X-Gm-Message-State: ACgBeo1yAkUt9IQ/bPzeHrxg0jtlZkCG9+t0fJQsO1hkvr/NwKmVt9G5 Q3jLnTZnDjRWYQRjo4OIRv29aPghnlvFwONP X-Received: by 2002:a05:6638:42cf:b0:343:db8:87c2 with SMTP id bm15-20020a05663842cf00b003430db887c2mr3914944jab.218.1660050026373; Tue, 09 Aug 2022 06:00:26 -0700 (PDT) Received: from maple.netwinder.org (rfs.netwinder.org. [206.248.184.2]) by smtp.gmail.com with ESMTPSA id g12-20020a056e021a2c00b002dea1e18a94sm1022197ile.47.2022.08.09.06.00.25 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 09 Aug 2022 06:00:25 -0700 (PDT) From: Ralph Siemsen To: u-boot@lists.denx.de Cc: Ralph Siemsen , Lukasz Majewski , Sean Anderson Subject: [RFC PATCH v1 3/9] clk: renesas: add R906G032 driver Date: Tue, 9 Aug 2022 08:59:53 -0400 Message-Id: <20220809125959.217333-4-ralph.siemsen@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220809125959.217333-1-ralph.siemsen@linaro.org> References: <20220809125959.217333-1-ralph.siemsen@linaro.org> MIME-Version: 1.0 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.6 at phobos.denx.de X-Virus-Status: Clean Clock driver for the Renesas RZ/N1 SoC family. This is based on the Linux kernel drivers/clk/renesas/r9a06g032-clocks.c. Notable difference: this version avoids allocating a 'struct clk' for each clock source, as this is problematic before relocation. Instead, it uses the same approach as existing Renesas RCAR2/3 clock drivers, using a temporary structure filled on-the-fly. Signed-off-by: Ralph Siemsen --- - TODO: add support for div_table drivers/clk/renesas/Kconfig | 6 + drivers/clk/renesas/Makefile | 1 + drivers/clk/renesas/r9a06g032-clocks.c | 734 +++++++++++++++++++++++++ 3 files changed, 741 insertions(+) create mode 100644 drivers/clk/renesas/r9a06g032-clocks.c diff --git a/drivers/clk/renesas/Kconfig b/drivers/clk/renesas/Kconfig index c53ff3ce01..e2f72fc04f 100644 --- a/drivers/clk/renesas/Kconfig +++ b/drivers/clk/renesas/Kconfig @@ -120,3 +120,9 @@ config CLK_R8A779A0 depends on CLK_RCAR_GEN3 help Enable this to support the clocks on Renesas R8A779A0 SoC. + +config CLK_R9A06G032 + bool "Renesas R9A06G032 clock driver" + depends on CLK_RENESAS + help + Enable this to support the clocks on Renesas R9A06G032 SoC. diff --git a/drivers/clk/renesas/Makefile b/drivers/clk/renesas/Makefile index 2cd2c69f68..9981f1a0bc 100644 --- a/drivers/clk/renesas/Makefile +++ b/drivers/clk/renesas/Makefile @@ -17,3 +17,4 @@ obj-$(CONFIG_CLK_R8A77980) += r8a77980-cpg-mssr.o obj-$(CONFIG_CLK_R8A77990) += r8a77990-cpg-mssr.o obj-$(CONFIG_CLK_R8A77995) += r8a77995-cpg-mssr.o obj-$(CONFIG_CLK_R8A779A0) += r8a779a0-cpg-mssr.o +obj-$(CONFIG_CLK_R9A06G032) += r9a06g032-clocks.o diff --git a/drivers/clk/renesas/r9a06g032-clocks.c b/drivers/clk/renesas/r9a06g032-clocks.c new file mode 100644 index 0000000000..9c8f51eb96 --- /dev/null +++ b/drivers/clk/renesas/r9a06g032-clocks.c @@ -0,0 +1,734 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * R9A06G032 clock driver + * + * Copyright (C) 2018 Renesas Electronics Europe Limited + * + * Michel Pollet , + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +struct r9a06g032_gate { + u16 gate, reset, ready, midle, + scon, mirack, mistat; +}; + +/* This is used to describe a clock for instantiation */ +struct r9a06g032_clkdesc { + const char *name; + uint32_t managed: 1; + uint32_t type: 3; + uint32_t index: 8; + uint32_t source : 8; /* source index + 1 (0 == none) */ + /* these are used to populate the bitsel struct */ + union { + struct r9a06g032_gate gate; + /* for dividers */ + struct { + unsigned int div_min : 10, div_max : 10, reg: 10; + u16 div_table[4]; + }; + /* For fixed-factor ones */ + struct { + u16 div, mul; + }; + /* for dual gate */ + struct { + uint16_t group : 1; + u16 sel, g1, r1, g2, r2; + } dual; + }; +}; + +#define I_GATE(_clk, _rst, _rdy, _midle, _scon, _mirack, _mistat) \ + { .gate = _clk, .reset = _rst, \ + .ready = _rdy, .midle = _midle, \ + .scon = _scon, .mirack = _mirack, .mistat = _mistat } +#define D_GATE(_idx, _n, _src, ...) \ + { .type = K_GATE, .index = R9A06G032_##_idx, \ + .source = 1 + R9A06G032_##_src, .name = _n, \ + .gate = I_GATE(__VA_ARGS__) } +#define D_MODULE(_idx, _n, _src, ...) \ + { .type = K_GATE, .index = R9A06G032_##_idx, \ + .source = 1 + R9A06G032_##_src, .name = _n, \ + .managed = 1, .gate = I_GATE(__VA_ARGS__) } +#define D_ROOT(_idx, _n, _mul, _div) \ + { .type = K_FFC, .index = R9A06G032_##_idx, .name = _n, \ + .div = _div, .mul = _mul } +#define D_FFC(_idx, _n, _src, _div) \ + { .type = K_FFC, .index = R9A06G032_##_idx, \ + .source = 1 + R9A06G032_##_src, .name = _n, \ + .div = _div, .mul = 1} +#define D_DIV(_idx, _n, _src, _reg, _min, _max, ...) \ + { .type = K_DIV, .index = R9A06G032_##_idx, \ + .source = 1 + R9A06G032_##_src, .name = _n, \ + .reg = _reg, .div_min = _min, .div_max = _max, \ + .div_table = { __VA_ARGS__ } } +#define D_UGATE(_idx, _n, _src, _g, _g1, _r1, _g2, _r2) \ + { .type = K_DUALGATE, .index = R9A06G032_##_idx, \ + .source = 1 + R9A06G032_##_src, .name = _n, \ + .dual = { .group = _g, \ + .g1 = _g1, .r1 = _r1, .g2 = _g2, .r2 = _r2 }, } + +enum { K_GATE = 0, K_FFC, K_DIV, K_BITSEL, K_DUALGATE }; + +/* Internal clock IDs */ +#define R9A06G032_CLKOUT 0 +#define R9A06G032_CLKOUT_D10 2 +#define R9A06G032_CLKOUT_D16 3 +#define R9A06G032_CLKOUT_D160 4 +#define R9A06G032_CLKOUT_D1OR2 5 +#define R9A06G032_CLKOUT_D20 6 +#define R9A06G032_CLKOUT_D40 7 +#define R9A06G032_CLKOUT_D5 8 +#define R9A06G032_CLKOUT_D8 9 +#define R9A06G032_DIV_ADC 10 +#define R9A06G032_DIV_I2C 11 +#define R9A06G032_DIV_NAND 12 +#define R9A06G032_DIV_P1_PG 13 +#define R9A06G032_DIV_P2_PG 14 +#define R9A06G032_DIV_P3_PG 15 +#define R9A06G032_DIV_P4_PG 16 +#define R9A06G032_DIV_P5_PG 17 +#define R9A06G032_DIV_P6_PG 18 +#define R9A06G032_DIV_QSPI0 19 +#define R9A06G032_DIV_QSPI1 20 +#define R9A06G032_DIV_REF_SYNC 21 +#define R9A06G032_DIV_SDIO0 22 +#define R9A06G032_DIV_SDIO1 23 +#define R9A06G032_DIV_SWITCH 24 +#define R9A06G032_DIV_UART 25 +#define R9A06G032_DIV_MOTOR 64 +#define R9A06G032_CLK_DDRPHY_PLLCLK_D4 78 +#define R9A06G032_CLK_ECAT100_D4 79 +#define R9A06G032_CLK_HSR100_D2 80 +#define R9A06G032_CLK_REF_SYNC_D4 81 +#define R9A06G032_CLK_REF_SYNC_D8 82 +#define R9A06G032_CLK_SERCOS100_D2 83 +#define R9A06G032_DIV_CA7 84 + +#define R9A06G032_UART_GROUP_012 154 +#define R9A06G032_UART_GROUP_34567 155 + +#define R9A06G032_CLOCK_COUNT (R9A06G032_UART_GROUP_34567 + 1) + +static const struct r9a06g032_clkdesc r9a06g032_clocks[] = { + D_ROOT(CLKOUT, "clkout", 25, 1), + D_ROOT(CLK_PLL_USB, "clk_pll_usb", 12, 10), + D_FFC(CLKOUT_D10, "clkout_d10", CLKOUT, 10), + D_FFC(CLKOUT_D16, "clkout_d16", CLKOUT, 16), + D_FFC(CLKOUT_D160, "clkout_d160", CLKOUT, 160), + D_DIV(CLKOUT_D1OR2, "clkout_d1or2", CLKOUT, 0, 1, 2), + D_FFC(CLKOUT_D20, "clkout_d20", CLKOUT, 20), + D_FFC(CLKOUT_D40, "clkout_d40", CLKOUT, 40), + D_FFC(CLKOUT_D5, "clkout_d5", CLKOUT, 5), + D_FFC(CLKOUT_D8, "clkout_d8", CLKOUT, 8), + D_DIV(DIV_ADC, "div_adc", CLKOUT, 77, 50, 250), + D_DIV(DIV_I2C, "div_i2c", CLKOUT, 78, 12, 16), + D_DIV(DIV_NAND, "div_nand", CLKOUT, 82, 12, 32), + D_DIV(DIV_P1_PG, "div_p1_pg", CLKOUT, 68, 12, 200), + D_DIV(DIV_P2_PG, "div_p2_pg", CLKOUT, 62, 12, 128), + D_DIV(DIV_P3_PG, "div_p3_pg", CLKOUT, 64, 8, 128), + D_DIV(DIV_P4_PG, "div_p4_pg", CLKOUT, 66, 8, 128), + D_DIV(DIV_P5_PG, "div_p5_pg", CLKOUT, 71, 10, 40), + D_DIV(DIV_P6_PG, "div_p6_pg", CLKOUT, 18, 12, 64), + D_DIV(DIV_QSPI0, "div_qspi0", CLKOUT, 73, 3, 7), + D_DIV(DIV_QSPI1, "div_qspi1", CLKOUT, 25, 3, 7), + D_DIV(DIV_REF_SYNC, "div_ref_sync", CLKOUT, 56, 2, 16, 2, 4, 8, 16), + D_DIV(DIV_SDIO0, "div_sdio0", CLKOUT, 74, 20, 128), + D_DIV(DIV_SDIO1, "div_sdio1", CLKOUT, 75, 20, 128), + D_DIV(DIV_SWITCH, "div_switch", CLKOUT, 37, 5, 40), + D_DIV(DIV_UART, "div_uart", CLKOUT, 79, 12, 128), + D_GATE(CLK_25_PG4, "clk_25_pg4", CLKOUT_D40, 0x749, 0x74a, 0x74b, 0, 0xae3, 0, 0), + D_GATE(CLK_25_PG5, "clk_25_pg5", CLKOUT_D40, 0x74c, 0x74d, 0x74e, 0, 0xae4, 0, 0), + D_GATE(CLK_25_PG6, "clk_25_pg6", CLKOUT_D40, 0x74f, 0x750, 0x751, 0, 0xae5, 0, 0), + D_GATE(CLK_25_PG7, "clk_25_pg7", CLKOUT_D40, 0x752, 0x753, 0x754, 0, 0xae6, 0, 0), + D_GATE(CLK_25_PG8, "clk_25_pg8", CLKOUT_D40, 0x755, 0x756, 0x757, 0, 0xae7, 0, 0), + D_GATE(CLK_ADC, "clk_adc", DIV_ADC, 0x1ea, 0x1eb, 0, 0, 0, 0, 0), + D_GATE(CLK_ECAT100, "clk_ecat100", CLKOUT_D10, 0x405, 0, 0, 0, 0, 0, 0), + D_GATE(CLK_HSR100, "clk_hsr100", CLKOUT_D10, 0x483, 0, 0, 0, 0, 0, 0), + D_GATE(CLK_I2C0, "clk_i2c0", DIV_I2C, 0x1e6, 0x1e7, 0, 0, 0, 0, 0), + D_GATE(CLK_I2C1, "clk_i2c1", DIV_I2C, 0x1e8, 0x1e9, 0, 0, 0, 0, 0), + D_GATE(CLK_MII_REF, "clk_mii_ref", CLKOUT_D40, 0x342, 0, 0, 0, 0, 0, 0), + D_GATE(CLK_NAND, "clk_nand", DIV_NAND, 0x284, 0x285, 0, 0, 0, 0, 0), + D_GATE(CLK_NOUSBP2_PG6, "clk_nousbp2_pg6", DIV_P2_PG, 0x774, 0x775, 0, 0, 0, 0, 0), + D_GATE(CLK_P1_PG2, "clk_p1_pg2", DIV_P1_PG, 0x862, 0x863, 0, 0, 0, 0, 0), + D_GATE(CLK_P1_PG3, "clk_p1_pg3", DIV_P1_PG, 0x864, 0x865, 0, 0, 0, 0, 0), + D_GATE(CLK_P1_PG4, "clk_p1_pg4", DIV_P1_PG, 0x866, 0x867, 0, 0, 0, 0, 0), + D_GATE(CLK_P4_PG3, "clk_p4_pg3", DIV_P4_PG, 0x824, 0x825, 0, 0, 0, 0, 0), + D_GATE(CLK_P4_PG4, "clk_p4_pg4", DIV_P4_PG, 0x826, 0x827, 0, 0, 0, 0, 0), + D_GATE(CLK_P6_PG1, "clk_p6_pg1", DIV_P6_PG, 0x8a0, 0x8a1, 0x8a2, 0, 0xb60, 0, 0), + D_GATE(CLK_P6_PG2, "clk_p6_pg2", DIV_P6_PG, 0x8a3, 0x8a4, 0x8a5, 0, 0xb61, 0, 0), + D_GATE(CLK_P6_PG3, "clk_p6_pg3", DIV_P6_PG, 0x8a6, 0x8a7, 0x8a8, 0, 0xb62, 0, 0), + D_GATE(CLK_P6_PG4, "clk_p6_pg4", DIV_P6_PG, 0x8a9, 0x8aa, 0x8ab, 0, 0xb63, 0, 0), + D_MODULE(CLK_PCI_USB, "clk_pci_usb", CLKOUT_D40, 0xe6, 0, 0, 0, 0, 0, 0), + D_GATE(CLK_QSPI0, "clk_qspi0", DIV_QSPI0, 0x2a4, 0x2a5, 0, 0, 0, 0, 0), + D_GATE(CLK_QSPI1, "clk_qspi1", DIV_QSPI1, 0x484, 0x485, 0, 0, 0, 0, 0), + D_GATE(CLK_RGMII_REF, "clk_rgmii_ref", CLKOUT_D8, 0x340, 0, 0, 0, 0, 0, 0), + D_GATE(CLK_RMII_REF, "clk_rmii_ref", CLKOUT_D20, 0x341, 0, 0, 0, 0, 0, 0), + D_GATE(CLK_SDIO0, "clk_sdio0", DIV_SDIO0, 0x64, 0, 0, 0, 0, 0, 0), + D_GATE(CLK_SDIO1, "clk_sdio1", DIV_SDIO1, 0x644, 0, 0, 0, 0, 0, 0), + D_GATE(CLK_SERCOS100, "clk_sercos100", CLKOUT_D10, 0x425, 0, 0, 0, 0, 0, 0), + D_GATE(CLK_SLCD, "clk_slcd", DIV_P1_PG, 0x860, 0x861, 0, 0, 0, 0, 0), + D_GATE(CLK_SPI0, "clk_spi0", DIV_P3_PG, 0x7e0, 0x7e1, 0, 0, 0, 0, 0), + D_GATE(CLK_SPI1, "clk_spi1", DIV_P3_PG, 0x7e2, 0x7e3, 0, 0, 0, 0, 0), + D_GATE(CLK_SPI2, "clk_spi2", DIV_P3_PG, 0x7e4, 0x7e5, 0, 0, 0, 0, 0), + D_GATE(CLK_SPI3, "clk_spi3", DIV_P3_PG, 0x7e6, 0x7e7, 0, 0, 0, 0, 0), + D_GATE(CLK_SPI4, "clk_spi4", DIV_P4_PG, 0x820, 0x821, 0, 0, 0, 0, 0), + D_GATE(CLK_SPI5, "clk_spi5", DIV_P4_PG, 0x822, 0x823, 0, 0, 0, 0, 0), + D_GATE(CLK_SWITCH, "clk_switch", DIV_SWITCH, 0x982, 0x983, 0, 0, 0, 0, 0), + D_DIV(DIV_MOTOR, "div_motor", CLKOUT_D5, 84, 2, 8), + D_MODULE(HCLK_ECAT125, "hclk_ecat125", CLKOUT_D8, 0x400, 0x401, 0, 0x402, 0, 0x440, 0x441), + D_MODULE(HCLK_PINCONFIG, "hclk_pinconfig", CLKOUT_D40, 0x740, 0x741, 0x742, 0, 0xae0, 0, 0), + D_MODULE(HCLK_SERCOS, "hclk_sercos", CLKOUT_D10, 0x420, 0x422, 0, 0x421, 0, 0x460, 0x461), + D_MODULE(HCLK_SGPIO2, "hclk_sgpio2", DIV_P5_PG, 0x8c3, 0x8c4, 0x8c5, 0, 0xb41, 0, 0), + D_MODULE(HCLK_SGPIO3, "hclk_sgpio3", DIV_P5_PG, 0x8c6, 0x8c7, 0x8c8, 0, 0xb42, 0, 0), + D_MODULE(HCLK_SGPIO4, "hclk_sgpio4", DIV_P5_PG, 0x8c9, 0x8ca, 0x8cb, 0, 0xb43, 0, 0), + D_MODULE(HCLK_TIMER0, "hclk_timer0", CLKOUT_D40, 0x743, 0x744, 0x745, 0, 0xae1, 0, 0), + D_MODULE(HCLK_TIMER1, "hclk_timer1", CLKOUT_D40, 0x746, 0x747, 0x748, 0, 0xae2, 0, 0), + D_MODULE(HCLK_USBF, "hclk_usbf", CLKOUT_D8, 0xe3, 0, 0, 0xe4, 0, 0x102, 0x103), + D_MODULE(HCLK_USBH, "hclk_usbh", CLKOUT_D8, 0xe0, 0xe1, 0, 0xe2, 0, 0x100, 0x101), + D_MODULE(HCLK_USBPM, "hclk_usbpm", CLKOUT_D8, 0xe5, 0, 0, 0, 0, 0, 0), + D_GATE(CLK_48_PG_F, "clk_48_pg_f", CLK_48, 0x78c, 0x78d, 0, 0x78e, 0, 0xb04, 0xb05), + D_GATE(CLK_48_PG4, "clk_48_pg4", CLK_48, 0x789, 0x78a, 0x78b, 0, 0xb03, 0, 0), + D_FFC(CLK_DDRPHY_PLLCLK_D4, "clk_ddrphy_pllclk_d4", CLK_DDRPHY_PLLCLK, 4), + D_FFC(CLK_ECAT100_D4, "clk_ecat100_d4", CLK_ECAT100, 4), + D_FFC(CLK_HSR100_D2, "clk_hsr100_d2", CLK_HSR100, 2), + D_FFC(CLK_REF_SYNC_D4, "clk_ref_sync_d4", CLK_REF_SYNC, 4), + D_FFC(CLK_REF_SYNC_D8, "clk_ref_sync_d8", CLK_REF_SYNC, 8), + D_FFC(CLK_SERCOS100_D2, "clk_sercos100_d2", CLK_SERCOS100, 2), + D_DIV(DIV_CA7, "div_ca7", CLK_REF_SYNC, 57, 1, 4, 1, 2, 4), + D_MODULE(HCLK_CAN0, "hclk_can0", CLK_48, 0x783, 0x784, 0x785, 0, 0xb01, 0, 0), + D_MODULE(HCLK_CAN1, "hclk_can1", CLK_48, 0x786, 0x787, 0x788, 0, 0xb02, 0, 0), + D_MODULE(HCLK_DELTASIGMA, "hclk_deltasigma", DIV_MOTOR, 0x1ef, 0x1f0, 0x1f1, 0, 0, 0, 0), + D_MODULE(HCLK_PWMPTO, "hclk_pwmpto", DIV_MOTOR, 0x1ec, 0x1ed, 0x1ee, 0, 0, 0, 0), + D_MODULE(HCLK_RSV, "hclk_rsv", CLK_48, 0x780, 0x781, 0x782, 0, 0xb00, 0, 0), + D_MODULE(HCLK_SGPIO0, "hclk_sgpio0", DIV_MOTOR, 0x1e0, 0x1e1, 0x1e2, 0, 0, 0, 0), + D_MODULE(HCLK_SGPIO1, "hclk_sgpio1", DIV_MOTOR, 0x1e3, 0x1e4, 0x1e5, 0, 0, 0, 0), + D_DIV(RTOS_MDC, "rtos_mdc", CLK_REF_SYNC, 100, 80, 640, 80, 160, 320, 640), + D_GATE(CLK_CM3, "clk_cm3", CLK_REF_SYNC_D4, 0xba0, 0xba1, 0, 0xba2, 0, 0xbc0, 0xbc1), + D_GATE(CLK_DDRC, "clk_ddrc", CLK_DDRPHY_PLLCLK_D4, 0x323, 0x324, 0, 0, 0, 0, 0), + D_GATE(CLK_ECAT25, "clk_ecat25", CLK_ECAT100_D4, 0x403, 0x404, 0, 0, 0, 0, 0), + D_GATE(CLK_HSR50, "clk_hsr50", CLK_HSR100_D2, 0x484, 0x485, 0, 0, 0, 0, 0), + D_GATE(CLK_HW_RTOS, "clk_hw_rtos", CLK_REF_SYNC_D4, 0xc60, 0xc61, 0, 0, 0, 0, 0), + D_GATE(CLK_SERCOS50, "clk_sercos50", CLK_SERCOS100_D2, 0x424, 0x423, 0, 0, 0, 0, 0), + D_MODULE(HCLK_ADC, "hclk_adc", CLK_REF_SYNC_D8, 0x1af, 0x1b0, 0x1b1, 0, 0, 0, 0), + D_MODULE(HCLK_CM3, "hclk_cm3", CLK_REF_SYNC_D4, 0xc20, 0xc21, 0xc22, 0, 0, 0, 0), + D_MODULE(HCLK_CRYPTO_EIP150, "hclk_crypto_eip150", CLK_REF_SYNC_D4, 0x123, 0x124, 0x125, 0, 0x142, 0, 0), + D_MODULE(HCLK_CRYPTO_EIP93, "hclk_crypto_eip93", CLK_REF_SYNC_D4, 0x120, 0x121, 0, 0x122, 0, 0x140, 0x141), + D_MODULE(HCLK_DDRC, "hclk_ddrc", CLK_REF_SYNC_D4, 0x320, 0x322, 0, 0x321, 0, 0x3a0, 0x3a1), + D_MODULE(HCLK_DMA0, "hclk_dma0", CLK_REF_SYNC_D4, 0x260, 0x261, 0x262, 0x263, 0x2c0, 0x2c1, 0x2c2), + D_MODULE(HCLK_DMA1, "hclk_dma1", CLK_REF_SYNC_D4, 0x264, 0x265, 0x266, 0x267, 0x2c3, 0x2c4, 0x2c5), + D_MODULE(HCLK_GMAC0, "hclk_gmac0", CLK_REF_SYNC_D4, 0x360, 0x361, 0x362, 0x363, 0x3c0, 0x3c1, 0x3c2), + D_MODULE(HCLK_GMAC1, "hclk_gmac1", CLK_REF_SYNC_D4, 0x380, 0x381, 0x382, 0x383, 0x3e0, 0x3e1, 0x3e2), + D_MODULE(HCLK_GPIO0, "hclk_gpio0", CLK_REF_SYNC_D4, 0x212, 0x213, 0x214, 0, 0, 0, 0), + D_MODULE(HCLK_GPIO1, "hclk_gpio1", CLK_REF_SYNC_D4, 0x215, 0x216, 0x217, 0, 0, 0, 0), + D_MODULE(HCLK_GPIO2, "hclk_gpio2", CLK_REF_SYNC_D4, 0x229, 0x22a, 0x22b, 0, 0, 0, 0), + D_MODULE(HCLK_HSR, "hclk_hsr", CLK_HSR100_D2, 0x480, 0x482, 0, 0x481, 0, 0x4c0, 0x4c1), + D_MODULE(HCLK_I2C0, "hclk_i2c0", CLK_REF_SYNC_D8, 0x1a9, 0x1aa, 0x1ab, 0, 0, 0, 0), + D_MODULE(HCLK_I2C1, "hclk_i2c1", CLK_REF_SYNC_D8, 0x1ac, 0x1ad, 0x1ae, 0, 0, 0, 0), + D_MODULE(HCLK_LCD, "hclk_lcd", CLK_REF_SYNC_D4, 0x7a0, 0x7a1, 0x7a2, 0, 0xb20, 0, 0), + D_MODULE(HCLK_MSEBI_M, "hclk_msebi_m", CLK_REF_SYNC_D4, 0x164, 0x165, 0x166, 0, 0x183, 0, 0), + D_MODULE(HCLK_MSEBI_S, "hclk_msebi_s", CLK_REF_SYNC_D4, 0x160, 0x161, 0x162, 0x163, 0x180, 0x181, 0x182), + D_MODULE(HCLK_NAND, "hclk_nand", CLK_REF_SYNC_D4, 0x280, 0x281, 0x282, 0x283, 0x2e0, 0x2e1, 0x2e2), + D_MODULE(HCLK_PG_I, "hclk_pg_i", CLK_REF_SYNC_D4, 0x7ac, 0x7ad, 0, 0x7ae, 0, 0xb24, 0xb25), + D_MODULE(HCLK_PG19, "hclk_pg19", CLK_REF_SYNC_D4, 0x22c, 0x22d, 0x22e, 0, 0, 0, 0), + D_MODULE(HCLK_PG20, "hclk_pg20", CLK_REF_SYNC_D4, 0x22f, 0x230, 0x231, 0, 0, 0, 0), + D_MODULE(HCLK_PG3, "hclk_pg3", CLK_REF_SYNC_D4, 0x7a6, 0x7a7, 0x7a8, 0, 0xb22, 0, 0), + D_MODULE(HCLK_PG4, "hclk_pg4", CLK_REF_SYNC_D4, 0x7a9, 0x7aa, 0x7ab, 0, 0xb23, 0, 0), + D_MODULE(HCLK_QSPI0, "hclk_qspi0", CLK_REF_SYNC_D4, 0x2a0, 0x2a1, 0x2a2, 0x2a3, 0x300, 0x301, 0x302), + D_MODULE(HCLK_QSPI1, "hclk_qspi1", CLK_REF_SYNC_D4, 0x480, 0x481, 0x482, 0x483, 0x4c0, 0x4c1, 0x4c2), + D_MODULE(HCLK_ROM, "hclk_rom", CLK_REF_SYNC_D4, 0xaa0, 0xaa1, 0xaa2, 0, 0xb80, 0, 0), + D_MODULE(HCLK_RTC, "hclk_rtc", CLK_REF_SYNC_D8, 0xa00, 0, 0, 0, 0, 0, 0), + D_MODULE(HCLK_SDIO0, "hclk_sdio0", CLK_REF_SYNC_D4, 0x60, 0x61, 0x62, 0x63, 0x80, 0x81, 0x82), + D_MODULE(HCLK_SDIO1, "hclk_sdio1", CLK_REF_SYNC_D4, 0x640, 0x641, 0x642, 0x643, 0x660, 0x661, 0x662), + D_MODULE(HCLK_SEMAP, "hclk_semap", CLK_REF_SYNC_D4, 0x7a3, 0x7a4, 0x7a5, 0, 0xb21, 0, 0), + D_MODULE(HCLK_SPI0, "hclk_spi0", CLK_REF_SYNC_D4, 0x200, 0x201, 0x202, 0, 0, 0, 0), + D_MODULE(HCLK_SPI1, "hclk_spi1", CLK_REF_SYNC_D4, 0x203, 0x204, 0x205, 0, 0, 0, 0), + D_MODULE(HCLK_SPI2, "hclk_spi2", CLK_REF_SYNC_D4, 0x206, 0x207, 0x208, 0, 0, 0, 0), + D_MODULE(HCLK_SPI3, "hclk_spi3", CLK_REF_SYNC_D4, 0x209, 0x20a, 0x20b, 0, 0, 0, 0), + D_MODULE(HCLK_SPI4, "hclk_spi4", CLK_REF_SYNC_D4, 0x20c, 0x20d, 0x20e, 0, 0, 0, 0), + D_MODULE(HCLK_SPI5, "hclk_spi5", CLK_REF_SYNC_D4, 0x20f, 0x210, 0x211, 0, 0, 0, 0), + D_MODULE(HCLK_SWITCH, "hclk_switch", CLK_REF_SYNC_D4, 0x980, 0, 0x981, 0, 0, 0, 0), + D_MODULE(HCLK_SWITCH_RG, "hclk_switch_rg", CLK_REF_SYNC_D4, 0xc40, 0xc41, 0xc42, 0, 0, 0, 0), + D_MODULE(HCLK_UART0, "hclk_uart0", CLK_REF_SYNC_D8, 0x1a0, 0x1a1, 0x1a2, 0, 0, 0, 0), + D_MODULE(HCLK_UART1, "hclk_uart1", CLK_REF_SYNC_D8, 0x1a3, 0x1a4, 0x1a5, 0, 0, 0, 0), + D_MODULE(HCLK_UART2, "hclk_uart2", CLK_REF_SYNC_D8, 0x1a6, 0x1a7, 0x1a8, 0, 0, 0, 0), + D_MODULE(HCLK_UART3, "hclk_uart3", CLK_REF_SYNC_D4, 0x218, 0x219, 0x21a, 0, 0, 0, 0), + D_MODULE(HCLK_UART4, "hclk_uart4", CLK_REF_SYNC_D4, 0x21b, 0x21c, 0x21d, 0, 0, 0, 0), + D_MODULE(HCLK_UART5, "hclk_uart5", CLK_REF_SYNC_D4, 0x220, 0x221, 0x222, 0, 0, 0, 0), + D_MODULE(HCLK_UART6, "hclk_uart6", CLK_REF_SYNC_D4, 0x223, 0x224, 0x225, 0, 0, 0, 0), + D_MODULE(HCLK_UART7, "hclk_uart7", CLK_REF_SYNC_D4, 0x226, 0x227, 0x228, 0, 0, 0, 0), + /* + * These are not hardware clocks, but are needed to handle the special + * case where we have a 'selector bit' that doesn't just change the + * parent for a clock, but also the gate it's supposed to use. + */ + { + .index = R9A06G032_UART_GROUP_012, + .name = "uart_group_012", + .type = K_BITSEL, + .source = 1 + R9A06G032_DIV_UART, + /* R9A06G032_SYSCTRL_REG_PWRCTRL_PG0_0 */ + .dual.sel = ((0x34 / 4) << 5) | 30, + .dual.group = 0, + }, + { + .index = R9A06G032_UART_GROUP_34567, + .name = "uart_group_34567", + .type = K_BITSEL, + .source = 1 + R9A06G032_DIV_P2_PG, + /* R9A06G032_SYSCTRL_REG_PWRCTRL_PG1_PR2 */ + .dual.sel = ((0xec / 4) << 5) | 24, + .dual.group = 1, + }, + D_UGATE(CLK_UART0, "clk_uart0", UART_GROUP_012, 0, 0x1b2, 0x1b3, 0x1b4, 0x1b5), + D_UGATE(CLK_UART1, "clk_uart1", UART_GROUP_012, 0, 0x1b6, 0x1b7, 0x1b8, 0x1b9), + D_UGATE(CLK_UART2, "clk_uart2", UART_GROUP_012, 0, 0x1ba, 0x1bb, 0x1bc, 0x1bd), + D_UGATE(CLK_UART3, "clk_uart3", UART_GROUP_34567, 1, 0x760, 0x761, 0x762, 0x763), + D_UGATE(CLK_UART4, "clk_uart4", UART_GROUP_34567, 1, 0x764, 0x765, 0x766, 0x767), + D_UGATE(CLK_UART5, "clk_uart5", UART_GROUP_34567, 1, 0x768, 0x769, 0x76a, 0x76b), + D_UGATE(CLK_UART6, "clk_uart6", UART_GROUP_34567, 1, 0x76c, 0x76d, 0x76e, 0x76f), + D_UGATE(CLK_UART7, "clk_uart7", UART_GROUP_34567, 1, 0x770, 0x771, 0x772, 0x773), +}; + +struct r9a06g032_priv { + struct regmap *regmap; + struct clk mclk; +}; + +static const struct r9a06g032_clkdesc *r9a06g032_clk_get(struct clk *clk) +{ + const unsigned long clkid = clk->id & 0xffff; + int i; + + for (i = 0; i < ARRAY_SIZE(r9a06g032_clocks); i++) { + if (r9a06g032_clocks[i].index == clkid) + return &r9a06g032_clocks[i]; + } + + return NULL; +} + +static int r9a06g032_clk_get_parent(struct clk *clk, struct clk *parent) +{ + const struct r9a06g032_clkdesc *desc = r9a06g032_clk_get(clk); + + if (!desc) + return -ENODEV; + + if (desc->source == 0) + parent->id = ~0; /* Top-level clock */ + else + parent->id = desc->source - 1; + + parent->dev = clk->dev; + + return 0; +} + +static ulong r9a06g032_clk_get_parent_rate(struct clk *clk) +{ + struct clk parent; + + if (r9a06g032_clk_get_parent(clk, &parent)) { + debug("Failed to get parent clock for id=%lu\b", clk->id); + return 0; + } + + if (parent.id == ~0) { + struct r9a06g032_priv *clocks = dev_get_priv(clk->dev); + ulong rate = clk_get_rate(&clocks->mclk); + return rate; + } + + return clk_get_rate(&parent); +} + +/* register/bit pairs are encoded as an uint16_t */ +static void +clk_rdesc_set(struct r9a06g032_priv *clocks, + u16 one, unsigned int on) +{ + uint offset = 4 * (one >> 5); + uint mask = 1U << (one & 0x1f); + uint val = ((!!on) << (one & 0x1f)); + + regmap_update_bits(clocks->regmap, offset, mask, val); +} + +static int +clk_rdesc_get(struct r9a06g032_priv *clocks, + uint16_t one) +{ + uint offset = 4 * (one >> 5); + u32 val = 0; + + regmap_read(clocks->regmap, offset, &val); + + return !!(val & (1U << (one & 0x1f))); +} + +/* + * Cheating a little bit here: leverage the existing code to control the + * per-clock reset. It should really be handled by a reset controller instead. + */ +void clk_rzn1_reset_state(struct clk *clk, int on) +{ + struct r9a06g032_priv *clocks = dev_get_priv(clk->dev); + const struct r9a06g032_clkdesc *desc = r9a06g032_clk_get(clk); + assert(desc); + assert(desc->type == K_GATE); + const struct r9a06g032_gate *g = &desc->gate; + assert(g->reset); + + clk_rdesc_set(clocks, g->reset, on); +} + +/* + * This implements the R9A06G032 clock gate 'driver'. We cannot use the system's + * clock gate framework as the gates on the R9A06G032 have a special enabling + * sequence, therefore we use this little proxy. + */ +static int r9a06g032_clk_gate_set(struct clk *clk, int on) +{ + struct r9a06g032_priv *clocks = dev_get_priv(clk->dev); + const struct r9a06g032_clkdesc *desc = r9a06g032_clk_get(clk); + assert(desc); + assert(desc->type == K_GATE); + const struct r9a06g032_gate *g = &desc->gate; + + clk_rdesc_set(clocks, g->gate, on); + /* De-assert reset */ + if (g->reset) + clk_rdesc_set(clocks, g->reset, 1); + + /* Hardware manual recommends 5us delay after enabling clock & reset */ + udelay(5); + + /* If the peripheral is memory mapped (i.e. an AXI slave), there is an + * associated SLVRDY bit in the System Controller that needs to be set + * so that the FlexWAY bus fabric passes on the read/write requests. + */ + if (g->ready || g->midle) { + if (g->ready) + clk_rdesc_set(clocks, g->ready, on); + /* Clear 'Master Idle Request' bit */ + if (g->midle) + clk_rdesc_set(clocks, g->midle, !on); + } + /* Note: We don't wait for FlexWAY Socket Connection signal */ + + return 0; +} + +static int r9a06g032_clk_gate_enable(struct clk *clk) +{ + return r9a06g032_clk_gate_set(clk, 1); +} + +static int r9a06g032_clk_gate_disable(struct clk *clk) +{ + return r9a06g032_clk_gate_set(clk, 0); +} + +/* + * Fixed factor clock + */ +static ulong r9a06g032_ffc_get_rate(struct clk *clk) +{ + const struct r9a06g032_clkdesc *desc = r9a06g032_clk_get(clk); + unsigned long parent_rate = r9a06g032_clk_get_parent_rate(clk); + unsigned long long rate; + + if (parent_rate == 0) { + debug("%s: parent_rate is zero\n", __func__); + return 0; + } + + rate = (unsigned long long)parent_rate * desc->mul; + rate = DIV_ROUND_UP(rate, desc->div); + return (ulong)rate; +} + +/* + * This implements R9A06G032 clock divider 'driver'. This differs from the + * standard clk_divider because the set_rate method must also set b[31] to + * trigger the hardware rate change. In theory it should also wait for this + * bit to clear. + */ +static ulong r9a06g032_div_get_rate(struct clk *clk) +{ + struct r9a06g032_priv *clocks = dev_get_priv(clk->dev); + const struct r9a06g032_clkdesc *desc = r9a06g032_clk_get(clk); + unsigned long parent_rate = r9a06g032_clk_get_parent_rate(clk); + u32 div = 0; + + if (parent_rate == 0) { + debug("%s: parent_rate is zero\n", __func__); + return 0; + } + + regmap_read(clocks->regmap, 4 * desc->reg, &div); + + if (div < desc->div_min) + div = desc->div_min; + else if (div > desc->div_max) + div = desc->div_max; + return DIV_ROUND_UP(parent_rate, div); +} + +static ulong r9a06g032_div_set_rate(struct clk *clk, ulong rate) +{ + struct r9a06g032_priv *clocks = dev_get_priv(clk->dev); + const struct r9a06g032_clkdesc *desc = r9a06g032_clk_get(clk); + unsigned long parent_rate = r9a06g032_clk_get_parent_rate(clk); + + if (parent_rate == 0) { + debug("%s: parent_rate is zero\n", __func__); + return 0; + } + + /* + 1 to cope with rates that have the remainder dropped */ + u32 div = DIV_ROUND_UP(parent_rate, rate + 1); + + /* Clamp to allowable range */ + if (div < desc->div_min) + div = desc->div_min; + else if (div > desc->div_max) + div = desc->div_max; + + /* TODO: use the .div_table if provided */ + if (desc->div_table[0]) + pr_err("ERROR: %s: div_table not implemented\n", __func__); + + pr_devel("%s clkid %lu rate %ld parent %ld div %d\n", __func__, clk->id, + rate, parent_rate, div); + + /* + * Need to write the bit 31 with the divider value to + * latch it. Technically we should wait until it has been + * cleared too. + * TODO: Find whether this callback is sleepable, in case + * the hardware /does/ require some sort of spinloop here. + */ + regmap_write(clocks->regmap, 4 * desc->reg, div | BIT(31)); + + return 0; +} + +/* + * Dual gate. This handles toggling the approprate clock/reset bits, + * which depends on the mux setting above. + */ +static int r9a06g032_clk_dualgate_setenable(struct r9a06g032_priv *clocks, + const struct r9a06g032_clkdesc *desc, + int enable) +{ + u8 sel_bit = clk_rdesc_get(clocks, desc->dual.sel); + u16 gate[2] = { desc->dual.g1, desc->dual.g2 }; + u16 reset[2] = { desc->dual.r1, desc->dual.r2 }; + + /* we always turn off the 'other' gate, regardless */ + clk_rdesc_set(clocks, gate[!sel_bit], 0); + if (reset[!sel_bit]) + clk_rdesc_set(clocks, reset[!sel_bit], 1); + + /* set the gate as requested */ + clk_rdesc_set(clocks, gate[sel_bit], enable); + if (reset[sel_bit]) + clk_rdesc_set(clocks, reset[sel_bit], 1); + + return 0; +} + +static int r9a06g032_clk_dualgate_enable(struct clk *clk) +{ + struct r9a06g032_priv *clocks = dev_get_priv(clk->dev); + const struct r9a06g032_clkdesc *desc = r9a06g032_clk_get(clk); + + return r9a06g032_clk_dualgate_setenable(clocks, desc, 1); +} + +static int r9a06g032_clk_dualgate_disable(struct clk *clk) +{ + struct r9a06g032_priv *clocks = dev_get_priv(clk->dev); + const struct r9a06g032_clkdesc *desc = r9a06g032_clk_get(clk); + + return r9a06g032_clk_dualgate_setenable(clocks, desc, 0); +} + +static int r9a06g032_clk_dualgate_is_enabled(struct clk *clk) +{ + struct r9a06g032_priv *clocks = dev_get_priv(clk->dev); + const struct r9a06g032_clkdesc *desc = r9a06g032_clk_get(clk); + u8 sel_bit = clk_rdesc_get(clocks, desc->dual.sel); + u16 gate[2] = { desc->dual.g1, desc->dual.g2 }; + + return clk_rdesc_get(clocks, gate[sel_bit]); +} + +/* + * Main clock driver + */ +static int r9a06g032_clk_enable(struct clk *clk) +{ + const struct r9a06g032_clkdesc *desc = r9a06g032_clk_get(clk); + + switch (desc->type) { + case K_GATE: + return r9a06g032_clk_gate_enable(clk); + case K_DUALGATE: + return r9a06g032_clk_dualgate_enable(clk); + default: + printf("ERROR: %s:%d unhandled type=%d\n", __func__, __LINE__, desc->type); + break; + } + + return 0; +} + +static int r9a06g032_clk_disable(struct clk *clk) +{ + const struct r9a06g032_clkdesc *desc = r9a06g032_clk_get(clk); + + switch (desc->type) { + case K_GATE: + return r9a06g032_clk_gate_disable(clk); + case K_DUALGATE: + return r9a06g032_clk_dualgate_disable(clk); + default: + printf("ERROR: %s:%d unhandled type=%d\n", __func__, __LINE__, desc->type); + break; + } + + return 0; +} + +static ulong r9a06g032_clk_get_rate(struct clk *clk) +{ + const struct r9a06g032_clkdesc *desc = r9a06g032_clk_get(clk); + ulong ret = 0; + + assert(desc); + + switch (desc->type) { + case K_FFC: + ret = r9a06g032_ffc_get_rate(clk); + break; + case K_GATE: + ret = r9a06g032_clk_get_parent_rate(clk); + break; + case K_DIV: + ret = r9a06g032_div_get_rate(clk); + break; + case K_BITSEL: + /* + * Look at the mux to determine parent. + * 0 means it is coming from UART DIV (group 012 or 34567) + * 1 means it is coming from USB_PLL + */ + if (r9a06g032_clk_dualgate_is_enabled(clk)) { + struct clk clk = { .id = R9A06G032_CLK_PLL_USB }; + ret = r9a06g032_clk_get_parent_rate(&clk); + } + ret = r9a06g032_clk_get_parent_rate(clk); + break; + case K_DUALGATE: + ret = r9a06g032_clk_get_parent_rate(clk); + break; + } + + return ret; +} + +static ulong r9a06g032_clk_set_rate(struct clk *clk, ulong rate) +{ + const struct r9a06g032_clkdesc *desc = r9a06g032_clk_get(clk); + ulong ret = 0; + + assert(desc); + + switch (desc->type) { + case K_DIV: + ret = r9a06g032_div_set_rate(clk, rate); + break; + default: + printf("ERROR: %s:%d not implemented yet\n", __func__, __LINE__); + }; + + return ret; +} + +static int r9a06g032_clk_of_xlate(struct clk *clk, struct ofnode_phandle_args *args) +{ + if (args->args_count != 1) { + debug("Invalid args_count: %d\n", args->args_count); + return -EINVAL; + } + + clk->id = args->args[0]; + + return 0; +} + +static const struct clk_ops r9a06g032_clk_ops = { + .enable = r9a06g032_clk_enable, + .disable = r9a06g032_clk_disable, + .get_rate = r9a06g032_clk_get_rate, + .set_rate = r9a06g032_clk_set_rate, + .of_xlate = r9a06g032_clk_of_xlate, +}; + +static int r9a06g032_clk_probe(struct udevice *dev) +{ + struct r9a06g032_priv *priv = dev_get_priv(dev); + int err; + + priv->regmap = syscon_regmap_lookup_by_phandle(dev, "regmap"); + if (!priv->regmap) { + pr_err("unable to find regmap\n"); + return -ENODEV; + } + + /* Enable S/W reset */ + regmap_write(priv->regmap, 0x120, 0x41); + + err = clk_get_by_name(dev, "mclk", &priv->mclk); + if (err) + return err; + + return 0; +} + +static int r9a06g032_clk_remove(struct udevice *dev) +{ + return 0; +} + +static const struct udevice_id r9a06g032_clk_ids[] = { + { .compatible = "renesas,r9a06g032-sysctrl" }, + { } +}; + +U_BOOT_DRIVER(clk_r9a06g032) = { + .name = "clk_r9a06g032", + .id = UCLASS_CLK, + .of_match = r9a06g032_clk_ids, + .priv_auto = sizeof(struct r9a06g032_priv), + .ops = &r9a06g032_clk_ops, + .probe = &r9a06g032_clk_probe, + .remove = &r9a06g032_clk_remove, + .flags = DM_FLAG_PRE_RELOC, +}; From patchwork Tue Aug 9 12:59:54 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ralph Siemsen X-Patchwork-Id: 596223 Delivered-To: patch@linaro.org Received: by 2002:a05:7000:b345:0:0:0:0 with SMTP id w5csp4152311maz; Tue, 9 Aug 2022 06:01:42 -0700 (PDT) X-Google-Smtp-Source: AA6agR43tbdyPsFW6o4gRJy++969E8Ch8+OwmH7kM5FcC2icaR9jFkyjg5Kw1lHwqOi1tMlc6NGy X-Received: by 2002:a05:6638:2586:b0:343:1c0a:8cf7 with SMTP id s6-20020a056638258600b003431c0a8cf7mr3142736jat.255.1660050102601; Tue, 09 Aug 2022 06:01:42 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1660050102; cv=none; d=google.com; s=arc-20160816; b=QafOxtoW1yiNWNQWIx/uea6aQTFVHH0s4D84htsOgh8J0HO6NaqUgothTc4m+2EpDr 3syTqbBG9QBr40WZnw6XfdGnhmEIePLIa1oLdzgN+c3w68wx/WJx3JG44BPJRPNzPMVq WCKTzpOUdHftFiq/6UViJAUo5aicDyR9BfU+CBcdA/8pUn8X7EPZjWfFvyAWV8XqkIq+ XH3MPBt6Z7y+xR5sqs8Q7+EfGMNoyxNFI0oreZVwTaePkAWrfI7sAohnBol0QUdo21/N BghT6+pNJzbkOXnjwusLL4hyp36S/zVb+olCbm21k3+ZurJ0/pB/sw3HzHehGdiomUsG 2zEA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=IToe94wYAsRKXJdesKLX3oocuSeeh6mYw/wazHlJP7k=; b=0YMuQA7XCRvG3tRzmcAQ5fp7e9zuW3BgBbKuw2CjFjSeJGu5YGPuqXJLz8aSyn2Qza g/g5noKFUJzFQeVclGP3sH0H+MN3EMhuf43C8so5Pk8G+LU7NFQJ1S/eXA41FYUcJsaH jbcmD/xIZG+3XIz0IQvYYi8nfwp9naRB4qpkyBk3jffFm+Ia3qBCdGLZmUE5a4s4td9Y 8nFb1gBpnU5dycs5ZzPdMQWc8NuyqCK/hsNErlSIxAsCehompcBUvHByhKonIS3MoPYl H1/c7PrFZCorcNKKxvZSvhMrU1DKX9EAdHe5GBK7VK9MVR407WMXWaUTHQPY1Gl7FLvK 6NCg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=olte0wVk; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from phobos.denx.de (phobos.denx.de. [85.214.62.61]) by mx.google.com with ESMTPS id l43-20020a02666b000000b003427a181860si9468343jaf.43.2022.08.09.06.01.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 09 Aug 2022 06:01:42 -0700 (PDT) Received-SPF: pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 as permitted sender) client-ip=85.214.62.61; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=olte0wVk; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id C5F5884A18; Tue, 9 Aug 2022 15:01:13 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org 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=linaro.org header.i=@linaro.org header.b="olte0wVk"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 1E19A84A46; Tue, 9 Aug 2022 15:00:59 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_NONE,SPF_PASS, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-io1-xd2e.google.com (mail-io1-xd2e.google.com [IPv6:2607:f8b0:4864:20::d2e]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 23DC084A30 for ; Tue, 9 Aug 2022 15:00:31 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=ralph.siemsen@linaro.org Received: by mail-io1-xd2e.google.com with SMTP id l24so9450540ion.13 for ; Tue, 09 Aug 2022 06:00:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc; bh=IToe94wYAsRKXJdesKLX3oocuSeeh6mYw/wazHlJP7k=; b=olte0wVkOabvs/DeF/ovM4fIDP6GvLs6JVd2uEgx9TkgE/sOWKUm5jRZqfRBhlYjbT ioDaYuQGdm0ASHkwhloqeYpQrTtmjJHfovK27akwl79dsRRYYQ+RWJLF8LJJv2J4gYx5 YbfrHsbcukQoC9xJ6T6HywRLAWmaD0E4G8YXD2regggjGc7V0YV8qKV2k995wUzbFLXd IjconsMxogt9z+KF2GOEtt9alkRHCvOV353ZdjNKBPRwReC/JeIRJmgyLOwu/SVqeuiU FP2Kr2wDAxI9ddJxXTMAXZ4EQjxLR5KwVGtNgfAhgq6Her+lDU9mf6mrAeycIYWhe3v1 TqHA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc; bh=IToe94wYAsRKXJdesKLX3oocuSeeh6mYw/wazHlJP7k=; b=Lqd8ms3/yueRcaVacF6e3u8j7Wb99QWL/gsqcTehhBJqS7OlRyy+aXR3HU25i5EPWw 1juCMzZij6NXsOteIM00lkdzGvl8Het1gZ6OQI7fL/eYeslCq9LPcHmVy1El4IpRJo8Z 47cEemKapdpilHBUlbqNagvBgpwt7a0hVxkv2i4hlpZXumNNdjbEmazM6NKuqxj5vZq7 Iz1efBCRGibi5L/VUFgqsfLnOGkgiQ5OWt0uDyrOOjfWCIzLLtRJpKoy7Z55YLpYaFyU UND5BqCs7Gwz/Tw1t6VYAsGLW0QvIBbZBPWUO/tzl7vPec9oBLLdLvC9VU+qAutZNkIX 9O/w== X-Gm-Message-State: ACgBeo1BCNVhAIzFvyxE9pJM5KFVfMjf7l4d1+57yTUuvre9UVFfuEPv xX8r/rxoGsnXHE2GPtIW0LIYGbi3A6imjDtK X-Received: by 2002:a05:6602:2289:b0:683:30fc:9535 with SMTP id d9-20020a056602228900b0068330fc9535mr8661323iod.71.1660050028668; Tue, 09 Aug 2022 06:00:28 -0700 (PDT) Received: from maple.netwinder.org (rfs.netwinder.org. [206.248.184.2]) by smtp.gmail.com with ESMTPSA id g12-20020a056e021a2c00b002dea1e18a94sm1022197ile.47.2022.08.09.06.00.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 09 Aug 2022 06:00:28 -0700 (PDT) From: Ralph Siemsen To: u-boot@lists.denx.de Cc: Ralph Siemsen , Ashok Reddy Soma , Damien Le Moal , Jim Liu , Mark Kettenis , Niklas Cassel , Samuel Holland Subject: [RFC PATCH v1 4/9] pinctrl: renesas: add R906G032 driver Date: Tue, 9 Aug 2022 08:59:54 -0400 Message-Id: <20220809125959.217333-5-ralph.siemsen@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220809125959.217333-1-ralph.siemsen@linaro.org> References: <20220809125959.217333-1-ralph.siemsen@linaro.org> MIME-Version: 1.0 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.6 at phobos.denx.de X-Virus-Status: Clean Pinctrl/pinconf driver for Renesas RZ/N1 (R906G032) SoC. This is quite rudimentary right now, and only supports applying a default pin configuration as specified by the device tree. TODO: - iterate over subnodes, so we can handle groups of pins with different bias/strength settings - use the regmap_update_bits for level1/level2 register updates --> does not exist for regmap_ranges, consider adding? Signed-off-by: Ralph Siemsen --- drivers/pinctrl/Makefile | 1 + drivers/pinctrl/renesas/Kconfig | 7 + drivers/pinctrl/renesas/Makefile | 1 + drivers/pinctrl/renesas/pinctrl-rzn1.c | 398 +++++++++++++++++++++ include/dt-bindings/pinctrl/rzn1-pinctrl.h | 141 ++++++++ 5 files changed, 548 insertions(+) create mode 100644 drivers/pinctrl/renesas/pinctrl-rzn1.c create mode 100644 include/dt-bindings/pinctrl/rzn1-pinctrl.h diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile index 3b167d099f..450267732c 100644 --- a/drivers/pinctrl/Makefile +++ b/drivers/pinctrl/Makefile @@ -14,6 +14,7 @@ obj-$(CONFIG_PINCTRL_INTEL) += intel/ obj-$(CONFIG_ARCH_MTMIPS) += mtmips/ obj-$(CONFIG_ARCH_NPCM) += nuvoton/ obj-$(CONFIG_ARCH_RMOBILE) += renesas/ +obj-$(CONFIG_ARCH_RZN1) += renesas/ obj-$(CONFIG_PINCTRL_SANDBOX) += pinctrl-sandbox.o obj-$(CONFIG_PINCTRL_SUNXI) += sunxi/ obj-$(CONFIG_PINCTRL_UNIPHIER) += uniphier/ diff --git a/drivers/pinctrl/renesas/Kconfig b/drivers/pinctrl/renesas/Kconfig index 1fedf63252..3fbc293e17 100644 --- a/drivers/pinctrl/renesas/Kconfig +++ b/drivers/pinctrl/renesas/Kconfig @@ -121,3 +121,10 @@ config PINCTRL_PFC_R7S72100 Support pin multiplexing control on Renesas RZ/A1 R7S72100 SoCs. endif + +config PINCTRL_RZN1 + bool "Renesas RZ/N1 R906G032 pin control driver" + depends on ARCH_RZN1 + default y if ARCH_RZN1 + help + Support pin multiplexing control on Renesas RZ/N1 R906G032 SoCs. diff --git a/drivers/pinctrl/renesas/Makefile b/drivers/pinctrl/renesas/Makefile index 1c65505eff..8f26f16098 100644 --- a/drivers/pinctrl/renesas/Makefile +++ b/drivers/pinctrl/renesas/Makefile @@ -17,3 +17,4 @@ obj-$(CONFIG_PINCTRL_PFC_R8A77990) += pfc-r8a77990.o obj-$(CONFIG_PINCTRL_PFC_R8A77995) += pfc-r8a77995.o obj-$(CONFIG_PINCTRL_PFC_R8A779A0) += pfc-r8a779a0.o obj-$(CONFIG_PINCTRL_PFC_R7S72100) += pfc-r7s72100.o +obj-$(CONFIG_PINCTRL_RZN1) += pinctrl-rzn1.o diff --git a/drivers/pinctrl/renesas/pinctrl-rzn1.c b/drivers/pinctrl/renesas/pinctrl-rzn1.c new file mode 100644 index 0000000000..39ff1fa8a1 --- /dev/null +++ b/drivers/pinctrl/renesas/pinctrl-rzn1.c @@ -0,0 +1,398 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2014-2018 Renesas Electronics Europe Limited + * + * Phil Edworthy + * Based on a driver originally written by Michel Pollet at Renesas. + */ + +#include + +#include +#include +#include +#include +#include + +/* Field positions and masks in the pinmux registers */ +#define RZN1_L1_PIN_DRIVE_STRENGTH 10 +#define RZN1_L1_PIN_DRIVE_STRENGTH_4MA 0 +#define RZN1_L1_PIN_DRIVE_STRENGTH_6MA 1 +#define RZN1_L1_PIN_DRIVE_STRENGTH_8MA 2 +#define RZN1_L1_PIN_DRIVE_STRENGTH_12MA 3 +#define RZN1_L1_PIN_PULL 8 +#define RZN1_L1_PIN_PULL_NONE 0 +#define RZN1_L1_PIN_PULL_UP 1 +#define RZN1_L1_PIN_PULL_DOWN 3 +#define RZN1_L1_FUNCTION 0 +#define RZN1_L1_FUNC_MASK 0xf +#define RZN1_L1_FUNCTION_L2 0xf + +/* + * The hardware manual describes two levels of multiplexing, but it's more + * logical to think of the hardware as three levels, with level 3 consisting of + * the multiplexing for Ethernet MDIO signals. + * + * Level 1 functions go from 0 to 9, with level 1 function '15' (0xf) specifying + * that level 2 functions are used instead. Level 2 has a lot more options, + * going from 0 to 61. Level 3 allows selection of MDIO functions which can be + * floating, or one of seven internal peripherals. Unfortunately, there are two + * level 2 functions that can select MDIO, and two MDIO channels so we have four + * sets of level 3 functions. + * + * For this driver, we've compounded the numbers together, so: + * 0 to 9 is level 1 + * 10 to 71 is 10 + level 2 number + * 72 to 79 is 72 + MDIO0 source for level 2 MDIO function. + * 80 to 87 is 80 + MDIO0 source for level 2 MDIO_E1 function. + * 88 to 95 is 88 + MDIO1 source for level 2 MDIO function. + * 96 to 103 is 96 + MDIO1 source for level 2 MDIO_E1 function. + * Examples: + * Function 28 corresponds UART0 + * Function 73 corresponds to MDIO0 to GMAC0 + * + * There are 170 configurable pins (called PL_GPIO in the datasheet). + */ + +/* + * Structure detailing the HW registers on the RZ/N1 devices. + * Both the Level 1 mux registers and Level 2 mux registers have the same + * structure. The only difference is that Level 2 has additional MDIO registers + * at the end. + */ +struct rzn1_pinctrl_regs { + u32 conf[170]; + u32 pad0[86]; + u32 status_protect; /* 0x400 */ + /* MDIO mux registers, level2 only */ + u32 l2_mdio[2]; +}; + +#define NUM_CONF ARRAY_SIZE(((struct rzn1_pinctrl_regs *)0)->conf) + +#define level1_write(map, member, val) \ + regmap_range_set(map, 0, struct rzn1_pinctrl_regs, member, val) + +#define level1_read(map, member, valp) \ + regmap_range_get(map, 0, struct rzn1_pinctrl_regs, member, valp) + +#define level2_write(map, member, val) \ + regmap_range_set(map, 1, struct rzn1_pinctrl_regs, member, val) + +#define level2_read(map, member, valp) \ + regmap_range_get(map, 1, struct rzn1_pinctrl_regs, member, valp) + +/** + * struct rzn1_pmx_func - describes rzn1 pinmux functions + * @name: the name of this specific function + * @groups: corresponding pin groups + * @num_groups: the number of groups + */ +struct rzn1_pmx_func { + const char *name; + const char **groups; + unsigned int num_groups; +}; + +/** + * struct rzn1_pin_group - describes an rzn1 pin group + * @name: the name of this specific pin group + * @func: the name of the function selected by this group + * @npins: the number of pins in this group array, i.e. the number of + * elements in .pins so we can iterate over that array + * @pins: array of pins. Needed due to pinctrl_ops.get_group_pins() + * @pin_ids: array of pin_ids, i.e. the value used to select the mux + */ +struct rzn1_pin_group { + const char *name; + const char *func; + unsigned int npins; + unsigned int *pins; + u8 *pin_ids; +}; + +struct rzn1_pinctrl { + struct device *dev; + struct clk *clk; + struct pinctrl_dev *pctl; + u32 lev1_protect_phys; + u32 lev2_protect_phys; + int mdio_func[2]; + + struct rzn1_pin_group *groups; + unsigned int ngroups; + + struct rzn1_pmx_func *functions; + unsigned int nfunctions; +}; + +struct rzn1_pinctrl_priv { + struct regmap *regmap; + u32 lev1_protect_phys; + u32 lev2_protect_phys; + + struct clk *clk; +}; + +enum { + LOCK_LEVEL1 = 0x1, + LOCK_LEVEL2 = 0x2, + LOCK_ALL = LOCK_LEVEL1 | LOCK_LEVEL2, +}; + +static void rzn1_hw_set_lock(struct rzn1_pinctrl_priv *priv, u8 lock, u8 value) +{ + /* + * The pinmux configuration is locked by writing the physical address of + * the status_protect register to itself. It is unlocked by writing the + * address | 1. + */ + if (lock & LOCK_LEVEL1) { + u32 val = priv->lev1_protect_phys | !(value & LOCK_LEVEL1); + + level1_write(priv->regmap, status_protect, val); + } + + if (lock & LOCK_LEVEL2) { + u32 val = priv->lev2_protect_phys | !(value & LOCK_LEVEL2); + + level2_write(priv->regmap, status_protect, val); + } +} + +static void rzn1_pinctrl_mdio_select(struct rzn1_pinctrl_priv *priv, int mdio, + u32 func) +{ + debug("setting mdio%d to %u\n", mdio, func); + + level2_write(priv->regmap, l2_mdio[mdio], func); +} + +/* + * Using a composite pin description, set the hardware pinmux registers + * with the corresponding values. + * Make sure to unlock write protection and reset it afterward. + * + * NOTE: There is no protection for potential concurrency, it is assumed these + * calls are serialized already. + */ +static int rzn1_set_hw_pin_func(struct rzn1_pinctrl_priv *priv, + unsigned int pin, unsigned int func) +{ + u32 l1_cache; + u32 l2_cache; + u32 l1; + u32 l2; + + /* Level 3 MDIO multiplexing */ + if (func >= RZN1_FUNC_MDIO0_HIGHZ && + func <= RZN1_FUNC_MDIO1_E1_SWITCH) { + int mdio_channel; + u32 mdio_func; + + if (func <= RZN1_FUNC_MDIO1_HIGHZ) + mdio_channel = 0; + else + mdio_channel = 1; + + /* Get MDIO func, and convert the func to the level 2 number */ + if (func <= RZN1_FUNC_MDIO0_SWITCH) { + mdio_func = func - RZN1_FUNC_MDIO0_HIGHZ; + func = RZN1_FUNC_ETH_MDIO; + } else if (func <= RZN1_FUNC_MDIO0_E1_SWITCH) { + mdio_func = func - RZN1_FUNC_MDIO0_E1_HIGHZ; + func = RZN1_FUNC_ETH_MDIO_E1; + } else if (func <= RZN1_FUNC_MDIO1_SWITCH) { + mdio_func = func - RZN1_FUNC_MDIO1_HIGHZ; + func = RZN1_FUNC_ETH_MDIO; + } else { + mdio_func = func - RZN1_FUNC_MDIO1_E1_HIGHZ; + func = RZN1_FUNC_ETH_MDIO_E1; + } + rzn1_pinctrl_mdio_select(priv, mdio_channel, mdio_func); + } + + /* Note here, we do not allow anything past the MDIO Mux values */ + if (pin >= NUM_CONF || func >= RZN1_FUNC_MDIO0_HIGHZ) + return -EINVAL; + + level1_read(priv->regmap, conf[pin], &l1); + l1_cache = l1; + level2_read(priv->regmap, conf[pin], &l2); + l2_cache = l2; + + debug("setting func for pin %u to %u\n", pin, func); + + l1 &= ~(RZN1_L1_FUNC_MASK << RZN1_L1_FUNCTION); + + if (func < RZN1_FUNC_L2_OFFSET) { + l1 |= (func << RZN1_L1_FUNCTION); + } else { + l1 |= (RZN1_L1_FUNCTION_L2 << RZN1_L1_FUNCTION); + + l2 = func - RZN1_FUNC_L2_OFFSET; + } + + /* If either configuration changes, we update both anyway */ + if (l1 != l1_cache || l2 != l2_cache) { + level1_write(priv->regmap, conf[pin], l1); + level2_write(priv->regmap, conf[pin], l2); + } + + return 0; +} + +static int rzn1_pinconf_set(struct rzn1_pinctrl_priv *priv, unsigned int pin, + unsigned int bias, unsigned int strength) +{ + u32 l1, l1_cache; + u32 drv = RZN1_L1_PIN_DRIVE_STRENGTH_8MA; + + level1_read(priv->regmap, conf[pin], &l1); + l1_cache = l1; + + switch (bias) { + case PIN_CONFIG_BIAS_PULL_UP: + debug("set pin %d pull up\n", pin); + l1 &= ~(0x3 << RZN1_L1_PIN_PULL); + l1 |= (RZN1_L1_PIN_PULL_UP << RZN1_L1_PIN_PULL); + break; + case PIN_CONFIG_BIAS_PULL_DOWN: + debug("set pin %d pull down\n", pin); + l1 &= ~(0x3 << RZN1_L1_PIN_PULL); + l1 |= (RZN1_L1_PIN_PULL_DOWN << RZN1_L1_PIN_PULL); + break; + case PIN_CONFIG_BIAS_DISABLE: + debug("set pin %d bias off\n", pin); + l1 &= ~(0x3 << RZN1_L1_PIN_PULL); + l1 |= (RZN1_L1_PIN_PULL_NONE << RZN1_L1_PIN_PULL); + break; + } + + switch (strength) { + case 4: + drv = RZN1_L1_PIN_DRIVE_STRENGTH_4MA; + break; + case 6: + drv = RZN1_L1_PIN_DRIVE_STRENGTH_6MA; + break; + case 8: + drv = RZN1_L1_PIN_DRIVE_STRENGTH_8MA; + break; + case 12: + drv = RZN1_L1_PIN_DRIVE_STRENGTH_12MA; + break; + } + + debug("set pin %d drv %umA\n", pin, drv); + + l1 &= ~(0x3 << RZN1_L1_PIN_DRIVE_STRENGTH); + l1 |= (drv << RZN1_L1_PIN_DRIVE_STRENGTH); + + if (l1 != l1_cache) + level1_write(priv->regmap, conf[pin], l1); + + return 0; +} + +static int rzn1_pinctrl_set_state_simple(struct udevice *dev, + struct udevice *periph) +{ + // FIXME this gets called for all device nodes which do not + // have a pinctrl-0 phandle property. If the function is missing + // then a warning gets printed by pinctrl-uclass. + + debug("%s:%d dev=%s periph=%s\n", __func__, __LINE__, dev->name, periph->name); + + return 0; +} + +static int rzn1_pinctrl_set_state(struct udevice *dev, struct udevice *config) +{ + struct rzn1_pinctrl_priv *priv = dev_get_priv(dev); + int size; + int ret; + u32 val; + + /* TODO: need to iterate over subgroups, needed so that it is possible + * to have different bias/strength settings for some pins. Currently + * none of our devices need that. + */ + + /* Pullup/down bias, common to all pins in group */ + u32 bias = PIN_CONFIG_BIAS_PULL_UP; + if (dev_read_bool(config, "bias-disable")) + bias = PIN_CONFIG_BIAS_DISABLE; + else if (dev_read_bool(config, "bias-pull-up")) + bias = PIN_CONFIG_BIAS_PULL_UP; + else if (dev_read_bool(config, "bias-pull-down")) + bias = PIN_CONFIG_BIAS_PULL_DOWN; + + /* Drive strength, common to all pins in group */ + u32 strength = dev_read_u32_default(config, "drive-strength", 8); + + /* Number of pins */ + ret = dev_read_size(config, "pinmux"); + if (ret < 0) + return ret; + + size = ret / sizeof(val); + + for (int i = 0; i < size; i++) { + ret = dev_read_u32_index(config, "pinmux", i, &val); + if (ret) + return ret; + unsigned int pin = val & 0xff; + unsigned int func = val >> 8; + + debug("%s pin %d func %d bias %d strength %d\n", + config->name, pin, func, bias, strength); + + rzn1_hw_set_lock(priv, LOCK_ALL, LOCK_ALL); + rzn1_set_hw_pin_func(priv, pin, func); + rzn1_pinconf_set(priv, pin, bias, strength); + rzn1_hw_set_lock(priv, LOCK_ALL, 0); + } + + return 0; +} + +static struct pinctrl_ops rzn1_pinctrl_ops = { + .set_state = rzn1_pinctrl_set_state, + + .set_state_simple = rzn1_pinctrl_set_state_simple, + +}; + +static int rzn1_pinctrl_probe(struct udevice *dev) +{ + struct rzn1_pinctrl_priv *priv = dev_get_priv(dev); + ofnode node = dev_ofnode(dev); + int ret; + + ret = regmap_init_mem(node, &priv->regmap); + if (ret) + return ret; + + priv->lev1_protect_phys = (u32)regmap_get_range(priv->regmap, 0) + + offsetof(struct rzn1_pinctrl_regs, status_protect); + priv->lev2_protect_phys = (u32)regmap_get_range(priv->regmap, 1) + + offsetof(struct rzn1_pinctrl_regs, status_protect); + + return 0; +} + +static const struct udevice_id rzn1_pinctrl_ids[] = { + { .compatible = "renesas,rzn1-pinctrl", }, + { }, +}; + +U_BOOT_DRIVER(pinctrl_rzn1) = { + .name = "rzn1-pinctrl", + .id = UCLASS_PINCTRL, + .of_match = rzn1_pinctrl_ids, + .priv_auto = sizeof(struct rzn1_pinctrl_priv), + .ops = &rzn1_pinctrl_ops, + .probe = rzn1_pinctrl_probe, + .flags = DM_FLAG_PRE_RELOC, +}; diff --git a/include/dt-bindings/pinctrl/rzn1-pinctrl.h b/include/dt-bindings/pinctrl/rzn1-pinctrl.h new file mode 100644 index 0000000000..21d6cc4d59 --- /dev/null +++ b/include/dt-bindings/pinctrl/rzn1-pinctrl.h @@ -0,0 +1,141 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Defines macros and constants for Renesas RZ/N1 pin controller pin + * muxing functions. + */ +#ifndef __DT_BINDINGS_RZN1_PINCTRL_H +#define __DT_BINDINGS_RZN1_PINCTRL_H + +#define RZN1_PINMUX(_gpio, _func) \ + (((_func) << 8) | (_gpio)) + +/* + * Given the different levels of muxing on the SoC, it was decided to + * 'linearize' them into one numerical space. So mux level 1, 2 and the MDIO + * muxes are all represented by one single value. + * + * You can derive the hardware value pretty easily too, as + * 0...9 are Level 1 + * 10...71 are Level 2. The Level 2 mux will be set to this + * value - RZN1_FUNC_L2_OFFSET, and the Level 1 mux will be + * set accordingly. + * 72...103 are for the 2 MDIO muxes. + */ +#define RZN1_FUNC_HIGHZ 0 +#define RZN1_FUNC_0L 1 +#define RZN1_FUNC_CLK_ETH_MII_RGMII_RMII 2 +#define RZN1_FUNC_CLK_ETH_NAND 3 +#define RZN1_FUNC_QSPI 4 +#define RZN1_FUNC_SDIO 5 +#define RZN1_FUNC_LCD 6 +#define RZN1_FUNC_LCD_E 7 +#define RZN1_FUNC_MSEBIM 8 +#define RZN1_FUNC_MSEBIS 9 +#define RZN1_FUNC_L2_OFFSET 10 /* I'm Special */ + +#define RZN1_FUNC_HIGHZ1 (RZN1_FUNC_L2_OFFSET + 0) +#define RZN1_FUNC_ETHERCAT (RZN1_FUNC_L2_OFFSET + 1) +#define RZN1_FUNC_SERCOS3 (RZN1_FUNC_L2_OFFSET + 2) +#define RZN1_FUNC_SDIO_E (RZN1_FUNC_L2_OFFSET + 3) +#define RZN1_FUNC_ETH_MDIO (RZN1_FUNC_L2_OFFSET + 4) +#define RZN1_FUNC_ETH_MDIO_E1 (RZN1_FUNC_L2_OFFSET + 5) +#define RZN1_FUNC_USB (RZN1_FUNC_L2_OFFSET + 6) +#define RZN1_FUNC_MSEBIM_E (RZN1_FUNC_L2_OFFSET + 7) +#define RZN1_FUNC_MSEBIS_E (RZN1_FUNC_L2_OFFSET + 8) +#define RZN1_FUNC_RSV (RZN1_FUNC_L2_OFFSET + 9) +#define RZN1_FUNC_RSV_E (RZN1_FUNC_L2_OFFSET + 10) +#define RZN1_FUNC_RSV_E1 (RZN1_FUNC_L2_OFFSET + 11) +#define RZN1_FUNC_UART0_I (RZN1_FUNC_L2_OFFSET + 12) +#define RZN1_FUNC_UART0_I_E (RZN1_FUNC_L2_OFFSET + 13) +#define RZN1_FUNC_UART1_I (RZN1_FUNC_L2_OFFSET + 14) +#define RZN1_FUNC_UART1_I_E (RZN1_FUNC_L2_OFFSET + 15) +#define RZN1_FUNC_UART2_I (RZN1_FUNC_L2_OFFSET + 16) +#define RZN1_FUNC_UART2_I_E (RZN1_FUNC_L2_OFFSET + 17) +#define RZN1_FUNC_UART0 (RZN1_FUNC_L2_OFFSET + 18) +#define RZN1_FUNC_UART0_E (RZN1_FUNC_L2_OFFSET + 19) +#define RZN1_FUNC_UART1 (RZN1_FUNC_L2_OFFSET + 20) +#define RZN1_FUNC_UART1_E (RZN1_FUNC_L2_OFFSET + 21) +#define RZN1_FUNC_UART2 (RZN1_FUNC_L2_OFFSET + 22) +#define RZN1_FUNC_UART2_E (RZN1_FUNC_L2_OFFSET + 23) +#define RZN1_FUNC_UART3 (RZN1_FUNC_L2_OFFSET + 24) +#define RZN1_FUNC_UART3_E (RZN1_FUNC_L2_OFFSET + 25) +#define RZN1_FUNC_UART4 (RZN1_FUNC_L2_OFFSET + 26) +#define RZN1_FUNC_UART4_E (RZN1_FUNC_L2_OFFSET + 27) +#define RZN1_FUNC_UART5 (RZN1_FUNC_L2_OFFSET + 28) +#define RZN1_FUNC_UART5_E (RZN1_FUNC_L2_OFFSET + 29) +#define RZN1_FUNC_UART6 (RZN1_FUNC_L2_OFFSET + 30) +#define RZN1_FUNC_UART6_E (RZN1_FUNC_L2_OFFSET + 31) +#define RZN1_FUNC_UART7 (RZN1_FUNC_L2_OFFSET + 32) +#define RZN1_FUNC_UART7_E (RZN1_FUNC_L2_OFFSET + 33) +#define RZN1_FUNC_SPI0_M (RZN1_FUNC_L2_OFFSET + 34) +#define RZN1_FUNC_SPI0_M_E (RZN1_FUNC_L2_OFFSET + 35) +#define RZN1_FUNC_SPI1_M (RZN1_FUNC_L2_OFFSET + 36) +#define RZN1_FUNC_SPI1_M_E (RZN1_FUNC_L2_OFFSET + 37) +#define RZN1_FUNC_SPI2_M (RZN1_FUNC_L2_OFFSET + 38) +#define RZN1_FUNC_SPI2_M_E (RZN1_FUNC_L2_OFFSET + 39) +#define RZN1_FUNC_SPI3_M (RZN1_FUNC_L2_OFFSET + 40) +#define RZN1_FUNC_SPI3_M_E (RZN1_FUNC_L2_OFFSET + 41) +#define RZN1_FUNC_SPI4_S (RZN1_FUNC_L2_OFFSET + 42) +#define RZN1_FUNC_SPI4_S_E (RZN1_FUNC_L2_OFFSET + 43) +#define RZN1_FUNC_SPI5_S (RZN1_FUNC_L2_OFFSET + 44) +#define RZN1_FUNC_SPI5_S_E (RZN1_FUNC_L2_OFFSET + 45) +#define RZN1_FUNC_SGPIO0_M (RZN1_FUNC_L2_OFFSET + 46) +#define RZN1_FUNC_SGPIO1_M (RZN1_FUNC_L2_OFFSET + 47) +#define RZN1_FUNC_GPIO (RZN1_FUNC_L2_OFFSET + 48) +#define RZN1_FUNC_CAN (RZN1_FUNC_L2_OFFSET + 49) +#define RZN1_FUNC_I2C (RZN1_FUNC_L2_OFFSET + 50) +#define RZN1_FUNC_SAFE (RZN1_FUNC_L2_OFFSET + 51) +#define RZN1_FUNC_PTO_PWM (RZN1_FUNC_L2_OFFSET + 52) +#define RZN1_FUNC_PTO_PWM1 (RZN1_FUNC_L2_OFFSET + 53) +#define RZN1_FUNC_PTO_PWM2 (RZN1_FUNC_L2_OFFSET + 54) +#define RZN1_FUNC_PTO_PWM3 (RZN1_FUNC_L2_OFFSET + 55) +#define RZN1_FUNC_PTO_PWM4 (RZN1_FUNC_L2_OFFSET + 56) +#define RZN1_FUNC_DELTA_SIGMA (RZN1_FUNC_L2_OFFSET + 57) +#define RZN1_FUNC_SGPIO2_M (RZN1_FUNC_L2_OFFSET + 58) +#define RZN1_FUNC_SGPIO3_M (RZN1_FUNC_L2_OFFSET + 59) +#define RZN1_FUNC_SGPIO4_S (RZN1_FUNC_L2_OFFSET + 60) +#define RZN1_FUNC_MAC_MTIP_SWITCH (RZN1_FUNC_L2_OFFSET + 61) + +#define RZN1_FUNC_MDIO_OFFSET (RZN1_FUNC_L2_OFFSET + 62) + +/* These are MDIO0 peripherals for the RZN1_FUNC_ETH_MDIO function */ +#define RZN1_FUNC_MDIO0_HIGHZ (RZN1_FUNC_MDIO_OFFSET + 0) +#define RZN1_FUNC_MDIO0_GMAC0 (RZN1_FUNC_MDIO_OFFSET + 1) +#define RZN1_FUNC_MDIO0_GMAC1 (RZN1_FUNC_MDIO_OFFSET + 2) +#define RZN1_FUNC_MDIO0_ECAT (RZN1_FUNC_MDIO_OFFSET + 3) +#define RZN1_FUNC_MDIO0_S3_MDIO0 (RZN1_FUNC_MDIO_OFFSET + 4) +#define RZN1_FUNC_MDIO0_S3_MDIO1 (RZN1_FUNC_MDIO_OFFSET + 5) +#define RZN1_FUNC_MDIO0_HWRTOS (RZN1_FUNC_MDIO_OFFSET + 6) +#define RZN1_FUNC_MDIO0_SWITCH (RZN1_FUNC_MDIO_OFFSET + 7) +/* These are MDIO0 peripherals for the RZN1_FUNC_ETH_MDIO_E1 function */ +#define RZN1_FUNC_MDIO0_E1_HIGHZ (RZN1_FUNC_MDIO_OFFSET + 8) +#define RZN1_FUNC_MDIO0_E1_GMAC0 (RZN1_FUNC_MDIO_OFFSET + 9) +#define RZN1_FUNC_MDIO0_E1_GMAC1 (RZN1_FUNC_MDIO_OFFSET + 10) +#define RZN1_FUNC_MDIO0_E1_ECAT (RZN1_FUNC_MDIO_OFFSET + 11) +#define RZN1_FUNC_MDIO0_E1_S3_MDIO0 (RZN1_FUNC_MDIO_OFFSET + 12) +#define RZN1_FUNC_MDIO0_E1_S3_MDIO1 (RZN1_FUNC_MDIO_OFFSET + 13) +#define RZN1_FUNC_MDIO0_E1_HWRTOS (RZN1_FUNC_MDIO_OFFSET + 14) +#define RZN1_FUNC_MDIO0_E1_SWITCH (RZN1_FUNC_MDIO_OFFSET + 15) + +/* These are MDIO1 peripherals for the RZN1_FUNC_ETH_MDIO function */ +#define RZN1_FUNC_MDIO1_HIGHZ (RZN1_FUNC_MDIO_OFFSET + 16) +#define RZN1_FUNC_MDIO1_GMAC0 (RZN1_FUNC_MDIO_OFFSET + 17) +#define RZN1_FUNC_MDIO1_GMAC1 (RZN1_FUNC_MDIO_OFFSET + 18) +#define RZN1_FUNC_MDIO1_ECAT (RZN1_FUNC_MDIO_OFFSET + 19) +#define RZN1_FUNC_MDIO1_S3_MDIO0 (RZN1_FUNC_MDIO_OFFSET + 20) +#define RZN1_FUNC_MDIO1_S3_MDIO1 (RZN1_FUNC_MDIO_OFFSET + 21) +#define RZN1_FUNC_MDIO1_HWRTOS (RZN1_FUNC_MDIO_OFFSET + 22) +#define RZN1_FUNC_MDIO1_SWITCH (RZN1_FUNC_MDIO_OFFSET + 23) +/* These are MDIO1 peripherals for the RZN1_FUNC_ETH_MDIO_E1 function */ +#define RZN1_FUNC_MDIO1_E1_HIGHZ (RZN1_FUNC_MDIO_OFFSET + 24) +#define RZN1_FUNC_MDIO1_E1_GMAC0 (RZN1_FUNC_MDIO_OFFSET + 25) +#define RZN1_FUNC_MDIO1_E1_GMAC1 (RZN1_FUNC_MDIO_OFFSET + 26) +#define RZN1_FUNC_MDIO1_E1_ECAT (RZN1_FUNC_MDIO_OFFSET + 27) +#define RZN1_FUNC_MDIO1_E1_S3_MDIO0 (RZN1_FUNC_MDIO_OFFSET + 28) +#define RZN1_FUNC_MDIO1_E1_S3_MDIO1 (RZN1_FUNC_MDIO_OFFSET + 29) +#define RZN1_FUNC_MDIO1_E1_HWRTOS (RZN1_FUNC_MDIO_OFFSET + 30) +#define RZN1_FUNC_MDIO1_E1_SWITCH (RZN1_FUNC_MDIO_OFFSET + 31) + +#define RZN1_FUNC_MAX (RZN1_FUNC_MDIO_OFFSET + 32) + +#endif /* __DT_BINDINGS_RZN1_PINCTRL_H */ From patchwork Tue Aug 9 12:59:55 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ralph Siemsen X-Patchwork-Id: 596226 Delivered-To: patch@linaro.org Received: by 2002:a05:7000:b345:0:0:0:0 with SMTP id w5csp4153329maz; Tue, 9 Aug 2022 06:02:26 -0700 (PDT) X-Google-Smtp-Source: AA6agR5XvDKCmYYU7AMbMCp5eAmj2T/P4TLNxFGC1IAwL5r8PjSYlIT0Nxk+VyO1h11HlDJw0nzT X-Received: by 2002:a05:6638:3282:b0:33f:6ed0:4c83 with SMTP id f2-20020a056638328200b0033f6ed04c83mr10583991jav.96.1660050145963; Tue, 09 Aug 2022 06:02:25 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1660050145; cv=none; d=google.com; s=arc-20160816; b=UEBdTLe454me+6koIw07Pto4t48gM4FxZ4h4vEyc1dgrIEXCIcZ9WN+nZd2DodewOn +jhi33a54JaXnpMaD/zT6hhO5qAYbd/VXpU6/DjymfbMvOIY9oLksbw4hLbkLdwr0gsd sREp5uUkwaKEuwGUcYoom23a028BndJ1eC58EVIoNyPGdI/E1TtgrMMXwUlsYRpUQ/Mb 9HXXxW1HVmslkYtI4UeVWmO6jezIUSX3Yof6WXe056Hlm8a+YEnuHOmH4dilhQ7JG+6K QOGuzNegYlGcBBOeNypVRQgzVyLyzH5h/6NtITTuuWMGMlU9h7XRQAiMapRmOjaZNGGU Nf9w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=oXurcJNsTtGwSu/Sx65/VXE9BMd/5FtzzSgOmJpGLUQ=; b=D89brQWwqS5aPSdUEZJITv1BTNi/9dx8Iva72YUDSgshKHk58yPjKIJLKv7OhCXfl1 sdpgIFC/tr7fLbBK/20fn17zj/f3eObZ7miA7wx3yd/dEQIE2Sa2a5L4FU75kyNvX9Y4 exvpxyjx++AooSOadU/Y9smq20dJEmWgLCEZntweHIdoXFgCujds/PDbMu+UKUThINja ImwbJai++eImLVYpJl6mjCRzaOWeBsyBNgH2Fbwx8flWsOSwArPuzAhrzIZzwWE0StI7 YcJ6sKSS8md1q4iTv6owJLoFxfEMCIVuJ0wgGYXcYikZrCgA0v07PCbjB2WZuOYdNFWN 1j0g== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b="pCmjS/oQ"; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 2a01:238:438b:c500:173d:9f52:ddab:ee01 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from phobos.denx.de (phobos.denx.de. [2a01:238:438b:c500:173d:9f52:ddab:ee01]) by mx.google.com with ESMTPS id b13-20020a92c56d000000b002deff9b98e5si1682683ilj.22.2022.08.09.06.02.25 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 09 Aug 2022 06:02:25 -0700 (PDT) Received-SPF: pass (google.com: domain of u-boot-bounces@lists.denx.de designates 2a01:238:438b:c500:173d:9f52:ddab:ee01 as permitted sender) client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b="pCmjS/oQ"; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 2a01:238:438b:c500:173d:9f52:ddab:ee01 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 8E82984A55; Tue, 9 Aug 2022 15:01:52 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org 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=linaro.org header.i=@linaro.org header.b="pCmjS/oQ"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 12238849FA; Tue, 9 Aug 2022 15:01:05 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_NONE,SPF_PASS, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-io1-xd34.google.com (mail-io1-xd34.google.com [IPv6:2607:f8b0:4864:20::d34]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id B821284A28 for ; Tue, 9 Aug 2022 15:00:32 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=ralph.siemsen@linaro.org Received: by mail-io1-xd34.google.com with SMTP id l24so9450663ion.13 for ; Tue, 09 Aug 2022 06:00:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc; bh=oXurcJNsTtGwSu/Sx65/VXE9BMd/5FtzzSgOmJpGLUQ=; b=pCmjS/oQhziCwO5Pe8XGWlJHdBoCxQMUpgmyXVV/bT8CbpHTAn5d+xlnouYY8mx1Ko Dx/4h7grMKRC8IRJSdYcDLmAaLU3771xyeIkAEZic2xPM1XhuPjMQtox5QKrvAYt1o1S qWXI02McEWyjEUwTZ02fP+wHhxyzdj3BVapIGqf7EFRUpYR8Lso7mYZgxdKXev0dZbAf oEqVmAVvvZccpwxSoZvTgDx5vNOwMHBdAIHbVFqd2MloZT6qc11Xw9DGpckyzmFJlRcY Q6prUZKB1q1kdZbk6ST2mqro5FnR4ooYzhFF8eknGA1aPb8FdL1u8Mzzz+jR51khYiWD 9VmQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc; bh=oXurcJNsTtGwSu/Sx65/VXE9BMd/5FtzzSgOmJpGLUQ=; b=CLAV3hT3FsdrCjKPOFyVkDVnVEGfocaannRqTmg4lAKbbmBreIFAjGhN+4aj/ZZ6TC EW4sNV/gOvCAqknqdF5UOXfY95B2Oo0bExnteR+ccMsldUbpzx5chfx5S348BoCG4V7s fBLz/bJ4f0Bu3r8/vcQ54I+FZfu+fyBs9uOHnF+x6v5LZUuiS1GdtcN+y19lT3RNhbU3 strOdvGzBuao/CpUa2NwtEQQm7cWLpOLbiVibb4NZE7tLm7b4gMHRmPeKHeaUsonR+13 tNlJuZG8olS0m7SEJNAHe/BekhOc2ZomPx0Z9Qp4GhROVM9cdA1ZrP7kW0i9D5G/p1lT HShg== X-Gm-Message-State: ACgBeo1Q0/wqpMiXJP/2vhfHrRMMbobZTBvDQu8QCkpdPcf3u29GFad1 FFQmXFOzE73OCorEXrRbTUZgN0Uw1b/gPSBh X-Received: by 2002:a02:a609:0:b0:342:e735:182c with SMTP id c9-20020a02a609000000b00342e735182cmr5705317jam.132.1660050030910; Tue, 09 Aug 2022 06:00:30 -0700 (PDT) Received: from maple.netwinder.org (rfs.netwinder.org. [206.248.184.2]) by smtp.gmail.com with ESMTPSA id g12-20020a056e021a2c00b002dea1e18a94sm1022197ile.47.2022.08.09.06.00.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 09 Aug 2022 06:00:30 -0700 (PDT) From: Ralph Siemsen To: u-boot@lists.denx.de Cc: Ralph Siemsen , Andrew Davis , Aswath Govindraju , David Huang , Nishanth Menon , Suman Anna Subject: [RFC PATCH v1 5/9] ram: cadence: add driver for Cadence EDAC Date: Tue, 9 Aug 2022 08:59:55 -0400 Message-Id: <20220809125959.217333-6-ralph.siemsen@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220809125959.217333-1-ralph.siemsen@linaro.org> References: <20220809125959.217333-1-ralph.siemsen@linaro.org> MIME-Version: 1.0 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.6 at phobos.denx.de X-Virus-Status: Clean Driver for Cadence EDAC DDR controller, as found in the Renesas RZ/N1. Only basic setup, not using the ECC features. Signed-off-by: Ralph Siemsen --- drivers/ram/Kconfig | 1 + drivers/ram/Makefile | 2 + drivers/ram/cadence/Kconfig | 24 ++ drivers/ram/cadence/Makefile | 1 + drivers/ram/cadence/ddr_async.c | 295 +++++++++++++++++++++++ drivers/ram/cadence/ddr_ctrl.c | 414 ++++++++++++++++++++++++++++++++ drivers/ram/cadence/ddr_ctrl.h | 172 +++++++++++++ 7 files changed, 909 insertions(+) create mode 100644 drivers/ram/cadence/Kconfig create mode 100644 drivers/ram/cadence/Makefile create mode 100644 drivers/ram/cadence/ddr_async.c create mode 100644 drivers/ram/cadence/ddr_ctrl.c create mode 100644 drivers/ram/cadence/ddr_ctrl.h diff --git a/drivers/ram/Kconfig b/drivers/ram/Kconfig index 86857c0627..ec0ab9ce8a 100644 --- a/drivers/ram/Kconfig +++ b/drivers/ram/Kconfig @@ -97,6 +97,7 @@ config IMXRT_SDRAM This driver is for the sdram memory interface with the SEMC. source "drivers/ram/aspeed/Kconfig" +source "drivers/ram/cadence/Kconfig" source "drivers/ram/rockchip/Kconfig" source "drivers/ram/sifive/Kconfig" source "drivers/ram/stm32mp1/Kconfig" diff --git a/drivers/ram/Makefile b/drivers/ram/Makefile index 5a39611349..2a015cda48 100644 --- a/drivers/ram/Makefile +++ b/drivers/ram/Makefile @@ -22,3 +22,5 @@ obj-$(CONFIG_IMXRT_SDRAM) += imxrt_sdram.o obj-$(CONFIG_RAM_SIFIVE) += sifive/ obj-$(CONFIG_ARCH_OCTEON) += octeon/ + +obj-$(CONFIG_CADENCE_DDR_CTRL) += cadence/ diff --git a/drivers/ram/cadence/Kconfig b/drivers/ram/cadence/Kconfig new file mode 100644 index 0000000000..864cadfd10 --- /dev/null +++ b/drivers/ram/cadence/Kconfig @@ -0,0 +1,24 @@ +if RAM || SPL_RAM + +config CADENCE_DDR_CTRL + bool "Enable Cadence DDR controller" + depends on DM + help + Enable support for Cadence DDR controller, as found on + the Renesas RZ/N1 SoC. This controller has a large number + of registers which need to be programmed, mostly using values + obtained from Denali SOMA files via a TCL script. + +if CADENCE_DDR_CTRL + +# TODO: convert this to devicetree option +config CADENCE_DDR_CTRL_ENABLE_ECC + bool "Enable ECC support" + +# TODO: conver this to devicetree option +config CADENCE_DDR_CTRL_8BIT_WIDTH + bool "Reduce data width from 16 to 8 bits" + +endif + +endif diff --git a/drivers/ram/cadence/Makefile b/drivers/ram/cadence/Makefile new file mode 100644 index 0000000000..16c7fe8488 --- /dev/null +++ b/drivers/ram/cadence/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_CADENCE_DDR_CTRL) += ddr_async.o ddr_ctrl.o diff --git a/drivers/ram/cadence/ddr_async.c b/drivers/ram/cadence/ddr_async.c new file mode 100644 index 0000000000..1d6d3bdc79 --- /dev/null +++ b/drivers/ram/cadence/ddr_async.c @@ -0,0 +1,295 @@ +// SPDX-License-Identifier: BSD-2-Clause +/* + * RZ/N1 DDR Controller initialisation + * + * The DDR Controller register values for a specific DDR device, mode and + * frequency are generated using a Cadence tool. + * + * Copyright (C) 2015 Renesas Electronics Europe Ltd + */ +#include +#include +#include +#include +#include +#include +#include +#include "ddr_ctrl.h" + +void clk_rzn1_reset_state(struct clk *clk, int on); + +extern u32 ddr_00_87_async[]; +extern u32 ddr_350_374_async[]; + +DECLARE_GLOBAL_DATA_PTR; + +struct cadence_ddr_info { + struct udevice *dev; + void __iomem *ddrc; + void __iomem *phy; + struct clk clk_ddrc; + struct clk hclk_ddrc; +}; + +static inline u32 cadence_readl(void __iomem *addr, unsigned int offset) +{ + return readl(addr + offset); +} + +static inline void cadence_writel(void __iomem *addr, unsigned int offset, + u32 data) +{ + debug("%s: addr = 0x%p, value = 0x%08x\n", __func__, addr + offset, data); + writel(data, addr + offset); +} + +#define ddrc_readl(off) cadence_readl(priv->ddrc, off) +#define ddrc_writel(val, off) cadence_writel(priv->ddrc, off, val) + +#define phy_readl(off) cadence_readl(priv->phy, off) +#define phy_writel(val, off) cadence_writel(priv->phy, off, val) + +#define RZN1_DDR3_SINGLE_BANK 3 +#define RZN1_DDR3_DUAL_BANK 32 + +#define FUNCCTRL 0x00 +#define FUNCCTRL_MASKSDLOFS (0x18 << 16) +#define FUNCCTRL_DVDDQ_1_5V (1 << 8) +#define FUNCCTRL_RESET_N (1 << 0) +#define DLLCTRL 0x04 +#define DLLCTRL_ASDLLOCK (1 << 26) +#define DLLCTRL_MFSL_500MHz (2 << 1) +#define DLLCTRL_MDLLSTBY (1 << 0) +#define ZQCALCTRL 0x08 +#define ZQCALCTRL_ZQCALEND (1 << 30) +#define ZQCALCTRL_ZQCALRSTB (1 << 0) +#define ZQODTCTRL 0x0c +#define RDCTRL 0x10 +#define RDTMG 0x14 +#define FIFOINIT 0x18 +#define FIFOINIT_RDPTINITEXE (1 << 8) +#define FIFOINIT_WRPTINITEXE (1 << 0) +#define OUTCTRL 0x1c +#define OUTCTRL_ADCMDOE (1 << 0) +#define WLCTRL1 0x40 +#define WLCTRL1_WLSTR (1 << 24) +#define DQCALOFS1 0xe8 + +/* DDR PHY setup */ +void ddr_phy_init(struct cadence_ddr_info *priv, int ddr_type) +{ + u32 val; + + /* Disable DDR Controller clock and FlexWAY connection */ + clk_disable(&priv->hclk_ddrc); + clk_disable(&priv->clk_ddrc); + + clk_rzn1_reset_state(&priv->hclk_ddrc, 0); + clk_rzn1_reset_state(&priv->clk_ddrc, 0); + + /* Enable DDR Controller clock and FlexWAY connection */ + clk_enable(&priv->clk_ddrc); + clk_enable(&priv->hclk_ddrc); + + /* DDR PHY Soft reset assert */ + ddrc_writel(FUNCCTRL_MASKSDLOFS | FUNCCTRL_DVDDQ_1_5V, FUNCCTRL); + + clk_rzn1_reset_state(&priv->hclk_ddrc, 1); + clk_rzn1_reset_state(&priv->clk_ddrc, 1); + + /* DDR PHY setup */ + phy_writel(DLLCTRL_MFSL_500MHz | DLLCTRL_MDLLSTBY, DLLCTRL); + phy_writel(0x00000182, ZQCALCTRL); + if (ddr_type == RZN1_DDR3_DUAL_BANK) + phy_writel(0xAB330031, ZQODTCTRL); + else if (ddr_type == RZN1_DDR3_SINGLE_BANK) + phy_writel(0xAB320051, ZQODTCTRL); + else /* DDR2 */ + phy_writel(0xAB330071, ZQODTCTRL); + phy_writel(0xB545B544, RDCTRL); + phy_writel(0x000000B0, RDTMG); + phy_writel(0x020A0806, OUTCTRL); + if (ddr_type == RZN1_DDR3_DUAL_BANK) + phy_writel(0x80005556, WLCTRL1); + else + phy_writel(0x80005C5D, WLCTRL1); + phy_writel(0x00000101, FIFOINIT); + phy_writel(0x00004545, DQCALOFS1); + + /* Step 9 MDLL reset release */ + val = phy_readl(DLLCTRL); + val &= ~DLLCTRL_MDLLSTBY; + phy_writel(val, DLLCTRL); + + /* Step 12 Soft reset release */ + val = phy_readl(FUNCCTRL); + val |= FUNCCTRL_RESET_N; + phy_writel(val, FUNCCTRL); + + /* Step 13 FIFO pointer initialize */ + phy_writel(FIFOINIT_RDPTINITEXE | FIFOINIT_WRPTINITEXE, FIFOINIT); + + /* Step 14 Execute ZQ Calibration */ + val = phy_readl(ZQCALCTRL); + val |= ZQCALCTRL_ZQCALRSTB; + phy_writel(val, ZQCALCTRL); + + /* Step 15 Wait for 200us or more, or wait for DFIINITCOMPLETE to be "1" */ + while (!(phy_readl(DLLCTRL) & DLLCTRL_ASDLLOCK)) + ; + while (!(phy_readl(ZQCALCTRL) & ZQCALCTRL_ZQCALEND)) + ; + + /* Step 16 Enable Address and Command output */ + val = phy_readl(OUTCTRL); + val |= OUTCTRL_ADCMDOE; + phy_writel(val, OUTCTRL); + + /* Step 17 Wait for 200us or more(from MRESETB=0) */ + udelay(200); +} + +void ddr_phy_enable_wl(struct cadence_ddr_info *priv) +{ + u32 val; + + /* Step 26 (Set Write Leveling) */ + val = phy_readl(WLCTRL1); + val |= WLCTRL1_WLSTR; + phy_writel(val, WLCTRL1); +} + +#define RZN1_DDR_BASE 0x4000D000 /* RZ/N1D only */ +#define RZN1_V_DDR_BASE 0x80000000 /* RZ/N1D only */ + +void rzn1_ddr3_single_bank(void *ddr_ctrl_base) +{ + /* CS0 */ + cdns_ddr_set_mr1(ddr_ctrl_base, 0, + MR1_ODT_IMPEDANCE_60_OHMS, + MR1_DRIVE_STRENGTH_40_OHMS); + cdns_ddr_set_mr2(ddr_ctrl_base, 0, + MR2_DYNAMIC_ODT_OFF, + MR2_SELF_REFRESH_TEMP_EXT); + + /* ODT_WR_MAP_CS0 = 1, ODT_RD_MAP_CS0 = 0 */ + cdns_ddr_set_odt_map(ddr_ctrl_base, 0, 0x0100); +} + +int rzn1_dram_init(struct cadence_ddr_info *priv) +{ + u32 ddr_start_addr = 0; + + ddr_phy_init(priv, RZN1_DDR3_SINGLE_BANK); + + /* + * Override DDR PHY Interface (DFI) related settings + * DFI is the internal interface between the DDR controller and the DDR PHY. + * These settings are specific to LCES2 and can't be known by the settings + * provided for each DDR model within the generated include. + */ + ddr_350_374_async[351 - 350] = 0x001e0000; + ddr_350_374_async[352 - 350] = 0x1e680000; + ddr_350_374_async[353 - 350] = 0x02000020; + ddr_350_374_async[354 - 350] = 0x02000200; + ddr_350_374_async[355 - 350] = 0x00000c30; + ddr_350_374_async[356 - 350] = 0x00009808; + ddr_350_374_async[357 - 350] = 0x020a0706; + ddr_350_374_async[372 - 350] = 0x01000000; + +#if 0 + /* + * On ES1.0 devices, the DDR start address that the DDR Controller sees + * is the physical address of the DDR. However, later devices changed it + * to be 0 in order to fix an issue with DDR out-of-range detection. + */ + if (sysctrl_readl(RZN1_SYSCTRL_REG_VERSION) == 0x10) + ddr_start_addr = RZN1_V_DDR_BASE; +#endif + + /* DDR Controller is always in ASYNC mode */ + cdns_ddr_ctrl_init((void *)RZN1_DDR_BASE, 1, + ddr_00_87_async, ddr_350_374_async, + ddr_start_addr, CONFIG_SYS_SDRAM_SIZE); + + rzn1_ddr3_single_bank((void *)RZN1_DDR_BASE); + cdns_ddr_set_diff_cs_delays((void *)RZN1_DDR_BASE, 2, 7, 2, 2); + cdns_ddr_set_same_cs_delays((void *)RZN1_DDR_BASE, 0, 7, 0, 0); + cdns_ddr_set_odt_times((void *)RZN1_DDR_BASE, 5, 6, 6, 0, 4); + cdns_ddr_ctrl_start((void *)RZN1_DDR_BASE); + + ddr_phy_enable_wl(priv); + + if (IS_ENABLED(CONFIG_CADENCE_DDR_CTRL_ENABLE_ECC)) { + /* + * Any read before a write will trigger an ECC un-correctable error, + * causing a data abort. However, this is also true for any read with a + * size less than the AXI bus width. So, the only sensible solution is + * to write to all of DDR now and take the hit... + */ + memset((void *)RZN1_V_DDR_BASE, 0xff, CONFIG_SYS_SDRAM_SIZE); + } + + return 0; +} + +static int cadence_ddr_get_info(struct udevice *udev, struct ram_info *info) +{ + info->base = 0; + info->size = gd->ram_size; + + return 0; +} + +static struct ram_ops cadence_ddr_ops = { + .get_info = cadence_ddr_get_info, +}; + +static int cadence_ddr_probe(struct udevice *dev) +{ + struct cadence_ddr_info *priv = dev_get_priv(dev); + int ret; + + priv->ddrc = dev_remap_addr_name(dev, "ddrc"); + if (!priv->ddrc) { + dev_err(dev, "No reg property for Cadence DDR CTRL\n"); + return -EINVAL; + } + + priv->phy = dev_remap_addr_name(dev, "phy"); + if (!priv->phy) { + dev_err(dev, "No reg property for Cadence DDR PHY\n"); + return -EINVAL; + } + + ret = clk_get_by_name(dev, "clk_ddrc", &priv->clk_ddrc); + if (ret) { + dev_err(dev, "No clock for Cadence DDR\n"); + return ret; + } + + ret = clk_get_by_name(dev, "hclk_ddrc", &priv->hclk_ddrc); + if (ret) { + dev_err(dev, "No HCLK for Cadence DDR\n"); + return ret; + } + + rzn1_dram_init(priv); + + return 0; +} + +static const struct udevice_id cadence_ddr_ids[] = { + { .compatible = "cadence,ddr-ctrl" }, + { } +}; + +U_BOOT_DRIVER(cadence_ddr) = { + .name = "cadence_ddr", + .id = UCLASS_RAM, + .of_match = cadence_ddr_ids, + .ops = &cadence_ddr_ops, + .probe = cadence_ddr_probe, + .priv_auto = sizeof(struct cadence_ddr_info), + .flags = DM_FLAG_PRE_RELOC, +}; diff --git a/drivers/ram/cadence/ddr_ctrl.c b/drivers/ram/cadence/ddr_ctrl.c new file mode 100644 index 0000000000..833d5d9197 --- /dev/null +++ b/drivers/ram/cadence/ddr_ctrl.c @@ -0,0 +1,414 @@ +// SPDX-License-Identifier: BSD-2-Clause +/* + * Cadence DDR Controller + * + * Copyright (C) 2015 Renesas Electronics Europe Ltd + */ + +/* + * The Cadence DDR Controller has a huge number of registers that principally + * cover two aspects, DDR specific timing information and AXI bus interfacing. + * Cadence's TCL script generates all of the register values for specific + * DDR devices operating at a specific frequency. The TCL script uses Denali + * SOMA files as inputs. The tool also generates the AXI bus register values as + * well, however this driver assumes that users will want to modifiy these to + * meet a specific application's needs. + * Therefore, this driver is passed two arrays containing register values for + * the DDR device specific information, and explicity sets the AXI registers. + * + * AXI bus interfacing: + * The controller has four AXI slaves connections, and each of these can be + * programmed to accept requests from specific AXI masters (using their IDs). + * The regions of DDR that can be accessed by each AXI slave can be set such + * as to isolate DDR used by one AXI master from another. Further, the maximum + * bandwidth allocated to each AXI slave can be set. + */ + +#include +#include +#include +#include +#include "ddr_ctrl.h" + +/* avoid warning for real pr_debug in */ +#ifdef pr_debug +#undef pr_debug +#endif + +#ifdef DEBUG + #define pr_debug(fmt, args...) printf(fmt, ##args) + #define pr_debug2(fmt, args...) printf(fmt, ##args) +#else + #define pr_debug(fmt, args...) + #define pr_debug2(fmt, args...) +#endif + +#define DDR_NR_AXI_PORTS 4 +#define DDR_NR_ENTRIES 16 + +#define DDR_START_REG (0) /* DENALI_CTL_00 */ +#define DDR_CS0_MR1_REG (32 * 4) /* DENALI_CTL_32 */ +#define DDR_CS0_MR2_REG (32 * 4 + 2) /* DENALI_CTL_32 */ +#define DDR_CS1_MR1_REG (34 * 4 + 2) /* DENALI_CTL_34 */ +#define DDR_CS1_MR2_REG (35 * 4) /* DENALI_CTL_35 */ +#define DDR_ECC_ENABLE_REG (36 * 4 + 2) /* DENALI_CTL_36 */ +#define DDR_ECC_DISABLE_W_UC_ERR_REG (37 * 4 + 2) /* DENALI_CTL_37 */ +#define DDR_HALF_DATAPATH_REG (54 * 4) /* DENALI_CTL_54 */ +#define DDR_INTERRUPT_STATUS (56 * 4) /* DENALI_CTL_56 */ +#define DDR_INTERRUPT_ACK (57 * 4) /* DENALI_CTL_57 */ +#define DDR_INTERRUPT_MASK (58 * 4) /* DENALI_CTL_58 */ +#define DDR_CS0_ODT_MAP_REG (62 * 4 + 2) /* DENALI_CTL_62 */ +#define DDR_CS1_ODT_MAP_REG (63 * 4) /* DENALI_CTL_63 */ +#define DDR_ODT_TODTL_2CMD (63 * 4 + 2) /* DENALI_CTL_63 */ +#define DDR_ODT_TODTH_WR (63 * 4 + 3) /* DENALI_CTL_63 */ +#define DDR_ODT_TODTH_RD (64 * 4 + 0) /* DENALI_CTL_64 */ +#define DDR_ODT_EN (64 * 4 + 1) /* DENALI_CTL_64 */ +#define DDR_ODT_WR_TO_ODTH (64 * 4 + 2) /* DENALI_CTL_64 */ +#define DDR_ODT_RD_TO_ODTH (64 * 4 + 3) /* DENALI_CTL_64 */ +#define DDR_DIFF_CS_DELAY_REG (66 * 4) /* DENALI_CTL_66 */ +#define DDR_SAME_CS_DELAY_REG (67 * 4) /* DENALI_CTL_67 */ +#define DDR_RW_PRIORITY_REGS (87 * 4 + 2) /* DENALI_CTL_87 */ +#define DDR_RW_FIFO_TYPE_REGS (88 * 4) /* DENALI_CTL_88 */ +#define DDR_AXI_PORT_PROT_ENABLE_REG (90 * 4 + 3) /* DENALI_CTL_90 */ +#define DDR_ADDR_RANGE_REGS (91 * 4) /* DENALI_CTL_91 */ +#define DDR_RANGE_PROT_REGS (218 * 4 + 2) /* DENALI_CTL_218 */ +#define DDR_ARB_CMD_Q_THRESHOLD_REG (346 * 4 + 2) /* DENALI_CTL_346 */ +#define DDR_AXI_PORT_BANDWIDTH_REG (346 * 4 + 3) /* DENALI_CTL_346 */ +#define DDR_OPT_RMODW_REG (372 * 4 + 3) /* DENALI_CTL_372 */ + +static void ddrc_writeb(u8 val, void *p) +{ + pr_debug2("DDR: %p = 0x%02x\n", p, val); + writeb(val, p); +} + +static void ddrc_writew(u16 val, void *p) +{ + pr_debug2("DDR: %p = 0x%04x\n", p, val); + writew(val, p); +} + +static void ddrc_writel(u32 val, void *p) +{ + pr_debug2("DDR: %p = 0x%08x\n", p, val); + writel(val, p); +} + +void cdns_ddr_set_mr1(void *base, int cs, u16 odt_impedance, u16 drive_strength) +{ + void *reg; + u16 tmp; + + if (cs == 0) + reg = (u8 *)base + DDR_CS0_MR1_REG; + else + reg = (u8 *)base + DDR_CS1_MR1_REG; + + tmp = readw(reg); + + tmp &= ~MODE_REGISTER_MASK; + tmp |= MODE_REGISTER_MR1; + + tmp &= ~MR1_ODT_IMPEDANCE_MASK; + tmp |= odt_impedance; + + tmp &= ~MR1_DRIVE_STRENGTH_MASK; + tmp |= drive_strength; + + writew(tmp, reg); +} + +void cdns_ddr_set_mr2(void *base, int cs, u16 dynamic_odt, u16 self_refresh_temp) +{ + void *reg; + u16 tmp; + + if (cs == 0) + reg = (u8 *)base + DDR_CS0_MR2_REG; + else + reg = (u8 *)base + DDR_CS1_MR2_REG; + + tmp = readw(reg); + + tmp &= ~MODE_REGISTER_MASK; + tmp |= MODE_REGISTER_MR2; + + tmp &= ~MR2_DYNAMIC_ODT_MASK; + tmp |= dynamic_odt; + + tmp &= ~MR2_SELF_REFRESH_TEMP_MASK; + tmp |= self_refresh_temp; + + writew(tmp, reg); +} + +void cdns_ddr_set_odt_map(void *base, int cs, u16 odt_map) +{ + void *reg; + + if (cs == 0) + reg = (u8 *)base + DDR_CS0_ODT_MAP_REG; + else + reg = (u8 *)base + DDR_CS1_ODT_MAP_REG; + + writew(odt_map, reg); +} + +void cdns_ddr_set_odt_times(void *base, u8 TODTL_2CMD, u8 TODTH_WR, u8 TODTH_RD, + u8 WR_TO_ODTH, u8 RD_TO_ODTH) +{ + writeb(TODTL_2CMD, (u8 *)base + DDR_ODT_TODTL_2CMD); + writeb(TODTH_WR, (u8 *)base + DDR_ODT_TODTH_WR); + writeb(TODTH_RD, (u8 *)base + DDR_ODT_TODTH_RD); + writeb(1, (u8 *)base + DDR_ODT_EN); + writeb(WR_TO_ODTH, (u8 *)base + DDR_ODT_WR_TO_ODTH); + writeb(RD_TO_ODTH, (u8 *)base + DDR_ODT_RD_TO_ODTH); +} + +void cdns_ddr_set_same_cs_delays(void *base, u8 r2r, u8 r2w, u8 w2r, u8 w2w) +{ + u32 val = (w2w << 24) | (w2r << 16) | (r2w << 8) | r2r; + + writel(val, (u8 *)base + DDR_SAME_CS_DELAY_REG); +} + +void cdns_ddr_set_diff_cs_delays(void *base, u8 r2r, u8 r2w, u8 w2r, u8 w2w) +{ + u32 val = (w2w << 24) | (w2r << 16) | (r2w << 8) | r2r; + + writel(val, (u8 *)base + DDR_DIFF_CS_DELAY_REG); +} + +void cdns_ddr_set_port_rw_priority(void *base, int port, + u8 read_pri, u8 write_pri) +{ + u8 *reg8 = (u8 *)base + DDR_RW_PRIORITY_REGS; + + reg8 += (port * 3); + pr_debug("%s port %d (reg8=%p, DENALI_CTL_%d)\n", + __func__, port, reg8, (reg8 - (u8 *)base) / 4); + + ddrc_writeb(read_pri, reg8++); + ddrc_writeb(write_pri, reg8++); +} + +/* The DDR Controller has 16 entries. Each entry can specify an allowed address + * range (with 16KB resolution) for one of the 4 AXI slave ports. + */ +void cdns_ddr_enable_port_addr_range(void *base, int port, int entry, + u32 addr_start, u32 size) +{ + u32 addr_end; + u32 *reg32 = (u32 *)((u8 *)base + DDR_ADDR_RANGE_REGS); + u32 tmp; + + reg32 += (port * DDR_NR_ENTRIES * 2); + reg32 += (entry * 2); + pr_debug("%s port %d, entry %d (reg32=%p, DENALI_CTL_%d)\n", + __func__, port, entry, reg32, ((u8 *)reg32 - (u8 *)base) / 4); + + /* These registers represent 16KB address blocks */ + addr_start /= SZ_16K; + size /= SZ_16K; + if (size) + addr_end = addr_start + size - 1; + else + addr_end = addr_start; + + ddrc_writel(addr_start, reg32++); + + /* + * end_addr: Ensure we only set the bottom 18-bits as DENALI_CTL_218 + * also contains the AXI0 range protection bits. + */ + tmp = readl(reg32); + tmp &= ~(BIT(18) - 1); + tmp |= addr_end; + ddrc_writel(tmp, reg32); +} + +void cdns_ddr_enable_addr_range(void *base, int entry, + u32 addr_start, u32 size) +{ + int axi; + + for (axi = 0; axi < DDR_NR_AXI_PORTS; axi++) + cdns_ddr_enable_port_addr_range(base, axi, entry, + addr_start, size); +} + +void cdns_ddr_enable_port_prot(void *base, int port, int entry, + enum cdns_ddr_range_prot range_protection_bits, + u16 range_RID_check_bits, + u16 range_WID_check_bits, + u8 range_RID_check_bits_ID_lookup, + u8 range_WID_check_bits_ID_lookup) +{ + /* + * Technically, the offset here points to the byte before the start of + * the range protection registers. However, all entries consist of 8 + * bytes, except the first one (which is missing a padding byte) so we + * work around that subtlely. + */ + u8 *reg8 = (u8 *)base + DDR_RANGE_PROT_REGS; + + reg8 += (port * DDR_NR_ENTRIES * 8); + reg8 += (entry * 8); + pr_debug("%s port %d, entry %d (reg8=%p, DENALI_CTL_%d)\n", + __func__, port, entry, reg8, (reg8 - (u8 *)base) / 4); + + if (port == 0 && entry == 0) + ddrc_writeb(range_protection_bits, reg8 + 1); + else + ddrc_writeb(range_protection_bits, reg8); + + ddrc_writew(range_RID_check_bits, reg8 + 2); + ddrc_writew(range_WID_check_bits, reg8 + 4); + ddrc_writeb(range_RID_check_bits_ID_lookup, reg8 + 6); + ddrc_writeb(range_WID_check_bits_ID_lookup, reg8 + 7); +} + +void cdns_ddr_enable_prot(void *base, int entry, + enum cdns_ddr_range_prot range_protection_bits, + u16 range_RID_check_bits, + u16 range_WID_check_bits, + u8 range_RID_check_bits_ID_lookup, + u8 range_WID_check_bits_ID_lookup) +{ + int axi; + + for (axi = 0; axi < DDR_NR_AXI_PORTS; axi++) + cdns_ddr_enable_port_prot(base, axi, entry, + range_protection_bits, + range_RID_check_bits, + range_WID_check_bits, + range_RID_check_bits_ID_lookup, + range_WID_check_bits_ID_lookup); +} + +void cdns_ddr_set_port_bandwidth(void *base, int port, + u8 max_percent, u8 overflow_ok) +{ + u8 *reg8 = (u8 *)base + DDR_AXI_PORT_BANDWIDTH_REG; + + reg8 += (port * 3); + pr_debug("%s port %d, (reg8=%p, DENALI_CTL_%d)\n", + __func__, port, reg8, (reg8 - (u8 *)base) / 4); + + ddrc_writeb(max_percent, reg8++); /* Maximum bandwidth percentage */ + ddrc_writeb(overflow_ok, reg8++); /* Bandwidth overflow allowed */ +} + +void cdns_ddr_ctrl_init(void *ddr_ctrl_basex, int async, + const u32 *reg0, const u32 *reg350, + u32 ddr_start_addr, u32 ddr_size) +{ + int i, axi, entry; + u32 *ddr_ctrl_base = (u32 *)ddr_ctrl_basex; + u8 *base8 = (u8 *)ddr_ctrl_basex; + + pr_debug("%s\n", __func__); + ddrc_writel(*reg0, ddr_ctrl_base + 0); + /* 1 to 6 are read only */ + for (i = 7; i <= 26; i++) + ddrc_writel(*(reg0 + i), ddr_ctrl_base + i); + /* 27 to 29 are not changed */ + for (i = 30; i <= 87; i++) + ddrc_writel(*(reg0 + i), ddr_ctrl_base + i); + + /* Enable/disable ECC */ + if (IS_ENABLED(CONFIG_CADENCE_DDR_CTRL_ENABLE_ECC)) { + pr_debug("%s enabling ECC\n", __func__); + ddrc_writeb(1, base8 + DDR_ECC_ENABLE_REG); + } else { + ddrc_writeb(0, base8 + DDR_ECC_ENABLE_REG); + } + + /* ECC: Disable corruption for read/modify/write operations */ + ddrc_writeb(1, base8 + DDR_ECC_DISABLE_W_UC_ERR_REG); + + /* Set 8/16-bit data width using reduc bit (enable half datapath)*/ + if (IS_ENABLED(CONFIG_CADENCE_DDR_CTRL_8BIT_WIDTH)) { + pr_debug("%s using 8-bit data\n", __func__); + ddrc_writeb(1, base8 + DDR_HALF_DATAPATH_REG); + } else { + ddrc_writeb(0, base8 + DDR_HALF_DATAPATH_REG); + } + + /* Threshold for command queue */ + ddrc_writeb(4, base8 + DDR_ARB_CMD_Q_THRESHOLD_REG); + + /* AXI port protection => enable */ + ddrc_writeb(0x01, base8 + DDR_AXI_PORT_PROT_ENABLE_REG); + + /* Set port interface type, default port priority and bandwidths */ + for (axi = 0; axi < DDR_NR_AXI_PORTS; axi++) { + /* port interface type: synchronous or asynchronous AXI clock */ + u8 *fifo_reg = base8 + DDR_RW_FIFO_TYPE_REGS + (axi * 3); + + if (async) + ddrc_writeb(0, fifo_reg); + else + ddrc_writeb(3, fifo_reg); + + /* R/W priorities */ + cdns_ddr_set_port_rw_priority(ddr_ctrl_base, axi, 2, 2); + + /* AXI bandwidth */ + cdns_ddr_set_port_bandwidth(ddr_ctrl_base, axi, 50, 1); + } + + /* + * The hardware requires that the valid address ranges must not overlap. + * So, we initialise all address ranges to be above the DDR, length 0. + */ + for (entry = 0; entry < DDR_NR_ENTRIES; entry++) + cdns_ddr_enable_addr_range(ddr_ctrl_base, entry, + ddr_start_addr + ddr_size, 0); + + for (i = 350; i <= 374; i++) + ddrc_writel(*(reg350 - 350 + i), ddr_ctrl_base + i); + + /* Disable optimised read-modify-write logic */ + ddrc_writeb(0, base8 + DDR_OPT_RMODW_REG); + + /* + * Disable all interrupts, we are not handling them. + * For detail of the interrupt mask, ack and status bits, see the + * manual's description of the 'int_status' parameter. + */ + ddrc_writel(0, base8 + DDR_INTERRUPT_MASK); + + /* + * Default settings to enable full access to the entire DDR. + * Users can set different ranges and access rights by calling these + * functions before calling cdns_ddr_ctrl_start(). + */ + cdns_ddr_enable_addr_range(ddr_ctrl_base, 0, + ddr_start_addr, ddr_size); + cdns_ddr_enable_prot(ddr_ctrl_base, 0, CDNS_DDR_RANGE_PROT_BITS_FULL, + 0xffff, 0xffff, 0x0f, 0x0f); +} + +void cdns_ddr_ctrl_start(void *ddr_ctrl_basex) +{ + u32 *ddr_ctrl_base = (u32 *)ddr_ctrl_basex; + u8 *base8 = (u8 *)ddr_ctrl_basex; + + /* Start */ + ddrc_writeb(1, base8 + DDR_START_REG); + + /* Wait for controller to be ready (interrupt status) */ + while (!(readl(base8 + DDR_INTERRUPT_STATUS) & 0x100)) + ; + + /* clear all interrupts */ + ddrc_writel(~0, base8 + DDR_INTERRUPT_ACK); + + /* Step 19 Wait 500us from MRESETB=1 */ + udelay(500); + + /* Step 20 tCKSRX wait (From supply stable clock for MCK) */ + /* DENALI_CTL_19 TREF_ENABLE=0x1(=1), AREFRESH=0x1(=1) */ + ddrc_writel(0x01000100, ddr_ctrl_base + 19); +} diff --git a/drivers/ram/cadence/ddr_ctrl.h b/drivers/ram/cadence/ddr_ctrl.h new file mode 100644 index 0000000000..638d986261 --- /dev/null +++ b/drivers/ram/cadence/ddr_ctrl.h @@ -0,0 +1,172 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ +/* + * Cadence DDR Controller + * + * Copyright (C) 2015 Renesas Electronics Europe Ltd + */ + +#ifndef CADENCE_DDR_CTRL_H +#define CADENCE_DDR_CTRL_H + +enum cdns_ddr_range_prot { + CDNS_DDR_RANGE_PROT_BITS_PRIV_SECURE = 0, + CDNS_DDR_RANGE_PROT_BITS_SECURE = 1, + CDNS_DDR_RANGE_PROT_BITS_PRIV = 2, + CDNS_DDR_RANGE_PROT_BITS_FULL = 3, +}; + +/** + * Initialise the Cadence DDR Controller, but doesn't start it. + * + * It sets up the controller so that all 4 AXI slave ports allow access to all + * of the DDR with the same settings. This means that: + * - Full access permisions. + * - All read/write priorities are set to 2. + * - Bandwidth is set to 50%, overflow is allowed, i.e. it's a soft limit. + * If you want different properties for different ports and/or addr ranges, call + * the other functions before calling cdns_ddr_ctrl_start(). + * + * @ddr_ctrl_base Physical address of the DDR Controller. + * @async 0 if DDR clock is synchronous with the controller clock + * otherwise 1. + * @reg0 Pointer to array of 32-bit values to be written to registers + * 0 to 87. The values are generated by Cadence TCL scripts. + * @reg350 Pointer to array of 32-bit values to be written to registers + * 350 to 374. The values are generated by Cadence TCL scripts. + * @ddr_start_addr Physical address of the start of DDR. + * @ddr_size Size of the DDR in bytes. The controller will set the port + * protection range to match this size. + */ +void cdns_ddr_ctrl_init(void *ddr_ctrl_base, int async, + const u32 *reg0, const u32 *reg350, + u32 ddr_start_addr, u32 ddr_size); + +/** + * Start the Cadence DDR Controller. + * + * @ddr_ctrl_base Physical address of the DDR Controller. + */ +void cdns_ddr_ctrl_start(void *ddr_ctrl_base); + +/** + * Set the priority for read and write operations for a specific AXI slave port. + * + * @base Physical address of the DDR Controller. + * @port Port number. Range is 0 to 3. + * @read_pri Priority for reads. Range is 0 to 3, where 0 is highest priority. + * @write_pri Priority for writes. Range is 0 to 3, where 0 is highest priority. + */ +void cdns_ddr_set_port_rw_priority(void *base, int port, + u8 read_pri, u8 write_pri); + +/** + * Specify address range for a protection entry, for a specific AXI slave port. + * + * @base Physical address of the DDR Controller. + * @port Port number. Range is 0 to 3. + * @entry The protection entry. Range is 0 to 15. + * @start_addr Physical of the address range, must be aligned to 16KB. + * @size Size of the address range, must be multiple of 16KB. + */ +void cdns_ddr_enable_port_addr_range(void *base, int port, int entry, + u32 addr_start, u32 size); + +/** + * Specify address range for a protection entry, for all AXI slave ports. + * + * @base Physical address of the DDR Controller. + * @entry The protection entry. Range is 0 to 15. + * @start_addr Physical of the address range, must be aligned to 16KB. + * @size Size of the address range, must be multiple of 16KB. + */ +void cdns_ddr_enable_addr_range(void *base, int entry, + u32 addr_start, u32 size); + +/** + * Specify protection entry details, for a specific AXI slave port. + * + * See the hardware manual for details of the range check bits. + * + * @base Physical address of the DDR Controller. + * @port Port number. Range is 0 to 3. + * @entry The protection entry. Range is 0 to 15. + */ +void cdns_ddr_enable_port_prot(void *base, int port, int entry, + enum cdns_ddr_range_prot range_protection_bits, + u16 range_RID_check_bits, + u16 range_WID_check_bits, + u8 range_RID_check_bits_ID_lookup, + u8 range_WID_check_bits_ID_lookup); + +/** + * Specify protection entry details, for all AXI slave ports. + * + * See the hardware manual for details of the range check bits. + * + * @base Physical address of the DDR Controller. + * @entry The protection entry. Range is 0 to 15. + */ +void cdns_ddr_enable_prot(void *base, int entry, + enum cdns_ddr_range_prot range_protection_bits, + u16 range_RID_check_bits, + u16 range_WID_check_bits, + u8 range_RID_check_bits_ID_lookup, + u8 range_WID_check_bits_ID_lookup); + +/** + * Specify bandwidth for each AXI port. + * + * See the hardware manual for details of the range check bits. + * + * @base Physical address of the DDR Controller. + * @port Port number. Range is 0 to 3. + * @max_percent 0 to 100. + */ +void cdns_ddr_set_port_bandwidth(void *base, int port, + u8 max_percent, u8 overflow_ok); + +/* Standard JEDEC registers */ +#define MODE_REGISTER_MASK (3 << 14) +#define MODE_REGISTER_MR0 (0 << 14) +#define MODE_REGISTER_MR1 (1 << 14) +#define MODE_REGISTER_MR2 (2 << 14) +#define MODE_REGISTER_MR3 (3 << 14) +#define MR1_DRIVE_STRENGTH_MASK ((1 << 5) | (1 << 1)) +#define MR1_DRIVE_STRENGTH_34_OHMS ((0 << 5) | (1 << 1)) +#define MR1_DRIVE_STRENGTH_40_OHMS ((0 << 5) | (0 << 1)) +#define MR1_ODT_IMPEDANCE_MASK ((1 << 9) | (1 << 6) | (1 << 2)) +#define MR1_ODT_IMPEDANCE_60_OHMS ((0 << 9) | (0 << 6) | (1 << 2)) +#define MR1_ODT_IMPEDANCE_120_OHMS ((0 << 9) | (1 << 6) | (0 << 2)) +#define MR1_ODT_IMPEDANCE_40_OHMS ((0 << 9) | (1 << 6) | (1 << 2)) +#define MR1_ODT_IMPEDANCE_20_OHMS ((1 << 9) | (0 << 6) | (0 << 2)) +#define MR1_ODT_IMPEDANCE_30_OHMS ((1 << 9) | (0 << 6) | (1 << 2)) +#define MR2_DYNAMIC_ODT_MASK (3 << 9) +#define MR2_DYNAMIC_ODT_OFF (0 << 9) +#define MR2_SELF_REFRESH_TEMP_MASK (1 << 7) +#define MR2_SELF_REFRESH_TEMP_EXT (1 << 7) + +/** + * Set certain fields of the JEDEC MR1 register. + */ +void cdns_ddr_set_mr1(void *base, int cs, u16 odt_impedance, u16 drive_strength); + +/** + * Set certain fields of the JEDEC MR2 register. + */ +void cdns_ddr_set_mr2(void *base, int cs, u16 dynamic_odt, u16 self_refresh_temp); + +/** + * Set ODT map of the DDR Controller. + */ +void cdns_ddr_set_odt_map(void *base, int cs, u16 odt_map); + +/** + * Set ODT settings in the DDR Controller. + */ +void cdns_ddr_set_odt_times(void *base, u8 TODTL_2CMD, u8 TODTH_WR, u8 TODTH_RD, + u8 WR_TO_ODTH, u8 RD_TO_ODTH); + +void cdns_ddr_set_same_cs_delays(void *base, u8 r2r, u8 r2w, u8 w2r, u8 w2w); +void cdns_ddr_set_diff_cs_delays(void *base, u8 r2r, u8 r2w, u8 w2r, u8 w2w); + +#endif From patchwork Tue Aug 9 12:59:56 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ralph Siemsen X-Patchwork-Id: 596224 Delivered-To: patch@linaro.org Received: by 2002:a05:7000:b345:0:0:0:0 with SMTP id w5csp4152770maz; Tue, 9 Aug 2022 06:01:58 -0700 (PDT) X-Google-Smtp-Source: AA6agR7F98umJRDYKY6ix0pLu9I4qGJKXUEROuGI1JmV4aFjYogowIUOVAdFyHrmF265dafIxG84 X-Received: by 2002:a05:6638:3385:b0:339:ea59:a31f with SMTP id h5-20020a056638338500b00339ea59a31fmr9702165jav.55.1660050117857; Tue, 09 Aug 2022 06:01:57 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1660050117; cv=none; d=google.com; s=arc-20160816; b=rHIn6FvXxlHOwKQuZl5buCS8s14/ZHERx4yoLSZhTov2kjV9EblLxQC85e3rPx0Hp+ DsaegFqFFveXTn60WUCFa0rHdr0jGNfzF7tjZczWmaPlR28sOAvBWVVyA+zVO3THiFtL XhTkaEtpfKkGXRHC0YdKxpgi/QuWIp4C8TfIl1u1E/nav2n1/cz/UF9nenVQzyxYi9/G upycXXi8YDRjBCzA8lH70tS2TzVwFuxbZT+qV//ddD8vxRC7sDlwPPd9Agr/kIVnsbZE VdLGrTJV35bfD7DWUz2Ihd5xRReTcPDzu06xsgr5IXEDkRbnDK++467VDJ0efRTtB1mq 1SKA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=nKZ+jyglP6OvgH4r2bEe4931CBogSQ6X+gl4Pj0izwU=; b=zkLWQJj6sE41aoNTwF7ghO5WF7hrTMDsNGCLCxB8IxNvklw6dXMUw24DoPkOaf7/Z/ r7xz/twitwh4LCXqXg3VY5qLWw/5gXDRXsnvbWGTDHDhKAZvzL5dF5/JGn+h8PZJEAjg Bq1JNh8hQExzwh8H9SE16vqAjMGlMFTb4Q3R0qtsQpOj9yP/Z+KMd6KylRW3ILhK9uqN cbA3NntxZpm8Edni2Lne1wuhwWBASH71Nu6PMFXNx4oTx0wTmLF9uP9ofrsr6dtBVPwc KwENEq0l36E8GNCa1gwsZqAc6CXQO5nM2PvVMuFI8igAn7tfQWpU/UGVzNmIS38E8XqX mntg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=kOok6bNI; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from phobos.denx.de (phobos.denx.de. [85.214.62.61]) by mx.google.com with ESMTPS id ca12-20020a0566381c0c00b00343159a0b1asi3220869jab.1.2022.08.09.06.01.57 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 09 Aug 2022 06:01:57 -0700 (PDT) Received-SPF: pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 as permitted sender) client-ip=85.214.62.61; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=kOok6bNI; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id BD8F284A37; Tue, 9 Aug 2022 15:01:37 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org 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=linaro.org header.i=@linaro.org header.b="kOok6bNI"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id C6F9E84A33; Tue, 9 Aug 2022 15:01:06 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_NONE,SPF_PASS, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-il1-x130.google.com (mail-il1-x130.google.com [IPv6:2607:f8b0:4864:20::130]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id B755A84A42 for ; Tue, 9 Aug 2022 15:00:34 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=ralph.siemsen@linaro.org Received: by mail-il1-x130.google.com with SMTP id l9so6449939ilq.1 for ; Tue, 09 Aug 2022 06:00:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc; bh=nKZ+jyglP6OvgH4r2bEe4931CBogSQ6X+gl4Pj0izwU=; b=kOok6bNIB11d2h8U7EtfkByNX+tr5EjlU9McNj3S3ngmTvfIL1rgKuk2DUduOWS2oO pdFXNVRRK+ktGyXoNoZmzQOr/cE4gfXbSRS8xZ72Rt9o1Lo1jpd11ErUnxrbZrgkwcMx kXZDZvYDjPWHDUU4IEekcim9ItVpzGIcNsJ89EdSZ3HSFwrY22KogXxx62or6W91xtIv 0WBcouOqrKHRQ/2/1dkT+lGea7lUQby5Kj38IfBMuFVs3K7UjNPiygl6tyLjLDIfoOiD dpnfeFLtSYduI5OQ/Cf4h/NXuynTGnbOQFJSyGRTlb/4uP808suwENijuniMzGUgBPhH 5qcQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc; bh=nKZ+jyglP6OvgH4r2bEe4931CBogSQ6X+gl4Pj0izwU=; b=A8OiajfiVIycMe06lHzAXdQ44Ux3zZeuxuXb1/+jPAsiCvLvCY372kNukevqh1o9Ju fHkLIO7q4KLhhbqPar0LSOIFxXH7i8FICqPA2RXz4VaSVjJnnK7evg8GpZBnpYJ8Yl+M ZgAkfOh0OyYv7UtVGA+rrHw2BaJXdTyVKznaMuaq+JoqoLFzL/s6McBuynSJgDgtgo9c mh3HV9OCw9V8JeOz2TGvz0krRmI17Nu5t6ytfs9DeHrA3Y0+1D1fXe3OMP+lzBQ0Kz4c qR0FzAuZNaFOT1cxa/XcqvVt3rQDGS9NTf8st6LOnKswRLoi+tYGAfhtccNoic5scB4z 5YxQ== X-Gm-Message-State: ACgBeo0ncQk1tP8HUJFYqoFBFB0/8w9Pf4VvhGjsqiAigf//Hv1bw8yu /ADbK4Secab+bXi0/Fd5ZBjWAUKAXBXD+q8k X-Received: by 2002:a05:6e02:1707:b0:2e0:d676:52f0 with SMTP id u7-20020a056e02170700b002e0d67652f0mr5761563ill.78.1660050032722; Tue, 09 Aug 2022 06:00:32 -0700 (PDT) Received: from maple.netwinder.org (rfs.netwinder.org. [206.248.184.2]) by smtp.gmail.com with ESMTPSA id g12-20020a056e021a2c00b002dea1e18a94sm1022197ile.47.2022.08.09.06.00.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 09 Aug 2022 06:00:32 -0700 (PDT) From: Ralph Siemsen To: u-boot@lists.denx.de Cc: Ralph Siemsen Subject: [RFC PATCH v1 6/9] dts: basic devicetree for Renesas RZ/N1 SoC Date: Tue, 9 Aug 2022 08:59:56 -0400 Message-Id: <20220809125959.217333-7-ralph.siemsen@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220809125959.217333-1-ralph.siemsen@linaro.org> References: <20220809125959.217333-1-ralph.siemsen@linaro.org> MIME-Version: 1.0 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.6 at phobos.denx.de X-Virus-Status: Clean This is taken from Linux kernel 5.17, and contains just bare minimum functionality: CPU, UART and system timer. Additional functionality (from newer kernel versions) will be added later. Note that the Linux side is under active development. Signed-off-by: Ralph Siemsen --- The following changes were made, compared with Linux 5.17: 1) Add node for system controller registers. Declare it as syscon to provide a regmap interface. 2) In the clock controller node (renesas,r9a06g032-sysctrl), replace regs with regmap. 3) Add syscon-reset node, making use of the syscon regmap. I could not find a way to avoid 1) and 2). Putting "syscon" in the compatible string for the clock controller leads to a catch-22, where the driver fails to initialize, and then boot hangs. arch/arm/dts/r9a06g032.dtsi | 225 ++++++++++++++++++ include/dt-bindings/clock/r9a06g032-sysctrl.h | 148 ++++++++++++ 2 files changed, 373 insertions(+) create mode 100644 arch/arm/dts/r9a06g032.dtsi create mode 100644 include/dt-bindings/clock/r9a06g032-sysctrl.h diff --git a/arch/arm/dts/r9a06g032.dtsi b/arch/arm/dts/r9a06g032.dtsi new file mode 100644 index 0000000000..a276a43e72 --- /dev/null +++ b/arch/arm/dts/r9a06g032.dtsi @@ -0,0 +1,225 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Base Device Tree Source for the Renesas RZ/N1D (R9A06G032) + * + * Copyright (C) 2018 Renesas Electronics Europe Limited + * + */ + +#include +#include + +/ { + compatible = "renesas,r9a06g032"; + #address-cells = <1>; + #size-cells = <1>; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a7"; + reg = <0>; + clocks = <&sysctrl R9A06G032_CLK_A7MP>; + }; + + cpu@1 { + device_type = "cpu"; + compatible = "arm,cortex-a7"; + reg = <1>; + clocks = <&sysctrl R9A06G032_CLK_A7MP>; + enable-method = "renesas,r9a06g032-smp"; + cpu-release-addr = <0 0x4000c204>; + }; + }; + + ext_jtag_clk: extjtagclk { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <0>; + }; + + ext_mclk: extmclk { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <40000000>; + }; + + ext_rgmii_ref: extrgmiiref { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <0>; + }; + + ext_rtc_clk: extrtcclk { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <0>; + }; + + soc { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + interrupt-parent = <&gic>; + ranges; + + plat_regs: system-controller@4000c000 { + compatible = "syscon"; + reg = <0x4000c000 0x1000>; + u-boot,dm-pre-reloc; + }; + + sysctrl: clock { + compatible = "renesas,r9a06g032-sysctrl"; + #clock-cells = <1>; + regmap = <&plat_regs>; + u-boot,dm-pre-reloc; + + clocks = <&ext_mclk>, <&ext_rtc_clk>, + <&ext_jtag_clk>, <&ext_rgmii_ref>; + clock-names = "mclk", "rtc", "jtag", "rgmii_ref_ext"; + }; + + ddrctrl: memory-controller@4000d000 { + compatible = "cadence,ddr-ctrl"; + reg = <0x4000d000 0x1000>, <0x4000e000 0x100>; + reg-names = "ddrc", "phy"; + interrupts = ; + clocks = <&sysctrl R9A06G032_CLK_DDRC>, <&sysctrl R9A06G032_HCLK_DDRC>; + clock-names = "clk_ddrc", "hclk_ddrc"; + status = "disabled"; + }; + + uart0: serial@40060000 { + compatible = "renesas,r9a06g032-uart", "renesas,rzn1-uart", "snps,dw-apb-uart"; + reg = <0x40060000 0x400>; + interrupts = ; + reg-shift = <2>; + reg-io-width = <4>; + clocks = <&sysctrl R9A06G032_CLK_UART0>, <&sysctrl R9A06G032_HCLK_UART0>; + clock-names = "baudclk", "apb_pclk"; + status = "disabled"; + }; + + uart1: serial@40061000 { + compatible = "renesas,r9a06g032-uart", "renesas,rzn1-uart", "snps,dw-apb-uart"; + reg = <0x40061000 0x400>; + interrupts = ; + reg-shift = <2>; + reg-io-width = <4>; + clocks = <&sysctrl R9A06G032_CLK_UART1>, <&sysctrl R9A06G032_HCLK_UART1>; + clock-names = "baudclk", "apb_pclk"; + status = "disabled"; + }; + + uart2: serial@40062000 { + compatible = "renesas,r9a06g032-uart", "renesas,rzn1-uart", "snps,dw-apb-uart"; + reg = <0x40062000 0x400>; + interrupts = ; + reg-shift = <2>; + reg-io-width = <4>; + clocks = <&sysctrl R9A06G032_CLK_UART2>, <&sysctrl R9A06G032_HCLK_UART2>; + clock-names = "baudclk", "apb_pclk"; + status = "disabled"; + }; + + uart3: serial@50000000 { + compatible = "renesas,r9a06g032-uart", "renesas,rzn1-uart"; + reg = <0x50000000 0x400>; + interrupts = ; + reg-shift = <2>; + reg-io-width = <4>; + clocks = <&sysctrl R9A06G032_CLK_UART3>, <&sysctrl R9A06G032_HCLK_UART3>; + clock-names = "baudclk", "apb_pclk"; + status = "disabled"; + }; + + uart4: serial@50001000 { + compatible = "renesas,r9a06g032-uart", "renesas,rzn1-uart"; + reg = <0x50001000 0x400>; + interrupts = ; + reg-shift = <2>; + reg-io-width = <4>; + clocks = <&sysctrl R9A06G032_CLK_UART4>, <&sysctrl R9A06G032_HCLK_UART4>; + clock-names = "baudclk", "apb_pclk"; + status = "disabled"; + }; + + uart5: serial@50002000 { + compatible = "renesas,r9a06g032-uart", "renesas,rzn1-uart"; + reg = <0x50002000 0x400>; + interrupts = ; + reg-shift = <2>; + reg-io-width = <4>; + clocks = <&sysctrl R9A06G032_CLK_UART5>, <&sysctrl R9A06G032_HCLK_UART5>; + clock-names = "baudclk", "apb_pclk"; + status = "disabled"; + }; + + uart6: serial@50003000 { + compatible = "renesas,r9a06g032-uart", "renesas,rzn1-uart"; + reg = <0x50003000 0x400>; + interrupts = ; + reg-shift = <2>; + reg-io-width = <4>; + clocks = <&sysctrl R9A06G032_CLK_UART6>, <&sysctrl R9A06G032_HCLK_UART6>; + clock-names = "baudclk", "apb_pclk"; + status = "disabled"; + }; + + uart7: serial@50004000 { + compatible = "renesas,r9a06g032-uart", "renesas,rzn1-uart"; + reg = <0x50004000 0x400>; + interrupts = ; + reg-shift = <2>; + reg-io-width = <4>; + clocks = <&sysctrl R9A06G032_CLK_UART7>, <&sysctrl R9A06G032_HCLK_UART7>; + clock-names = "baudclk", "apb_pclk"; + status = "disabled"; + }; + + pinctrl: pinctrl@40067000 { + compatible = "renesas,r9a06g032-pinctrl", "renesas,rzn1-pinctrl"; + reg = <0x40067000 0x1000>, <0x51000000 0x480>; + clocks = <&sysctrl R9A06G032_HCLK_PINCONFIG>; + clock-names = "bus"; + status = "disabled"; + }; + + gic: interrupt-controller@44101000 { + compatible = "arm,gic-400", "arm,cortex-a7-gic"; + interrupt-controller; + #interrupt-cells = <3>; + reg = <0x44101000 0x1000>, /* Distributer */ + <0x44102000 0x2000>, /* CPU interface */ + <0x44104000 0x2000>, /* Virt interface control */ + <0x44106000 0x2000>; /* Virt CPU interface */ + interrupts = + ; + }; + }; + + timer { + compatible = "arm,cortex-a7-timer", + "arm,armv7-timer"; + interrupt-parent = <&gic>; + arm,cpu-registers-not-fw-configured; + always-on; + interrupts = + , + , + , + ; + }; + + reboot { + compatible = "syscon-reboot"; + regmap = <&plat_regs>; + offset = <0x198>; /* sysctrl.RSTEN */ + mask = <0x40>; /* bit 6 = SWRST_REQ */ + value = <0x40>; + }; +}; diff --git a/include/dt-bindings/clock/r9a06g032-sysctrl.h b/include/dt-bindings/clock/r9a06g032-sysctrl.h new file mode 100644 index 0000000000..90c0f3dc1b --- /dev/null +++ b/include/dt-bindings/clock/r9a06g032-sysctrl.h @@ -0,0 +1,148 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * R9A06G032 sysctrl IDs + * + * Copyright (C) 2018 Renesas Electronics Europe Limited + * + * Michel Pollet , + */ + +#ifndef __DT_BINDINGS_R9A06G032_SYSCTRL_H__ +#define __DT_BINDINGS_R9A06G032_SYSCTRL_H__ + +#define R9A06G032_CLK_PLL_USB 1 +#define R9A06G032_CLK_48 1 /* AKA CLK_PLL_USB */ +#define R9A06G032_MSEBIS_CLK 3 /* AKA CLKOUT_D16 */ +#define R9A06G032_MSEBIM_CLK 3 /* AKA CLKOUT_D16 */ +#define R9A06G032_CLK_DDRPHY_PLLCLK 5 /* AKA CLKOUT_D1OR2 */ +#define R9A06G032_CLK50 6 /* AKA CLKOUT_D20 */ +#define R9A06G032_CLK25 7 /* AKA CLKOUT_D40 */ +#define R9A06G032_CLK125 9 /* AKA CLKOUT_D8 */ +#define R9A06G032_CLK_P5_PG1 17 /* AKA DIV_P5_PG */ +#define R9A06G032_CLK_REF_SYNC 21 /* AKA DIV_REF_SYNC */ +#define R9A06G032_CLK_25_PG4 26 +#define R9A06G032_CLK_25_PG5 27 +#define R9A06G032_CLK_25_PG6 28 +#define R9A06G032_CLK_25_PG7 29 +#define R9A06G032_CLK_25_PG8 30 +#define R9A06G032_CLK_ADC 31 +#define R9A06G032_CLK_ECAT100 32 +#define R9A06G032_CLK_HSR100 33 +#define R9A06G032_CLK_I2C0 34 +#define R9A06G032_CLK_I2C1 35 +#define R9A06G032_CLK_MII_REF 36 +#define R9A06G032_CLK_NAND 37 +#define R9A06G032_CLK_NOUSBP2_PG6 38 +#define R9A06G032_CLK_P1_PG2 39 +#define R9A06G032_CLK_P1_PG3 40 +#define R9A06G032_CLK_P1_PG4 41 +#define R9A06G032_CLK_P4_PG3 42 +#define R9A06G032_CLK_P4_PG4 43 +#define R9A06G032_CLK_P6_PG1 44 +#define R9A06G032_CLK_P6_PG2 45 +#define R9A06G032_CLK_P6_PG3 46 +#define R9A06G032_CLK_P6_PG4 47 +#define R9A06G032_CLK_PCI_USB 48 +#define R9A06G032_CLK_QSPI0 49 +#define R9A06G032_CLK_QSPI1 50 +#define R9A06G032_CLK_RGMII_REF 51 +#define R9A06G032_CLK_RMII_REF 52 +#define R9A06G032_CLK_SDIO0 53 +#define R9A06G032_CLK_SDIO1 54 +#define R9A06G032_CLK_SERCOS100 55 +#define R9A06G032_CLK_SLCD 56 +#define R9A06G032_CLK_SPI0 57 +#define R9A06G032_CLK_SPI1 58 +#define R9A06G032_CLK_SPI2 59 +#define R9A06G032_CLK_SPI3 60 +#define R9A06G032_CLK_SPI4 61 +#define R9A06G032_CLK_SPI5 62 +#define R9A06G032_CLK_SWITCH 63 +#define R9A06G032_HCLK_ECAT125 65 +#define R9A06G032_HCLK_PINCONFIG 66 +#define R9A06G032_HCLK_SERCOS 67 +#define R9A06G032_HCLK_SGPIO2 68 +#define R9A06G032_HCLK_SGPIO3 69 +#define R9A06G032_HCLK_SGPIO4 70 +#define R9A06G032_HCLK_TIMER0 71 +#define R9A06G032_HCLK_TIMER1 72 +#define R9A06G032_HCLK_USBF 73 +#define R9A06G032_HCLK_USBH 74 +#define R9A06G032_HCLK_USBPM 75 +#define R9A06G032_CLK_48_PG_F 76 +#define R9A06G032_CLK_48_PG4 77 +#define R9A06G032_CLK_DDRPHY_PCLK 81 /* AKA CLK_REF_SYNC_D4 */ +#define R9A06G032_CLK_FW 81 /* AKA CLK_REF_SYNC_D4 */ +#define R9A06G032_CLK_CRYPTO 81 /* AKA CLK_REF_SYNC_D4 */ +#define R9A06G032_CLK_A7MP 84 /* AKA DIV_CA7 */ +#define R9A06G032_HCLK_CAN0 85 +#define R9A06G032_HCLK_CAN1 86 +#define R9A06G032_HCLK_DELTASIGMA 87 +#define R9A06G032_HCLK_PWMPTO 88 +#define R9A06G032_HCLK_RSV 89 +#define R9A06G032_HCLK_SGPIO0 90 +#define R9A06G032_HCLK_SGPIO1 91 +#define R9A06G032_RTOS_MDC 92 +#define R9A06G032_CLK_CM3 93 +#define R9A06G032_CLK_DDRC 94 +#define R9A06G032_CLK_ECAT25 95 +#define R9A06G032_CLK_HSR50 96 +#define R9A06G032_CLK_HW_RTOS 97 +#define R9A06G032_CLK_SERCOS50 98 +#define R9A06G032_HCLK_ADC 99 +#define R9A06G032_HCLK_CM3 100 +#define R9A06G032_HCLK_CRYPTO_EIP150 101 +#define R9A06G032_HCLK_CRYPTO_EIP93 102 +#define R9A06G032_HCLK_DDRC 103 +#define R9A06G032_HCLK_DMA0 104 +#define R9A06G032_HCLK_DMA1 105 +#define R9A06G032_HCLK_GMAC0 106 +#define R9A06G032_HCLK_GMAC1 107 +#define R9A06G032_HCLK_GPIO0 108 +#define R9A06G032_HCLK_GPIO1 109 +#define R9A06G032_HCLK_GPIO2 110 +#define R9A06G032_HCLK_HSR 111 +#define R9A06G032_HCLK_I2C0 112 +#define R9A06G032_HCLK_I2C1 113 +#define R9A06G032_HCLK_LCD 114 +#define R9A06G032_HCLK_MSEBI_M 115 +#define R9A06G032_HCLK_MSEBI_S 116 +#define R9A06G032_HCLK_NAND 117 +#define R9A06G032_HCLK_PG_I 118 +#define R9A06G032_HCLK_PG19 119 +#define R9A06G032_HCLK_PG20 120 +#define R9A06G032_HCLK_PG3 121 +#define R9A06G032_HCLK_PG4 122 +#define R9A06G032_HCLK_QSPI0 123 +#define R9A06G032_HCLK_QSPI1 124 +#define R9A06G032_HCLK_ROM 125 +#define R9A06G032_HCLK_RTC 126 +#define R9A06G032_HCLK_SDIO0 127 +#define R9A06G032_HCLK_SDIO1 128 +#define R9A06G032_HCLK_SEMAP 129 +#define R9A06G032_HCLK_SPI0 130 +#define R9A06G032_HCLK_SPI1 131 +#define R9A06G032_HCLK_SPI2 132 +#define R9A06G032_HCLK_SPI3 133 +#define R9A06G032_HCLK_SPI4 134 +#define R9A06G032_HCLK_SPI5 135 +#define R9A06G032_HCLK_SWITCH 136 +#define R9A06G032_HCLK_SWITCH_RG 137 +#define R9A06G032_HCLK_UART0 138 +#define R9A06G032_HCLK_UART1 139 +#define R9A06G032_HCLK_UART2 140 +#define R9A06G032_HCLK_UART3 141 +#define R9A06G032_HCLK_UART4 142 +#define R9A06G032_HCLK_UART5 143 +#define R9A06G032_HCLK_UART6 144 +#define R9A06G032_HCLK_UART7 145 +#define R9A06G032_CLK_UART0 146 +#define R9A06G032_CLK_UART1 147 +#define R9A06G032_CLK_UART2 148 +#define R9A06G032_CLK_UART3 149 +#define R9A06G032_CLK_UART4 150 +#define R9A06G032_CLK_UART5 151 +#define R9A06G032_CLK_UART6 152 +#define R9A06G032_CLK_UART7 153 + +#endif /* __DT_BINDINGS_R9A06G032_SYSCTRL_H__ */ From patchwork Tue Aug 9 12:59:57 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ralph Siemsen X-Patchwork-Id: 596227 Delivered-To: patch@linaro.org Received: by 2002:a05:7000:b345:0:0:0:0 with SMTP id w5csp4153586maz; Tue, 9 Aug 2022 06:02:40 -0700 (PDT) X-Google-Smtp-Source: AA6agR4geK4RN0PlrUzPC+FYN+Z8NcYXj2HrLH9mYoqJBvlhDjioYb65IRJIIg22KYrBnYNc079e X-Received: by 2002:a05:6e02:1685:b0:2df:2dd5:80f3 with SMTP id f5-20020a056e02168500b002df2dd580f3mr10392767ila.17.1660050160233; Tue, 09 Aug 2022 06:02:40 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1660050160; cv=none; d=google.com; s=arc-20160816; b=H+l2W/rJFDnZm537ncMeZyXX+PB5KO/BAb63jl76sIiMBlqUyavgaWNYrhr6aCGEA0 RQYb3Q0Yz7ENTMkCLEiQXLgIQtRsMzhrTiT4kOaseC+64m47H8DwBHdvXxPA5PBfpjfy bQQejrUXUhjQFYsNq8aQ34XkBnKBR2qK5ItstnSGxvHDbFeiKSjMyAV7T168JcO+S0+f GMZQvGxQAKAQP+ocKVEe9p20p2TioEQ+9gIFW3aM2pvwEGhGieCBxKf8/VQLV6iA/76H JEWdn9M1BVkA8t0Cn4WWPOIovImXDiwK0LlSy1zrRC4lt+yl6A2jLpQW76VciTI/wXlN URGQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=QwSDXVh3M0SPz3HGNjFLY+2td5IptDvLM6kh7m8Ffl4=; b=rBheuHP6AK5oB6WwxFNea/By+rzv/DQGvlwty2Jq4Oo3ytzLwLZ+RikVtQcEzwqVWM iDXjDPm526KChqwq5kBC7nO+JKTOO2RyFk7rhkREeJ/GLqmRUYhZpNDqtTOVolKQECH4 2DzAsRf5Qw1XFfGGJbjMoDBmrJYd4WoVjp9qziVQlJtLf7cU5hfCBTVNB5jAeuj3hj75 pw6vsF1jaHMjAa0fpcgm7wRmTTl0tjsvsooyGss7GJ5gGSJRCbGTSD1CgmBqhDAgcoN9 1dB+EaoBNQqOCCfoEFCV0F4CzMS0ynkaDBAkb6sty6V8zTrP5Qw9RGK6SVTeiVtvPA+F 4OqA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=L5mvPkeL; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from phobos.denx.de (phobos.denx.de. [85.214.62.61]) by mx.google.com with ESMTPS id v8-20020a056e02164800b002dc2b3f860fsi1971142ilu.17.2022.08.09.06.02.39 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 09 Aug 2022 06:02:40 -0700 (PDT) Received-SPF: pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 as permitted sender) client-ip=85.214.62.61; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=L5mvPkeL; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 7810284A54; Tue, 9 Aug 2022 15:01:57 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org 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=linaro.org header.i=@linaro.org header.b="L5mvPkeL"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id D812F84A07; Tue, 9 Aug 2022 15:01:14 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_NONE,SPF_PASS, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-io1-xd33.google.com (mail-io1-xd33.google.com [IPv6:2607:f8b0:4864:20::d33]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 37B7584A07 for ; Tue, 9 Aug 2022 15:00:37 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=ralph.siemsen@linaro.org Received: by mail-io1-xd33.google.com with SMTP id d187so2714721iof.4 for ; Tue, 09 Aug 2022 06:00:37 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc; bh=QwSDXVh3M0SPz3HGNjFLY+2td5IptDvLM6kh7m8Ffl4=; b=L5mvPkeLMgHDX5Lsxo7acmiw2rHRCAa3VJCci6cmNP5pssaUhaeKZADxA9t9ahUnY0 NGwlLbjj3jUJ0FNMGHO+k6pURtUsBQmSIuCmG3sfnDVGo8jEafVoTHrBWrFZ8RwILuXa qDtkwx+ugxWjmxILi031DXYZLBCbbmCmCtF6bvLusGAT0MaqZUsoWkpyQOmenM7820EI 9IwjuULd/xWOtwt50Ke/e0uHp/ApCsLn2z08O6GbPHxh+qraBy5XBz6QJMcGJuNmUL5f 0spRaX0x8auIs9bOHFBtsry2Liq8UYgd1MFCxo5D5/D6dGuz0AaSeNPMsaiFYCu694iu VIuA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc; bh=QwSDXVh3M0SPz3HGNjFLY+2td5IptDvLM6kh7m8Ffl4=; b=BreoDjT9JIQuMieL8QcMe7z2oOPGmWuuAc/TwNLS8sIwvNynDv2AanSb72lvKKnwK4 4SxcsR03PMRdMsJNeRAp9Gat+eQKMOrTuf+j0fAUv6xn1Mho4pAK3EhZyKLNi/6wE6wX yMexjYYx5faz6U0znUJ3W7BVxJZCfHDP1wpmLkmMyJqqPEFDw6KUeGdOQ9YfLBJ6z3u3 9/rqi4eUNwoeyHug7mLlwBCrO58O7ArYHm2sGHG2ONwElTILJNzafjIcV201RIVcV06k MA1HAgDT6zM6OnD20t2I8MV8m9IcWg3MerrdvfoP4qUNvE6kPTJQASgW7t/s2qFtQptu cC1A== X-Gm-Message-State: ACgBeo1JHm/aZ2q/Z5IdGme/4fnETPlOyL7nuJdOb5BzCyDfWggZzKRi 2WSEZ6whQezZwRrhH0tRIonQQPbSMH/vfZi9 X-Received: by 2002:a05:6638:4194:b0:33f:4795:5c68 with SMTP id az20-20020a056638419400b0033f47955c68mr10077104jab.193.1660050035288; Tue, 09 Aug 2022 06:00:35 -0700 (PDT) Received: from maple.netwinder.org (rfs.netwinder.org. [206.248.184.2]) by smtp.gmail.com with ESMTPSA id g12-20020a056e021a2c00b002dea1e18a94sm1022197ile.47.2022.08.09.06.00.34 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 09 Aug 2022 06:00:35 -0700 (PDT) From: Ralph Siemsen To: u-boot@lists.denx.de Cc: Ralph Siemsen , Bharat Gooty , Rayagonda Kokatanur Subject: [RFC PATCH v1 7/9] ARM: rzn1: basic support for Renesas RZ/N1 SoC Date: Tue, 9 Aug 2022 08:59:57 -0400 Message-Id: <20220809125959.217333-8-ralph.siemsen@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220809125959.217333-1-ralph.siemsen@linaro.org> References: <20220809125959.217333-1-ralph.siemsen@linaro.org> MIME-Version: 1.0 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.6 at phobos.denx.de X-Virus-Status: Clean The RZ/N1 is a family of SoC devics from Renesas, featuring: * ARM Cortex-A7 CPU (single/dual core) and/or Cortex-M3 * Integrated SRAM up to 6MB * Integrated gigabit ethernet switch * Optional DDR2/3 controller * I2C, SPI, UART, NAND, QSPI, SDIO, USB, CAN, RTC, LCD Add basic support in the form of ARCH_RZN1 symbol. Signed-off-by: Ralph Siemsen --- arch/arm/Kconfig | 17 +++++++++++++++++ arch/arm/Makefile | 1 + arch/arm/mach-rzn1/Kconfig | 18 ++++++++++++++++++ arch/arm/mach-rzn1/Makefile | 3 +++ arch/arm/mach-rzn1/cpu_info.c | 20 ++++++++++++++++++++ 5 files changed, 59 insertions(+) create mode 100644 arch/arm/mach-rzn1/Kconfig create mode 100644 arch/arm/mach-rzn1/Makefile create mode 100644 arch/arm/mach-rzn1/cpu_info.c diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 949ebb46ba..e4a4aba4bc 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1083,6 +1083,21 @@ config ARCH_RMOBILE imply SYS_THUMB_BUILD imply ARCH_MISC_INIT if DISPLAY_CPUINFO +config ARCH_RZN1 + bool "Reneasa RZ/N1 SoC" + select CLK + select CLK_RENESAS + select CLK_R9A06G032 + select DM + select DM_ETH + select DM_SERIAL + select PINCTRL + select PINCONF + select REGMAP + select SYSRESET + select SYSRESET_SYSCON + imply CMD_DM + config ARCH_SNAPDRAGON bool "Qualcomm Snapdragon SoCs" select ARM64 @@ -2243,6 +2258,8 @@ source "arch/arm/mach-owl/Kconfig" source "arch/arm/mach-rmobile/Kconfig" +source "arch/arm/mach-rzn1/Kconfig" + source "arch/arm/mach-meson/Kconfig" source "arch/arm/mach-mediatek/Kconfig" diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 1f4a1d5788..f8b6b35a47 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -76,6 +76,7 @@ machine-$(CONFIG_ARCH_ORION5X) += orion5x machine-$(CONFIG_ARCH_OWL) += owl machine-$(CONFIG_ARCH_RMOBILE) += rmobile machine-$(CONFIG_ARCH_ROCKCHIP) += rockchip +machine-$(CONFIG_ARCH_RZN1) += rzn1 machine-$(CONFIG_ARCH_S5PC1XX) += s5pc1xx machine-$(CONFIG_ARCH_SNAPDRAGON) += snapdragon machine-$(CONFIG_ARCH_SOCFPGA) += socfpga diff --git a/arch/arm/mach-rzn1/Kconfig b/arch/arm/mach-rzn1/Kconfig new file mode 100644 index 0000000000..707895874d --- /dev/null +++ b/arch/arm/mach-rzn1/Kconfig @@ -0,0 +1,18 @@ +if ARCH_RZN1 + +choice + prompt "Target Renesas RZ/N1 SoC select" + default RZN1 + +config RZN1 + bool "Renesas ARM SoCs RZ/N1 (32bit)" + select CPU_V7A + select ARMV7_SET_CORTEX_SMPEN if !SPL + select SPL_ARMV7_SET_CORTEX_SMPEN if SPL + +endchoice + +config SYS_SOC + default "rzn1" + +endif diff --git a/arch/arm/mach-rzn1/Makefile b/arch/arm/mach-rzn1/Makefile new file mode 100644 index 0000000000..b20f845c0f --- /dev/null +++ b/arch/arm/mach-rzn1/Makefile @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0+ + +obj-y = cpu_info.o diff --git a/arch/arm/mach-rzn1/cpu_info.c b/arch/arm/mach-rzn1/cpu_info.c new file mode 100644 index 0000000000..af02a26af8 --- /dev/null +++ b/arch/arm/mach-rzn1/cpu_info.c @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: GPL-2.0+ + +#include +#include + +#if !CONFIG_IS_ENABLED(SYS_DCACHE_OFF) +void enable_caches(void) +{ + /* FIXME: when enabled, boot hangs at relocate_code */ + //dcache_enable(); +} +#endif + +#ifdef CONFIG_DISPLAY_CPUINFO +int print_cpuinfo(void) +{ + printf("CPU: Renesas Electronics RZ/N1\n"); + return 0; +} +#endif From patchwork Tue Aug 9 12:59:58 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ralph Siemsen X-Patchwork-Id: 596228 Delivered-To: patch@linaro.org Received: by 2002:a05:7000:b345:0:0:0:0 with SMTP id w5csp4153819maz; Tue, 9 Aug 2022 06:02:55 -0700 (PDT) X-Google-Smtp-Source: AA6agR4TnK/TI01X3lbTyxb68lrpWvtF3yZ/BYZPM8Qogfnz1Fa59jZp7GpBlvSCBcUgU0rXlOq4 X-Received: by 2002:a05:6638:1612:b0:342:7bee:3422 with SMTP id x18-20020a056638161200b003427bee3422mr11005037jas.144.1660050175438; Tue, 09 Aug 2022 06:02:55 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1660050175; cv=none; d=google.com; s=arc-20160816; b=UsVILjRShz1rAEqMG2BGhGXKnFGJ8MT+EgyOYGhglRl8HAh2C0vOnCcnLDGwjF06je dtuv+LkHaQWERLtmdooKe0nxB59a0uoEgywqQyiv2kay/vrH5xJNTDG3onQSi2/yhBie O3HW9ml5onj09do+GuK/QOV29yrPg3SZysWS5Jlm4oJ4wI+WPZKLeqSrdbc3I/kmch4c lWZBYbNUBiWArbz0XZdrS1Zfb180BEcQP13f8NUyKu+KRLLbBVHIJnwFIZoCLNKNGxpV v4uUXfM8Z43jPXRWkpcCNasxWHMFeCNtYVgxNKSLgBEksipttG9v8misna7z/71aFjDo ZVKg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=Y1AJQrlDds8fRCXJQjaVHTDbrPdAbpILRQ/neZMhkxY=; b=ppnSO1lvtzYXsnGfsvsMP/CpkDDHhdzgiLygupgNcBpptATc4wubYjCHmLAtTKygRc JmhGsZELlEr0U0Swdl7ITxgfggAGNGS2XuJFzr0NcMX0+tdEMGSaqFgStsoPIFrFtZIn W1mJYqPK8T1pwRYQvLn3y85bysW3tV0gne1RMB03bue160cl8hgjcfl548F5RPJcX//t RyZQw2NfRRsWyCPsTutlPhu8piwsN7Y4cLPa2vkPVIvhzJehfNTS1/0rz6Ts7p72Fwae b/miv34hg1eBnhZwheJIE9OC9N0Scb8szFTnD8/n8Pv4uIsbHVYd7dJGyuA8ImW2e+DQ cqpQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b="vN/l5hn0"; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 2a01:238:438b:c500:173d:9f52:ddab:ee01 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from phobos.denx.de (phobos.denx.de. [2a01:238:438b:c500:173d:9f52:ddab:ee01]) by mx.google.com with ESMTPS id m6-20020a0566022e8600b0067be74f435asi1822674iow.47.2022.08.09.06.02.54 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 09 Aug 2022 06:02:55 -0700 (PDT) Received-SPF: pass (google.com: domain of u-boot-bounces@lists.denx.de designates 2a01:238:438b:c500:173d:9f52:ddab:ee01 as permitted sender) client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b="vN/l5hn0"; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 2a01:238:438b:c500:173d:9f52:ddab:ee01 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 18D1A84A4D; Tue, 9 Aug 2022 15:02:02 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org 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=linaro.org header.i=@linaro.org header.b="vN/l5hn0"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 7F3B184A37; Tue, 9 Aug 2022 15:01:17 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_NONE,SPF_PASS, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.2 Received: from mail-io1-xd33.google.com (mail-io1-xd33.google.com [IPv6:2607:f8b0:4864:20::d33]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id CEF4184A3D for ; Tue, 9 Aug 2022 15:00:38 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=ralph.siemsen@linaro.org Received: by mail-io1-xd33.google.com with SMTP id 68so2819106iou.2 for ; Tue, 09 Aug 2022 06:00:38 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc; bh=Y1AJQrlDds8fRCXJQjaVHTDbrPdAbpILRQ/neZMhkxY=; b=vN/l5hn07l3pN2ZYnvcUn/6Pv+3T1S2i591CizUFXdsxBsoiIFNGsOsBI1q9YkNXBH x/mx+CNU0aWdo4Ewy8Ocs4OG8E8DYWADpJlJOWRxFSqyWgv/5k0nMID2z1ap97jwok7i Qp4us0wqhg7+C/m1SqPKE0u1sDVtSJPLhxKa88xIQ1zyHKihSncMmnZC5vXrF/ZVT47Q HGNKTspPo0ZJk40yQ7NgsDxNzF14fDfstLrNe3UQj3VrOB6bS07kzywXH7opf318WpH2 RLcASqfRvOywttvdon39WhTwnZKdkMI2UwVhZ7wK2uRnS3RaEZd7yib+7jnWe26kJai6 mcPw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc; bh=Y1AJQrlDds8fRCXJQjaVHTDbrPdAbpILRQ/neZMhkxY=; b=kaUr1pAhAWdZ1+3Jy9cECC1aaCDo7i82QoD2HWbgWEG5l5ccteijPlmoxBS/Lc4nWl B+7ZQFhNeAh9+tkC5MHiI576NH7T04vhCoKTPuFAjWvsInzfPUpzuGiUKmlbmykpZXie U3rpMOTGCHSn9Mwp+7SQj+K7faq058In91I1oqhOyubL+VcHt3sZ8M+B+PkDH4IM76pg G1ipzDazbxhI7dnyLzdm9Sw5uBvCAqgnk9s0PeyEE6M91LWOp9DTVtWkHtPsQqDYpjHX i+pwA83NZvAvvFLaWd3khH+pUkxuD7dpnMUvnfUOPpgb7Sw5AEI7ti45ohbTyhR3wFkH dO8g== X-Gm-Message-State: ACgBeo0p4nxFit8wmdCAHUWlW5GyNfxBRA2rjyC9tuR/Am/QY8usEIXI bdzZ6xZ/bZNktXBG7tiT+Qx2hb8GyTXstV8b X-Received: by 2002:a05:6638:c53:b0:342:a7e7:6829 with SMTP id g19-20020a0566380c5300b00342a7e76829mr10196689jal.112.1660050037226; Tue, 09 Aug 2022 06:00:37 -0700 (PDT) Received: from maple.netwinder.org (rfs.netwinder.org. [206.248.184.2]) by smtp.gmail.com with ESMTPSA id g12-20020a056e021a2c00b002dea1e18a94sm1022197ile.47.2022.08.09.06.00.36 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 09 Aug 2022 06:00:36 -0700 (PDT) From: Ralph Siemsen To: u-boot@lists.denx.de Cc: Ralph Siemsen Subject: [RFC PATCH v1 8/9] board: schneider: add LCES board support Date: Tue, 9 Aug 2022 08:59:58 -0400 Message-Id: <20220809125959.217333-9-ralph.siemsen@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220809125959.217333-1-ralph.siemsen@linaro.org> References: <20220809125959.217333-1-ralph.siemsen@linaro.org> MIME-Version: 1.0 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.6 at phobos.denx.de X-Virus-Status: Clean Add support for Schneider Electronics LCES1 / LCES2 boards, which are based on the Reneasas RZ/N1 SoC devices. The intention is to support both boards using a single defconfig, and to handle the differences at runtime. Signed-off-by: Ralph Siemsen --- TODO: remove the debug UART settings from lces_defconfig. arch/arm/dts/r9a06g032-rzn1d400-lces.dts | 50 +++ arch/arm/mach-rzn1/Kconfig | 14 + board/schneider/lces/Kconfig | 12 + board/schneider/lces/Makefile | 3 + board/schneider/lces/ddr_timing.c | 140 ++++++ .../lces/jedec_ddr3_2g_x16_1333h_500_cl8.h | 399 ++++++++++++++++++ board/schneider/lces/lces.c | 41 ++ configs/lces_defconfig | 26 ++ include/configs/lces.h | 22 + 9 files changed, 707 insertions(+) create mode 100644 arch/arm/dts/r9a06g032-rzn1d400-lces.dts create mode 100644 board/schneider/lces/Kconfig create mode 100644 board/schneider/lces/Makefile create mode 100644 board/schneider/lces/ddr_timing.c create mode 100644 board/schneider/lces/jedec_ddr3_2g_x16_1333h_500_cl8.h create mode 100644 board/schneider/lces/lces.c create mode 100644 configs/lces_defconfig create mode 100644 include/configs/lces.h diff --git a/arch/arm/dts/r9a06g032-rzn1d400-lces.dts b/arch/arm/dts/r9a06g032-rzn1d400-lces.dts new file mode 100644 index 0000000000..7ba4dedc10 --- /dev/null +++ b/arch/arm/dts/r9a06g032-rzn1d400-lces.dts @@ -0,0 +1,50 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Device Tree Source for Schneider LCES Board + * + * Based on r9a06g032-rzn1d400-db.dts + */ + +/dts-v1/; + +#include "r9a06g032.dtsi" +#include + +/ { + model = "Schneider LCES Board"; + compatible = "schneider,rzn1d400-lces", "renesas,r9a06g032"; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + aliases { + serial0 = &uart0; + }; + + /* TODO: (RFS) only RZN1D has DDR */ + memory { + device_type = "memory"; + reg = <0x80000000 0x10000000>; + }; +}; + +&ddrctrl { + status = "okay"; +}; +&pinctrl { + status = "okay"; + + pins_uart0: pins_uart0 { + pinmux = < + RZN1_PINMUX(103, RZN1_FUNC_UART0_I) /* UART0_TXD */ + RZN1_PINMUX(104, RZN1_FUNC_UART0_I) /* UART0_RXD */ + >; + bias-disable; + }; +}; +&uart0 { + pinctrl-0 = <&pins_uart0>; + pinctrl-names = "default"; + status = "okay"; +}; diff --git a/arch/arm/mach-rzn1/Kconfig b/arch/arm/mach-rzn1/Kconfig index 707895874d..9bbafeb6db 100644 --- a/arch/arm/mach-rzn1/Kconfig +++ b/arch/arm/mach-rzn1/Kconfig @@ -15,4 +15,18 @@ endchoice config SYS_SOC default "rzn1" +choice + prompt "Board select" + default TARGET_SCHNEIDER_LCES + +config TARGET_SCHNEIDER_LCES + bool "Schneider LCES board" + help + Support the Schneider LCES1 and LCES2 boards, which are based + on the Renesas RZ/N1 SoC. + +endchoice + +source "board/schneider/lces/Kconfig" + endif diff --git a/board/schneider/lces/Kconfig b/board/schneider/lces/Kconfig new file mode 100644 index 0000000000..6a1448bbd7 --- /dev/null +++ b/board/schneider/lces/Kconfig @@ -0,0 +1,12 @@ +if TARGET_SCHNEIDER_LCES + +config SYS_BOARD + default "lces" + +config SYS_VENDOR + default "schneider" + +config SYS_CONFIG_NAME + default "lces" + +endif diff --git a/board/schneider/lces/Makefile b/board/schneider/lces/Makefile new file mode 100644 index 0000000000..b8f6a8f53f --- /dev/null +++ b/board/schneider/lces/Makefile @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0+ + +obj-y := lces.o ddr_timing.o diff --git a/board/schneider/lces/ddr_timing.c b/board/schneider/lces/ddr_timing.c new file mode 100644 index 0000000000..8bc3fe7be4 --- /dev/null +++ b/board/schneider/lces/ddr_timing.c @@ -0,0 +1,140 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include + +#include "jedec_ddr3_2g_x16_1333h_500_cl8.h" + +u32 ddr_00_87_async[] = { + DENALI_CTL_00_DATA, + DENALI_CTL_01_DATA, + DENALI_CTL_02_DATA, + DENALI_CTL_03_DATA, + DENALI_CTL_04_DATA, + DENALI_CTL_05_DATA, + DENALI_CTL_06_DATA, + DENALI_CTL_07_DATA, + DENALI_CTL_08_DATA, + DENALI_CTL_09_DATA, + + DENALI_CTL_10_DATA, + DENALI_CTL_11_DATA, + DENALI_CTL_12_DATA, + DENALI_CTL_13_DATA, + DENALI_CTL_14_DATA, + DENALI_CTL_15_DATA, + DENALI_CTL_16_DATA, + DENALI_CTL_17_DATA, + DENALI_CTL_18_DATA, + DENALI_CTL_19_DATA, + + DENALI_CTL_20_DATA, + DENALI_CTL_21_DATA, + DENALI_CTL_22_DATA, + DENALI_CTL_23_DATA, + DENALI_CTL_24_DATA, + DENALI_CTL_25_DATA, + DENALI_CTL_26_DATA, + DENALI_CTL_27_DATA, + DENALI_CTL_28_DATA, + DENALI_CTL_29_DATA, + + DENALI_CTL_30_DATA, + DENALI_CTL_31_DATA, + DENALI_CTL_32_DATA, + DENALI_CTL_33_DATA, + DENALI_CTL_34_DATA, + DENALI_CTL_35_DATA, + DENALI_CTL_36_DATA, + DENALI_CTL_37_DATA, + DENALI_CTL_38_DATA, + DENALI_CTL_39_DATA, + + DENALI_CTL_40_DATA, + DENALI_CTL_41_DATA, + DENALI_CTL_42_DATA, + DENALI_CTL_43_DATA, + DENALI_CTL_44_DATA, + DENALI_CTL_45_DATA, + DENALI_CTL_46_DATA, + DENALI_CTL_47_DATA, + DENALI_CTL_48_DATA, + DENALI_CTL_49_DATA, + + DENALI_CTL_50_DATA, + DENALI_CTL_51_DATA, + DENALI_CTL_52_DATA, + DENALI_CTL_53_DATA, + DENALI_CTL_54_DATA, + DENALI_CTL_55_DATA, + DENALI_CTL_56_DATA, + DENALI_CTL_57_DATA, + DENALI_CTL_58_DATA, + DENALI_CTL_59_DATA, + + DENALI_CTL_60_DATA, + DENALI_CTL_61_DATA, + DENALI_CTL_62_DATA, + DENALI_CTL_63_DATA, + DENALI_CTL_64_DATA, + DENALI_CTL_65_DATA, + DENALI_CTL_66_DATA, + DENALI_CTL_67_DATA, + DENALI_CTL_68_DATA, + DENALI_CTL_69_DATA, + + DENALI_CTL_70_DATA, + DENALI_CTL_71_DATA, + DENALI_CTL_72_DATA, + DENALI_CTL_73_DATA, + DENALI_CTL_74_DATA, + DENALI_CTL_75_DATA, + DENALI_CTL_76_DATA, + DENALI_CTL_77_DATA, + DENALI_CTL_78_DATA, + DENALI_CTL_79_DATA, + + DENALI_CTL_80_DATA, + DENALI_CTL_81_DATA, + DENALI_CTL_82_DATA, + DENALI_CTL_83_DATA, + DENALI_CTL_84_DATA, + DENALI_CTL_85_DATA, + DENALI_CTL_86_DATA, + DENALI_CTL_87_DATA, + DENALI_CTL_88_DATA, + DENALI_CTL_89_DATA, + + DENALI_CTL_90_DATA, + DENALI_CTL_91_DATA, + DENALI_CTL_92_DATA, +}; + +u32 ddr_350_374_async[] = { + DENALI_CTL_350_DATA, + DENALI_CTL_351_DATA, + DENALI_CTL_352_DATA, + DENALI_CTL_353_DATA, + DENALI_CTL_354_DATA, + DENALI_CTL_355_DATA, + DENALI_CTL_356_DATA, + DENALI_CTL_357_DATA, + DENALI_CTL_358_DATA, + DENALI_CTL_359_DATA, + + DENALI_CTL_360_DATA, + DENALI_CTL_361_DATA, + DENALI_CTL_362_DATA, + DENALI_CTL_363_DATA, + DENALI_CTL_364_DATA, + DENALI_CTL_365_DATA, + DENALI_CTL_366_DATA, + DENALI_CTL_367_DATA, + DENALI_CTL_368_DATA, + DENALI_CTL_369_DATA, + + DENALI_CTL_370_DATA, + DENALI_CTL_371_DATA, + DENALI_CTL_372_DATA, + DENALI_CTL_373_DATA, + DENALI_CTL_374_DATA, +}; diff --git a/board/schneider/lces/jedec_ddr3_2g_x16_1333h_500_cl8.h b/board/schneider/lces/jedec_ddr3_2g_x16_1333h_500_cl8.h new file mode 100644 index 0000000000..5c55518bc1 --- /dev/null +++ b/board/schneider/lces/jedec_ddr3_2g_x16_1333h_500_cl8.h @@ -0,0 +1,399 @@ + +/* **************************************************************** + * CADENCE Copyright (c) 2001-2011 * + * Cadence Design Systems, Inc. * + * All rights reserved. * + * * + ****************************************************************** + * The values calculated from this script are meant to be * + * representative programmings. The values may not reflect the * + * actual required programming for production use. Please * + * closely review all programmed values for technical accuracy * + * before use in production parts. * + ****************************************************************** + * + * Module: regconfig.h + * Documentation: Register programming header file + * + ****************************************************************** + ****************************************************************** + * WARNING: This file was automatically generated. Manual + * editing may result in undetermined behavior. + ****************************************************************** + ******************************************************************/ + +#define DENALI_CTL_00_DATA 0x00000600 +#define DENALI_CTL_01_DATA 0x00000000 +#define DENALI_CTL_02_DATA 0x00000000 +#define DENALI_CTL_03_DATA 0x00000000 +#define DENALI_CTL_04_DATA 0x00000000 +#define DENALI_CTL_05_DATA 0x00000000 +#define DENALI_CTL_06_DATA 0x00000000 +#define DENALI_CTL_07_DATA 0x00000005 +#define DENALI_CTL_08_DATA 0x000186a0 +#define DENALI_CTL_09_DATA 0x0003d090 +#define DENALI_CTL_10_DATA 0x00000000 +#define DENALI_CTL_11_DATA 0x10000200 +#define DENALI_CTL_12_DATA 0x04040006 +#define DENALI_CTL_13_DATA 0x04121904 +#define DENALI_CTL_14_DATA 0x04041707 +#define DENALI_CTL_15_DATA 0x00891c0c +#define DENALI_CTL_16_DATA 0x07000503 +#define DENALI_CTL_17_DATA 0x01010008 +#define DENALI_CTL_18_DATA 0x0007030f +#define DENALI_CTL_19_DATA 0x01000000 +#define DENALI_CTL_20_DATA 0x0f340050 +#define DENALI_CTL_21_DATA 0x00000005 +#define DENALI_CTL_22_DATA 0x000c0003 +#define DENALI_CTL_23_DATA 0x00000000 +#define DENALI_CTL_24_DATA 0x00550200 +#define DENALI_CTL_25_DATA 0x00010000 +#define DENALI_CTL_26_DATA 0x00050500 +#define DENALI_CTL_27_DATA 0x00000000 +#define DENALI_CTL_28_DATA 0x00000000 +#define DENALI_CTL_29_DATA 0x00000000 +#define DENALI_CTL_30_DATA 0x00000000 +#define DENALI_CTL_31_DATA 0x00084000 +#define DENALI_CTL_32_DATA 0x00080046 +#define DENALI_CTL_33_DATA 0x00000000 +#define DENALI_CTL_34_DATA 0x00460840 +#define DENALI_CTL_35_DATA 0x00000008 +#define DENALI_CTL_36_DATA 0x00010000 +#define DENALI_CTL_37_DATA 0x00000000 +#define DENALI_CTL_38_DATA 0x00000000 +#define DENALI_CTL_39_DATA 0x00000000 +#define DENALI_CTL_40_DATA 0x00000000 +#define DENALI_CTL_41_DATA 0x00000000 +#define DENALI_CTL_42_DATA 0x00000000 +#define DENALI_CTL_43_DATA 0x00000000 +#define DENALI_CTL_44_DATA 0x00000000 +#define DENALI_CTL_45_DATA 0x01000200 +#define DENALI_CTL_46_DATA 0x02000040 +#define DENALI_CTL_47_DATA 0x00000040 +#define DENALI_CTL_48_DATA 0x02000100 +#define DENALI_CTL_49_DATA 0xffff0a01 +#define DENALI_CTL_50_DATA 0x01010101 +#define DENALI_CTL_51_DATA 0x01010101 +#define DENALI_CTL_52_DATA 0x01030101 +#define DENALI_CTL_53_DATA 0x0c030000 +#define DENALI_CTL_54_DATA 0x00000000 +#define DENALI_CTL_55_DATA 0x00000100 +#define DENALI_CTL_56_DATA 0x00000000 +#define DENALI_CTL_57_DATA 0x00000000 +#define DENALI_CTL_58_DATA 0x00000000 +#define DENALI_CTL_59_DATA 0x00000000 +#define DENALI_CTL_60_DATA 0x00000000 +#define DENALI_CTL_61_DATA 0x00000000 +#define DENALI_CTL_62_DATA 0x01020000 +#define DENALI_CTL_63_DATA 0x06050201 +#define DENALI_CTL_64_DATA 0x02000106 +#define DENALI_CTL_65_DATA 0x00000000 +#define DENALI_CTL_66_DATA 0x02020202 +#define DENALI_CTL_67_DATA 0x00000200 +#define DENALI_CTL_68_DATA 0x00000000 +#define DENALI_CTL_69_DATA 0x00000000 +#define DENALI_CTL_70_DATA 0x00000000 +#define DENALI_CTL_71_DATA 0x00280d00 +#define DENALI_CTL_72_DATA 0x00000000 +#define DENALI_CTL_73_DATA 0x00000100 +#define DENALI_CTL_74_DATA 0x00010001 +#define DENALI_CTL_75_DATA 0x00000000 +#define DENALI_CTL_76_DATA 0x00000000 +#define DENALI_CTL_77_DATA 0x00000000 +#define DENALI_CTL_78_DATA 0x00000000 +#define DENALI_CTL_79_DATA 0x00222200 +#define DENALI_CTL_80_DATA 0x00000001 +#define DENALI_CTL_81_DATA 0x00000000 +#define DENALI_CTL_82_DATA 0x00000000 +#define DENALI_CTL_83_DATA 0x00012222 +#define DENALI_CTL_84_DATA 0x00000000 +#define DENALI_CTL_85_DATA 0x00000000 +#define DENALI_CTL_86_DATA 0x00222200 +#define DENALI_CTL_87_DATA 0x02020001 +#define DENALI_CTL_88_DATA 0x00020200 +#define DENALI_CTL_89_DATA 0x02000202 +#define DENALI_CTL_90_DATA 0x01000002 +#define DENALI_CTL_91_DATA 0x00000000 +#define DENALI_CTL_92_DATA 0x0003ffff +#define DENALI_CTL_93_DATA 0x00000000 +#define DENALI_CTL_94_DATA 0x0003ffff +#define DENALI_CTL_95_DATA 0x00000000 +#define DENALI_CTL_96_DATA 0x0003ffff +#define DENALI_CTL_97_DATA 0x00000000 +#define DENALI_CTL_98_DATA 0x0003ffff +#define DENALI_CTL_99_DATA 0x00000000 +#define DENALI_CTL_100_DATA 0x0003ffff +#define DENALI_CTL_101_DATA 0x00000000 +#define DENALI_CTL_102_DATA 0x0003ffff +#define DENALI_CTL_103_DATA 0x00000000 +#define DENALI_CTL_104_DATA 0x0003ffff +#define DENALI_CTL_105_DATA 0x00000000 +#define DENALI_CTL_106_DATA 0x0003ffff +#define DENALI_CTL_107_DATA 0x00000000 +#define DENALI_CTL_108_DATA 0x0003ffff +#define DENALI_CTL_109_DATA 0x00000000 +#define DENALI_CTL_110_DATA 0x0003ffff +#define DENALI_CTL_111_DATA 0x00000000 +#define DENALI_CTL_112_DATA 0x0003ffff +#define DENALI_CTL_113_DATA 0x00000000 +#define DENALI_CTL_114_DATA 0x0003ffff +#define DENALI_CTL_115_DATA 0x00000000 +#define DENALI_CTL_116_DATA 0x0003ffff +#define DENALI_CTL_117_DATA 0x00000000 +#define DENALI_CTL_118_DATA 0x0003ffff +#define DENALI_CTL_119_DATA 0x00000000 +#define DENALI_CTL_120_DATA 0x0003ffff +#define DENALI_CTL_121_DATA 0x00000000 +#define DENALI_CTL_122_DATA 0x0003ffff +#define DENALI_CTL_123_DATA 0x00000000 +#define DENALI_CTL_124_DATA 0x0003ffff +#define DENALI_CTL_125_DATA 0x00000000 +#define DENALI_CTL_126_DATA 0x0003ffff +#define DENALI_CTL_127_DATA 0x00000000 +#define DENALI_CTL_128_DATA 0x0003ffff +#define DENALI_CTL_129_DATA 0x00000000 +#define DENALI_CTL_130_DATA 0x0003ffff +#define DENALI_CTL_131_DATA 0x00000000 +#define DENALI_CTL_132_DATA 0x0003ffff +#define DENALI_CTL_133_DATA 0x00000000 +#define DENALI_CTL_134_DATA 0x0003ffff +#define DENALI_CTL_135_DATA 0x00000000 +#define DENALI_CTL_136_DATA 0x0003ffff +#define DENALI_CTL_137_DATA 0x00000000 +#define DENALI_CTL_138_DATA 0x0003ffff +#define DENALI_CTL_139_DATA 0x00000000 +#define DENALI_CTL_140_DATA 0x0003ffff +#define DENALI_CTL_141_DATA 0x00000000 +#define DENALI_CTL_142_DATA 0x0003ffff +#define DENALI_CTL_143_DATA 0x00000000 +#define DENALI_CTL_144_DATA 0x0003ffff +#define DENALI_CTL_145_DATA 0x00000000 +#define DENALI_CTL_146_DATA 0x0003ffff +#define DENALI_CTL_147_DATA 0x00000000 +#define DENALI_CTL_148_DATA 0x0003ffff +#define DENALI_CTL_149_DATA 0x00000000 +#define DENALI_CTL_150_DATA 0x0003ffff +#define DENALI_CTL_151_DATA 0x00000000 +#define DENALI_CTL_152_DATA 0x0003ffff +#define DENALI_CTL_153_DATA 0x00000000 +#define DENALI_CTL_154_DATA 0x0003ffff +#define DENALI_CTL_155_DATA 0x00000000 +#define DENALI_CTL_156_DATA 0x0003ffff +#define DENALI_CTL_157_DATA 0x00000000 +#define DENALI_CTL_158_DATA 0x0003ffff +#define DENALI_CTL_159_DATA 0x00000000 +#define DENALI_CTL_160_DATA 0x0003ffff +#define DENALI_CTL_161_DATA 0x00000000 +#define DENALI_CTL_162_DATA 0x0003ffff +#define DENALI_CTL_163_DATA 0x00000000 +#define DENALI_CTL_164_DATA 0x0003ffff +#define DENALI_CTL_165_DATA 0x00000000 +#define DENALI_CTL_166_DATA 0x0003ffff +#define DENALI_CTL_167_DATA 0x00000000 +#define DENALI_CTL_168_DATA 0x0003ffff +#define DENALI_CTL_169_DATA 0x00000000 +#define DENALI_CTL_170_DATA 0x0003ffff +#define DENALI_CTL_171_DATA 0x00000000 +#define DENALI_CTL_172_DATA 0x0003ffff +#define DENALI_CTL_173_DATA 0x00000000 +#define DENALI_CTL_174_DATA 0x0003ffff +#define DENALI_CTL_175_DATA 0x00000000 +#define DENALI_CTL_176_DATA 0x0003ffff +#define DENALI_CTL_177_DATA 0x00000000 +#define DENALI_CTL_178_DATA 0x0003ffff +#define DENALI_CTL_179_DATA 0x00000000 +#define DENALI_CTL_180_DATA 0x0003ffff +#define DENALI_CTL_181_DATA 0x00000000 +#define DENALI_CTL_182_DATA 0x0003ffff +#define DENALI_CTL_183_DATA 0x00000000 +#define DENALI_CTL_184_DATA 0x0003ffff +#define DENALI_CTL_185_DATA 0x00000000 +#define DENALI_CTL_186_DATA 0x0003ffff +#define DENALI_CTL_187_DATA 0x00000000 +#define DENALI_CTL_188_DATA 0x0003ffff +#define DENALI_CTL_189_DATA 0x00000000 +#define DENALI_CTL_190_DATA 0x0003ffff +#define DENALI_CTL_191_DATA 0x00000000 +#define DENALI_CTL_192_DATA 0x0003ffff +#define DENALI_CTL_193_DATA 0x00000000 +#define DENALI_CTL_194_DATA 0x0003ffff +#define DENALI_CTL_195_DATA 0x00000000 +#define DENALI_CTL_196_DATA 0x0003ffff +#define DENALI_CTL_197_DATA 0x00000000 +#define DENALI_CTL_198_DATA 0x0003ffff +#define DENALI_CTL_199_DATA 0x00000000 +#define DENALI_CTL_200_DATA 0x0003ffff +#define DENALI_CTL_201_DATA 0x00000000 +#define DENALI_CTL_202_DATA 0x0003ffff +#define DENALI_CTL_203_DATA 0x00000000 +#define DENALI_CTL_204_DATA 0x0003ffff +#define DENALI_CTL_205_DATA 0x00000000 +#define DENALI_CTL_206_DATA 0x0003ffff +#define DENALI_CTL_207_DATA 0x00000000 +#define DENALI_CTL_208_DATA 0x0003ffff +#define DENALI_CTL_209_DATA 0x00000000 +#define DENALI_CTL_210_DATA 0x0003ffff +#define DENALI_CTL_211_DATA 0x00000000 +#define DENALI_CTL_212_DATA 0x0003ffff +#define DENALI_CTL_213_DATA 0x00000000 +#define DENALI_CTL_214_DATA 0x0003ffff +#define DENALI_CTL_215_DATA 0x00000000 +#define DENALI_CTL_216_DATA 0x0003ffff +#define DENALI_CTL_217_DATA 0x00000000 +#define DENALI_CTL_218_DATA 0x0303ffff +#define DENALI_CTL_219_DATA 0xffffffff +#define DENALI_CTL_220_DATA 0x00030f0f +#define DENALI_CTL_221_DATA 0xffffffff +#define DENALI_CTL_222_DATA 0x00030f0f +#define DENALI_CTL_223_DATA 0xffffffff +#define DENALI_CTL_224_DATA 0x00030f0f +#define DENALI_CTL_225_DATA 0xffffffff +#define DENALI_CTL_226_DATA 0x00030f0f +#define DENALI_CTL_227_DATA 0xffffffff +#define DENALI_CTL_228_DATA 0x00030f0f +#define DENALI_CTL_229_DATA 0xffffffff +#define DENALI_CTL_230_DATA 0x00030f0f +#define DENALI_CTL_231_DATA 0xffffffff +#define DENALI_CTL_232_DATA 0x00030f0f +#define DENALI_CTL_233_DATA 0xffffffff +#define DENALI_CTL_234_DATA 0x00030f0f +#define DENALI_CTL_235_DATA 0xffffffff +#define DENALI_CTL_236_DATA 0x00030f0f +#define DENALI_CTL_237_DATA 0xffffffff +#define DENALI_CTL_238_DATA 0x00030f0f +#define DENALI_CTL_239_DATA 0xffffffff +#define DENALI_CTL_240_DATA 0x00030f0f +#define DENALI_CTL_241_DATA 0xffffffff +#define DENALI_CTL_242_DATA 0x00030f0f +#define DENALI_CTL_243_DATA 0xffffffff +#define DENALI_CTL_244_DATA 0x00030f0f +#define DENALI_CTL_245_DATA 0xffffffff +#define DENALI_CTL_246_DATA 0x00030f0f +#define DENALI_CTL_247_DATA 0xffffffff +#define DENALI_CTL_248_DATA 0x00030f0f +#define DENALI_CTL_249_DATA 0xffffffff +#define DENALI_CTL_250_DATA 0x00030f0f +#define DENALI_CTL_251_DATA 0xffffffff +#define DENALI_CTL_252_DATA 0x00030f0f +#define DENALI_CTL_253_DATA 0xffffffff +#define DENALI_CTL_254_DATA 0x00030f0f +#define DENALI_CTL_255_DATA 0xffffffff +#define DENALI_CTL_256_DATA 0x00030f0f +#define DENALI_CTL_257_DATA 0xffffffff +#define DENALI_CTL_258_DATA 0x00030f0f +#define DENALI_CTL_259_DATA 0xffffffff +#define DENALI_CTL_260_DATA 0x00030f0f +#define DENALI_CTL_261_DATA 0xffffffff +#define DENALI_CTL_262_DATA 0x00030f0f +#define DENALI_CTL_263_DATA 0xffffffff +#define DENALI_CTL_264_DATA 0x00030f0f +#define DENALI_CTL_265_DATA 0xffffffff +#define DENALI_CTL_266_DATA 0x00030f0f +#define DENALI_CTL_267_DATA 0xffffffff +#define DENALI_CTL_268_DATA 0x00030f0f +#define DENALI_CTL_269_DATA 0xffffffff +#define DENALI_CTL_270_DATA 0x00030f0f +#define DENALI_CTL_271_DATA 0xffffffff +#define DENALI_CTL_272_DATA 0x00030f0f +#define DENALI_CTL_273_DATA 0xffffffff +#define DENALI_CTL_274_DATA 0x00030f0f +#define DENALI_CTL_275_DATA 0xffffffff +#define DENALI_CTL_276_DATA 0x00030f0f +#define DENALI_CTL_277_DATA 0xffffffff +#define DENALI_CTL_278_DATA 0x00030f0f +#define DENALI_CTL_279_DATA 0xffffffff +#define DENALI_CTL_280_DATA 0x00030f0f +#define DENALI_CTL_281_DATA 0xffffffff +#define DENALI_CTL_282_DATA 0x00030f0f +#define DENALI_CTL_283_DATA 0xffffffff +#define DENALI_CTL_284_DATA 0x00030f0f +#define DENALI_CTL_285_DATA 0xffffffff +#define DENALI_CTL_286_DATA 0x00030f0f +#define DENALI_CTL_287_DATA 0xffffffff +#define DENALI_CTL_288_DATA 0x00030f0f +#define DENALI_CTL_289_DATA 0xffffffff +#define DENALI_CTL_290_DATA 0x00030f0f +#define DENALI_CTL_291_DATA 0xffffffff +#define DENALI_CTL_292_DATA 0x00030f0f +#define DENALI_CTL_293_DATA 0xffffffff +#define DENALI_CTL_294_DATA 0x00030f0f +#define DENALI_CTL_295_DATA 0xffffffff +#define DENALI_CTL_296_DATA 0x00030f0f +#define DENALI_CTL_297_DATA 0xffffffff +#define DENALI_CTL_298_DATA 0x00030f0f +#define DENALI_CTL_299_DATA 0xffffffff +#define DENALI_CTL_300_DATA 0x00030f0f +#define DENALI_CTL_301_DATA 0xffffffff +#define DENALI_CTL_302_DATA 0x00030f0f +#define DENALI_CTL_303_DATA 0xffffffff +#define DENALI_CTL_304_DATA 0x00030f0f +#define DENALI_CTL_305_DATA 0xffffffff +#define DENALI_CTL_306_DATA 0x00030f0f +#define DENALI_CTL_307_DATA 0xffffffff +#define DENALI_CTL_308_DATA 0x00030f0f +#define DENALI_CTL_309_DATA 0xffffffff +#define DENALI_CTL_310_DATA 0x00030f0f +#define DENALI_CTL_311_DATA 0xffffffff +#define DENALI_CTL_312_DATA 0x00030f0f +#define DENALI_CTL_313_DATA 0xffffffff +#define DENALI_CTL_314_DATA 0x00030f0f +#define DENALI_CTL_315_DATA 0xffffffff +#define DENALI_CTL_316_DATA 0x00030f0f +#define DENALI_CTL_317_DATA 0xffffffff +#define DENALI_CTL_318_DATA 0x00030f0f +#define DENALI_CTL_319_DATA 0xffffffff +#define DENALI_CTL_320_DATA 0x00030f0f +#define DENALI_CTL_321_DATA 0xffffffff +#define DENALI_CTL_322_DATA 0x00030f0f +#define DENALI_CTL_323_DATA 0xffffffff +#define DENALI_CTL_324_DATA 0x00030f0f +#define DENALI_CTL_325_DATA 0xffffffff +#define DENALI_CTL_326_DATA 0x00030f0f +#define DENALI_CTL_327_DATA 0xffffffff +#define DENALI_CTL_328_DATA 0x00030f0f +#define DENALI_CTL_329_DATA 0xffffffff +#define DENALI_CTL_330_DATA 0x00030f0f +#define DENALI_CTL_331_DATA 0xffffffff +#define DENALI_CTL_332_DATA 0x00030f0f +#define DENALI_CTL_333_DATA 0xffffffff +#define DENALI_CTL_334_DATA 0x00030f0f +#define DENALI_CTL_335_DATA 0xffffffff +#define DENALI_CTL_336_DATA 0x00030f0f +#define DENALI_CTL_337_DATA 0xffffffff +#define DENALI_CTL_338_DATA 0x00030f0f +#define DENALI_CTL_339_DATA 0xffffffff +#define DENALI_CTL_340_DATA 0x00030f0f +#define DENALI_CTL_341_DATA 0xffffffff +#define DENALI_CTL_342_DATA 0x00030f0f +#define DENALI_CTL_343_DATA 0xffffffff +#define DENALI_CTL_344_DATA 0x00030f0f +#define DENALI_CTL_345_DATA 0xffffffff +#define DENALI_CTL_346_DATA 0x32030f0f +#define DENALI_CTL_347_DATA 0x01320001 +#define DENALI_CTL_348_DATA 0x00013200 +#define DENALI_CTL_349_DATA 0x00000132 +#define DENALI_CTL_350_DATA 0x00000000 +#define DENALI_CTL_351_DATA 0x000d0000 +#define DENALI_CTL_352_DATA 0x1e680000 +#define DENALI_CTL_353_DATA 0x02000200 +#define DENALI_CTL_354_DATA 0x02000200 +#define DENALI_CTL_355_DATA 0x00001e68 +#define DENALI_CTL_356_DATA 0x00009808 +#define DENALI_CTL_357_DATA 0x00020608 +#define DENALI_CTL_358_DATA 0x000a0a01 +#define DENALI_CTL_359_DATA 0x00000000 +#define DENALI_CTL_360_DATA 0x00000000 +#define DENALI_CTL_361_DATA 0x04038000 +#define DENALI_CTL_362_DATA 0x07030a07 +#define DENALI_CTL_363_DATA 0x00ffff22 +#define DENALI_CTL_364_DATA 0x000f0010 +#define DENALI_CTL_365_DATA 0x00000000 +#define DENALI_CTL_366_DATA 0x00000000 +#define DENALI_CTL_367_DATA 0x00000000 +#define DENALI_CTL_368_DATA 0x00000000 +#define DENALI_CTL_369_DATA 0x00000000 +#define DENALI_CTL_370_DATA 0x00000204 +#define DENALI_CTL_371_DATA 0x00000000 +#define DENALI_CTL_372_DATA 0x01000001 +#define DENALI_CTL_373_DATA 0x00000001 +#define DENALI_CTL_374_DATA 0x00000000 diff --git a/board/schneider/lces/lces.c b/board/schneider/lces/lces.c new file mode 100644 index 0000000000..e520b1e9e4 --- /dev/null +++ b/board/schneider/lces/lces.c @@ -0,0 +1,41 @@ +// SPDX-License-Identifier: GPL-2.0+ + +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +int board_init(void) +{ + gd->bd->bi_boot_params = (CONFIG_SYS_SDRAM_BASE + 0x100); + + return 0; +} + +int dram_init(void) +{ + struct udevice *dev; + int err; + + /* This will end up calling cadence_ddr_probe() */ + err = uclass_get_device(UCLASS_RAM, 0, &dev); + if (err) { + debug("DRAM init failed: %d\n", err); + return err; + } + + // FIXME: checkpatch says to use dev_read_... + if (fdtdec_setup_mem_size_base() != 0) + return -EINVAL; + + return 0; +} + +int dram_init_banksize(void) +{ + // FIXME: checkpatch says to use dev_read_... + fdtdec_setup_memory_banksize(); + + return 0; +} diff --git a/configs/lces_defconfig b/configs/lces_defconfig new file mode 100644 index 0000000000..c10f1a2133 --- /dev/null +++ b/configs/lces_defconfig @@ -0,0 +1,26 @@ +CONFIG_ARM=y +CONFIG_SYS_ARCH_TIMER=y +CONFIG_SYS_THUMB_BUILD=y +CONFIG_ARCH_RZN1=y +CONFIG_SYS_TEXT_BASE=0x20040000 +CONFIG_SYS_MALLOC_LEN=0xb0000 +CONFIG_SYS_MALLOC_F_LEN=0x800 +CONFIG_NR_DRAM_BANKS=1 +CONFIG_DEFAULT_DEVICE_TREE="r9a06g032-rzn1d400-lces" +CONFIG_DEBUG_UART_BASE=0x40060000 +CONFIG_DEBUG_UART_CLOCK=20000000 +CONFIG_SYS_LOAD_ADDR=0x80008000 +CONFIG_DEBUG_UART=y +CONFIG_SYS_MEMTEST_START=0x80000000 +CONFIG_SYS_MEMTEST_END=0x8fffffff +CONFIG_CMD_MEMTEST=y +CONFIG_SYS_ALT_MEMTEST=y +# CONFIG_SYS_ALT_MEMTEST_BITFLIP is not set +CONFIG_CMD_CLK=y +CONFIG_OF_CONTROL=y +CONFIG_RAM=y +CONFIG_CADENCE_DDR_CTRL=y +CONFIG_DEBUG_UART_SHIFT=2 +CONFIG_DEBUG_UART_ANNOUNCE=y +CONFIG_SYS_NS16550=y +# CONFIG_EFI_LOADER is not set diff --git a/include/configs/lces.h b/include/configs/lces.h new file mode 100644 index 0000000000..37e9854758 --- /dev/null +++ b/include/configs/lces.h @@ -0,0 +1,22 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Configuration settings for the Schneider LCES board + */ + +#ifndef __LCES_H +#define __LCES_H + +/* Internal RAM */ +#define CONFIG_SYS_INIT_RAM_ADDR 0x20000000 +#define CONFIG_SYS_INIT_RAM_SIZE (1 * 1024 * 1024) + +/* DDR */ +#define CONFIG_SYS_SDRAM_BASE 0x80000000 +#define CONFIG_SYS_SDRAM_SIZE (256 * 1024 * 1024) + +#define CONFIG_SYS_MONITOR_LEN (512 * 1024) + +/* Serial port is memory-mapped as 32-bit registers */ +#define CONFIG_SYS_NS16550_MEM32 + +#endif /* __LCES2_H */ From patchwork Tue Aug 9 12:59:59 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ralph Siemsen X-Patchwork-Id: 596225 Delivered-To: patch@linaro.org Received: by 2002:a05:7000:b345:0:0:0:0 with SMTP id w5csp4153094maz; Tue, 9 Aug 2022 06:02:13 -0700 (PDT) X-Google-Smtp-Source: AA6agR6QcWiGwfMLu/Ny1EVmp7RsbIzeY2GVDhsxp/UNkX3ebxtuBDnaCVTUs2yYNd7Z18MdCc4d X-Received: by 2002:a05:6638:1925:b0:342:9fb4:8fd3 with SMTP id p37-20020a056638192500b003429fb48fd3mr10390042jal.153.1660050133007; Tue, 09 Aug 2022 06:02:13 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1660050133; cv=none; d=google.com; s=arc-20160816; b=TGFmIeNcajamxqNTGaaHRIV6WpagZfmYE/gFtBAEk/ncgrcUsNh40WJ6IAKZb1vFgg MrMyrBIRTG6uwdfUXI0ift//9w7i1nfVSFIEx5qLwohEU+cDeD54L/EQYVLLJuzwh+s3 En+9/haEUKBuVTUB9hecqaGXJiC+7LIraqf31uofWfAPtMFB48dBKMYKeAhMZPVW3tju G2WqE+slslMm6dj1uq1M52E1ij+jjFZd8M5BkcIXxj3LiGV4WijC8aXx2vKf0zZmUqbq CBeoo8RQGbbvX6G0M4nJKgfLOjS4Dhtrorrj0IP1ggNApltdfbXKOSVuHsonXFeJ0FxQ hKDg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=iiM0N/+2FEg/5dBHEhSFBsCNRl8qPvEy1Ft4+1GvSjg=; b=BxK1ELBxUd5/ju1tAoji0ydoL+rPPoN7LfS+xZcVa2tBzQNSH4dhnSaS24/7ljZt55 0Qh715WyF5qbNIT07o0g1rmfAiCp5diph43u4mo/T5MxTZ8ApJ862UCDWeYMAUTGTFvI D1az7hKVBnNOqcMeHm9cH1ymVxLPWk+OQgpAtZ4O0bA8Wko73MkBziCtuyXBsU43Mgfr mLrsGVnYOA322NMVDX0bf5By99hEUx4nUHy1aAYpI3Ddr1uS3LBbOfMN8v1QRlKaQAoP jGfpSrLpksnQYVHsIZ3TblMEDGJXNkNyC+WUtOWhY4B6xagh6gqlBDDDipiLH9/94hTd odVA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b="s3/ph24a"; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from phobos.denx.de (phobos.denx.de. [85.214.62.61]) by mx.google.com with ESMTPS id g13-20020a056e02198d00b002de0aa57e92si1926765ilf.47.2022.08.09.06.02.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 09 Aug 2022 06:02:12 -0700 (PDT) Received-SPF: pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 as permitted sender) client-ip=85.214.62.61; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b="s3/ph24a"; spf=pass (google.com: domain of u-boot-bounces@lists.denx.de designates 85.214.62.61 as permitted sender) smtp.mailfrom=u-boot-bounces@lists.denx.de; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 426F584A3D; Tue, 9 Aug 2022 15:01:45 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org 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=linaro.org header.i=@linaro.org header.b="s3/ph24a"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id AA91384A40; Tue, 9 Aug 2022 15:01:13 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_NONE,SPF_PASS, T_SCC_BODY_TEXT_LINE autolearn=unavailable autolearn_force=no version=3.4.2 Received: from mail-io1-xd33.google.com (mail-io1-xd33.google.com [IPv6:2607:f8b0:4864:20::d33]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 4F5B484A3E for ; Tue, 9 Aug 2022 15:00:40 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=ralph.siemsen@linaro.org Received: by mail-io1-xd33.google.com with SMTP id d187so2714899iof.4 for ; Tue, 09 Aug 2022 06:00:40 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc; bh=iiM0N/+2FEg/5dBHEhSFBsCNRl8qPvEy1Ft4+1GvSjg=; b=s3/ph24aGl1zvd/1UWwbDYzEpFc6sjDLXNTRrHhD58RDtxTOA9jAt4nrJ6c/GH9A8p 5iNlorsWGf3ySaDm64X9GXRlGxhpSmQsmK6XXxd2IaxJ4wMwfEGtOOyywzww7PJQwmeM 5dEhI07uNTwu06XqOIuM/y1OpAS+qI47ciitXsNPJidWcP6vUriEazwTOg9TkVMY+N4Y sBOSAaMRV8RFao5ts/nO8hZpZR7IJtwMsoFgUdIPVynC1H4pRn2ijdGp5J5hjbm2NL3j gJt/ITsWebu6B1USR3JfHyutrbUuY5GZ1dBvB7Nu6MYPZSevapDO/DYV6WNxNPBHZ23k l5tA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc; bh=iiM0N/+2FEg/5dBHEhSFBsCNRl8qPvEy1Ft4+1GvSjg=; b=nWFnFETStHXirPilbJt2G7qdcm4ldAlShyf6neBGKI+AeM6VHXB8apNTORl1DbeBZL ozuCH7Ia51pBrA/olnnrQG8DToxXIOXfrp3KD047c/CFU7/aAiO0fPEfWuGlPBwMhcxq 3RM4oHNejh/yjJBGJOPEyiBtlZDQ0CNxTaNx9VRNJZTfSwEGpXKXdeVvFmIwA/R9zBtS Tz5584ihkZyu4Ms/3sMcfAITMKYtmZpV8MElYjcCsUCWreq4vmH9OYcG7qqvrIsEeHPz tb5cKIzVyDa589TiszLYa5cR3V0I4kUZIMS0jSFYQZGYUcNbgvGCAeLS/5nhrmm9FJjU p2Gw== X-Gm-Message-State: ACgBeo2V75m3mAZX0Gp48PCA1a2kCDjs4JGBhypF8p103yfLJLztA+Kb Tu5KH94ZrSpmOAMmf4xrE3w9TnS2U6RIGF2p X-Received: by 2002:a05:6638:4809:b0:342:6dbe:6f85 with SMTP id cp9-20020a056638480900b003426dbe6f85mr10677185jab.78.1660050039730; Tue, 09 Aug 2022 06:00:39 -0700 (PDT) Received: from maple.netwinder.org (rfs.netwinder.org. [206.248.184.2]) by smtp.gmail.com with ESMTPSA id g12-20020a056e021a2c00b002dea1e18a94sm1022197ile.47.2022.08.09.06.00.38 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 09 Aug 2022 06:00:39 -0700 (PDT) From: Ralph Siemsen To: u-boot@lists.denx.de Cc: Michel Pollet , Ralph Siemsen , AKASHI Takahiro , Andre Przywara , Heiko Thiery , =?utf-8?q?Pali_Roh=C3=A1r?= , Samuel Holland , Simon Glass , Stefan Roese Subject: [RFC PATCH v1 9/9] tools: Add tool to create Renesas SPKG images Date: Tue, 9 Aug 2022 08:59:59 -0400 Message-Id: <20220809125959.217333-10-ralph.siemsen@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220809125959.217333-1-ralph.siemsen@linaro.org> References: <20220809125959.217333-1-ralph.siemsen@linaro.org> MIME-Version: 1.0 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.6 at phobos.denx.de X-Virus-Status: Clean From: Michel Pollet Renesas RZ/N1 devices contain BootROM code that loads a custom SPKG image from QSPI, NAND or USB DFU. This tool converts a binary image into an SPKG. SPKGs can optionally be signed, however this tool does not currently support signed SPKGs. Signed-off-by: Michel Pollet Signed-off-by: Ralph Siemsen --- This tool could possibly be incorporated into mkimage / imagetools. However it is unclear how to handle the extra commandline parameters (NAND ECC settings, etc). So for now it is stand-alone tool. tools/Makefile | 2 + tools/spkg_header.h | 49 +++++++ tools/spkg_utility.c | 306 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 357 insertions(+) create mode 100644 tools/spkg_header.h create mode 100644 tools/spkg_utility.c diff --git a/tools/Makefile b/tools/Makefile index 005e7362a3..c5dc92a13f 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -68,6 +68,8 @@ HOSTCFLAGS_img2srec.o := -pedantic hostprogs-$(CONFIG_XWAY_SWAP_BYTES) += xway-swap-bytes HOSTCFLAGS_xway-swap-bytes.o := -pedantic +hostprogs-$(CONFIG_ARCH_RZN1) += spkg_utility + hostprogs-y += mkenvimage mkenvimage-objs := mkenvimage.o os_support.o lib/crc32.o diff --git a/tools/spkg_header.h b/tools/spkg_header.h new file mode 100644 index 0000000000..029930cbf8 --- /dev/null +++ b/tools/spkg_header.h @@ -0,0 +1,49 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ +/* + * Renesas RZ/N1 Linux tools: Package Table format + * (C) 2015-2016 Renesas Electronics Europe, LTD + * All rights reserved. + */ + +#ifndef _SKGT_HEADER_H_ +#define _SKGT_HEADER_H_ + +#define SPKG_HEADER_SIGNATURE (('R'<<0)|('Z'<<8)|('N'<<16)|('1'<<24)) +#define SPKG_HEADER_COUNT 8 +#define SPKG_BLP_SIZE 264 + +#define SPKG_HEADER_SIZE 24 +#define SPKG_HEADER_SIZE_ALL (SPKG_HEADER_SIZE * SPKG_HEADER_COUNT) +#define SPKG_HEADER_CRC_SIZE 4 + +/* Index into SPKG */ +#define INDEX_BLP_START SPKG_HEADER_SIZE_ALL +#define INDEX_IMAGE_START (INDEX_BLP_START + SPKG_BLP_SIZE) + +/* Flags, not supported by ROM code, only used for U-Boot SPL */ +enum { + SPKG_CODE_NONSEC_BIT = 0, + SPKG_CODE_HYP_BIT, +}; + +/* SPKG header */ +struct spkg_hdr { + uint32_t signature; + uint8_t version; + uint8_t ecc; + uint8_t ecc_scheme; + uint8_t ecc_bytes; + uint32_t payload_length; /* only HIGHER 24 bits */ + uint32_t load_address; + uint32_t execution_offset; + uint32_t crc; /* of this header */ +} __attribute__((packed)); + +struct spkg_file { + struct spkg_hdr header[SPKG_HEADER_COUNT]; + uint8_t blp[SPKG_BLP_SIZE]; + uint8_t data[0]; + /* then the CRC */ +} __attribute__((packed)); + +#endif diff --git a/tools/spkg_utility.c b/tools/spkg_utility.c new file mode 100644 index 0000000000..235e23e0f1 --- /dev/null +++ b/tools/spkg_utility.c @@ -0,0 +1,306 @@ +// SPDX-License-Identifier: BSD-2-Clause +/* + * This is a utility to create a SPKG file. + * It packages the binary code into the SPKG. + * + * (C) Copyright 2016 Renesas Electronics Europe Ltd + */ + +#include +#include +#include +#include +#include + +#include "spkg_header.h" + +/* For Windows compatibility */ +#ifndef htole32 +#if __BYTE_ORDER == __LITTLE_ENDIAN + #define htole32(x) (x) +#elif __BYTE_ORDER == __BIG_ENDIAN + #define htole32(x) __builtin_bswap32((uint32_t)(x)) +#endif +#endif + +#define MAX_PATH 300 + +// Note: Order of bit fields is not used, this is purely just holding the SPKG information. +struct spkg_header { + char input[MAX_PATH]; + char output[MAX_PATH + 5]; + unsigned int version:4; + unsigned int ecc_enable:1; + unsigned int ecc_block_size:2; + unsigned int ecc_scheme:3; + unsigned int ecc_bytes:8; + unsigned int dummy_blp_length:10; + unsigned int payload_length:24; + unsigned int spl_nonsec:1; + unsigned int spl_hyp:1; + unsigned int load_address; + unsigned int execution_offset; + uint32_t padding; +}; + +struct spkg_header g_header = { + .version = 1, + .padding = 256, +}; + +int verbose; + +static uint32_t crc32(const uint8_t *message, uint32_t l) +{ + uint32_t crc = ~0; + + while (l--) { + uint32_t byte = *message++; // Get next byte. + + crc = crc ^ byte; + for (int8_t j = 7; j >= 0; j--) { // Do eight times. + uint32_t mask = -(crc & 1); + + crc = (crc >> 1) ^ (0xEDB88320 & mask); + } + } + return ~crc; +} + +static int spkg_write(struct spkg_header *h, FILE *file_input, FILE *file_SPKG) +{ + int i; + uint32_t length_inputfile; + uint32_t length_read; + uint32_t length_written; + uint32_t length_total; + uint32_t padding = 0; + uint8_t *data, *start; + uint32_t crc; + + /* Calculate length of input file */ + fseek(file_input, 0, SEEK_END); // seek to end of file + length_inputfile = ftell(file_input); // get current file pointer + fseek(file_input, 0, SEEK_SET); // seek back to beginning of file + + /* Set payload_length field. */ + h->payload_length = + length_inputfile + h->dummy_blp_length + SPKG_HEADER_CRC_SIZE; + + /* Calculate total length of SPKG */ + length_total = + (SPKG_HEADER_SIZE * SPKG_HEADER_COUNT) + h->dummy_blp_length + + length_inputfile + SPKG_HEADER_CRC_SIZE; + padding = h->padding ? h->padding - (length_total % h->padding) : 0; + length_total += padding; + /* Padding needs to be part of the payload size, otherwise the ROM DFU + * refuses to accept the extra bytes and return and error. + */ + h->payload_length += padding; + + printf("Addr: 0x%08x ", h->load_address); + printf("In: %8d ", length_inputfile); + printf("padding to %3dKB: %6d ", h->padding / 1024, padding); + printf("Total: 0x%08x ", length_total); + printf("%s\n", h->output); + + /* Create and zero array for SPKG */ + data = malloc(length_total); + memset(data, 0, length_total); + + /* Fill the SPKG with the headers */ + { + struct spkg_hdr head = { + .signature = SPKG_HEADER_SIGNATURE, + .version = h->version, + .ecc = (h->ecc_enable << 5) | (h->ecc_block_size << 1), + .ecc_scheme = h->ecc_scheme, + .ecc_bytes = h->ecc_bytes, + .payload_length = htole32((h->payload_length << 8) | + (h->spl_nonsec << SPKG_CODE_NONSEC_BIT) | + (h->spl_hyp << SPKG_CODE_HYP_BIT)), + .load_address = htole32(h->load_address), + .execution_offset = htole32(h->execution_offset), + }; + + head.crc = crc32((uint8_t *)&head, sizeof(head) - SPKG_HEADER_CRC_SIZE); + for (i = 0; i < SPKG_HEADER_COUNT; i++) + ((struct spkg_hdr *)data)[i] = head; + } + + start = data + INDEX_BLP_START; + + /* Fill the SPKG with the Dummy BLp */ + for (i = 0; i < h->dummy_blp_length; i++) + *start++ = 0x88; + /* Fill the SPKG with the data from the code file. */ + length_read = + fread(start, sizeof(char), length_inputfile, + file_input); + + if (length_read != length_inputfile) { + fprintf(stderr, "Error reading %s: ferror=%d, feof=%d\n", + h->input, ferror(file_input), feof(file_input)); + + return -1; + } + /* fill padding with flash friendly one bits */ + memset(start + length_inputfile + SPKG_HEADER_CRC_SIZE, 0xff, padding); + + /* Add Payload CRC */ + crc = crc32(&data[INDEX_BLP_START], + h->dummy_blp_length + length_inputfile + padding); + + start += length_inputfile + padding; + start[0] = crc; + start[1] = crc >> 8; + start[2] = crc >> 16; + start[3] = crc >> 24; + + /* Write the completed SKPG to file */ + length_written = fwrite(data, sizeof(char), length_total, file_SPKG); + + if (length_written != length_total) { + fprintf(stderr, "Error writing to %s\n", h->output); + return -1; + } + + return 0; +} + +const char *usage = + "%s\n" + " [-i ] : input file\n" + " [-o ] : output file\n" + " [--load_address ] : code load address\n" + " [--execution_offset ] : starting offset\n" + " [--nand_ecc_enable] : Enable nand ECC\n" + " [--nand_ecc_blksize ] : Block size code\n" + " 0=256 bytes, 1=512 bytes, 2=1024 bytes\n" + " [--nand_ecc_scheme ] : ECC scheme code\n" + " 0=BCH2 1=BCH4 2=BCH8 3=BCH16 4=BCH24 5=BCH32\n" + " [--add_dummy_blp] : Add a passthru BLP\n" + " [--spl_nonsec] : Code package run in NONSEC\n" + " [--spl_hyp] : Code package run in HYP (and NONSEC)\n" + " [--padding [K|M]] : Pass SPKG to size block\n" + ; + +static int spkg_parse_option(struct spkg_header *h, const char *name, + const char *sz, uint32_t value) +{ +// printf("%s %s=%s %08x\n", __func__, name, sz, value); + if (!strcmp("file_input", name) || !strcmp("i", name)) { + strncpy(h->input, sz, sizeof(h->input) - 1); + h->input[sizeof(h->input) - 1] = 0; + } else if (!strcmp("file_output", name) || !strcmp("o", name)) { + strncpy(h->output, sz, sizeof(h->output) - 1); + h->output[sizeof(h->output) - 1] = 0; + } else if (!strcmp("version", name)) { + h->version = value; + } else if (!strcmp("load_address", name)) { + h->load_address = value; + } else if (!strcmp("execution_offset", name)) { + h->execution_offset = value; + } else if (!strcmp("nand_ecc_enable", name)) { + h->ecc_enable = value; + } else if (!strcmp("nand_ecc_blksize", name)) { + h->ecc_block_size = value; + } else if (!strcmp("nand_ecc_scheme", name)) { + h->ecc_scheme = value; + } else if (!strcmp("nand_bytes_per_ecc_block", name)) { + h->ecc_bytes = value; + } else if (!strcmp("add_dummy_blp", name)) { + h->dummy_blp_length = value ? SPKG_BLP_SIZE : 0; + } else if (!strcmp("spl_nonsec", name)) { + h->spl_nonsec = !!value; + } else if (!strcmp("spl_hyp", name)) { + h->spl_hyp = !!value; + } else if (!strcmp("help", name) || !strcmp("h", name)) { + fprintf(stderr, usage, "spkg_utility"); + exit(0); + } else if (!strcmp("padding", name) && sz && value) { + if (strchr(sz, 'K')) + h->padding = value * 1024; + else if (strchr(sz, 'M')) + h->padding = value * 1024 * 1024; + else + h->padding = value; + } else { + return -1; + } + + return 0; +} + +int main(int argc, char *argv[]) +{ + FILE *file_SPKG = NULL; + FILE *file_input = NULL; + int result = -1; + + for (int i = 1; i < argc; i++) { + unsigned long value = 0; + char *name = argv[i]; + char *sz = NULL; + + if (!name || name[0] != '-') { + fprintf(stderr, "%s invalid argument '%s'\n", + argv[0], argv[i]); + return -1; + } + name++; + if (name[0] == '-') + name++; + + if (i < argc - 1 && argv[i + 1][0] != '-') + sz = argv[++i]; + + if (sz) { + if (!sscanf(sz, "0x%lx", &value)) + sscanf(sz, "%lu", &value); + } else { + value = 1; + } + if (spkg_parse_option(&g_header, name, sz, value)) { + fprintf(stderr, "%s Error invalid '%s'\n", + argv[0], argv[i]); + return -1; + } + } + + if (!g_header.input[0]) { + fprintf(stderr, usage, argv[0]); + exit(1); + } + if (!g_header.output[0]) + snprintf(g_header.output, sizeof(g_header.output), + "%s.spkg", g_header.input); + if (verbose) + printf("%s -> %s\n", g_header.input, g_header.output); + + /*NOTE: Using binary mode as this seems necessary if running in Windows */ + file_SPKG = fopen(g_header.output, "wb"); + file_input = fopen(g_header.input, "rb"); + + if (!file_SPKG) + perror(g_header.output); + if (!file_input) + perror(g_header.input); + + if (file_input && file_SPKG) + result = spkg_write(&g_header, file_input, file_SPKG); + + if (file_SPKG) + fclose(file_SPKG); + if (file_input) + fclose(file_input); + + if (result >= 0) { + if (verbose) + printf("%s created\n", g_header.output); + } else { + fprintf(stderr, "ERROR creating %s\n", g_header.output); + } + + return result; +}