Lines Matching refs:ss
61 int sun8i_ss_get_engine_number(struct sun8i_ss_dev *ss) in sun8i_ss_get_engine_number() argument
63 return atomic_inc_return(&ss->flow) % MAXFLOW; in sun8i_ss_get_engine_number()
66 int sun8i_ss_run_task(struct sun8i_ss_dev *ss, struct sun8i_cipher_req_ctx *rctx, in sun8i_ss_run_task() argument
75 ss->flows[flow].stat_req++; in sun8i_ss_run_task()
106 mutex_lock(&ss->mlock); in sun8i_ss_run_task()
107 writel(rctx->p_key, ss->base + SS_KEY_ADR_REG); in sun8i_ss_run_task()
112 writel(rctx->p_iv[0], ss->base + SS_IV_ADR_REG); in sun8i_ss_run_task()
114 writel(rctx->t_dst[i - 1].addr + rctx->t_dst[i - 1].len * 4 - ivlen, ss->base + SS_IV_ADR_REG); in sun8i_ss_run_task()
116 writel(rctx->p_iv[i], ss->base + SS_IV_ADR_REG); in sun8i_ss_run_task()
120 dev_dbg(ss->dev, in sun8i_ss_run_task()
127 writel(rctx->t_src[i].addr, ss->base + SS_SRC_ADR_REG); in sun8i_ss_run_task()
128 writel(rctx->t_dst[i].addr, ss->base + SS_DST_ADR_REG); in sun8i_ss_run_task()
129 writel(rctx->t_src[i].len, ss->base + SS_LEN_ADR_REG); in sun8i_ss_run_task()
131 reinit_completion(&ss->flows[flow].complete); in sun8i_ss_run_task()
132 ss->flows[flow].status = 0; in sun8i_ss_run_task()
135 writel(v, ss->base + SS_CTL_REG); in sun8i_ss_run_task()
136 mutex_unlock(&ss->mlock); in sun8i_ss_run_task()
137 wait_for_completion_interruptible_timeout(&ss->flows[flow].complete, in sun8i_ss_run_task()
139 if (ss->flows[flow].status == 0) { in sun8i_ss_run_task()
140 dev_err(ss->dev, "DMA timeout for %s\n", name); in sun8i_ss_run_task()
150 struct sun8i_ss_dev *ss = (struct sun8i_ss_dev *)data; in ss_irq_handler() local
154 p = readl(ss->base + SS_INT_STA_REG); in ss_irq_handler()
157 writel(BIT(flow), ss->base + SS_INT_STA_REG); in ss_irq_handler()
158 ss->flows[flow].status = 1; in ss_irq_handler()
159 complete(&ss->flows[flow].complete); in ss_irq_handler()
450 struct sun8i_ss_dev *ss = seq->private; in sun8i_ss_debugfs_show() local
454 seq_printf(seq, "Channel %d: nreq %lu\n", i, ss->flows[i].stat_req); in sun8i_ss_debugfs_show()
457 if (!ss_algs[i].ss) in sun8i_ss_debugfs_show()
507 static void sun8i_ss_free_flows(struct sun8i_ss_dev *ss, int i) in sun8i_ss_free_flows() argument
510 crypto_engine_exit(ss->flows[i].engine); in sun8i_ss_free_flows()
518 static int allocate_flows(struct sun8i_ss_dev *ss) in allocate_flows() argument
522 ss->flows = devm_kcalloc(ss->dev, MAXFLOW, sizeof(struct sun8i_ss_flow), in allocate_flows()
524 if (!ss->flows) in allocate_flows()
528 init_completion(&ss->flows[i].complete); in allocate_flows()
530 ss->flows[i].biv = devm_kmalloc(ss->dev, AES_BLOCK_SIZE, in allocate_flows()
532 if (!ss->flows[i].biv) { in allocate_flows()
538 ss->flows[i].iv[j] = devm_kmalloc(ss->dev, AES_BLOCK_SIZE, in allocate_flows()
540 if (!ss->flows[i].iv[j]) { in allocate_flows()
547 ss->flows[i].pad = devm_kmalloc(ss->dev, MAX_PAD_SIZE, in allocate_flows()
549 if (!ss->flows[i].pad) { in allocate_flows()
553 ss->flows[i].result = in allocate_flows()
554 devm_kmalloc(ss->dev, max(SHA256_DIGEST_SIZE, in allocate_flows()
557 if (!ss->flows[i].result) { in allocate_flows()
562 ss->flows[i].engine = crypto_engine_alloc_init(ss->dev, true); in allocate_flows()
563 if (!ss->flows[i].engine) { in allocate_flows()
564 dev_err(ss->dev, "Cannot allocate engine\n"); in allocate_flows()
569 err = crypto_engine_start(ss->flows[i].engine); in allocate_flows()
571 dev_err(ss->dev, "Cannot start engine\n"); in allocate_flows()
577 sun8i_ss_free_flows(ss, i); in allocate_flows()
587 struct sun8i_ss_dev *ss = dev_get_drvdata(dev); in sun8i_ss_pm_suspend() local
590 reset_control_assert(ss->reset); in sun8i_ss_pm_suspend()
592 clk_disable_unprepare(ss->ssclks[i]); in sun8i_ss_pm_suspend()
598 struct sun8i_ss_dev *ss = dev_get_drvdata(dev); in sun8i_ss_pm_resume() local
602 if (!ss->variant->ss_clks[i].name) in sun8i_ss_pm_resume()
604 err = clk_prepare_enable(ss->ssclks[i]); in sun8i_ss_pm_resume()
606 dev_err(ss->dev, "Cannot prepare_enable %s\n", in sun8i_ss_pm_resume()
607 ss->variant->ss_clks[i].name); in sun8i_ss_pm_resume()
611 err = reset_control_deassert(ss->reset); in sun8i_ss_pm_resume()
613 dev_err(ss->dev, "Cannot deassert reset control\n"); in sun8i_ss_pm_resume()
617 writel(BIT(0) | BIT(1), ss->base + SS_INT_CTL_REG); in sun8i_ss_pm_resume()
629 static int sun8i_ss_pm_init(struct sun8i_ss_dev *ss) in sun8i_ss_pm_init() argument
633 pm_runtime_use_autosuspend(ss->dev); in sun8i_ss_pm_init()
634 pm_runtime_set_autosuspend_delay(ss->dev, 2000); in sun8i_ss_pm_init()
636 err = pm_runtime_set_suspended(ss->dev); in sun8i_ss_pm_init()
639 pm_runtime_enable(ss->dev); in sun8i_ss_pm_init()
643 static void sun8i_ss_pm_exit(struct sun8i_ss_dev *ss) in sun8i_ss_pm_exit() argument
645 pm_runtime_disable(ss->dev); in sun8i_ss_pm_exit()
648 static int sun8i_ss_register_algs(struct sun8i_ss_dev *ss) in sun8i_ss_register_algs() argument
654 ss_algs[i].ss = ss; in sun8i_ss_register_algs()
658 ss_method = ss->variant->alg_cipher[id]; in sun8i_ss_register_algs()
660 dev_info(ss->dev, in sun8i_ss_register_algs()
663 ss_algs[i].ss = NULL; in sun8i_ss_register_algs()
667 ss_method = ss->variant->op_mode[id]; in sun8i_ss_register_algs()
669 dev_info(ss->dev, "DEBUG: Blockmode of %s not supported\n", in sun8i_ss_register_algs()
671 ss_algs[i].ss = NULL; in sun8i_ss_register_algs()
674 dev_info(ss->dev, "DEBUG: Register %s\n", in sun8i_ss_register_algs()
678 dev_err(ss->dev, "Fail to register %s\n", in sun8i_ss_register_algs()
680 ss_algs[i].ss = NULL; in sun8i_ss_register_algs()
687 dev_err(ss->dev, "Fail to register %s\n", in sun8i_ss_register_algs()
689 ss_algs[i].ss = NULL; in sun8i_ss_register_algs()
694 ss_method = ss->variant->alg_hash[id]; in sun8i_ss_register_algs()
696 dev_info(ss->dev, in sun8i_ss_register_algs()
699 ss_algs[i].ss = NULL; in sun8i_ss_register_algs()
702 dev_info(ss->dev, "Register %s\n", in sun8i_ss_register_algs()
706 dev_err(ss->dev, "ERROR: Fail to register %s\n", in sun8i_ss_register_algs()
708 ss_algs[i].ss = NULL; in sun8i_ss_register_algs()
713 ss_algs[i].ss = NULL; in sun8i_ss_register_algs()
714 dev_err(ss->dev, "ERROR: tried to register an unknown algo\n"); in sun8i_ss_register_algs()
720 static void sun8i_ss_unregister_algs(struct sun8i_ss_dev *ss) in sun8i_ss_unregister_algs() argument
725 if (!ss_algs[i].ss) in sun8i_ss_unregister_algs()
729 dev_info(ss->dev, "Unregister %d %s\n", i, in sun8i_ss_unregister_algs()
734 dev_info(ss->dev, "Unregister %d %s\n", i, in sun8i_ss_unregister_algs()
739 dev_info(ss->dev, "Unregister %d %s\n", i, in sun8i_ss_unregister_algs()
747 static int sun8i_ss_get_clks(struct sun8i_ss_dev *ss) in sun8i_ss_get_clks() argument
753 if (!ss->variant->ss_clks[i].name) in sun8i_ss_get_clks()
755 ss->ssclks[i] = devm_clk_get(ss->dev, ss->variant->ss_clks[i].name); in sun8i_ss_get_clks()
756 if (IS_ERR(ss->ssclks[i])) { in sun8i_ss_get_clks()
757 err = PTR_ERR(ss->ssclks[i]); in sun8i_ss_get_clks()
758 dev_err(ss->dev, "Cannot get %s SS clock err=%d\n", in sun8i_ss_get_clks()
759 ss->variant->ss_clks[i].name, err); in sun8i_ss_get_clks()
762 cr = clk_get_rate(ss->ssclks[i]); in sun8i_ss_get_clks()
765 if (ss->variant->ss_clks[i].freq > 0 && in sun8i_ss_get_clks()
766 cr != ss->variant->ss_clks[i].freq) { in sun8i_ss_get_clks()
767 dev_info(ss->dev, "Set %s clock to %lu (%lu Mhz) from %lu (%lu Mhz)\n", in sun8i_ss_get_clks()
768 ss->variant->ss_clks[i].name, in sun8i_ss_get_clks()
769 ss->variant->ss_clks[i].freq, in sun8i_ss_get_clks()
770 ss->variant->ss_clks[i].freq / 1000000, in sun8i_ss_get_clks()
772 err = clk_set_rate(ss->ssclks[i], ss->variant->ss_clks[i].freq); in sun8i_ss_get_clks()
774 dev_err(ss->dev, "Fail to set %s clk speed to %lu hz\n", in sun8i_ss_get_clks()
775 ss->variant->ss_clks[i].name, in sun8i_ss_get_clks()
776 ss->variant->ss_clks[i].freq); in sun8i_ss_get_clks()
778 if (ss->variant->ss_clks[i].max_freq > 0 && in sun8i_ss_get_clks()
779 cr > ss->variant->ss_clks[i].max_freq) in sun8i_ss_get_clks()
780 dev_warn(ss->dev, "Frequency for %s (%lu hz) is higher than datasheet's recommendation (%lu hz)", in sun8i_ss_get_clks()
781 ss->variant->ss_clks[i].name, cr, in sun8i_ss_get_clks()
782 ss->variant->ss_clks[i].max_freq); in sun8i_ss_get_clks()
789 struct sun8i_ss_dev *ss; in sun8i_ss_probe() local
793 ss = devm_kzalloc(&pdev->dev, sizeof(*ss), GFP_KERNEL); in sun8i_ss_probe()
794 if (!ss) in sun8i_ss_probe()
797 ss->dev = &pdev->dev; in sun8i_ss_probe()
798 platform_set_drvdata(pdev, ss); in sun8i_ss_probe()
800 ss->variant = of_device_get_match_data(&pdev->dev); in sun8i_ss_probe()
801 if (!ss->variant) { in sun8i_ss_probe()
806 ss->base = devm_platform_ioremap_resource(pdev, 0); in sun8i_ss_probe()
807 if (IS_ERR(ss->base)) in sun8i_ss_probe()
808 return PTR_ERR(ss->base); in sun8i_ss_probe()
810 err = sun8i_ss_get_clks(ss); in sun8i_ss_probe()
818 ss->reset = devm_reset_control_get(&pdev->dev, NULL); in sun8i_ss_probe()
819 if (IS_ERR(ss->reset)) in sun8i_ss_probe()
820 return dev_err_probe(&pdev->dev, PTR_ERR(ss->reset), in sun8i_ss_probe()
823 mutex_init(&ss->mlock); in sun8i_ss_probe()
825 err = allocate_flows(ss); in sun8i_ss_probe()
829 err = sun8i_ss_pm_init(ss); in sun8i_ss_probe()
833 err = devm_request_irq(&pdev->dev, irq, ss_irq_handler, 0, "sun8i-ss", ss); in sun8i_ss_probe()
835 dev_err(ss->dev, "Cannot request SecuritySystem IRQ (err=%d)\n", err); in sun8i_ss_probe()
839 err = sun8i_ss_register_algs(ss); in sun8i_ss_probe()
843 err = pm_runtime_resume_and_get(ss->dev); in sun8i_ss_probe()
847 v = readl(ss->base + SS_CTL_REG); in sun8i_ss_probe()
852 pm_runtime_put_sync(ss->dev); in sun8i_ss_probe()
856 ss->dbgfs_dir = debugfs_create_dir("sun8i-ss", NULL); in sun8i_ss_probe()
857 ss->dbgfs_stats = debugfs_create_file("stats", 0444, in sun8i_ss_probe()
858 ss->dbgfs_dir, ss, in sun8i_ss_probe()
864 sun8i_ss_unregister_algs(ss); in sun8i_ss_probe()
866 sun8i_ss_pm_exit(ss); in sun8i_ss_probe()
868 sun8i_ss_free_flows(ss, MAXFLOW - 1); in sun8i_ss_probe()
874 struct sun8i_ss_dev *ss = platform_get_drvdata(pdev); in sun8i_ss_remove() local
876 sun8i_ss_unregister_algs(ss); in sun8i_ss_remove()
879 debugfs_remove_recursive(ss->dbgfs_dir); in sun8i_ss_remove()
882 sun8i_ss_free_flows(ss, MAXFLOW - 1); in sun8i_ss_remove()
884 sun8i_ss_pm_exit(ss); in sun8i_ss_remove()