1a583ed31SHadar Gat // SPDX-License-Identifier: GPL-2.0
2a583ed31SHadar Gat /* Copyright (C) 2019-2020 ARM Limited or its affiliates. */
3a583ed31SHadar Gat
4a583ed31SHadar Gat #include <linux/kernel.h>
5a583ed31SHadar Gat #include <linux/module.h>
6a583ed31SHadar Gat #include <linux/clk.h>
7a583ed31SHadar Gat #include <linux/hw_random.h>
8a583ed31SHadar Gat #include <linux/io.h>
9a583ed31SHadar Gat #include <linux/platform_device.h>
10a583ed31SHadar Gat #include <linux/pm_runtime.h>
11a583ed31SHadar Gat #include <linux/interrupt.h>
12a583ed31SHadar Gat #include <linux/irqreturn.h>
13a583ed31SHadar Gat #include <linux/workqueue.h>
14a583ed31SHadar Gat #include <linux/circ_buf.h>
15a583ed31SHadar Gat #include <linux/completion.h>
16a583ed31SHadar Gat #include <linux/of.h>
17a583ed31SHadar Gat #include <linux/bitfield.h>
183357b611SHadar Gat #include <linux/fips.h>
19a583ed31SHadar Gat
20a583ed31SHadar Gat #include "cctrng.h"
21a583ed31SHadar Gat
22a583ed31SHadar Gat #define CC_REG_LOW(name) (name ## _BIT_SHIFT)
23a583ed31SHadar Gat #define CC_REG_HIGH(name) (CC_REG_LOW(name) + name ## _BIT_SIZE - 1)
24a583ed31SHadar Gat #define CC_GENMASK(name) GENMASK(CC_REG_HIGH(name), CC_REG_LOW(name))
25a583ed31SHadar Gat
26a583ed31SHadar Gat #define CC_REG_FLD_GET(reg_name, fld_name, reg_val) \
27a583ed31SHadar Gat (FIELD_GET(CC_GENMASK(CC_ ## reg_name ## _ ## fld_name), reg_val))
28a583ed31SHadar Gat
29a583ed31SHadar Gat #define CC_HW_RESET_LOOP_COUNT 10
30a583ed31SHadar Gat #define CC_TRNG_SUSPEND_TIMEOUT 3000
31a583ed31SHadar Gat
32a583ed31SHadar Gat /* data circular buffer in words must be:
33a583ed31SHadar Gat * - of a power-of-2 size (limitation of circ_buf.h macros)
34a583ed31SHadar Gat * - at least 6, the size generated in the EHR according to HW implementation
35a583ed31SHadar Gat */
36a583ed31SHadar Gat #define CCTRNG_DATA_BUF_WORDS 32
37a583ed31SHadar Gat
38a583ed31SHadar Gat /* The timeout for the TRNG operation should be calculated with the formula:
39a583ed31SHadar Gat * Timeout = EHR_NUM * VN_COEFF * EHR_LENGTH * SAMPLE_CNT * SCALE_VALUE
40a583ed31SHadar Gat * while:
41a583ed31SHadar Gat * - SAMPLE_CNT is input value from the characterisation process
42a583ed31SHadar Gat * - all the rest are constants
43a583ed31SHadar Gat */
44a583ed31SHadar Gat #define EHR_NUM 1
45a583ed31SHadar Gat #define VN_COEFF 4
46a583ed31SHadar Gat #define EHR_LENGTH CC_TRNG_EHR_IN_BITS
47a583ed31SHadar Gat #define SCALE_VALUE 2
48a583ed31SHadar Gat #define CCTRNG_TIMEOUT(smpl_cnt) \
49a583ed31SHadar Gat (EHR_NUM * VN_COEFF * EHR_LENGTH * smpl_cnt * SCALE_VALUE)
50a583ed31SHadar Gat
51a583ed31SHadar Gat struct cctrng_drvdata {
52a583ed31SHadar Gat struct platform_device *pdev;
53a583ed31SHadar Gat void __iomem *cc_base;
54a583ed31SHadar Gat struct clk *clk;
55a583ed31SHadar Gat struct hwrng rng;
56a583ed31SHadar Gat u32 active_rosc;
57a583ed31SHadar Gat /* Sampling interval for each ring oscillator:
58a583ed31SHadar Gat * count of ring oscillator cycles between consecutive bits sampling.
59a583ed31SHadar Gat * Value of 0 indicates non-valid rosc
60a583ed31SHadar Gat */
61a583ed31SHadar Gat u32 smpl_ratio[CC_TRNG_NUM_OF_ROSCS];
62a583ed31SHadar Gat
63a583ed31SHadar Gat u32 data_buf[CCTRNG_DATA_BUF_WORDS];
64a583ed31SHadar Gat struct circ_buf circ;
65a583ed31SHadar Gat struct work_struct compwork;
66a583ed31SHadar Gat struct work_struct startwork;
67a583ed31SHadar Gat
68a583ed31SHadar Gat /* pending_hw - 1 when HW is pending, 0 when it is idle */
69a583ed31SHadar Gat atomic_t pending_hw;
70a583ed31SHadar Gat
71a583ed31SHadar Gat /* protects against multiple concurrent consumers of data_buf */
72a583ed31SHadar Gat spinlock_t read_lock;
73a583ed31SHadar Gat };
74a583ed31SHadar Gat
75a583ed31SHadar Gat
76a583ed31SHadar Gat /* functions for write/read CC registers */
cc_iowrite(struct cctrng_drvdata * drvdata,u32 reg,u32 val)77a583ed31SHadar Gat static inline void cc_iowrite(struct cctrng_drvdata *drvdata, u32 reg, u32 val)
78a583ed31SHadar Gat {
79a583ed31SHadar Gat iowrite32(val, (drvdata->cc_base + reg));
80a583ed31SHadar Gat }
cc_ioread(struct cctrng_drvdata * drvdata,u32 reg)81a583ed31SHadar Gat static inline u32 cc_ioread(struct cctrng_drvdata *drvdata, u32 reg)
82a583ed31SHadar Gat {
83a583ed31SHadar Gat return ioread32(drvdata->cc_base + reg);
84a583ed31SHadar Gat }
85a583ed31SHadar Gat
86a583ed31SHadar Gat
cc_trng_pm_get(struct device * dev)87a583ed31SHadar Gat static int cc_trng_pm_get(struct device *dev)
88a583ed31SHadar Gat {
89a583ed31SHadar Gat int rc = 0;
90a583ed31SHadar Gat
91a583ed31SHadar Gat rc = pm_runtime_get_sync(dev);
92a583ed31SHadar Gat
93a583ed31SHadar Gat /* pm_runtime_get_sync() can return 1 as a valid return code */
94a583ed31SHadar Gat return (rc == 1 ? 0 : rc);
95a583ed31SHadar Gat }
96a583ed31SHadar Gat
cc_trng_pm_put_suspend(struct device * dev)97a583ed31SHadar Gat static void cc_trng_pm_put_suspend(struct device *dev)
98a583ed31SHadar Gat {
99a583ed31SHadar Gat int rc = 0;
100a583ed31SHadar Gat
101a583ed31SHadar Gat pm_runtime_mark_last_busy(dev);
102a583ed31SHadar Gat rc = pm_runtime_put_autosuspend(dev);
103a583ed31SHadar Gat if (rc)
104a583ed31SHadar Gat dev_err(dev, "pm_runtime_put_autosuspend returned %x\n", rc);
105a583ed31SHadar Gat }
106a583ed31SHadar Gat
cc_trng_pm_init(struct cctrng_drvdata * drvdata)107a583ed31SHadar Gat static int cc_trng_pm_init(struct cctrng_drvdata *drvdata)
108a583ed31SHadar Gat {
109a583ed31SHadar Gat struct device *dev = &(drvdata->pdev->dev);
110a583ed31SHadar Gat
111a583ed31SHadar Gat /* must be before the enabling to avoid redundant suspending */
112a583ed31SHadar Gat pm_runtime_set_autosuspend_delay(dev, CC_TRNG_SUSPEND_TIMEOUT);
113a583ed31SHadar Gat pm_runtime_use_autosuspend(dev);
114a583ed31SHadar Gat /* set us as active - note we won't do PM ops until cc_trng_pm_go()! */
115a583ed31SHadar Gat return pm_runtime_set_active(dev);
116a583ed31SHadar Gat }
117a583ed31SHadar Gat
cc_trng_pm_go(struct cctrng_drvdata * drvdata)118a583ed31SHadar Gat static void cc_trng_pm_go(struct cctrng_drvdata *drvdata)
119a583ed31SHadar Gat {
120a583ed31SHadar Gat struct device *dev = &(drvdata->pdev->dev);
121a583ed31SHadar Gat
122a583ed31SHadar Gat /* enable the PM module*/
123a583ed31SHadar Gat pm_runtime_enable(dev);
124a583ed31SHadar Gat }
125a583ed31SHadar Gat
cc_trng_pm_fini(struct cctrng_drvdata * drvdata)126a583ed31SHadar Gat static void cc_trng_pm_fini(struct cctrng_drvdata *drvdata)
127a583ed31SHadar Gat {
128a583ed31SHadar Gat struct device *dev = &(drvdata->pdev->dev);
129a583ed31SHadar Gat
130a583ed31SHadar Gat pm_runtime_disable(dev);
131a583ed31SHadar Gat }
132a583ed31SHadar Gat
133a583ed31SHadar Gat
cc_trng_parse_sampling_ratio(struct cctrng_drvdata * drvdata)134a583ed31SHadar Gat static inline int cc_trng_parse_sampling_ratio(struct cctrng_drvdata *drvdata)
135a583ed31SHadar Gat {
136a583ed31SHadar Gat struct device *dev = &(drvdata->pdev->dev);
137a583ed31SHadar Gat struct device_node *np = drvdata->pdev->dev.of_node;
138a583ed31SHadar Gat int rc;
139a583ed31SHadar Gat int i;
140a583ed31SHadar Gat /* ret will be set to 0 if at least one rosc has (sampling ratio > 0) */
141a583ed31SHadar Gat int ret = -EINVAL;
142a583ed31SHadar Gat
143a583ed31SHadar Gat rc = of_property_read_u32_array(np, "arm,rosc-ratio",
144a583ed31SHadar Gat drvdata->smpl_ratio,
145a583ed31SHadar Gat CC_TRNG_NUM_OF_ROSCS);
146a583ed31SHadar Gat if (rc) {
147a583ed31SHadar Gat /* arm,rosc-ratio was not found in device tree */
148a583ed31SHadar Gat return rc;
149a583ed31SHadar Gat }
150a583ed31SHadar Gat
151a583ed31SHadar Gat /* verify that at least one rosc has (sampling ratio > 0) */
152a583ed31SHadar Gat for (i = 0; i < CC_TRNG_NUM_OF_ROSCS; ++i) {
153a583ed31SHadar Gat dev_dbg(dev, "rosc %d sampling ratio %u",
154a583ed31SHadar Gat i, drvdata->smpl_ratio[i]);
155a583ed31SHadar Gat
156a583ed31SHadar Gat if (drvdata->smpl_ratio[i] > 0)
157a583ed31SHadar Gat ret = 0;
158a583ed31SHadar Gat }
159a583ed31SHadar Gat
160a583ed31SHadar Gat return ret;
161a583ed31SHadar Gat }
162a583ed31SHadar Gat
cc_trng_change_rosc(struct cctrng_drvdata * drvdata)163a583ed31SHadar Gat static int cc_trng_change_rosc(struct cctrng_drvdata *drvdata)
164a583ed31SHadar Gat {
165a583ed31SHadar Gat struct device *dev = &(drvdata->pdev->dev);
166a583ed31SHadar Gat
167a583ed31SHadar Gat dev_dbg(dev, "cctrng change rosc (was %d)\n", drvdata->active_rosc);
168a583ed31SHadar Gat drvdata->active_rosc += 1;
169a583ed31SHadar Gat
170a583ed31SHadar Gat while (drvdata->active_rosc < CC_TRNG_NUM_OF_ROSCS) {
171a583ed31SHadar Gat if (drvdata->smpl_ratio[drvdata->active_rosc] > 0)
172a583ed31SHadar Gat return 0;
173a583ed31SHadar Gat
174a583ed31SHadar Gat drvdata->active_rosc += 1;
175a583ed31SHadar Gat }
176a583ed31SHadar Gat return -EINVAL;
177a583ed31SHadar Gat }
178a583ed31SHadar Gat
179a583ed31SHadar Gat
cc_trng_enable_rnd_source(struct cctrng_drvdata * drvdata)180a583ed31SHadar Gat static void cc_trng_enable_rnd_source(struct cctrng_drvdata *drvdata)
181a583ed31SHadar Gat {
182a583ed31SHadar Gat u32 max_cycles;
183a583ed31SHadar Gat
184a583ed31SHadar Gat /* Set watchdog threshold to maximal allowed time (in CPU cycles) */
185a583ed31SHadar Gat max_cycles = CCTRNG_TIMEOUT(drvdata->smpl_ratio[drvdata->active_rosc]);
186a583ed31SHadar Gat cc_iowrite(drvdata, CC_RNG_WATCHDOG_VAL_REG_OFFSET, max_cycles);
187a583ed31SHadar Gat
188a583ed31SHadar Gat /* enable the RND source */
189a583ed31SHadar Gat cc_iowrite(drvdata, CC_RND_SOURCE_ENABLE_REG_OFFSET, 0x1);
190a583ed31SHadar Gat
191a583ed31SHadar Gat /* unmask RNG interrupts */
192a583ed31SHadar Gat cc_iowrite(drvdata, CC_RNG_IMR_REG_OFFSET, (u32)~CC_RNG_INT_MASK);
193a583ed31SHadar Gat }
194a583ed31SHadar Gat
195a583ed31SHadar Gat
196a583ed31SHadar Gat /* increase circular data buffer index (head/tail) */
circ_idx_inc(int * idx,int bytes)197a583ed31SHadar Gat static inline void circ_idx_inc(int *idx, int bytes)
198a583ed31SHadar Gat {
199a583ed31SHadar Gat *idx += (bytes + 3) >> 2;
200a583ed31SHadar Gat *idx &= (CCTRNG_DATA_BUF_WORDS - 1);
201a583ed31SHadar Gat }
202a583ed31SHadar Gat
circ_buf_space(struct cctrng_drvdata * drvdata)203a583ed31SHadar Gat static inline size_t circ_buf_space(struct cctrng_drvdata *drvdata)
204a583ed31SHadar Gat {
205a583ed31SHadar Gat return CIRC_SPACE(drvdata->circ.head,
206a583ed31SHadar Gat drvdata->circ.tail, CCTRNG_DATA_BUF_WORDS);
207a583ed31SHadar Gat
208a583ed31SHadar Gat }
209a583ed31SHadar Gat
cctrng_read(struct hwrng * rng,void * data,size_t max,bool wait)210a583ed31SHadar Gat static int cctrng_read(struct hwrng *rng, void *data, size_t max, bool wait)
211a583ed31SHadar Gat {
212a583ed31SHadar Gat /* current implementation ignores "wait" */
213a583ed31SHadar Gat
214a583ed31SHadar Gat struct cctrng_drvdata *drvdata = (struct cctrng_drvdata *)rng->priv;
215a583ed31SHadar Gat struct device *dev = &(drvdata->pdev->dev);
216a583ed31SHadar Gat u32 *buf = (u32 *)drvdata->circ.buf;
217a583ed31SHadar Gat size_t copied = 0;
218a583ed31SHadar Gat size_t cnt_w;
219a583ed31SHadar Gat size_t size;
220a583ed31SHadar Gat size_t left;
221a583ed31SHadar Gat
222a583ed31SHadar Gat if (!spin_trylock(&drvdata->read_lock)) {
223a583ed31SHadar Gat /* concurrent consumers from data_buf cannot be served */
224a583ed31SHadar Gat dev_dbg_ratelimited(dev, "unable to hold lock\n");
225a583ed31SHadar Gat return 0;
226a583ed31SHadar Gat }
227a583ed31SHadar Gat
228a583ed31SHadar Gat /* copy till end of data buffer (without wrap back) */
229a583ed31SHadar Gat cnt_w = CIRC_CNT_TO_END(drvdata->circ.head,
230a583ed31SHadar Gat drvdata->circ.tail, CCTRNG_DATA_BUF_WORDS);
231a583ed31SHadar Gat size = min((cnt_w<<2), max);
232a583ed31SHadar Gat memcpy(data, &(buf[drvdata->circ.tail]), size);
233a583ed31SHadar Gat copied = size;
234a583ed31SHadar Gat circ_idx_inc(&drvdata->circ.tail, size);
235a583ed31SHadar Gat /* copy rest of data in data buffer */
236a583ed31SHadar Gat left = max - copied;
237a583ed31SHadar Gat if (left > 0) {
238a583ed31SHadar Gat cnt_w = CIRC_CNT(drvdata->circ.head,
239a583ed31SHadar Gat drvdata->circ.tail, CCTRNG_DATA_BUF_WORDS);
240a583ed31SHadar Gat size = min((cnt_w<<2), left);
241a583ed31SHadar Gat memcpy(data, &(buf[drvdata->circ.tail]), size);
242a583ed31SHadar Gat copied += size;
243a583ed31SHadar Gat circ_idx_inc(&drvdata->circ.tail, size);
244a583ed31SHadar Gat }
245a583ed31SHadar Gat
246a583ed31SHadar Gat spin_unlock(&drvdata->read_lock);
247a583ed31SHadar Gat
248a583ed31SHadar Gat if (circ_buf_space(drvdata) >= CC_TRNG_EHR_IN_WORDS) {
249a583ed31SHadar Gat if (atomic_cmpxchg(&drvdata->pending_hw, 0, 1) == 0) {
250a583ed31SHadar Gat /* re-check space in buffer to avoid potential race */
251a583ed31SHadar Gat if (circ_buf_space(drvdata) >= CC_TRNG_EHR_IN_WORDS) {
252a583ed31SHadar Gat /* increment device's usage counter */
253a583ed31SHadar Gat int rc = cc_trng_pm_get(dev);
254a583ed31SHadar Gat
255a583ed31SHadar Gat if (rc) {
256a583ed31SHadar Gat dev_err(dev,
257a583ed31SHadar Gat "cc_trng_pm_get returned %x\n",
258a583ed31SHadar Gat rc);
259a583ed31SHadar Gat return rc;
260a583ed31SHadar Gat }
261a583ed31SHadar Gat
262a583ed31SHadar Gat /* schedule execution of deferred work handler
263a583ed31SHadar Gat * for filling of data buffer
264a583ed31SHadar Gat */
265a583ed31SHadar Gat schedule_work(&drvdata->startwork);
266a583ed31SHadar Gat } else {
267a583ed31SHadar Gat atomic_set(&drvdata->pending_hw, 0);
268a583ed31SHadar Gat }
269a583ed31SHadar Gat }
270a583ed31SHadar Gat }
271a583ed31SHadar Gat
272a583ed31SHadar Gat return copied;
273a583ed31SHadar Gat }
274a583ed31SHadar Gat
cc_trng_hw_trigger(struct cctrng_drvdata * drvdata)275a583ed31SHadar Gat static void cc_trng_hw_trigger(struct cctrng_drvdata *drvdata)
276a583ed31SHadar Gat {
277a583ed31SHadar Gat u32 tmp_smpl_cnt = 0;
278a583ed31SHadar Gat struct device *dev = &(drvdata->pdev->dev);
279a583ed31SHadar Gat
280a583ed31SHadar Gat dev_dbg(dev, "cctrng hw trigger.\n");
281a583ed31SHadar Gat
282a583ed31SHadar Gat /* enable the HW RND clock */
283a583ed31SHadar Gat cc_iowrite(drvdata, CC_RNG_CLK_ENABLE_REG_OFFSET, 0x1);
284a583ed31SHadar Gat
285a583ed31SHadar Gat /* do software reset */
286a583ed31SHadar Gat cc_iowrite(drvdata, CC_RNG_SW_RESET_REG_OFFSET, 0x1);
287a583ed31SHadar Gat /* in order to verify that the reset has completed,
288a583ed31SHadar Gat * the sample count need to be verified
289a583ed31SHadar Gat */
290a583ed31SHadar Gat do {
291a583ed31SHadar Gat /* enable the HW RND clock */
292a583ed31SHadar Gat cc_iowrite(drvdata, CC_RNG_CLK_ENABLE_REG_OFFSET, 0x1);
293a583ed31SHadar Gat
294a583ed31SHadar Gat /* set sampling ratio (rng_clocks) between consecutive bits */
295a583ed31SHadar Gat cc_iowrite(drvdata, CC_SAMPLE_CNT1_REG_OFFSET,
296a583ed31SHadar Gat drvdata->smpl_ratio[drvdata->active_rosc]);
297a583ed31SHadar Gat
298a583ed31SHadar Gat /* read the sampling ratio */
299a583ed31SHadar Gat tmp_smpl_cnt = cc_ioread(drvdata, CC_SAMPLE_CNT1_REG_OFFSET);
300a583ed31SHadar Gat
301a583ed31SHadar Gat } while (tmp_smpl_cnt != drvdata->smpl_ratio[drvdata->active_rosc]);
302a583ed31SHadar Gat
303a583ed31SHadar Gat /* disable the RND source for setting new parameters in HW */
304a583ed31SHadar Gat cc_iowrite(drvdata, CC_RND_SOURCE_ENABLE_REG_OFFSET, 0);
305a583ed31SHadar Gat
306a583ed31SHadar Gat cc_iowrite(drvdata, CC_RNG_ICR_REG_OFFSET, 0xFFFFFFFF);
307a583ed31SHadar Gat
308a583ed31SHadar Gat cc_iowrite(drvdata, CC_TRNG_CONFIG_REG_OFFSET, drvdata->active_rosc);
309a583ed31SHadar Gat
310a583ed31SHadar Gat /* Debug Control register: set to 0 - no bypasses */
311a583ed31SHadar Gat cc_iowrite(drvdata, CC_TRNG_DEBUG_CONTROL_REG_OFFSET, 0);
312a583ed31SHadar Gat
313a583ed31SHadar Gat cc_trng_enable_rnd_source(drvdata);
314a583ed31SHadar Gat }
315a583ed31SHadar Gat
cc_trng_compwork_handler(struct work_struct * w)31643f3c2b4SZou Wei static void cc_trng_compwork_handler(struct work_struct *w)
317a583ed31SHadar Gat {
318a583ed31SHadar Gat u32 isr = 0;
319a583ed31SHadar Gat u32 ehr_valid = 0;
320a583ed31SHadar Gat struct cctrng_drvdata *drvdata =
321a583ed31SHadar Gat container_of(w, struct cctrng_drvdata, compwork);
322a583ed31SHadar Gat struct device *dev = &(drvdata->pdev->dev);
323a583ed31SHadar Gat int i;
324a583ed31SHadar Gat
325a583ed31SHadar Gat /* stop DMA and the RNG source */
326a583ed31SHadar Gat cc_iowrite(drvdata, CC_RNG_DMA_ENABLE_REG_OFFSET, 0);
327a583ed31SHadar Gat cc_iowrite(drvdata, CC_RND_SOURCE_ENABLE_REG_OFFSET, 0);
328a583ed31SHadar Gat
329a583ed31SHadar Gat /* read RNG_ISR and check for errors */
330a583ed31SHadar Gat isr = cc_ioread(drvdata, CC_RNG_ISR_REG_OFFSET);
331a583ed31SHadar Gat ehr_valid = CC_REG_FLD_GET(RNG_ISR, EHR_VALID, isr);
332a583ed31SHadar Gat dev_dbg(dev, "Got RNG_ISR=0x%08X (EHR_VALID=%u)\n", isr, ehr_valid);
333a583ed31SHadar Gat
334b2d7e8bcSHerbert Xu if (fips_enabled && CC_REG_FLD_GET(RNG_ISR, CRNGT_ERR, isr)) {
335a583ed31SHadar Gat fips_fail_notify();
336a583ed31SHadar Gat /* FIPS error is fatal */
337a583ed31SHadar Gat panic("Got HW CRNGT error while fips is enabled!\n");
338a583ed31SHadar Gat }
339a583ed31SHadar Gat
340a583ed31SHadar Gat /* Clear all pending RNG interrupts */
341a583ed31SHadar Gat cc_iowrite(drvdata, CC_RNG_ICR_REG_OFFSET, isr);
342a583ed31SHadar Gat
343a583ed31SHadar Gat
344a583ed31SHadar Gat if (!ehr_valid) {
345a583ed31SHadar Gat /* in case of AUTOCORR/TIMEOUT error, try the next ROSC */
346a583ed31SHadar Gat if (CC_REG_FLD_GET(RNG_ISR, AUTOCORR_ERR, isr) ||
347a583ed31SHadar Gat CC_REG_FLD_GET(RNG_ISR, WATCHDOG, isr)) {
348a583ed31SHadar Gat dev_dbg(dev, "cctrng autocorr/timeout error.\n");
349a583ed31SHadar Gat goto next_rosc;
350a583ed31SHadar Gat }
351a583ed31SHadar Gat
352a583ed31SHadar Gat /* in case of VN error, ignore it */
353a583ed31SHadar Gat }
354a583ed31SHadar Gat
355a583ed31SHadar Gat /* read EHR data from registers */
356a583ed31SHadar Gat for (i = 0; i < CC_TRNG_EHR_IN_WORDS; i++) {
357a583ed31SHadar Gat /* calc word ptr in data_buf */
358a583ed31SHadar Gat u32 *buf = (u32 *)drvdata->circ.buf;
359a583ed31SHadar Gat
360a583ed31SHadar Gat buf[drvdata->circ.head] = cc_ioread(drvdata,
361a583ed31SHadar Gat CC_EHR_DATA_0_REG_OFFSET + (i*sizeof(u32)));
362a583ed31SHadar Gat
363a583ed31SHadar Gat /* EHR_DATA registers are cleared on read. In case 0 value was
364a583ed31SHadar Gat * returned, restart the entropy collection.
365a583ed31SHadar Gat */
366a583ed31SHadar Gat if (buf[drvdata->circ.head] == 0) {
367a583ed31SHadar Gat dev_dbg(dev, "Got 0 value in EHR. active_rosc %u\n",
368a583ed31SHadar Gat drvdata->active_rosc);
369a583ed31SHadar Gat goto next_rosc;
370a583ed31SHadar Gat }
371a583ed31SHadar Gat
372a583ed31SHadar Gat circ_idx_inc(&drvdata->circ.head, 1<<2);
373a583ed31SHadar Gat }
374a583ed31SHadar Gat
375a583ed31SHadar Gat atomic_set(&drvdata->pending_hw, 0);
376a583ed31SHadar Gat
377a583ed31SHadar Gat /* continue to fill data buffer if needed */
378a583ed31SHadar Gat if (circ_buf_space(drvdata) >= CC_TRNG_EHR_IN_WORDS) {
379a583ed31SHadar Gat if (atomic_cmpxchg(&drvdata->pending_hw, 0, 1) == 0) {
380a583ed31SHadar Gat /* Re-enable rnd source */
381a583ed31SHadar Gat cc_trng_enable_rnd_source(drvdata);
382a583ed31SHadar Gat return;
383a583ed31SHadar Gat }
384a583ed31SHadar Gat }
385a583ed31SHadar Gat
386a583ed31SHadar Gat cc_trng_pm_put_suspend(dev);
387a583ed31SHadar Gat
388a583ed31SHadar Gat dev_dbg(dev, "compwork handler done\n");
389a583ed31SHadar Gat return;
390a583ed31SHadar Gat
391a583ed31SHadar Gat next_rosc:
392a583ed31SHadar Gat if ((circ_buf_space(drvdata) >= CC_TRNG_EHR_IN_WORDS) &&
393a583ed31SHadar Gat (cc_trng_change_rosc(drvdata) == 0)) {
394a583ed31SHadar Gat /* trigger trng hw with next rosc */
395a583ed31SHadar Gat cc_trng_hw_trigger(drvdata);
396a583ed31SHadar Gat } else {
397a583ed31SHadar Gat atomic_set(&drvdata->pending_hw, 0);
398a583ed31SHadar Gat cc_trng_pm_put_suspend(dev);
399a583ed31SHadar Gat }
400a583ed31SHadar Gat }
401a583ed31SHadar Gat
cc_isr(int irq,void * dev_id)402a583ed31SHadar Gat static irqreturn_t cc_isr(int irq, void *dev_id)
403a583ed31SHadar Gat {
404a583ed31SHadar Gat struct cctrng_drvdata *drvdata = (struct cctrng_drvdata *)dev_id;
405a583ed31SHadar Gat struct device *dev = &(drvdata->pdev->dev);
406a583ed31SHadar Gat u32 irr;
407a583ed31SHadar Gat
408a583ed31SHadar Gat /* if driver suspended return, probably shared interrupt */
409a583ed31SHadar Gat if (pm_runtime_suspended(dev))
410a583ed31SHadar Gat return IRQ_NONE;
411a583ed31SHadar Gat
412a583ed31SHadar Gat /* read the interrupt status */
413a583ed31SHadar Gat irr = cc_ioread(drvdata, CC_HOST_RGF_IRR_REG_OFFSET);
414a583ed31SHadar Gat dev_dbg(dev, "Got IRR=0x%08X\n", irr);
415a583ed31SHadar Gat
416a583ed31SHadar Gat if (irr == 0) /* Probably shared interrupt line */
417a583ed31SHadar Gat return IRQ_NONE;
418a583ed31SHadar Gat
419a583ed31SHadar Gat /* clear interrupt - must be before processing events */
420a583ed31SHadar Gat cc_iowrite(drvdata, CC_HOST_RGF_ICR_REG_OFFSET, irr);
421a583ed31SHadar Gat
422a583ed31SHadar Gat /* RNG interrupt - most probable */
423a583ed31SHadar Gat if (irr & CC_HOST_RNG_IRQ_MASK) {
424a583ed31SHadar Gat /* Mask RNG interrupts - will be unmasked in deferred work */
425a583ed31SHadar Gat cc_iowrite(drvdata, CC_RNG_IMR_REG_OFFSET, 0xFFFFFFFF);
426a583ed31SHadar Gat
427a583ed31SHadar Gat /* We clear RNG interrupt here,
428a583ed31SHadar Gat * to avoid it from firing as we'll unmask RNG interrupts.
429a583ed31SHadar Gat */
430a583ed31SHadar Gat cc_iowrite(drvdata, CC_HOST_RGF_ICR_REG_OFFSET,
431a583ed31SHadar Gat CC_HOST_RNG_IRQ_MASK);
432a583ed31SHadar Gat
433a583ed31SHadar Gat irr &= ~CC_HOST_RNG_IRQ_MASK;
434a583ed31SHadar Gat
435a583ed31SHadar Gat /* schedule execution of deferred work handler */
436a583ed31SHadar Gat schedule_work(&drvdata->compwork);
437a583ed31SHadar Gat }
438a583ed31SHadar Gat
439a583ed31SHadar Gat if (irr) {
440a583ed31SHadar Gat dev_dbg_ratelimited(dev,
441a583ed31SHadar Gat "IRR includes unknown cause bits (0x%08X)\n",
442a583ed31SHadar Gat irr);
443a583ed31SHadar Gat /* Just warning */
444a583ed31SHadar Gat }
445a583ed31SHadar Gat
446a583ed31SHadar Gat return IRQ_HANDLED;
447a583ed31SHadar Gat }
448a583ed31SHadar Gat
cc_trng_startwork_handler(struct work_struct * w)44943f3c2b4SZou Wei static void cc_trng_startwork_handler(struct work_struct *w)
450a583ed31SHadar Gat {
451a583ed31SHadar Gat struct cctrng_drvdata *drvdata =
452a583ed31SHadar Gat container_of(w, struct cctrng_drvdata, startwork);
453a583ed31SHadar Gat
454a583ed31SHadar Gat drvdata->active_rosc = 0;
455a583ed31SHadar Gat cc_trng_hw_trigger(drvdata);
456a583ed31SHadar Gat }
457a583ed31SHadar Gat
cctrng_probe(struct platform_device * pdev)458a583ed31SHadar Gat static int cctrng_probe(struct platform_device *pdev)
459a583ed31SHadar Gat {
460a583ed31SHadar Gat struct cctrng_drvdata *drvdata;
461a583ed31SHadar Gat struct device *dev = &pdev->dev;
462a583ed31SHadar Gat int rc = 0;
463a583ed31SHadar Gat u32 val;
464a583ed31SHadar Gat int irq;
465a583ed31SHadar Gat
46680e40feaSMartin Kaiser /* Compile time assertion checks */
46780e40feaSMartin Kaiser BUILD_BUG_ON(CCTRNG_DATA_BUF_WORDS < 6);
46880e40feaSMartin Kaiser BUILD_BUG_ON((CCTRNG_DATA_BUF_WORDS & (CCTRNG_DATA_BUF_WORDS-1)) != 0);
46980e40feaSMartin Kaiser
470a583ed31SHadar Gat drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
471a583ed31SHadar Gat if (!drvdata)
472a583ed31SHadar Gat return -ENOMEM;
473a583ed31SHadar Gat
474a583ed31SHadar Gat drvdata->rng.name = devm_kstrdup(dev, dev_name(dev), GFP_KERNEL);
475a583ed31SHadar Gat if (!drvdata->rng.name)
476a583ed31SHadar Gat return -ENOMEM;
477a583ed31SHadar Gat
478a583ed31SHadar Gat drvdata->rng.read = cctrng_read;
479a583ed31SHadar Gat drvdata->rng.priv = (unsigned long)drvdata;
480a583ed31SHadar Gat drvdata->rng.quality = CC_TRNG_QUALITY;
481a583ed31SHadar Gat
482a583ed31SHadar Gat platform_set_drvdata(pdev, drvdata);
483a583ed31SHadar Gat drvdata->pdev = pdev;
484a583ed31SHadar Gat
485a583ed31SHadar Gat drvdata->circ.buf = (char *)drvdata->data_buf;
486a583ed31SHadar Gat
487f50281dfSTian Tao drvdata->cc_base = devm_platform_ioremap_resource(pdev, 0);
4889553ae34SMartin Kaiser if (IS_ERR(drvdata->cc_base))
4899553ae34SMartin Kaiser return dev_err_probe(dev, PTR_ERR(drvdata->cc_base), "Failed to ioremap registers");
490a583ed31SHadar Gat
491a583ed31SHadar Gat /* Then IRQ */
492a583ed31SHadar Gat irq = platform_get_irq(pdev, 0);
493befb1ddaSWang Qing if (irq < 0)
494a583ed31SHadar Gat return irq;
495a583ed31SHadar Gat
496a583ed31SHadar Gat /* parse sampling rate from device tree */
497a583ed31SHadar Gat rc = cc_trng_parse_sampling_ratio(drvdata);
4989553ae34SMartin Kaiser if (rc)
4999553ae34SMartin Kaiser return dev_err_probe(dev, rc, "Failed to get legal sampling ratio for rosc\n");
500a583ed31SHadar Gat
50180a34c03SMartin Kaiser drvdata->clk = devm_clk_get_optional_enabled(dev, NULL);
50280a34c03SMartin Kaiser if (IS_ERR(drvdata->clk))
50380a34c03SMartin Kaiser return dev_err_probe(dev, PTR_ERR(drvdata->clk),
50480a34c03SMartin Kaiser "Failed to get or enable the clock\n");
505a583ed31SHadar Gat
506a583ed31SHadar Gat INIT_WORK(&drvdata->compwork, cc_trng_compwork_handler);
507a583ed31SHadar Gat INIT_WORK(&drvdata->startwork, cc_trng_startwork_handler);
508a583ed31SHadar Gat spin_lock_init(&drvdata->read_lock);
509a583ed31SHadar Gat
510a583ed31SHadar Gat /* register the driver isr function */
511a583ed31SHadar Gat rc = devm_request_irq(dev, irq, cc_isr, IRQF_SHARED, "cctrng", drvdata);
5129553ae34SMartin Kaiser if (rc)
5139553ae34SMartin Kaiser return dev_err_probe(dev, rc, "Could not register to interrupt %d\n", irq);
514a583ed31SHadar Gat dev_dbg(dev, "Registered to IRQ: %d\n", irq);
515a583ed31SHadar Gat
516a583ed31SHadar Gat /* Clear all pending interrupts */
517a583ed31SHadar Gat val = cc_ioread(drvdata, CC_HOST_RGF_IRR_REG_OFFSET);
518a583ed31SHadar Gat dev_dbg(dev, "IRR=0x%08X\n", val);
519a583ed31SHadar Gat cc_iowrite(drvdata, CC_HOST_RGF_ICR_REG_OFFSET, val);
520a583ed31SHadar Gat
521a583ed31SHadar Gat /* unmask HOST RNG interrupt */
522a583ed31SHadar Gat cc_iowrite(drvdata, CC_HOST_RGF_IMR_REG_OFFSET,
523a583ed31SHadar Gat cc_ioread(drvdata, CC_HOST_RGF_IMR_REG_OFFSET) &
524a583ed31SHadar Gat ~CC_HOST_RNG_IRQ_MASK);
525a583ed31SHadar Gat
526a583ed31SHadar Gat /* init PM */
527a583ed31SHadar Gat rc = cc_trng_pm_init(drvdata);
5289553ae34SMartin Kaiser if (rc)
5299553ae34SMartin Kaiser return dev_err_probe(dev, rc, "cc_trng_pm_init failed\n");
530a583ed31SHadar Gat
531a583ed31SHadar Gat /* increment device's usage counter */
532a583ed31SHadar Gat rc = cc_trng_pm_get(dev);
5339553ae34SMartin Kaiser if (rc)
5349553ae34SMartin Kaiser return dev_err_probe(dev, rc, "cc_trng_pm_get returned %x\n", rc);
535a583ed31SHadar Gat
536a583ed31SHadar Gat /* set pending_hw to verify that HW won't be triggered from read */
537a583ed31SHadar Gat atomic_set(&drvdata->pending_hw, 1);
538a583ed31SHadar Gat
539a583ed31SHadar Gat /* registration of the hwrng device */
540ae835128STian Tao rc = devm_hwrng_register(dev, &drvdata->rng);
541a583ed31SHadar Gat if (rc) {
542a583ed31SHadar Gat dev_err(dev, "Could not register hwrng device.\n");
543a583ed31SHadar Gat goto post_pm_err;
544a583ed31SHadar Gat }
545a583ed31SHadar Gat
546a583ed31SHadar Gat /* trigger HW to start generate data */
547a583ed31SHadar Gat drvdata->active_rosc = 0;
548a583ed31SHadar Gat cc_trng_hw_trigger(drvdata);
549a583ed31SHadar Gat
550a583ed31SHadar Gat /* All set, we can allow auto-suspend */
551a583ed31SHadar Gat cc_trng_pm_go(drvdata);
552a583ed31SHadar Gat
553a583ed31SHadar Gat dev_info(dev, "ARM cctrng device initialized\n");
554a583ed31SHadar Gat
555a583ed31SHadar Gat return 0;
556a583ed31SHadar Gat
557a583ed31SHadar Gat post_pm_err:
558a583ed31SHadar Gat cc_trng_pm_fini(drvdata);
559a583ed31SHadar Gat
560a583ed31SHadar Gat return rc;
561a583ed31SHadar Gat }
562a583ed31SHadar Gat
cctrng_remove(struct platform_device * pdev)563a583ed31SHadar Gat static int cctrng_remove(struct platform_device *pdev)
564a583ed31SHadar Gat {
565a583ed31SHadar Gat struct cctrng_drvdata *drvdata = platform_get_drvdata(pdev);
566a583ed31SHadar Gat struct device *dev = &pdev->dev;
567a583ed31SHadar Gat
568a583ed31SHadar Gat dev_dbg(dev, "Releasing cctrng resources...\n");
569a583ed31SHadar Gat
570a583ed31SHadar Gat cc_trng_pm_fini(drvdata);
571a583ed31SHadar Gat
572a583ed31SHadar Gat dev_info(dev, "ARM cctrng device terminated\n");
573a583ed31SHadar Gat
574a583ed31SHadar Gat return 0;
575a583ed31SHadar Gat }
576a583ed31SHadar Gat
cctrng_suspend(struct device * dev)577a583ed31SHadar Gat static int __maybe_unused cctrng_suspend(struct device *dev)
578a583ed31SHadar Gat {
579a583ed31SHadar Gat struct cctrng_drvdata *drvdata = dev_get_drvdata(dev);
580a583ed31SHadar Gat
581a583ed31SHadar Gat dev_dbg(dev, "set HOST_POWER_DOWN_EN\n");
582a583ed31SHadar Gat cc_iowrite(drvdata, CC_HOST_POWER_DOWN_EN_REG_OFFSET,
583a583ed31SHadar Gat POWER_DOWN_ENABLE);
584a583ed31SHadar Gat
585a583ed31SHadar Gat clk_disable_unprepare(drvdata->clk);
586a583ed31SHadar Gat
587a583ed31SHadar Gat return 0;
588a583ed31SHadar Gat }
589a583ed31SHadar Gat
cctrng_wait_for_reset_completion(struct cctrng_drvdata * drvdata)590a583ed31SHadar Gat static bool cctrng_wait_for_reset_completion(struct cctrng_drvdata *drvdata)
591a583ed31SHadar Gat {
592a583ed31SHadar Gat unsigned int val;
593a583ed31SHadar Gat unsigned int i;
594a583ed31SHadar Gat
595a583ed31SHadar Gat for (i = 0; i < CC_HW_RESET_LOOP_COUNT; i++) {
596a583ed31SHadar Gat /* in cc7x3 NVM_IS_IDLE indicates that CC reset is
597a583ed31SHadar Gat * completed and device is fully functional
598a583ed31SHadar Gat */
599a583ed31SHadar Gat val = cc_ioread(drvdata, CC_NVM_IS_IDLE_REG_OFFSET);
600a583ed31SHadar Gat if (val & BIT(CC_NVM_IS_IDLE_VALUE_BIT_SHIFT)) {
601a583ed31SHadar Gat /* hw indicate reset completed */
602a583ed31SHadar Gat return true;
603a583ed31SHadar Gat }
604a583ed31SHadar Gat /* allow scheduling other process on the processor */
605a583ed31SHadar Gat schedule();
606a583ed31SHadar Gat }
607a583ed31SHadar Gat /* reset not completed */
608a583ed31SHadar Gat return false;
609a583ed31SHadar Gat }
610a583ed31SHadar Gat
cctrng_resume(struct device * dev)611a583ed31SHadar Gat static int __maybe_unused cctrng_resume(struct device *dev)
612a583ed31SHadar Gat {
613a583ed31SHadar Gat struct cctrng_drvdata *drvdata = dev_get_drvdata(dev);
614a583ed31SHadar Gat int rc;
615a583ed31SHadar Gat
616a583ed31SHadar Gat dev_dbg(dev, "unset HOST_POWER_DOWN_EN\n");
617a583ed31SHadar Gat /* Enables the device source clk */
618a583ed31SHadar Gat rc = clk_prepare_enable(drvdata->clk);
619a583ed31SHadar Gat if (rc) {
620a583ed31SHadar Gat dev_err(dev, "failed getting clock back on. We're toast.\n");
621a583ed31SHadar Gat return rc;
622a583ed31SHadar Gat }
623a583ed31SHadar Gat
624a583ed31SHadar Gat /* wait for Cryptocell reset completion */
625a583ed31SHadar Gat if (!cctrng_wait_for_reset_completion(drvdata)) {
626a583ed31SHadar Gat dev_err(dev, "Cryptocell reset not completed");
627*1b4089d5SGaosheng Cui clk_disable_unprepare(drvdata->clk);
628a583ed31SHadar Gat return -EBUSY;
629a583ed31SHadar Gat }
630a583ed31SHadar Gat
631a583ed31SHadar Gat /* unmask HOST RNG interrupt */
632a583ed31SHadar Gat cc_iowrite(drvdata, CC_HOST_RGF_IMR_REG_OFFSET,
633a583ed31SHadar Gat cc_ioread(drvdata, CC_HOST_RGF_IMR_REG_OFFSET) &
634a583ed31SHadar Gat ~CC_HOST_RNG_IRQ_MASK);
635a583ed31SHadar Gat
636a583ed31SHadar Gat cc_iowrite(drvdata, CC_HOST_POWER_DOWN_EN_REG_OFFSET,
637a583ed31SHadar Gat POWER_DOWN_DISABLE);
638a583ed31SHadar Gat
639a583ed31SHadar Gat return 0;
640a583ed31SHadar Gat }
641a583ed31SHadar Gat
642a583ed31SHadar Gat static UNIVERSAL_DEV_PM_OPS(cctrng_pm, cctrng_suspend, cctrng_resume, NULL);
643a583ed31SHadar Gat
644a583ed31SHadar Gat static const struct of_device_id arm_cctrng_dt_match[] = {
645a583ed31SHadar Gat { .compatible = "arm,cryptocell-713-trng", },
646a583ed31SHadar Gat { .compatible = "arm,cryptocell-703-trng", },
647a583ed31SHadar Gat {},
648a583ed31SHadar Gat };
649a583ed31SHadar Gat MODULE_DEVICE_TABLE(of, arm_cctrng_dt_match);
650a583ed31SHadar Gat
651a583ed31SHadar Gat static struct platform_driver cctrng_driver = {
652a583ed31SHadar Gat .driver = {
653a583ed31SHadar Gat .name = "cctrng",
654a583ed31SHadar Gat .of_match_table = arm_cctrng_dt_match,
655a583ed31SHadar Gat .pm = &cctrng_pm,
656a583ed31SHadar Gat },
657a583ed31SHadar Gat .probe = cctrng_probe,
658a583ed31SHadar Gat .remove = cctrng_remove,
659a583ed31SHadar Gat };
660a583ed31SHadar Gat
66180e40feaSMartin Kaiser module_platform_driver(cctrng_driver);
662a583ed31SHadar Gat
663a583ed31SHadar Gat /* Module description */
664a583ed31SHadar Gat MODULE_DESCRIPTION("ARM CryptoCell TRNG Driver");
665a583ed31SHadar Gat MODULE_AUTHOR("ARM");
666a583ed31SHadar Gat MODULE_LICENSE("GPL v2");
667