2 * CAAM/SEC 4.x transport/backend driver
3 * JobR backend functionality
5 * Copyright 2008-2012 Freescale Semiconductor, Inc.
8 #include <linux/of_irq.h>
9 #include <linux/of_address.h>
18 struct jr_driver_data
{
19 /* List of Physical JobR's with the Driver */
20 struct list_head jr_list
;
21 spinlock_t jr_alloc_lock
; /* jr_list lock */
22 } ____cacheline_aligned
;
24 static struct jr_driver_data driver_data
;
26 static int caam_reset_hw_jr(struct device
*dev
)
28 struct caam_drv_private_jr
*jrp
= dev_get_drvdata(dev
);
29 unsigned int timeout
= 100000;
32 * mask interrupts since we are going to poll
33 * for reset completion status
35 clrsetbits_32(&jrp
->rregs
->rconfig_lo
, 0, JRCFG_IMSK
);
37 /* initiate flush (required prior to reset) */
38 wr_reg32(&jrp
->rregs
->jrcommand
, JRCR_RESET
);
39 while (((rd_reg32(&jrp
->rregs
->jrintstatus
) & JRINT_ERR_HALT_MASK
) ==
40 JRINT_ERR_HALT_INPROGRESS
) && --timeout
)
43 if ((rd_reg32(&jrp
->rregs
->jrintstatus
) & JRINT_ERR_HALT_MASK
) !=
44 JRINT_ERR_HALT_COMPLETE
|| timeout
== 0) {
45 dev_err(dev
, "failed to flush job ring %d\n", jrp
->ridx
);
51 wr_reg32(&jrp
->rregs
->jrcommand
, JRCR_RESET
);
52 while ((rd_reg32(&jrp
->rregs
->jrcommand
) & JRCR_RESET
) && --timeout
)
56 dev_err(dev
, "failed to reset job ring %d\n", jrp
->ridx
);
60 /* unmask interrupts */
61 clrsetbits_32(&jrp
->rregs
->rconfig_lo
, JRCFG_IMSK
, 0);
67 * Shutdown JobR independent of platform property code
69 static int caam_jr_shutdown(struct device
*dev
)
71 struct caam_drv_private_jr
*jrp
= dev_get_drvdata(dev
);
72 dma_addr_t inpbusaddr
, outbusaddr
;
75 ret
= caam_reset_hw_jr(dev
);
77 tasklet_kill(&jrp
->irqtask
);
79 /* Release interrupt */
80 free_irq(jrp
->irq
, dev
);
83 inpbusaddr
= rd_reg64(&jrp
->rregs
->inpring_base
);
84 outbusaddr
= rd_reg64(&jrp
->rregs
->outring_base
);
85 dma_free_coherent(dev
, sizeof(dma_addr_t
) * JOBR_DEPTH
,
86 jrp
->inpring
, inpbusaddr
);
87 dma_free_coherent(dev
, sizeof(struct jr_outentry
) * JOBR_DEPTH
,
88 jrp
->outring
, outbusaddr
);
94 static int caam_jr_remove(struct platform_device
*pdev
)
98 struct caam_drv_private_jr
*jrpriv
;
101 jrpriv
= dev_get_drvdata(jrdev
);
104 * Return EBUSY if job ring already allocated.
106 if (atomic_read(&jrpriv
->tfm_count
)) {
107 dev_err(jrdev
, "Device is busy\n");
111 /* Remove the node from Physical JobR list maintained by driver */
112 spin_lock(&driver_data
.jr_alloc_lock
);
113 list_del(&jrpriv
->list_node
);
114 spin_unlock(&driver_data
.jr_alloc_lock
);
117 ret
= caam_jr_shutdown(jrdev
);
119 dev_err(jrdev
, "Failed to shut down job ring\n");
120 irq_dispose_mapping(jrpriv
->irq
);
125 /* Main per-ring interrupt handler */
126 static irqreturn_t
caam_jr_interrupt(int irq
, void *st_dev
)
128 struct device
*dev
= st_dev
;
129 struct caam_drv_private_jr
*jrp
= dev_get_drvdata(dev
);
133 * Check the output ring for ready responses, kick
134 * tasklet if jobs done.
136 irqstate
= rd_reg32(&jrp
->rregs
->jrintstatus
);
141 * If JobR error, we got more development work to do
142 * Flag a bug now, but we really need to shut down and
143 * restart the queue (and fix code).
145 if (irqstate
& JRINT_JR_ERROR
) {
146 dev_err(dev
, "job ring error: irqstate: %08x\n", irqstate
);
150 /* mask valid interrupts */
151 clrsetbits_32(&jrp
->rregs
->rconfig_lo
, 0, JRCFG_IMSK
);
153 /* Have valid interrupt at this point, just ACK and trigger */
154 wr_reg32(&jrp
->rregs
->jrintstatus
, irqstate
);
157 tasklet_schedule(&jrp
->irqtask
);
163 /* Deferred service handler, run as interrupt-fired tasklet */
164 static void caam_jr_dequeue(unsigned long devarg
)
166 int hw_idx
, sw_idx
, i
, head
, tail
;
167 struct device
*dev
= (struct device
*)devarg
;
168 struct caam_drv_private_jr
*jrp
= dev_get_drvdata(dev
);
169 void (*usercall
)(struct device
*dev
, u32
*desc
, u32 status
, void *arg
);
170 u32
*userdesc
, userstatus
;
173 while (rd_reg32(&jrp
->rregs
->outring_used
)) {
175 head
= READ_ONCE(jrp
->head
);
177 spin_lock(&jrp
->outlock
);
179 sw_idx
= tail
= jrp
->tail
;
180 hw_idx
= jrp
->out_ring_read_index
;
182 for (i
= 0; CIRC_CNT(head
, tail
+ i
, JOBR_DEPTH
) >= 1; i
++) {
183 sw_idx
= (tail
+ i
) & (JOBR_DEPTH
- 1);
185 if (jrp
->outring
[hw_idx
].desc
==
186 caam_dma_to_cpu(jrp
->entinfo
[sw_idx
].desc_addr_dma
))
189 /* we should never fail to find a matching descriptor */
190 BUG_ON(CIRC_CNT(head
, tail
+ i
, JOBR_DEPTH
) <= 0);
192 /* Unmap just-run descriptor so we can post-process */
193 dma_unmap_single(dev
, jrp
->outring
[hw_idx
].desc
,
194 jrp
->entinfo
[sw_idx
].desc_size
,
197 /* mark completed, avoid matching on a recycled desc addr */
198 jrp
->entinfo
[sw_idx
].desc_addr_dma
= 0;
200 /* Stash callback params for use outside of lock */
201 usercall
= jrp
->entinfo
[sw_idx
].callbk
;
202 userarg
= jrp
->entinfo
[sw_idx
].cbkarg
;
203 userdesc
= jrp
->entinfo
[sw_idx
].desc_addr_virt
;
204 userstatus
= caam32_to_cpu(jrp
->outring
[hw_idx
].jrstatus
);
207 * Make sure all information from the job has been obtained
208 * before telling CAAM that the job has been removed from the
214 wr_reg32(&jrp
->rregs
->outring_rmvd
, 1);
216 jrp
->out_ring_read_index
= (jrp
->out_ring_read_index
+ 1) &
220 * if this job completed out-of-order, do not increment
221 * the tail. Otherwise, increment tail by 1 plus the
222 * number of subsequent jobs already completed out-of-order
224 if (sw_idx
== tail
) {
226 tail
= (tail
+ 1) & (JOBR_DEPTH
- 1);
227 } while (CIRC_CNT(head
, tail
, JOBR_DEPTH
) >= 1 &&
228 jrp
->entinfo
[tail
].desc_addr_dma
== 0);
233 spin_unlock(&jrp
->outlock
);
235 /* Finally, execute user's callback */
236 usercall(dev
, userdesc
, userstatus
, userarg
);
239 /* reenable / unmask IRQs */
240 clrsetbits_32(&jrp
->rregs
->rconfig_lo
, JRCFG_IMSK
, 0);
244 * caam_jr_alloc() - Alloc a job ring for someone to use as needed.
246 * returns : pointer to the newly allocated physical
247 * JobR dev can be written to if successful.
249 struct device
*caam_jr_alloc(void)
251 struct caam_drv_private_jr
*jrpriv
, *min_jrpriv
= NULL
;
252 struct device
*dev
= ERR_PTR(-ENODEV
);
253 int min_tfm_cnt
= INT_MAX
;
256 spin_lock(&driver_data
.jr_alloc_lock
);
258 if (list_empty(&driver_data
.jr_list
)) {
259 spin_unlock(&driver_data
.jr_alloc_lock
);
260 return ERR_PTR(-ENODEV
);
263 list_for_each_entry(jrpriv
, &driver_data
.jr_list
, list_node
) {
264 tfm_cnt
= atomic_read(&jrpriv
->tfm_count
);
265 if (tfm_cnt
< min_tfm_cnt
) {
266 min_tfm_cnt
= tfm_cnt
;
274 atomic_inc(&min_jrpriv
->tfm_count
);
275 dev
= min_jrpriv
->dev
;
277 spin_unlock(&driver_data
.jr_alloc_lock
);
281 EXPORT_SYMBOL(caam_jr_alloc
);
284 * caam_jr_free() - Free the Job Ring
285 * @rdev - points to the dev that identifies the Job ring to
288 void caam_jr_free(struct device
*rdev
)
290 struct caam_drv_private_jr
*jrpriv
= dev_get_drvdata(rdev
);
292 atomic_dec(&jrpriv
->tfm_count
);
294 EXPORT_SYMBOL(caam_jr_free
);
297 * caam_jr_enqueue() - Enqueue a job descriptor head. Returns 0 if OK,
298 * -EBUSY if the queue is full, -EIO if it cannot map the caller's
300 * @dev: device of the job ring to be used. This device should have
301 * been assigned prior by caam_jr_register().
302 * @desc: points to a job descriptor that execute our request. All
303 * descriptors (and all referenced data) must be in a DMAable
304 * region, and all data references must be physical addresses
305 * accessible to CAAM (i.e. within a PAMU window granted
307 * @cbk: pointer to a callback function to be invoked upon completion
308 * of this request. This has the form:
309 * callback(struct device *dev, u32 *desc, u32 stat, void *arg)
311 * @dev: contains the job ring device that processed this
313 * @desc: descriptor that initiated the request, same as
314 * "desc" being argued to caam_jr_enqueue().
315 * @status: untranslated status received from CAAM. See the
316 * reference manual for a detailed description of
317 * error meaning, or see the JRSTA definitions in the
318 * register header file
319 * @areq: optional pointer to an argument passed with the
321 * @areq: optional pointer to a user argument for use at callback
324 int caam_jr_enqueue(struct device
*dev
, u32
*desc
,
325 void (*cbk
)(struct device
*dev
, u32
*desc
,
326 u32 status
, void *areq
),
329 struct caam_drv_private_jr
*jrp
= dev_get_drvdata(dev
);
330 struct caam_jrentry_info
*head_entry
;
331 int head
, tail
, desc_size
;
334 desc_size
= (caam32_to_cpu(*desc
) & HDR_JD_LENGTH_MASK
) * sizeof(u32
);
335 desc_dma
= dma_map_single(dev
, desc
, desc_size
, DMA_TO_DEVICE
);
336 if (dma_mapping_error(dev
, desc_dma
)) {
337 dev_err(dev
, "caam_jr_enqueue(): can't map jobdesc\n");
341 spin_lock_bh(&jrp
->inplock
);
344 tail
= READ_ONCE(jrp
->tail
);
346 if (!rd_reg32(&jrp
->rregs
->inpring_avail
) ||
347 CIRC_SPACE(head
, tail
, JOBR_DEPTH
) <= 0) {
348 spin_unlock_bh(&jrp
->inplock
);
349 dma_unmap_single(dev
, desc_dma
, desc_size
, DMA_TO_DEVICE
);
353 head_entry
= &jrp
->entinfo
[head
];
354 head_entry
->desc_addr_virt
= desc
;
355 head_entry
->desc_size
= desc_size
;
356 head_entry
->callbk
= (void *)cbk
;
357 head_entry
->cbkarg
= areq
;
358 head_entry
->desc_addr_dma
= desc_dma
;
360 jrp
->inpring
[jrp
->inp_ring_write_index
] = cpu_to_caam_dma(desc_dma
);
363 * Guarantee that the descriptor's DMA address has been written to
364 * the next slot in the ring before the write index is updated, since
365 * other cores may update this index independently.
369 jrp
->inp_ring_write_index
= (jrp
->inp_ring_write_index
+ 1) &
371 jrp
->head
= (head
+ 1) & (JOBR_DEPTH
- 1);
374 * Ensure that all job information has been written before
375 * notifying CAAM that a new job was added to the input ring.
379 wr_reg32(&jrp
->rregs
->inpring_jobadd
, 1);
381 spin_unlock_bh(&jrp
->inplock
);
385 EXPORT_SYMBOL(caam_jr_enqueue
);
388 * Init JobR independent of platform property detection
390 static int caam_jr_init(struct device
*dev
)
392 struct caam_drv_private_jr
*jrp
;
393 dma_addr_t inpbusaddr
, outbusaddr
;
396 jrp
= dev_get_drvdata(dev
);
398 tasklet_init(&jrp
->irqtask
, caam_jr_dequeue
, (unsigned long)dev
);
400 /* Connect job ring interrupt handler. */
401 error
= request_irq(jrp
->irq
, caam_jr_interrupt
, IRQF_SHARED
,
404 dev_err(dev
, "can't connect JobR %d interrupt (%d)\n",
405 jrp
->ridx
, jrp
->irq
);
409 error
= caam_reset_hw_jr(dev
);
414 jrp
->inpring
= dma_alloc_coherent(dev
, sizeof(*jrp
->inpring
) *
415 JOBR_DEPTH
, &inpbusaddr
, GFP_KERNEL
);
419 jrp
->outring
= dma_alloc_coherent(dev
, sizeof(*jrp
->outring
) *
420 JOBR_DEPTH
, &outbusaddr
, GFP_KERNEL
);
422 goto out_free_inpring
;
424 jrp
->entinfo
= kcalloc(JOBR_DEPTH
, sizeof(*jrp
->entinfo
), GFP_KERNEL
);
426 goto out_free_outring
;
428 for (i
= 0; i
< JOBR_DEPTH
; i
++)
429 jrp
->entinfo
[i
].desc_addr_dma
= !0;
432 jrp
->inp_ring_write_index
= 0;
433 jrp
->out_ring_read_index
= 0;
437 wr_reg64(&jrp
->rregs
->inpring_base
, inpbusaddr
);
438 wr_reg64(&jrp
->rregs
->outring_base
, outbusaddr
);
439 wr_reg32(&jrp
->rregs
->inpring_size
, JOBR_DEPTH
);
440 wr_reg32(&jrp
->rregs
->outring_size
, JOBR_DEPTH
);
442 jrp
->ringsize
= JOBR_DEPTH
;
444 spin_lock_init(&jrp
->inplock
);
445 spin_lock_init(&jrp
->outlock
);
447 /* Select interrupt coalescing parameters */
448 clrsetbits_32(&jrp
->rregs
->rconfig_lo
, 0, JOBR_INTC
|
449 (JOBR_INTC_COUNT_THLD
<< JRCFG_ICDCT_SHIFT
) |
450 (JOBR_INTC_TIME_THLD
<< JRCFG_ICTT_SHIFT
));
455 dma_free_coherent(dev
, sizeof(struct jr_outentry
) * JOBR_DEPTH
,
456 jrp
->outring
, outbusaddr
);
458 dma_free_coherent(dev
, sizeof(dma_addr_t
) * JOBR_DEPTH
,
459 jrp
->inpring
, inpbusaddr
);
460 dev_err(dev
, "can't allocate job rings for %d\n", jrp
->ridx
);
462 free_irq(jrp
->irq
, dev
);
464 tasklet_kill(&jrp
->irqtask
);
470 * Probe routine for each detected JobR subsystem.
472 static int caam_jr_probe(struct platform_device
*pdev
)
474 struct device
*jrdev
;
475 struct device_node
*nprop
;
476 struct caam_job_ring __iomem
*ctrl
;
477 struct caam_drv_private_jr
*jrpriv
;
478 static int total_jobrs
;
482 jrpriv
= devm_kmalloc(jrdev
, sizeof(*jrpriv
), GFP_KERNEL
);
486 dev_set_drvdata(jrdev
, jrpriv
);
488 /* save ring identity relative to detection */
489 jrpriv
->ridx
= total_jobrs
++;
491 nprop
= pdev
->dev
.of_node
;
492 /* Get configuration properties from device tree */
493 /* First, get register page */
494 ctrl
= of_iomap(nprop
, 0);
496 dev_err(jrdev
, "of_iomap() failed\n");
500 jrpriv
->rregs
= (struct caam_job_ring __iomem __force
*)ctrl
;
502 if (sizeof(dma_addr_t
) == sizeof(u64
)) {
504 error
= dma_set_mask_and_coherent(jrdev
,
506 else if (of_device_is_compatible(nprop
,
507 "fsl,sec-v5.0-job-ring"))
508 error
= dma_set_mask_and_coherent(jrdev
,
511 error
= dma_set_mask_and_coherent(jrdev
,
514 error
= dma_set_mask_and_coherent(jrdev
, DMA_BIT_MASK(32));
517 dev_err(jrdev
, "dma_set_mask_and_coherent failed (%d)\n",
523 /* Identify the interrupt */
524 jrpriv
->irq
= irq_of_parse_and_map(nprop
, 0);
526 /* Now do the platform independent part */
527 error
= caam_jr_init(jrdev
); /* now turn on hardware */
529 irq_dispose_mapping(jrpriv
->irq
);
535 spin_lock(&driver_data
.jr_alloc_lock
);
536 list_add_tail(&jrpriv
->list_node
, &driver_data
.jr_list
);
537 spin_unlock(&driver_data
.jr_alloc_lock
);
539 atomic_set(&jrpriv
->tfm_count
, 0);
544 static const struct of_device_id caam_jr_match
[] = {
546 .compatible
= "fsl,sec-v4.0-job-ring",
549 .compatible
= "fsl,sec4.0-job-ring",
553 MODULE_DEVICE_TABLE(of
, caam_jr_match
);
555 static struct platform_driver caam_jr_driver
= {
558 .of_match_table
= caam_jr_match
,
560 .probe
= caam_jr_probe
,
561 .remove
= caam_jr_remove
,
564 static int __init
jr_driver_init(void)
566 spin_lock_init(&driver_data
.jr_alloc_lock
);
567 INIT_LIST_HEAD(&driver_data
.jr_list
);
568 return platform_driver_register(&caam_jr_driver
);
571 static void __exit
jr_driver_exit(void)
573 platform_driver_unregister(&caam_jr_driver
);
576 module_init(jr_driver_init
);
577 module_exit(jr_driver_exit
);
579 MODULE_LICENSE("GPL");
580 MODULE_DESCRIPTION("FSL CAAM JR request backend");
581 MODULE_AUTHOR("Freescale Semiconductor - NMG/STC");