From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id C2360C76196 for ; Thu, 6 Apr 2023 16:18:12 +0000 (UTC) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id CA366860A1; Thu, 6 Apr 2023 18:17:57 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="NYv9hUWX"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 12D1586083; Thu, 6 Apr 2023 18:17:50 +0200 (CEST) Received: from mail-ot1-x336.google.com (mail-ot1-x336.google.com [IPv6:2607:f8b0:4864:20::336]) (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 26D7186085 for ; Thu, 6 Apr 2023 18:17:45 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=macroalpha82@gmail.com Received: by mail-ot1-x336.google.com with SMTP id cm7-20020a056830650700b006a11f365d13so19653094otb.0 for ; Thu, 06 Apr 2023 09:17:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; t=1680797863; x=1683389863; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=fGb9H/Q/Gmkn4+Ckww5aEN2qdtx28eCYhasisP7eapA=; b=NYv9hUWXc7LjSZDkrh87Sxa7wrXvM1Nq420StmclKsSOLlMoUnolwZPgsfbse7AtGN tSMjzkHs+Bs9q9/oAM4jMZC/NHDrENxjQ7xtesY+lods6Kq7J2pBF7MEJfTBuvz3PFb8 xplec1ToH+z4sKSOpEYeDaJz2ZyDhDKI957uXR58YDHNBJVJ4nPoTbyDarboz8X4EiTF 7Yd76FiZApvtQdRcxGNefW57tqGCEmK+2fnVw+un0HDP2Sr90vASX99k30zpUkZdjVQl CSye9hE3XOJPRomZo/ydJmNxj15uA8Pu5mmMkOi2op7Bu63xwbM/+8fX90kYqHXYYB4T spxQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1680797863; x=1683389863; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=fGb9H/Q/Gmkn4+Ckww5aEN2qdtx28eCYhasisP7eapA=; b=mrLVObIdjvnKB18FHwZwZdnEL/RnMNVFiA7/UhMOQE90cdMM3KIS71qtj1tS0VnMWB 0nEdBbsXSLU6xRqS9FJtTJy7D5YIVsF1cFIx2P9e9LfZpp68LZMgOhatRVAf6N1I0Pq9 oJ5w8HXx/MOaGkY/jrDYTXmJqqr8Ar3hej9rASw0M39QkuVZYtbUOcQLnxMANGMMDfUb CH6tPap5QAX07BT/9Eqsb6794jARp19Y0KPSGEBZc5nA/2olNcedTX4n2Zya/NtPh8jn ElFNkfSO8Y9DLpmeHoox8ExiYTwhwb6bX1trQjBbctt0YpDkF2drKryB6y2eHWuUQ2XN iF+A== X-Gm-Message-State: AAQBX9cDEb2igZ4dmIvnl6Pv4uYD352N8xW01UcP5G2DrAwEVVTR/u68 bplhjKdxufbObSyYEvWoR7ZLtGJl0uM= X-Google-Smtp-Source: AKy350bDp+AkxfCx3xyD2GMJnxuYGjeevvg+9hGuP+G5r5QQwQVbIM8e2Vyo2gq1z6kNKw4uHn9Mcw== X-Received: by 2002:a05:6830:1296:b0:6a3:3641:8d77 with SMTP id z22-20020a056830129600b006a336418d77mr5154771otp.15.1680797863502; Thu, 06 Apr 2023 09:17:43 -0700 (PDT) Received: from localhost.localdomain (76-244-6-13.lightspeed.rcsntx.sbcglobal.net. [76.244.6.13]) by smtp.gmail.com with ESMTPSA id z9-20020a0568301da900b006a249e69aebsm824342oti.81.2023.04.06.09.17.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 06 Apr 2023 09:17:42 -0700 (PDT) From: Chris Morgan To: u-boot@lists.denx.de Cc: xypron.glpk@gmx.de, sughosh.ganu@linaro.org, kever.yang@rock-chips.com, philipp.tomsich@vrull.eu, sjg@chromium.org, Chris Morgan , Lin Jinhan Subject: [PATCH 1/2] rockchip: rng: add trngv1 for rk3588 Date: Thu, 6 Apr 2023 11:17:35 -0500 Message-Id: <20230406161736.112696-2-macroalpha82@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230406161736.112696-1-macroalpha82@gmail.com> References: <20230406161736.112696-1-macroalpha82@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.8 at phobos.denx.de X-Virus-Status: Clean From: Chris Morgan This adds support for the TRNG found in the RK3588 SoC to the rockchip_rng driver so that it can be used for things such as seeding randomness to Linux. This code was taken wholesale from the Rockchip BSP U-Boot source located here: https://github.com/rockchip-linux/u-boot/commit/09f31aed858c36a8a5ee20789712e65bb4762068 Tested on an Indiedroid Nova with an RK3588s. Signed-off-by: Lin Jinhan Signed-off-by: Chris Morgan --- drivers/rng/rockchip_rng.c | 120 ++++++++++++++++++++++++++++++++++--- 1 file changed, 111 insertions(+), 9 deletions(-) diff --git a/drivers/rng/rockchip_rng.c b/drivers/rng/rockchip_rng.c index 800150f114..705b424cf3 100644 --- a/drivers/rng/rockchip_rng.c +++ b/drivers/rng/rockchip_rng.c @@ -43,9 +43,41 @@ #define CRYPTO_V2_RNG_DOUT_0 0x0410 /* end of CRYPTO V2 register define */ +/* start of TRNG V1 register define */ +#define TRNG_V1_CTRL 0x0000 +#define TRNG_V1_CTRL_NOP _SBF(0, 0x00) +#define TRNG_V1_CTRL_RAND _SBF(0, 0x01) +#define TRNG_V1_CTRL_SEED _SBF(0, 0x02) + +#define TRNG_V1_MODE 0x0008 +#define TRNG_V1_MODE_128_BIT _SBF(3, 0x00) +#define TRNG_V1_MODE_256_BIT _SBF(3, 0x01) + +#define TRNG_V1_IE 0x0010 +#define TRNG_V1_IE_GLBL_EN BIT(31) +#define TRNG_V1_IE_SEED_DONE_EN BIT(1) +#define TRNG_V1_IE_RAND_RDY_EN BIT(0) + +#define TRNG_V1_ISTAT 0x0014 +#define TRNG_V1_ISTAT_RAND_RDY BIT(0) + +/* RAND0 ~ RAND7 */ +#define TRNG_V1_RAND0 0x0020 +#define TRNG_V1_RAND7 0x003C + +#define TRNG_V1_AUTO_RQSTS 0x0060 + +#define TRNG_V1_VERSION 0x00F0 +#define TRNG_v1_VERSION_CODE 0x46BC +/* end of TRNG V1 register define */ + #define RK_RNG_TIME_OUT 50000 /* max 50ms */ +#define trng_write(pdata, pos, val) writel(val, (pdata)->base + (pos)) +#define trng_read(pdata, pos) readl((pdata)->base + (pos)) + struct rk_rng_soc_data { + int (*rk_rng_init)(struct udevice *dev); int (*rk_rng_read)(struct udevice *dev, void *data, size_t len); }; @@ -75,7 +107,7 @@ static int rk_rng_read_regs(fdt_addr_t addr, void *buf, size_t size) return 0; } -static int rk_v1_rng_read(struct udevice *dev, void *data, size_t len) +static int rk_cryptov1_rng_read(struct udevice *dev, void *data, size_t len) { struct rk_rng_plat *pdata = dev_get_priv(dev); u32 reg = 0; @@ -106,7 +138,7 @@ exit: return 0; } -static int rk_v2_rng_read(struct udevice *dev, void *data, size_t len) +static int rk_cryptov2_rng_read(struct udevice *dev, void *data, size_t len) { struct rk_rng_plat *pdata = dev_get_priv(dev); u32 reg = 0; @@ -140,6 +172,63 @@ exit: return retval; } +static int rk_trngv1_init(struct udevice *dev) +{ + u32 status, version; + u32 auto_reseed_cnt = 1000; + struct rk_rng_plat *pdata = dev_get_priv(dev); + + version = trng_read(pdata, TRNG_V1_VERSION); + if (version != TRNG_v1_VERSION_CODE) { + printf("wrong trng version, expected = %08x, actual = %08x", + TRNG_V1_VERSION, version); + return -EFAULT; + } + + /* wait in case of RND_RDY triggered at firs power on */ + readl_poll_timeout(pdata->base + TRNG_V1_ISTAT, status, + (status & TRNG_V1_ISTAT_RAND_RDY), + RK_RNG_TIME_OUT); + + /* clear RAND_RDY flag for first power on */ + trng_write(pdata, TRNG_V1_ISTAT, status); + + /* auto reseed after (auto_reseed_cnt * 16) byte rand generate */ + trng_write(pdata, TRNG_V1_AUTO_RQSTS, auto_reseed_cnt); + + return 0; +} + +static int rk_trngv1_rng_read(struct udevice *dev, void *data, size_t len) +{ + struct rk_rng_plat *pdata = dev_get_priv(dev); + u32 reg = 0; + int retval; + + if (len > RK_HW_RNG_MAX) + return -EINVAL; + + trng_write(pdata, TRNG_V1_MODE, TRNG_V1_MODE_256_BIT); + trng_write(pdata, TRNG_V1_CTRL, TRNG_V1_CTRL_RAND); + + retval = readl_poll_timeout(pdata->base + TRNG_V1_ISTAT, reg, + (reg & TRNG_V1_ISTAT_RAND_RDY), + RK_RNG_TIME_OUT); + /* clear ISTAT */ + trng_write(pdata, TRNG_V1_ISTAT, reg); + + if (retval) + goto exit; + + rk_rng_read_regs(pdata->base + TRNG_V1_RAND0, data, len); + +exit: + /* close TRNG */ + trng_write(pdata, TRNG_V1_CTRL, TRNG_V1_CTRL_NOP); + + return retval; +} + static int rockchip_rng_read(struct udevice *dev, void *data, size_t len) { unsigned char *buf = data; @@ -184,18 +273,27 @@ static int rockchip_rng_of_to_plat(struct udevice *dev) static int rockchip_rng_probe(struct udevice *dev) { struct rk_rng_plat *pdata = dev_get_priv(dev); + int ret = 0; pdata->soc_data = (struct rk_rng_soc_data *)dev_get_driver_data(dev); - return 0; + if (pdata->soc_data->rk_rng_init) + ret = pdata->soc_data->rk_rng_init(dev); + + return ret; } -static const struct rk_rng_soc_data rk_rng_v1_soc_data = { - .rk_rng_read = rk_v1_rng_read, +static const struct rk_rng_soc_data rk_cryptov1_soc_data = { + .rk_rng_read = rk_cryptov1_rng_read, +}; + +static const struct rk_rng_soc_data rk_cryptov2_soc_data = { + .rk_rng_read = rk_cryptov2_rng_read, }; -static const struct rk_rng_soc_data rk_rng_v2_soc_data = { - .rk_rng_read = rk_v2_rng_read, +static const struct rk_rng_soc_data rk_trngv1_soc_data = { + .rk_rng_init = rk_trngv1_init, + .rk_rng_read = rk_trngv1_rng_read, }; static const struct dm_rng_ops rockchip_rng_ops = { @@ -205,11 +303,15 @@ static const struct dm_rng_ops rockchip_rng_ops = { static const struct udevice_id rockchip_rng_match[] = { { .compatible = "rockchip,cryptov1-rng", - .data = (ulong)&rk_rng_v1_soc_data, + .data = (ulong)&rk_cryptov1_soc_data, }, { .compatible = "rockchip,cryptov2-rng", - .data = (ulong)&rk_rng_v2_soc_data, + .data = (ulong)&rk_cryptov2_soc_data, + }, + { + .compatible = "rockchip,trngv1", + .data = (ulong)&rk_trngv1_soc_data, }, {}, }; -- 2.34.1