summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/crypto/tegra-se.c71
1 files changed, 70 insertions, 1 deletions
diff --git a/drivers/crypto/tegra-se.c b/drivers/crypto/tegra-se.c
index a8287a786..e8daaabe5 100644
--- a/drivers/crypto/tegra-se.c
+++ b/drivers/crypto/tegra-se.c
@@ -26,6 +26,7 @@
26#include <linux/errno.h> 26#include <linux/errno.h>
27#include <linux/kernel.h> 27#include <linux/kernel.h>
28#include <linux/clk.h> 28#include <linux/clk.h>
29#include <linux/delay.h>
29#include <linux/platform_device.h> 30#include <linux/platform_device.h>
30#include <linux/scatterlist.h> 31#include <linux/scatterlist.h>
31#include <linux/dma-mapping.h> 32#include <linux/dma-mapping.h>
@@ -38,6 +39,7 @@
38#include <linux/errno.h> 39#include <linux/errno.h>
39#include <soc/tegra/fuse.h> 40#include <soc/tegra/fuse.h>
40#include <soc/tegra/chip-id.h> 41#include <soc/tegra/chip-id.h>
42#include <soc/tegra/ahb.h>
41#include <crypto/scatterwalk.h> 43#include <crypto/scatterwalk.h>
42#include <soc/tegra/pmc.h> 44#include <soc/tegra/pmc.h>
43#include <crypto/algapi.h> 45#include <crypto/algapi.h>
@@ -112,6 +114,7 @@ struct tegra_se_chipdata {
112 bool mccif_supported; 114 bool mccif_supported;
113 bool rsa_key_rw_op; 115 bool rsa_key_rw_op;
114 u32 aes_keydata_reg_sz; 116 u32 aes_keydata_reg_sz;
117 bool ahb_ack;
115}; 118};
116 119
117struct tegra_se_dev { 120struct tegra_se_dev {
@@ -141,6 +144,7 @@ struct tegra_se_dev {
141 bool work_q_busy; /* Work queue busy status */ 144 bool work_q_busy; /* Work queue busy status */
142 bool polling; 145 bool polling;
143 struct tegra_se_chipdata *chipdata; /* chip specific data */ 146 struct tegra_se_chipdata *chipdata; /* chip specific data */
147 u32 ahb_id;
144}; 148};
145 149
146static struct tegra_se_dev *sg_tegra_se_dev; 150static struct tegra_se_dev *sg_tegra_se_dev;
@@ -711,7 +715,7 @@ static int tegra_se_start_operation(struct tegra_se_dev *se_dev, u32 nbytes,
711{ 715{
712 u32 nblocks = nbytes / TEGRA_SE_AES_BLOCK_SIZE; 716 u32 nblocks = nbytes / TEGRA_SE_AES_BLOCK_SIZE;
713 int ret = 0, err = 0; 717 int ret = 0, err = 0;
714 u32 val = 0; 718 u32 val = 0, timeout = TEGRA_SE_TIMEOUT_1S;
715 719
716 if ((tegra_get_chip_id() == TEGRA114) && 720 if ((tegra_get_chip_id() == TEGRA114) &&
717 nblocks > SE_MAX_LAST_BLOCK_SIZE) 721 nblocks > SE_MAX_LAST_BLOCK_SIZE)
@@ -754,6 +758,7 @@ static int tegra_se_start_operation(struct tegra_se_dev *se_dev, u32 nbytes,
754 if (!SE_OP_DONE(val, OP_DONE)) { 758 if (!SE_OP_DONE(val, OP_DONE)) {
755 dev_err(se_dev->dev, "\nAbrupt end of operation\n"); 759 dev_err(se_dev->dev, "\nAbrupt end of operation\n");
756 err = -EINVAL; 760 err = -EINVAL;
761 goto exit;
757 } 762 }
758 } else { 763 } else {
759 ret = wait_for_completion_timeout(&se_dev->complete, 764 ret = wait_for_completion_timeout(&se_dev->complete,
@@ -761,9 +766,37 @@ static int tegra_se_start_operation(struct tegra_se_dev *se_dev, u32 nbytes,
761 if (ret == 0) { 766 if (ret == 0) {
762 dev_err(se_dev->dev, "operation timed out no interrupt\n"); 767 dev_err(se_dev->dev, "operation timed out no interrupt\n");
763 err = -ETIMEDOUT; 768 err = -ETIMEDOUT;
769 goto exit;
770 }
771 }
772
773 if (se_dev->chipdata->ahb_ack) {
774 /* Ensure data is out from SE using MEM_INTERFACE signal */
775 val = se_readl(se_dev, SE_STATUS_REG_OFFSET);
776 while (val & SE_STATUS_MEM_INTERFACE(MEM_INTERFACE_BUSY)) {
777 if (!timeout) {
778 dev_err(se_dev->dev, "mem operation timeout\n");
779 err = -ETIMEDOUT;
780 goto exit;
781 }
782 udelay(1);
783 timeout--;
784 val = se_readl(se_dev, SE_STATUS_REG_OFFSET);
785 }
786
787 timeout = TEGRA_SE_TIMEOUT_1S;
788 while (tegra_ahb_is_mem_wrque_busy(se_dev->ahb_id)) {
789 if (!timeout) {
790 dev_err(se_dev->dev, "mem operation timeout\n");
791 err = -ETIMEDOUT;
792 goto exit;
793 }
794 udelay(1);
795 timeout--;
764 } 796 }
765 } 797 }
766 798
799exit:
767 return err; 800 return err;
768} 801}
769 802
@@ -2468,6 +2501,7 @@ static struct tegra_se_chipdata tegra_se_chipdata = {
2468 .mccif_supported = false, 2501 .mccif_supported = false,
2469 .rsa_key_rw_op = true, 2502 .rsa_key_rw_op = true,
2470 .aes_keydata_reg_sz = 128, 2503 .aes_keydata_reg_sz = 128,
2504 .ahb_ack = false,
2471}; 2505};
2472 2506
2473static struct tegra_se_chipdata tegra11_se_chipdata = { 2507static struct tegra_se_chipdata tegra11_se_chipdata = {
@@ -2486,6 +2520,7 @@ static struct tegra_se_chipdata tegra11_se_chipdata = {
2486 .mccif_supported = false, 2520 .mccif_supported = false,
2487 .rsa_key_rw_op = true, 2521 .rsa_key_rw_op = true,
2488 .aes_keydata_reg_sz = 128, 2522 .aes_keydata_reg_sz = 128,
2523 .ahb_ack = false,
2489}; 2524};
2490 2525
2491static struct tegra_se_chipdata tegra21_se_chipdata = { 2526static struct tegra_se_chipdata tegra21_se_chipdata = {
@@ -2504,6 +2539,26 @@ static struct tegra_se_chipdata tegra21_se_chipdata = {
2504 .mccif_supported = true, 2539 .mccif_supported = true,
2505 .rsa_key_rw_op = false, 2540 .rsa_key_rw_op = false,
2506 .aes_keydata_reg_sz = 32, 2541 .aes_keydata_reg_sz = 32,
2542 .ahb_ack = false,
2543};
2544
2545static struct tegra_se_chipdata tegra210b01_se_chipdata = {
2546 .rsa_supported = true,
2547 .cprng_supported = false,
2548 .drbg_supported = true,
2549 .const_freq = true,
2550 .aes_freq = 510000000,
2551 .rng_freq = 510000000,
2552 .sha1_freq = 510000000,
2553 .sha224_freq = 510000000,
2554 .sha256_freq = 510000000,
2555 .sha384_freq = 510000000,
2556 .sha512_freq = 510000000,
2557 .rsa_freq = 510000000,
2558 .mccif_supported = true,
2559 .rsa_key_rw_op = false,
2560 .aes_keydata_reg_sz = 32,
2561 .ahb_ack = true,
2507}; 2562};
2508 2563
2509static struct of_device_id tegra_se_of_match[] = { 2564static struct of_device_id tegra_se_of_match[] = {
@@ -2514,6 +2569,10 @@ static struct of_device_id tegra_se_of_match[] = {
2514 { 2569 {
2515 .compatible = "nvidia,tegra210-se", 2570 .compatible = "nvidia,tegra210-se",
2516 .data = &tegra21_se_chipdata, 2571 .data = &tegra21_se_chipdata,
2572 },
2573 {
2574 .compatible = "nvidia,tegra210b01-se",
2575 .data = &tegra210b01_se_chipdata,
2517 }, { 2576 }, {
2518 } 2577 }
2519}; 2578};
@@ -2550,6 +2609,16 @@ static int tegra_se_probe(struct platform_device *pdev)
2550 (struct tegra_se_chipdata *)pdev->id_entry->driver_data; 2609 (struct tegra_se_chipdata *)pdev->id_entry->driver_data;
2551 } 2610 }
2552 2611
2612 if (se_dev->chipdata->ahb_ack) {
2613 val = tegra_ahb_get_master_id(&pdev->dev);
2614 if (val < 0) {
2615 err = -EINVAL;
2616 dev_err(&pdev->dev, "Error: AHB master id not found\n");
2617 goto fail;
2618 } else
2619 se_dev->ahb_id = val;
2620 }
2621
2553 spin_lock_init(&se_dev->lock); 2622 spin_lock_init(&se_dev->lock);
2554 crypto_init_queue(&se_dev->queue, TEGRA_SE_CRYPTO_QUEUE_LENGTH); 2623 crypto_init_queue(&se_dev->queue, TEGRA_SE_CRYPTO_QUEUE_LENGTH);
2555 platform_set_drvdata(pdev, se_dev); 2624 platform_set_drvdata(pdev, se_dev);