Lines Matching +full:required +full:- +full:for +full:- +full:hardware +full:- +full:jobs

1 // SPDX-License-Identifier: GPL-2.0+
6 * Copyright 2008-2012 Freescale Semiconductor, Inc.
42 jrpriv->hwrng = !caam_rng_init(dev); in register_algs()
54 if (--active_devs != 0) in unregister_algs()
72 /* Free the resources of crypto-engine */ in caam_jr_crypto_engine_exit()
73 crypto_engine_exit(jrpriv->engine); in caam_jr_crypto_engine_exit()
87 if (rd_reg32(&jrp->rregs->jrintstatus) & JRINT_ERR_HALT_INPROGRESS) in caam_jr_stop_processing()
91 clrsetbits_32(&jrp->rregs->jrintstatus, JRINT_ERR_HALT_MASK, 0); in caam_jr_stop_processing()
93 /* initiate flush / park (required prior to reset) */ in caam_jr_stop_processing()
94 wr_reg32(&jrp->rregs->jrcommand, jrcr_bits); in caam_jr_stop_processing()
97 while (((rd_reg32(&jrp->rregs->jrintstatus) & JRINT_ERR_HALT_MASK) == in caam_jr_stop_processing()
98 JRINT_ERR_HALT_INPROGRESS) && --timeout) in caam_jr_stop_processing()
101 if ((rd_reg32(&jrp->rregs->jrintstatus) & JRINT_ERR_HALT_MASK) != in caam_jr_stop_processing()
103 dev_err(dev, "failed to flush job ring %d\n", jrp->ridx); in caam_jr_stop_processing()
104 return -EIO; in caam_jr_stop_processing()
111 * Flush the job ring, so the jobs running will be stopped, jobs queued will be
125 u32 halt_status = rd_reg32(&jrp->rregs->jrintstatus) & in caam_jr_restart_processing()
130 return -1; in caam_jr_restart_processing()
132 /* Resume processing of jobs */ in caam_jr_restart_processing()
133 clrsetbits_32(&jrp->rregs->jrintstatus, 0, JRINT_ERR_HALT_COMPLETE); in caam_jr_restart_processing()
145 * for reset completion status in caam_reset_hw_jr()
147 clrsetbits_32(&jrp->rregs->rconfig_lo, 0, JRCFG_IMSK); in caam_reset_hw_jr()
153 wr_reg32(&jrp->rregs->jrcommand, JRCR_RESET); in caam_reset_hw_jr()
154 while ((rd_reg32(&jrp->rregs->jrcommand) & JRCR_RESET) && --timeout) in caam_reset_hw_jr()
158 dev_err(dev, "failed to reset job ring %d\n", jrp->ridx); in caam_reset_hw_jr()
159 return -EIO; in caam_reset_hw_jr()
163 clrsetbits_32(&jrp->rregs->rconfig_lo, JRCFG_IMSK, 0); in caam_reset_hw_jr()
178 tasklet_kill(&jrp->irqtask); in caam_jr_shutdown()
189 jrdev = &pdev->dev; in caam_jr_remove()
192 if (jrpriv->hwrng) in caam_jr_remove()
193 caam_rng_exit(jrdev->parent); in caam_jr_remove()
198 if (atomic_read(&jrpriv->tfm_count)) { in caam_jr_remove()
200 return -EBUSY; in caam_jr_remove()
203 /* Unregister JR-based RNG & crypto algorithms */ in caam_jr_remove()
208 list_del(&jrpriv->list_node); in caam_jr_remove()
224 /* Main per-ring interrupt handler */
232 * Check the output ring for ready responses, kick in caam_jr_interrupt()
233 * tasklet if jobs done. in caam_jr_interrupt()
235 irqstate = rd_reg32(&jrp->rregs->jrintstatus); in caam_jr_interrupt()
250 clrsetbits_32(&jrp->rregs->rconfig_lo, 0, JRCFG_IMSK); in caam_jr_interrupt()
253 wr_reg32(&jrp->rregs->jrintstatus, irqstate); in caam_jr_interrupt()
256 tasklet_schedule(&jrp->irqtask); in caam_jr_interrupt()
262 /* Deferred service handler, run as interrupt-fired tasklet */
267 struct device *dev = params->dev; in caam_jr_dequeue()
275 (outring_used = rd_reg32(&jrp->rregs->outring_used))) { in caam_jr_dequeue()
277 head = READ_ONCE(jrp->head); in caam_jr_dequeue()
279 sw_idx = tail = jrp->tail; in caam_jr_dequeue()
280 hw_idx = jrp->out_ring_read_index; in caam_jr_dequeue()
282 for (i = 0; CIRC_CNT(head, tail + i, JOBR_DEPTH) >= 1; i++) { in caam_jr_dequeue()
283 sw_idx = (tail + i) & (JOBR_DEPTH - 1); in caam_jr_dequeue()
285 if (jr_outentry_desc(jrp->outring, hw_idx) == in caam_jr_dequeue()
286 caam_dma_to_cpu(jrp->entinfo[sw_idx].desc_addr_dma)) in caam_jr_dequeue()
292 /* Unmap just-run descriptor so we can post-process */ in caam_jr_dequeue()
294 caam_dma_to_cpu(jr_outentry_desc(jrp->outring, in caam_jr_dequeue()
296 jrp->entinfo[sw_idx].desc_size, in caam_jr_dequeue()
300 jrp->entinfo[sw_idx].desc_addr_dma = 0; in caam_jr_dequeue()
303 usercall = jrp->entinfo[sw_idx].callbk; in caam_jr_dequeue()
304 userarg = jrp->entinfo[sw_idx].cbkarg; in caam_jr_dequeue()
305 userdesc = jrp->entinfo[sw_idx].desc_addr_virt; in caam_jr_dequeue()
306 userstatus = caam32_to_cpu(jr_outentry_jrstatus(jrp->outring, in caam_jr_dequeue()
317 wr_reg32(&jrp->rregs->outring_rmvd, 1); in caam_jr_dequeue()
319 jrp->out_ring_read_index = (jrp->out_ring_read_index + 1) & in caam_jr_dequeue()
320 (JOBR_DEPTH - 1); in caam_jr_dequeue()
323 * if this job completed out-of-order, do not increment in caam_jr_dequeue()
325 * number of subsequent jobs already completed out-of-order in caam_jr_dequeue()
329 tail = (tail + 1) & (JOBR_DEPTH - 1); in caam_jr_dequeue()
331 jrp->entinfo[tail].desc_addr_dma == 0); in caam_jr_dequeue()
333 jrp->tail = tail; in caam_jr_dequeue()
338 outring_used--; in caam_jr_dequeue()
341 if (params->enable_itr) in caam_jr_dequeue()
343 clrsetbits_32(&jrp->rregs->rconfig_lo, JRCFG_IMSK, 0); in caam_jr_dequeue()
347 * caam_jr_alloc() - Alloc a job ring for someone to use as needed.
355 struct device *dev = ERR_PTR(-ENODEV); in caam_jr_alloc()
363 return ERR_PTR(-ENODEV); in caam_jr_alloc()
367 tfm_cnt = atomic_read(&jrpriv->tfm_count); in caam_jr_alloc()
377 atomic_inc(&min_jrpriv->tfm_count); in caam_jr_alloc()
378 dev = min_jrpriv->dev; in caam_jr_alloc()
387 * caam_jr_free() - Free the Job Ring
395 atomic_dec(&jrpriv->tfm_count); in caam_jr_free()
400 * caam_jr_enqueue() - Enqueue a job descriptor head. Returns -EINPROGRESS
401 * if OK, -ENOSPC if the queue is full, -EIO if it cannot map the caller's
418 * reference manual for a detailed description of
423 * @areq: optional pointer to a user argument for use at callback
440 return -EIO; in caam_jr_enqueue()
443 spin_lock_bh(&jrp->inplock); in caam_jr_enqueue()
445 head = jrp->head; in caam_jr_enqueue()
446 tail = READ_ONCE(jrp->tail); in caam_jr_enqueue()
448 if (!jrp->inpring_avail || in caam_jr_enqueue()
450 spin_unlock_bh(&jrp->inplock); in caam_jr_enqueue()
452 return -ENOSPC; in caam_jr_enqueue()
455 head_entry = &jrp->entinfo[head]; in caam_jr_enqueue()
456 head_entry->desc_addr_virt = desc; in caam_jr_enqueue()
457 head_entry->desc_size = desc_size; in caam_jr_enqueue()
458 head_entry->callbk = (void *)cbk; in caam_jr_enqueue()
459 head_entry->cbkarg = areq; in caam_jr_enqueue()
460 head_entry->desc_addr_dma = desc_dma; in caam_jr_enqueue()
462 jr_inpentry_set(jrp->inpring, head, cpu_to_caam_dma(desc_dma)); in caam_jr_enqueue()
479 jrp->head = (head + 1) & (JOBR_DEPTH - 1); in caam_jr_enqueue()
489 wr_reg32(&jrp->rregs->inpring_jobadd, 1); in caam_jr_enqueue()
491 jrp->inpring_avail--; in caam_jr_enqueue()
492 if (!jrp->inpring_avail) in caam_jr_enqueue()
493 jrp->inpring_avail = rd_reg32(&jrp->rregs->inpring_avail); in caam_jr_enqueue()
495 spin_unlock_bh(&jrp->inplock); in caam_jr_enqueue()
497 return -EINPROGRESS; in caam_jr_enqueue()
506 wr_reg64(&jrp->rregs->inpring_base, inpbusaddr); in caam_jr_init_hw()
507 wr_reg64(&jrp->rregs->outring_base, outbusaddr); in caam_jr_init_hw()
508 wr_reg32(&jrp->rregs->inpring_size, JOBR_DEPTH); in caam_jr_init_hw()
509 wr_reg32(&jrp->rregs->outring_size, JOBR_DEPTH); in caam_jr_init_hw()
512 clrsetbits_32(&jrp->rregs->rconfig_lo, 0, JOBR_INTC | in caam_jr_init_hw()
519 jrp->out_ring_read_index = 0; in caam_jr_reset_index()
520 jrp->head = 0; in caam_jr_reset_index()
521 jrp->tail = 0; in caam_jr_reset_index()
539 jrp->inpring = dmam_alloc_coherent(dev, SIZEOF_JR_INPENTRY * in caam_jr_init()
542 if (!jrp->inpring) in caam_jr_init()
543 return -ENOMEM; in caam_jr_init()
545 jrp->outring = dmam_alloc_coherent(dev, SIZEOF_JR_OUTENTRY * in caam_jr_init()
548 if (!jrp->outring) in caam_jr_init()
549 return -ENOMEM; in caam_jr_init()
551 jrp->entinfo = devm_kcalloc(dev, JOBR_DEPTH, sizeof(*jrp->entinfo), in caam_jr_init()
553 if (!jrp->entinfo) in caam_jr_init()
554 return -ENOMEM; in caam_jr_init()
556 for (i = 0; i < JOBR_DEPTH; i++) in caam_jr_init()
557 jrp->entinfo[i].desc_addr_dma = !0; in caam_jr_init()
561 jrp->inpring_avail = JOBR_DEPTH; in caam_jr_init()
564 spin_lock_init(&jrp->inplock); in caam_jr_init()
566 jrp->tasklet_params.dev = dev; in caam_jr_init()
567 jrp->tasklet_params.enable_itr = 1; in caam_jr_init()
568 tasklet_init(&jrp->irqtask, caam_jr_dequeue, in caam_jr_init()
569 (unsigned long)&jrp->tasklet_params); in caam_jr_init()
572 error = devm_request_irq(dev, jrp->irq, caam_jr_interrupt, IRQF_SHARED, in caam_jr_init()
576 jrp->ridx, jrp->irq); in caam_jr_init()
577 tasklet_kill(&jrp->irqtask); in caam_jr_init()
589 * Probe routine for each detected JobR subsystem.
601 jrdev = &pdev->dev; in caam_jr_probe()
604 return -ENOMEM; in caam_jr_probe()
609 jrpriv->ridx = total_jobrs++; in caam_jr_probe()
611 nprop = pdev->dev.of_node; in caam_jr_probe()
617 return -ENOMEM; in caam_jr_probe()
620 ctrl = devm_ioremap(jrdev, r->start, resource_size(r)); in caam_jr_probe()
623 return -ENOMEM; in caam_jr_probe()
626 jrpriv->rregs = (struct caam_job_ring __iomem __force *)ctrl; in caam_jr_probe()
636 jrpriv->engine = crypto_engine_alloc_init_and_set(jrdev, true, NULL, in caam_jr_probe()
639 if (!jrpriv->engine) { in caam_jr_probe()
640 dev_err(jrdev, "Could not init crypto-engine\n"); in caam_jr_probe()
641 return -ENOMEM; in caam_jr_probe()
650 error = crypto_engine_start(jrpriv->engine); in caam_jr_probe()
652 dev_err(jrdev, "Could not start crypto-engine\n"); in caam_jr_probe()
657 jrpriv->irq = irq_of_parse_and_map(nprop, 0); in caam_jr_probe()
658 if (!jrpriv->irq) { in caam_jr_probe()
660 return -EINVAL; in caam_jr_probe()
664 (void *)(unsigned long)jrpriv->irq); in caam_jr_probe()
669 error = caam_jr_init(jrdev); /* now turn on hardware */ in caam_jr_probe()
673 jrpriv->dev = jrdev; in caam_jr_probe()
675 list_add_tail(&jrpriv->list_node, &driver_data.jr_list); in caam_jr_probe()
678 atomic_set(&jrpriv->tfm_count, 0); in caam_jr_probe()
680 device_init_wakeup(&pdev->dev, 1); in caam_jr_probe()
681 device_set_wakeup_enable(&pdev->dev, false); in caam_jr_probe()
683 register_algs(jrpriv, jrdev->parent); in caam_jr_probe()
692 jrp->state.inpbusaddr = rd_reg64(&jrp->rregs->inpring_base); in caam_jr_get_hw_state()
693 jrp->state.outbusaddr = rd_reg64(&jrp->rregs->outring_base); in caam_jr_get_hw_state()
700 struct caam_drv_private *ctrlpriv = dev_get_drvdata(dev->parent); in caam_jr_suspend()
708 list_del(&jrpriv->list_node); in caam_jr_suspend()
711 if (jrpriv->hwrng) in caam_jr_suspend()
712 caam_rng_exit(dev->parent); in caam_jr_suspend()
714 if (ctrlpriv->caam_off_during_pm) { in caam_jr_suspend()
717 tasklet_disable(&jrpriv->irqtask); in caam_jr_suspend()
720 clrsetbits_32(&jrpriv->rregs->rconfig_lo, 0, JRCFG_IMSK); in caam_jr_suspend()
729 /* Dequeing jobs flushed */ in caam_jr_suspend()
734 } else if (device_may_wakeup(&pdev->dev)) { in caam_jr_suspend()
735 enable_irq_wake(jrpriv->irq); in caam_jr_suspend()
745 struct caam_drv_private *ctrlpriv = dev_get_drvdata(dev->parent); in caam_jr_resume()
747 if (ctrlpriv->caam_off_during_pm) { in caam_jr_resume()
755 inp_addr = rd_reg64(&jrpriv->rregs->inpring_base); in caam_jr_resume()
758 if (inp_addr == jrpriv->state.inpbusaddr) { in caam_jr_resume()
767 tasklet_enable(&jrpriv->irqtask); in caam_jr_resume()
769 clrsetbits_32(&jrpriv->rregs->rconfig_lo, in caam_jr_resume()
773 } else if (ctrlpriv->optee_en) { in caam_jr_resume()
782 return -EIO; in caam_jr_resume()
787 caam_jr_init_hw(dev, jrpriv->state.inpbusaddr, in caam_jr_resume()
788 jrpriv->state.outbusaddr); in caam_jr_resume()
790 tasklet_enable(&jrpriv->irqtask); in caam_jr_resume()
791 } else if (device_may_wakeup(&pdev->dev)) { in caam_jr_resume()
792 disable_irq_wake(jrpriv->irq); in caam_jr_resume()
797 list_add_tail(&jrpriv->list_node, &driver_data.jr_list); in caam_jr_resume()
800 if (jrpriv->hwrng) in caam_jr_resume()
801 jrpriv->hwrng = !caam_rng_init(dev->parent); in caam_jr_resume()
810 .compatible = "fsl,sec-v4.0-job-ring",
813 .compatible = "fsl,sec4.0-job-ring",
847 MODULE_AUTHOR("Freescale Semiconductor - NMG/STC");