1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * Random Number Generator driver for the Keystone SOC 4 * 5 * Copyright (C) 2016 Texas Instruments Incorporated - https://www.ti.com 6 * 7 * Authors: Sandeep Nair 8 * Vitaly Andrianov 9 */ 10 11#include <linux/hw_random.h> 12#include <linux/kernel.h> 13#include <linux/module.h> 14#include <linux/io.h> 15#include <linux/platform_device.h> 16#include <linux/clk.h> 17#include <linux/pm_runtime.h> 18#include <linux/err.h> 19#include <linux/regmap.h> 20#include <linux/mfd/syscon.h> 21#include <linux/of.h> 22#include <linux/of_address.h> 23#include <linux/delay.h> 24#include <linux/timekeeping.h> 25 26#define SA_CMD_STATUS_OFS 0x8 27 28/* TRNG enable control in SA System module*/ 29#define SA_CMD_STATUS_REG_TRNG_ENABLE BIT(3) 30 31/* TRNG start control in TRNG module */ 32#define TRNG_CNTL_REG_TRNG_ENABLE BIT(10) 33 34/* Data ready indicator in STATUS register */ 35#define TRNG_STATUS_REG_READY BIT(0) 36 37/* Data ready clear control in INTACK register */ 38#define TRNG_INTACK_REG_READY BIT(0) 39 40/* 41 * Number of samples taken to gather entropy during startup. 42 * If value is 0, the number of samples is 2^24 else 43 * equals value times 2^8. 44 */ 45#define TRNG_DEF_STARTUP_CYCLES 0 46#define TRNG_CNTL_REG_STARTUP_CYCLES_SHIFT 16 47 48/* 49 * Minimum number of samples taken to regenerate entropy 50 * If value is 0, the number of samples is 2^24 else 51 * equals value times 2^6. 52 */ 53#define TRNG_DEF_MIN_REFILL_CYCLES 1 54#define TRNG_CFG_REG_MIN_REFILL_CYCLES_SHIFT 0 55 56/* 57 * Maximum number of samples taken to regenerate entropy 58 * If value is 0, the number of samples is 2^24 else 59 * equals value times 2^8. 60 */ 61#define TRNG_DEF_MAX_REFILL_CYCLES 0 62#define TRNG_CFG_REG_MAX_REFILL_CYCLES_SHIFT 16 63 64/* Number of CLK input cycles between samples */ 65#define TRNG_DEF_CLK_DIV_CYCLES 0 66#define TRNG_CFG_REG_SAMPLE_DIV_SHIFT 8 67 68/* Maximum retries to get rng data */ 69#define SA_MAX_RNG_DATA_RETRIES 5 70/* Delay between retries (in usecs) */ 71#define SA_RNG_DATA_RETRY_DELAY 5 72 73struct trng_regs { 74 u32 output_l; 75 u32 output_h; 76 u32 status; 77 u32 intmask; 78 u32 intack; 79 u32 control; 80 u32 config; 81}; 82 83struct ks_sa_rng { 84 struct hwrng rng; 85 struct clk *clk; 86 struct regmap *regmap_cfg; 87 struct trng_regs __iomem *reg_rng; 88 u64 ready_ts; 89 unsigned int refill_delay_ns; 90}; 91 92static unsigned int cycles_to_ns(unsigned long clk_rate, unsigned int cycles) 93{ 94 return DIV_ROUND_UP_ULL((TRNG_DEF_CLK_DIV_CYCLES + 1) * 1000000000ull * 95 cycles, clk_rate); 96} 97 98static unsigned int startup_delay_ns(unsigned long clk_rate) 99{ 100 if (!TRNG_DEF_STARTUP_CYCLES) 101 return cycles_to_ns(clk_rate, BIT(24)); 102 return cycles_to_ns(clk_rate, 256 * TRNG_DEF_STARTUP_CYCLES); 103} 104 105static unsigned int refill_delay_ns(unsigned long clk_rate) 106{ 107 if (!TRNG_DEF_MAX_REFILL_CYCLES) 108 return cycles_to_ns(clk_rate, BIT(24)); 109 return cycles_to_ns(clk_rate, 256 * TRNG_DEF_MAX_REFILL_CYCLES); 110} 111 112static int ks_sa_rng_init(struct hwrng *rng) 113{ 114 u32 value; 115 struct ks_sa_rng *ks_sa_rng = container_of(rng, struct ks_sa_rng, rng); 116 unsigned long clk_rate = clk_get_rate(ks_sa_rng->clk); 117 118 /* Enable RNG module */ 119 regmap_write_bits(ks_sa_rng->regmap_cfg, SA_CMD_STATUS_OFS, 120 SA_CMD_STATUS_REG_TRNG_ENABLE, 121 SA_CMD_STATUS_REG_TRNG_ENABLE); 122 123 /* Configure RNG module */ 124 writel(0, &ks_sa_rng->reg_rng->control); 125 value = TRNG_DEF_STARTUP_CYCLES << TRNG_CNTL_REG_STARTUP_CYCLES_SHIFT; 126 writel(value, &ks_sa_rng->reg_rng->control); 127 128 value = (TRNG_DEF_MIN_REFILL_CYCLES << 129 TRNG_CFG_REG_MIN_REFILL_CYCLES_SHIFT) | 130 (TRNG_DEF_MAX_REFILL_CYCLES << 131 TRNG_CFG_REG_MAX_REFILL_CYCLES_SHIFT) | 132 (TRNG_DEF_CLK_DIV_CYCLES << 133 TRNG_CFG_REG_SAMPLE_DIV_SHIFT); 134 135 writel(value, &ks_sa_rng->reg_rng->config); 136 137 /* Disable all interrupts from TRNG */ 138 writel(0, &ks_sa_rng->reg_rng->intmask); 139 140 /* Enable RNG */ 141 value = readl(&ks_sa_rng->reg_rng->control); 142 value |= TRNG_CNTL_REG_TRNG_ENABLE; 143 writel(value, &ks_sa_rng->reg_rng->control); 144 145 ks_sa_rng->refill_delay_ns = refill_delay_ns(clk_rate); 146 ks_sa_rng->ready_ts = ktime_get_ns() + 147 startup_delay_ns(clk_rate); 148 149 return 0; 150} 151 152static void ks_sa_rng_cleanup(struct hwrng *rng) 153{ 154 struct ks_sa_rng *ks_sa_rng = container_of(rng, struct ks_sa_rng, rng); 155 156 /* Disable RNG */ 157 writel(0, &ks_sa_rng->reg_rng->control); 158 regmap_write_bits(ks_sa_rng->regmap_cfg, SA_CMD_STATUS_OFS, 159 SA_CMD_STATUS_REG_TRNG_ENABLE, 0); 160} 161 162static int ks_sa_rng_data_read(struct hwrng *rng, u32 *data) 163{ 164 struct ks_sa_rng *ks_sa_rng = container_of(rng, struct ks_sa_rng, rng); 165 166 /* Read random data */ 167 data[0] = readl(&ks_sa_rng->reg_rng->output_l); 168 data[1] = readl(&ks_sa_rng->reg_rng->output_h); 169 170 writel(TRNG_INTACK_REG_READY, &ks_sa_rng->reg_rng->intack); 171 ks_sa_rng->ready_ts = ktime_get_ns() + ks_sa_rng->refill_delay_ns; 172 173 return sizeof(u32) * 2; 174} 175 176static int ks_sa_rng_data_present(struct hwrng *rng, int wait) 177{ 178 struct ks_sa_rng *ks_sa_rng = container_of(rng, struct ks_sa_rng, rng); 179 u64 now = ktime_get_ns(); 180 181 u32 ready; 182 int j; 183 184 if (wait && now < ks_sa_rng->ready_ts) { 185 /* Max delay expected here is 81920000 ns */ 186 unsigned long min_delay = 187 DIV_ROUND_UP((u32)(ks_sa_rng->ready_ts - now), 1000); 188 189 usleep_range(min_delay, min_delay + SA_RNG_DATA_RETRY_DELAY); 190 } 191 192 for (j = 0; j < SA_MAX_RNG_DATA_RETRIES; j++) { 193 ready = readl(&ks_sa_rng->reg_rng->status); 194 ready &= TRNG_STATUS_REG_READY; 195 196 if (ready || !wait) 197 break; 198 199 udelay(SA_RNG_DATA_RETRY_DELAY); 200 } 201 202 return ready; 203} 204 205static int ks_sa_rng_probe(struct platform_device *pdev) 206{ 207 struct ks_sa_rng *ks_sa_rng; 208 struct device *dev = &pdev->dev; 209 int ret; 210 211 ks_sa_rng = devm_kzalloc(dev, sizeof(*ks_sa_rng), GFP_KERNEL); 212 if (!ks_sa_rng) 213 return -ENOMEM; 214 215 ks_sa_rng->rng = (struct hwrng) { 216 .name = "ks_sa_hwrng", 217 .init = ks_sa_rng_init, 218 .data_read = ks_sa_rng_data_read, 219 .data_present = ks_sa_rng_data_present, 220 .cleanup = ks_sa_rng_cleanup, 221 }; 222 223 ks_sa_rng->reg_rng = devm_platform_ioremap_resource(pdev, 0); 224 if (IS_ERR(ks_sa_rng->reg_rng)) 225 return PTR_ERR(ks_sa_rng->reg_rng); 226 227 ks_sa_rng->regmap_cfg = 228 syscon_regmap_lookup_by_phandle(dev->of_node, 229 "ti,syscon-sa-cfg"); 230 231 if (IS_ERR(ks_sa_rng->regmap_cfg)) 232 return dev_err_probe(dev, -EINVAL, "syscon_node_to_regmap failed\n"); 233 234 pm_runtime_enable(dev); 235 ret = pm_runtime_resume_and_get(dev); 236 if (ret < 0) { 237 pm_runtime_disable(dev); 238 return dev_err_probe(dev, ret, "Failed to enable SA power-domain\n"); 239 } 240 241 return devm_hwrng_register(&pdev->dev, &ks_sa_rng->rng); 242} 243 244static void ks_sa_rng_remove(struct platform_device *pdev) 245{ 246 pm_runtime_put_sync(&pdev->dev); 247 pm_runtime_disable(&pdev->dev); 248} 249 250static const struct of_device_id ks_sa_rng_dt_match[] = { 251 { 252 .compatible = "ti,keystone-rng", 253 }, 254 { }, 255}; 256MODULE_DEVICE_TABLE(of, ks_sa_rng_dt_match); 257 258static struct platform_driver ks_sa_rng_driver = { 259 .driver = { 260 .name = "ks-sa-rng", 261 .of_match_table = ks_sa_rng_dt_match, 262 }, 263 .probe = ks_sa_rng_probe, 264 .remove_new = ks_sa_rng_remove, 265}; 266 267module_platform_driver(ks_sa_rng_driver); 268 269MODULE_DESCRIPTION("Keystone NETCP SA H/W Random Number Generator driver"); 270MODULE_AUTHOR("Vitaly Andrianov <vitalya@ti.com>"); 271MODULE_LICENSE("GPL"); 272