Lines Matching refs:ce
150 int sun8i_ce_get_engine_number(struct sun8i_ce_dev *ce) in sun8i_ce_get_engine_number() argument
152 return atomic_inc_return(&ce->flow) % (MAXFLOW - 1); in sun8i_ce_get_engine_number()
155 int sun8i_ce_run_task(struct sun8i_ce_dev *ce, int flow, const char *name) in sun8i_ce_run_task() argument
159 struct ce_task *cet = ce->chanlist[flow].tl; in sun8i_ce_run_task()
162 ce->chanlist[flow].stat_req++; in sun8i_ce_run_task()
165 mutex_lock(&ce->mlock); in sun8i_ce_run_task()
167 v = readl(ce->base + CE_ICR); in sun8i_ce_run_task()
169 writel(v, ce->base + CE_ICR); in sun8i_ce_run_task()
171 reinit_completion(&ce->chanlist[flow].complete); in sun8i_ce_run_task()
172 writel(ce->chanlist[flow].t_phy, ce->base + CE_TDQ); in sun8i_ce_run_task()
174 ce->chanlist[flow].status = 0; in sun8i_ce_run_task()
181 v = 1 | ((le32_to_cpu(ce->chanlist[flow].tl->t_common_ctl) & 0x7F) << 8); in sun8i_ce_run_task()
182 writel(v, ce->base + CE_TLR); in sun8i_ce_run_task()
183 mutex_unlock(&ce->mlock); in sun8i_ce_run_task()
185 wait_for_completion_interruptible_timeout(&ce->chanlist[flow].complete, in sun8i_ce_run_task()
186 msecs_to_jiffies(ce->chanlist[flow].timeout)); in sun8i_ce_run_task()
188 if (ce->chanlist[flow].status == 0) { in sun8i_ce_run_task()
189 dev_err(ce->dev, "DMA timeout for %s (tm=%d) on flow %d\n", name, in sun8i_ce_run_task()
190 ce->chanlist[flow].timeout, flow); in sun8i_ce_run_task()
196 v = readl(ce->base + CE_ESR); in sun8i_ce_run_task()
197 switch (ce->variant->esr) { in sun8i_ce_run_task()
201 dev_err(ce->dev, "CE ERROR: %x for flow %x\n", v, flow); in sun8i_ce_run_task()
207 dev_err(ce->dev, "CE ERROR: algorithm not supported\n"); in sun8i_ce_run_task()
209 dev_err(ce->dev, "CE ERROR: data length error\n"); in sun8i_ce_run_task()
211 dev_err(ce->dev, "CE ERROR: keysram access error for AES\n"); in sun8i_ce_run_task()
220 dev_err(ce->dev, "CE ERROR: %x for flow %x\n", v, flow); in sun8i_ce_run_task()
226 dev_err(ce->dev, "CE ERROR: algorithm not supported\n"); in sun8i_ce_run_task()
228 dev_err(ce->dev, "CE ERROR: data length error\n"); in sun8i_ce_run_task()
230 dev_err(ce->dev, "CE ERROR: keysram access error for AES\n"); in sun8i_ce_run_task()
236 dev_err(ce->dev, "CE ERROR: %x for flow %x\n", v, flow); in sun8i_ce_run_task()
242 dev_err(ce->dev, "CE ERROR: algorithm not supported\n"); in sun8i_ce_run_task()
244 dev_err(ce->dev, "CE ERROR: data length error\n"); in sun8i_ce_run_task()
246 dev_err(ce->dev, "CE ERROR: keysram access error for AES\n"); in sun8i_ce_run_task()
248 dev_err(ce->dev, "CE ERROR: address invalid\n"); in sun8i_ce_run_task()
250 dev_err(ce->dev, "CE ERROR: key ladder configuration error\n"); in sun8i_ce_run_task()
259 struct sun8i_ce_dev *ce = (struct sun8i_ce_dev *)data; in ce_irq_handler() local
263 p = readl(ce->base + CE_ISR); in ce_irq_handler()
266 writel(BIT(flow), ce->base + CE_ISR); in ce_irq_handler()
267 ce->chanlist[flow].status = 1; in ce_irq_handler()
268 complete(&ce->chanlist[flow].complete); in ce_irq_handler()
588 struct sun8i_ce_dev *ce = seq->private; in sun8i_ce_debugfs_show() local
592 seq_printf(seq, "Channel %d: nreq %lu\n", i, ce->chanlist[i].stat_req); in sun8i_ce_debugfs_show()
595 if (!ce_algs[i].ce) in sun8i_ce_debugfs_show()
648 ce->hwrng_stat_req, ce->hwrng_stat_bytes); in sun8i_ce_debugfs_show()
656 static void sun8i_ce_free_chanlist(struct sun8i_ce_dev *ce, int i) in sun8i_ce_free_chanlist() argument
659 crypto_engine_exit(ce->chanlist[i].engine); in sun8i_ce_free_chanlist()
660 if (ce->chanlist[i].tl) in sun8i_ce_free_chanlist()
661 dma_free_coherent(ce->dev, sizeof(struct ce_task), in sun8i_ce_free_chanlist()
662 ce->chanlist[i].tl, in sun8i_ce_free_chanlist()
663 ce->chanlist[i].t_phy); in sun8i_ce_free_chanlist()
671 static int sun8i_ce_allocate_chanlist(struct sun8i_ce_dev *ce) in sun8i_ce_allocate_chanlist() argument
675 ce->chanlist = devm_kcalloc(ce->dev, MAXFLOW, in sun8i_ce_allocate_chanlist()
677 if (!ce->chanlist) in sun8i_ce_allocate_chanlist()
681 init_completion(&ce->chanlist[i].complete); in sun8i_ce_allocate_chanlist()
683 ce->chanlist[i].engine = crypto_engine_alloc_init(ce->dev, true); in sun8i_ce_allocate_chanlist()
684 if (!ce->chanlist[i].engine) { in sun8i_ce_allocate_chanlist()
685 dev_err(ce->dev, "Cannot allocate engine\n"); in sun8i_ce_allocate_chanlist()
690 err = crypto_engine_start(ce->chanlist[i].engine); in sun8i_ce_allocate_chanlist()
692 dev_err(ce->dev, "Cannot start engine\n"); in sun8i_ce_allocate_chanlist()
695 ce->chanlist[i].tl = dma_alloc_coherent(ce->dev, in sun8i_ce_allocate_chanlist()
697 &ce->chanlist[i].t_phy, in sun8i_ce_allocate_chanlist()
699 if (!ce->chanlist[i].tl) { in sun8i_ce_allocate_chanlist()
700 dev_err(ce->dev, "Cannot get DMA memory for task %d\n", in sun8i_ce_allocate_chanlist()
705 ce->chanlist[i].bounce_iv = devm_kmalloc(ce->dev, AES_BLOCK_SIZE, in sun8i_ce_allocate_chanlist()
707 if (!ce->chanlist[i].bounce_iv) { in sun8i_ce_allocate_chanlist()
711 ce->chanlist[i].backup_iv = devm_kmalloc(ce->dev, AES_BLOCK_SIZE, in sun8i_ce_allocate_chanlist()
713 if (!ce->chanlist[i].backup_iv) { in sun8i_ce_allocate_chanlist()
720 sun8i_ce_free_chanlist(ce, i); in sun8i_ce_allocate_chanlist()
730 struct sun8i_ce_dev *ce = dev_get_drvdata(dev); in sun8i_ce_pm_suspend() local
733 reset_control_assert(ce->reset); in sun8i_ce_pm_suspend()
735 clk_disable_unprepare(ce->ceclks[i]); in sun8i_ce_pm_suspend()
741 struct sun8i_ce_dev *ce = dev_get_drvdata(dev); in sun8i_ce_pm_resume() local
745 if (!ce->variant->ce_clks[i].name) in sun8i_ce_pm_resume()
747 err = clk_prepare_enable(ce->ceclks[i]); in sun8i_ce_pm_resume()
749 dev_err(ce->dev, "Cannot prepare_enable %s\n", in sun8i_ce_pm_resume()
750 ce->variant->ce_clks[i].name); in sun8i_ce_pm_resume()
754 err = reset_control_deassert(ce->reset); in sun8i_ce_pm_resume()
756 dev_err(ce->dev, "Cannot deassert reset control\n"); in sun8i_ce_pm_resume()
769 static int sun8i_ce_pm_init(struct sun8i_ce_dev *ce) in sun8i_ce_pm_init() argument
773 pm_runtime_use_autosuspend(ce->dev); in sun8i_ce_pm_init()
774 pm_runtime_set_autosuspend_delay(ce->dev, 2000); in sun8i_ce_pm_init()
776 err = pm_runtime_set_suspended(ce->dev); in sun8i_ce_pm_init()
779 pm_runtime_enable(ce->dev); in sun8i_ce_pm_init()
783 static void sun8i_ce_pm_exit(struct sun8i_ce_dev *ce) in sun8i_ce_pm_exit() argument
785 pm_runtime_disable(ce->dev); in sun8i_ce_pm_exit()
788 static int sun8i_ce_get_clks(struct sun8i_ce_dev *ce) in sun8i_ce_get_clks() argument
794 if (!ce->variant->ce_clks[i].name) in sun8i_ce_get_clks()
796 ce->ceclks[i] = devm_clk_get(ce->dev, ce->variant->ce_clks[i].name); in sun8i_ce_get_clks()
797 if (IS_ERR(ce->ceclks[i])) { in sun8i_ce_get_clks()
798 err = PTR_ERR(ce->ceclks[i]); in sun8i_ce_get_clks()
799 dev_err(ce->dev, "Cannot get %s CE clock err=%d\n", in sun8i_ce_get_clks()
800 ce->variant->ce_clks[i].name, err); in sun8i_ce_get_clks()
803 cr = clk_get_rate(ce->ceclks[i]); in sun8i_ce_get_clks()
806 if (ce->variant->ce_clks[i].freq > 0 && in sun8i_ce_get_clks()
807 cr != ce->variant->ce_clks[i].freq) { in sun8i_ce_get_clks()
808 dev_info(ce->dev, "Set %s clock to %lu (%lu Mhz) from %lu (%lu Mhz)\n", in sun8i_ce_get_clks()
809 ce->variant->ce_clks[i].name, in sun8i_ce_get_clks()
810 ce->variant->ce_clks[i].freq, in sun8i_ce_get_clks()
811 ce->variant->ce_clks[i].freq / 1000000, in sun8i_ce_get_clks()
813 err = clk_set_rate(ce->ceclks[i], ce->variant->ce_clks[i].freq); in sun8i_ce_get_clks()
815 dev_err(ce->dev, "Fail to set %s clk speed to %lu hz\n", in sun8i_ce_get_clks()
816 ce->variant->ce_clks[i].name, in sun8i_ce_get_clks()
817 ce->variant->ce_clks[i].freq); in sun8i_ce_get_clks()
819 if (ce->variant->ce_clks[i].max_freq > 0 && in sun8i_ce_get_clks()
820 cr > ce->variant->ce_clks[i].max_freq) in sun8i_ce_get_clks()
821 dev_warn(ce->dev, "Frequency for %s (%lu hz) is higher than datasheet's recommendation (%lu hz)", in sun8i_ce_get_clks()
822 ce->variant->ce_clks[i].name, cr, in sun8i_ce_get_clks()
823 ce->variant->ce_clks[i].max_freq); in sun8i_ce_get_clks()
828 static int sun8i_ce_register_algs(struct sun8i_ce_dev *ce) in sun8i_ce_register_algs() argument
834 ce_algs[i].ce = ce; in sun8i_ce_register_algs()
838 ce_method = ce->variant->alg_cipher[id]; in sun8i_ce_register_algs()
840 dev_dbg(ce->dev, in sun8i_ce_register_algs()
843 ce_algs[i].ce = NULL; in sun8i_ce_register_algs()
847 ce_method = ce->variant->op_mode[id]; in sun8i_ce_register_algs()
849 dev_dbg(ce->dev, "DEBUG: Blockmode of %s not supported\n", in sun8i_ce_register_algs()
851 ce_algs[i].ce = NULL; in sun8i_ce_register_algs()
854 dev_info(ce->dev, "Register %s\n", in sun8i_ce_register_algs()
858 dev_err(ce->dev, "ERROR: Fail to register %s\n", in sun8i_ce_register_algs()
860 ce_algs[i].ce = NULL; in sun8i_ce_register_algs()
866 ce_method = ce->variant->alg_hash[id]; in sun8i_ce_register_algs()
868 dev_info(ce->dev, in sun8i_ce_register_algs()
871 ce_algs[i].ce = NULL; in sun8i_ce_register_algs()
874 dev_info(ce->dev, "Register %s\n", in sun8i_ce_register_algs()
878 dev_err(ce->dev, "ERROR: Fail to register %s\n", in sun8i_ce_register_algs()
880 ce_algs[i].ce = NULL; in sun8i_ce_register_algs()
885 if (ce->variant->prng == CE_ID_NOTSUPP) { in sun8i_ce_register_algs()
886 dev_info(ce->dev, in sun8i_ce_register_algs()
889 ce_algs[i].ce = NULL; in sun8i_ce_register_algs()
892 dev_info(ce->dev, "Register %s\n", in sun8i_ce_register_algs()
896 dev_err(ce->dev, "Fail to register %s\n", in sun8i_ce_register_algs()
898 ce_algs[i].ce = NULL; in sun8i_ce_register_algs()
902 ce_algs[i].ce = NULL; in sun8i_ce_register_algs()
903 dev_err(ce->dev, "ERROR: tried to register an unknown algo\n"); in sun8i_ce_register_algs()
909 static void sun8i_ce_unregister_algs(struct sun8i_ce_dev *ce) in sun8i_ce_unregister_algs() argument
914 if (!ce_algs[i].ce) in sun8i_ce_unregister_algs()
918 dev_info(ce->dev, "Unregister %d %s\n", i, in sun8i_ce_unregister_algs()
923 dev_info(ce->dev, "Unregister %d %s\n", i, in sun8i_ce_unregister_algs()
928 dev_info(ce->dev, "Unregister %d %s\n", i, in sun8i_ce_unregister_algs()
938 struct sun8i_ce_dev *ce; in sun8i_ce_probe() local
942 ce = devm_kzalloc(&pdev->dev, sizeof(*ce), GFP_KERNEL); in sun8i_ce_probe()
943 if (!ce) in sun8i_ce_probe()
946 ce->dev = &pdev->dev; in sun8i_ce_probe()
947 platform_set_drvdata(pdev, ce); in sun8i_ce_probe()
949 ce->variant = of_device_get_match_data(&pdev->dev); in sun8i_ce_probe()
950 if (!ce->variant) { in sun8i_ce_probe()
955 ce->base = devm_platform_ioremap_resource(pdev, 0); in sun8i_ce_probe()
956 if (IS_ERR(ce->base)) in sun8i_ce_probe()
957 return PTR_ERR(ce->base); in sun8i_ce_probe()
959 err = sun8i_ce_get_clks(ce); in sun8i_ce_probe()
968 ce->reset = devm_reset_control_get(&pdev->dev, NULL); in sun8i_ce_probe()
969 if (IS_ERR(ce->reset)) in sun8i_ce_probe()
970 return dev_err_probe(&pdev->dev, PTR_ERR(ce->reset), in sun8i_ce_probe()
973 mutex_init(&ce->mlock); in sun8i_ce_probe()
974 mutex_init(&ce->rnglock); in sun8i_ce_probe()
976 err = sun8i_ce_allocate_chanlist(ce); in sun8i_ce_probe()
980 err = sun8i_ce_pm_init(ce); in sun8i_ce_probe()
985 "sun8i-ce-ns", ce); in sun8i_ce_probe()
987 dev_err(ce->dev, "Cannot request CryptoEngine Non-secure IRQ (err=%d)\n", err); in sun8i_ce_probe()
991 err = sun8i_ce_register_algs(ce); in sun8i_ce_probe()
995 err = pm_runtime_resume_and_get(ce->dev); in sun8i_ce_probe()
1000 sun8i_ce_hwrng_register(ce); in sun8i_ce_probe()
1003 v = readl(ce->base + CE_CTR); in sun8i_ce_probe()
1008 pm_runtime_put_sync(ce->dev); in sun8i_ce_probe()
1012 ce->dbgfs_dir = debugfs_create_dir("sun8i-ce", NULL); in sun8i_ce_probe()
1013 ce->dbgfs_stats = debugfs_create_file("stats", 0444, in sun8i_ce_probe()
1014 ce->dbgfs_dir, ce, in sun8i_ce_probe()
1020 sun8i_ce_unregister_algs(ce); in sun8i_ce_probe()
1022 sun8i_ce_pm_exit(ce); in sun8i_ce_probe()
1024 sun8i_ce_free_chanlist(ce, MAXFLOW - 1); in sun8i_ce_probe()
1030 struct sun8i_ce_dev *ce = platform_get_drvdata(pdev); in sun8i_ce_remove() local
1033 sun8i_ce_hwrng_unregister(ce); in sun8i_ce_remove()
1036 sun8i_ce_unregister_algs(ce); in sun8i_ce_remove()
1039 debugfs_remove_recursive(ce->dbgfs_dir); in sun8i_ce_remove()
1042 sun8i_ce_free_chanlist(ce, MAXFLOW - 1); in sun8i_ce_remove()
1044 sun8i_ce_pm_exit(ce); in sun8i_ce_remove()