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()
201 if (atomic_read(&jrpriv->tfm_count)) { in caam_jr_remove()
206 /* Unregister JR-based RNG & crypto algorithms */ in caam_jr_remove()
211 list_del(&jrpriv->list_node); in caam_jr_remove()
220 /* Main per-ring interrupt handler */
228 * Check the output ring for ready responses, kick in caam_jr_interrupt()
229 * tasklet if jobs done. in caam_jr_interrupt()
231 irqstate = rd_reg32(&jrp->rregs->jrintstatus); in caam_jr_interrupt()
246 clrsetbits_32(&jrp->rregs->rconfig_lo, 0, JRCFG_IMSK); in caam_jr_interrupt()
249 wr_reg32(&jrp->rregs->jrintstatus, irqstate); in caam_jr_interrupt()
252 tasklet_schedule(&jrp->irqtask); in caam_jr_interrupt()
258 /* Deferred service handler, run as interrupt-fired tasklet */
263 struct device *dev = params->dev; in caam_jr_dequeue()
271 (outring_used = rd_reg32(&jrp->rregs->outring_used))) { in caam_jr_dequeue()
273 head = READ_ONCE(jrp->head); in caam_jr_dequeue()
275 sw_idx = tail = jrp->tail; in caam_jr_dequeue()
276 hw_idx = jrp->out_ring_read_index; in caam_jr_dequeue()
278 for (i = 0; CIRC_CNT(head, tail + i, JOBR_DEPTH) >= 1; i++) { in caam_jr_dequeue()
279 sw_idx = (tail + i) & (JOBR_DEPTH - 1); in caam_jr_dequeue()
281 if (jr_outentry_desc(jrp->outring, hw_idx) == in caam_jr_dequeue()
282 caam_dma_to_cpu(jrp->entinfo[sw_idx].desc_addr_dma)) in caam_jr_dequeue()
288 /* Unmap just-run descriptor so we can post-process */ in caam_jr_dequeue()
290 caam_dma_to_cpu(jr_outentry_desc(jrp->outring, in caam_jr_dequeue()
292 jrp->entinfo[sw_idx].desc_size, in caam_jr_dequeue()
296 jrp->entinfo[sw_idx].desc_addr_dma = 0; in caam_jr_dequeue()
299 usercall = jrp->entinfo[sw_idx].callbk; in caam_jr_dequeue()
300 userarg = jrp->entinfo[sw_idx].cbkarg; in caam_jr_dequeue()
301 userdesc = jrp->entinfo[sw_idx].desc_addr_virt; in caam_jr_dequeue()
302 userstatus = caam32_to_cpu(jr_outentry_jrstatus(jrp->outring, in caam_jr_dequeue()
313 wr_reg32(&jrp->rregs->outring_rmvd, 1); in caam_jr_dequeue()
315 jrp->out_ring_read_index = (jrp->out_ring_read_index + 1) & in caam_jr_dequeue()
316 (JOBR_DEPTH - 1); in caam_jr_dequeue()
319 * if this job completed out-of-order, do not increment in caam_jr_dequeue()
321 * number of subsequent jobs already completed out-of-order in caam_jr_dequeue()
325 tail = (tail + 1) & (JOBR_DEPTH - 1); in caam_jr_dequeue()
327 jrp->entinfo[tail].desc_addr_dma == 0); in caam_jr_dequeue()
329 jrp->tail = tail; in caam_jr_dequeue()
334 outring_used--; in caam_jr_dequeue()
337 if (params->enable_itr) in caam_jr_dequeue()
339 clrsetbits_32(&jrp->rregs->rconfig_lo, JRCFG_IMSK, 0); in caam_jr_dequeue()
343 * caam_jr_alloc() - Alloc a job ring for someone to use as needed.
351 struct device *dev = ERR_PTR(-ENODEV); in caam_jr_alloc()
359 return ERR_PTR(-ENODEV); in caam_jr_alloc()
363 tfm_cnt = atomic_read(&jrpriv->tfm_count); in caam_jr_alloc()
373 atomic_inc(&min_jrpriv->tfm_count); in caam_jr_alloc()
374 dev = min_jrpriv->dev; in caam_jr_alloc()
383 * caam_jr_free() - Free the Job Ring
391 atomic_dec(&jrpriv->tfm_count); in caam_jr_free()
396 * caam_jr_enqueue() - Enqueue a job descriptor head. Returns -EINPROGRESS
397 * if OK, -ENOSPC if the queue is full, -EIO if it cannot map the caller's
414 * reference manual for a detailed description of
419 * @areq: optional pointer to a user argument for use at callback
436 return -EIO; in caam_jr_enqueue()
439 spin_lock_bh(&jrp->inplock); in caam_jr_enqueue()
441 head = jrp->head; in caam_jr_enqueue()
442 tail = READ_ONCE(jrp->tail); in caam_jr_enqueue()
444 if (!jrp->inpring_avail || in caam_jr_enqueue()
446 spin_unlock_bh(&jrp->inplock); in caam_jr_enqueue()
448 return -ENOSPC; in caam_jr_enqueue()
451 head_entry = &jrp->entinfo[head]; in caam_jr_enqueue()
452 head_entry->desc_addr_virt = desc; in caam_jr_enqueue()
453 head_entry->desc_size = desc_size; in caam_jr_enqueue()
454 head_entry->callbk = (void *)cbk; in caam_jr_enqueue()
455 head_entry->cbkarg = areq; in caam_jr_enqueue()
456 head_entry->desc_addr_dma = desc_dma; in caam_jr_enqueue()
458 jr_inpentry_set(jrp->inpring, head, cpu_to_caam_dma(desc_dma)); in caam_jr_enqueue()
475 jrp->head = (head + 1) & (JOBR_DEPTH - 1); in caam_jr_enqueue()
485 wr_reg32(&jrp->rregs->inpring_jobadd, 1); in caam_jr_enqueue()
487 jrp->inpring_avail--; in caam_jr_enqueue()
488 if (!jrp->inpring_avail) in caam_jr_enqueue()
489 jrp->inpring_avail = rd_reg32(&jrp->rregs->inpring_avail); in caam_jr_enqueue()
491 spin_unlock_bh(&jrp->inplock); in caam_jr_enqueue()
493 return -EINPROGRESS; in caam_jr_enqueue()
502 wr_reg64(&jrp->rregs->inpring_base, inpbusaddr); in caam_jr_init_hw()
503 wr_reg64(&jrp->rregs->outring_base, outbusaddr); in caam_jr_init_hw()
504 wr_reg32(&jrp->rregs->inpring_size, JOBR_DEPTH); in caam_jr_init_hw()
505 wr_reg32(&jrp->rregs->outring_size, JOBR_DEPTH); in caam_jr_init_hw()
508 clrsetbits_32(&jrp->rregs->rconfig_lo, 0, JOBR_INTC | in caam_jr_init_hw()
515 jrp->out_ring_read_index = 0; in caam_jr_reset_index()
516 jrp->head = 0; in caam_jr_reset_index()
517 jrp->tail = 0; in caam_jr_reset_index()
535 jrp->inpring = dmam_alloc_coherent(dev, SIZEOF_JR_INPENTRY * in caam_jr_init()
538 if (!jrp->inpring) in caam_jr_init()
539 return -ENOMEM; in caam_jr_init()
541 jrp->outring = dmam_alloc_coherent(dev, SIZEOF_JR_OUTENTRY * in caam_jr_init()
544 if (!jrp->outring) in caam_jr_init()
545 return -ENOMEM; in caam_jr_init()
547 jrp->entinfo = devm_kcalloc(dev, JOBR_DEPTH, sizeof(*jrp->entinfo), in caam_jr_init()
549 if (!jrp->entinfo) in caam_jr_init()
550 return -ENOMEM; in caam_jr_init()
552 for (i = 0; i < JOBR_DEPTH; i++) in caam_jr_init()
553 jrp->entinfo[i].desc_addr_dma = !0; in caam_jr_init()
557 jrp->inpring_avail = JOBR_DEPTH; in caam_jr_init()
560 spin_lock_init(&jrp->inplock); in caam_jr_init()
562 jrp->tasklet_params.dev = dev; in caam_jr_init()
563 jrp->tasklet_params.enable_itr = 1; in caam_jr_init()
564 tasklet_init(&jrp->irqtask, caam_jr_dequeue, in caam_jr_init()
565 (unsigned long)&jrp->tasklet_params); in caam_jr_init()
568 error = devm_request_irq(dev, jrp->irq, caam_jr_interrupt, IRQF_SHARED, in caam_jr_init()
572 jrp->ridx, jrp->irq); in caam_jr_init()
573 tasklet_kill(&jrp->irqtask); in caam_jr_init()
585 * Probe routine for each detected JobR subsystem.
597 jrdev = &pdev->dev; in caam_jr_probe()
600 return -ENOMEM; in caam_jr_probe()
605 jrpriv->ridx = total_jobrs++; in caam_jr_probe()
607 nprop = pdev->dev.of_node; in caam_jr_probe()
613 return -ENOMEM; in caam_jr_probe()
616 ctrl = devm_ioremap(jrdev, r->start, resource_size(r)); in caam_jr_probe()
619 return -ENOMEM; in caam_jr_probe()
622 jrpriv->rregs = (struct caam_job_ring __iomem __force *)ctrl; in caam_jr_probe()
632 jrpriv->engine = crypto_engine_alloc_init_and_set(jrdev, true, NULL, in caam_jr_probe()
635 if (!jrpriv->engine) { in caam_jr_probe()
636 dev_err(jrdev, "Could not init crypto-engine\n"); in caam_jr_probe()
637 return -ENOMEM; in caam_jr_probe()
646 error = crypto_engine_start(jrpriv->engine); in caam_jr_probe()
648 dev_err(jrdev, "Could not start crypto-engine\n"); in caam_jr_probe()
653 jrpriv->irq = irq_of_parse_and_map(nprop, 0); in caam_jr_probe()
654 if (!jrpriv->irq) { in caam_jr_probe()
656 return -EINVAL; in caam_jr_probe()
660 (void *)(unsigned long)jrpriv->irq); in caam_jr_probe()
665 error = caam_jr_init(jrdev); /* now turn on hardware */ in caam_jr_probe()
669 jrpriv->dev = jrdev; in caam_jr_probe()
671 list_add_tail(&jrpriv->list_node, &driver_data.jr_list); in caam_jr_probe()
674 atomic_set(&jrpriv->tfm_count, 0); in caam_jr_probe()
676 device_init_wakeup(&pdev->dev, 1); in caam_jr_probe()
677 device_set_wakeup_enable(&pdev->dev, false); in caam_jr_probe()
679 register_algs(jrpriv, jrdev->parent); in caam_jr_probe()
688 jrp->state.inpbusaddr = rd_reg64(&jrp->rregs->inpring_base); in caam_jr_get_hw_state()
689 jrp->state.outbusaddr = rd_reg64(&jrp->rregs->outring_base); in caam_jr_get_hw_state()
696 struct caam_drv_private *ctrlpriv = dev_get_drvdata(dev->parent); in caam_jr_suspend()
704 list_del(&jrpriv->list_node); in caam_jr_suspend()
707 if (jrpriv->hwrng) in caam_jr_suspend()
708 caam_rng_exit(dev->parent); in caam_jr_suspend()
710 if (ctrlpriv->caam_off_during_pm) { in caam_jr_suspend()
713 tasklet_disable(&jrpriv->irqtask); in caam_jr_suspend()
716 clrsetbits_32(&jrpriv->rregs->rconfig_lo, 0, JRCFG_IMSK); in caam_jr_suspend()
725 /* Dequeing jobs flushed */ in caam_jr_suspend()
730 } else if (device_may_wakeup(&pdev->dev)) { in caam_jr_suspend()
731 enable_irq_wake(jrpriv->irq); in caam_jr_suspend()
741 struct caam_drv_private *ctrlpriv = dev_get_drvdata(dev->parent); in caam_jr_resume()
743 if (ctrlpriv->caam_off_during_pm) { in caam_jr_resume()
751 inp_addr = rd_reg64(&jrpriv->rregs->inpring_base); in caam_jr_resume()
754 if (inp_addr == jrpriv->state.inpbusaddr) { in caam_jr_resume()
763 tasklet_enable(&jrpriv->irqtask); in caam_jr_resume()
765 clrsetbits_32(&jrpriv->rregs->rconfig_lo, in caam_jr_resume()
769 } else if (ctrlpriv->optee_en) { in caam_jr_resume()
778 return -EIO; in caam_jr_resume()
783 caam_jr_init_hw(dev, jrpriv->state.inpbusaddr, in caam_jr_resume()
784 jrpriv->state.outbusaddr); in caam_jr_resume()
786 tasklet_enable(&jrpriv->irqtask); in caam_jr_resume()
787 } else if (device_may_wakeup(&pdev->dev)) { in caam_jr_resume()
788 disable_irq_wake(jrpriv->irq); in caam_jr_resume()
793 list_add_tail(&jrpriv->list_node, &driver_data.jr_list); in caam_jr_resume()
796 if (jrpriv->hwrng) in caam_jr_resume()
797 jrpriv->hwrng = !caam_rng_init(dev->parent); in caam_jr_resume()
806 .compatible = "fsl,sec-v4.0-job-ring",
809 .compatible = "fsl,sec4.0-job-ring",
843 MODULE_AUTHOR("Freescale Semiconductor - NMG/STC");