diff options
Diffstat (limited to 'drivers/crypto')
-rw-r--r-- | drivers/crypto/hifn_795x.c | 110 |
1 files changed, 108 insertions, 2 deletions
diff --git a/drivers/crypto/hifn_795x.c b/drivers/crypto/hifn_795x.c index bf817d4ecae2..de594bc97742 100644 --- a/drivers/crypto/hifn_795x.c +++ b/drivers/crypto/hifn_795x.c | |||
@@ -19,6 +19,7 @@ | |||
19 | 19 | ||
20 | #include <linux/kernel.h> | 20 | #include <linux/kernel.h> |
21 | #include <linux/module.h> | 21 | #include <linux/module.h> |
22 | #include <linux/moduleparam.h> | ||
22 | #include <linux/mod_devicetable.h> | 23 | #include <linux/mod_devicetable.h> |
23 | #include <linux/interrupt.h> | 24 | #include <linux/interrupt.h> |
24 | #include <linux/pci.h> | 25 | #include <linux/pci.h> |
@@ -47,6 +48,11 @@ | |||
47 | #define dprintk(f, a...) do {} while (0) | 48 | #define dprintk(f, a...) do {} while (0) |
48 | #endif | 49 | #endif |
49 | 50 | ||
51 | static char hifn_pll_ref[sizeof("extNNN")] = "ext"; | ||
52 | module_param_string(hifn_pll_ref, hifn_pll_ref, sizeof(hifn_pll_ref), 0444); | ||
53 | MODULE_PARM_DESC(hifn_pll_ref, | ||
54 | "PLL reference clock (pci[freq] or ext[freq], default ext)"); | ||
55 | |||
50 | static atomic_t hifn_dev_number; | 56 | static atomic_t hifn_dev_number; |
51 | 57 | ||
52 | #define ACRYPTO_OP_DECRYPT 0 | 58 | #define ACRYPTO_OP_DECRYPT 0 |
@@ -286,7 +292,26 @@ static atomic_t hifn_dev_number; | |||
286 | #define HIFN_DMACNFG_DMARESET 0x00000002 /* DMA Reset # */ | 292 | #define HIFN_DMACNFG_DMARESET 0x00000002 /* DMA Reset # */ |
287 | #define HIFN_DMACNFG_MSTRESET 0x00000001 /* Master Reset # */ | 293 | #define HIFN_DMACNFG_MSTRESET 0x00000001 /* Master Reset # */ |
288 | 294 | ||
289 | #define HIFN_PLL_7956 0x00001d18 /* 7956 PLL config value */ | 295 | /* PLL configuration register */ |
296 | #define HIFN_PLL_REF_CLK_HBI 0x00000000 /* HBI reference clock */ | ||
297 | #define HIFN_PLL_REF_CLK_PLL 0x00000001 /* PLL reference clock */ | ||
298 | #define HIFN_PLL_BP 0x00000002 /* Reference clock bypass */ | ||
299 | #define HIFN_PLL_PK_CLK_HBI 0x00000000 /* PK engine HBI clock */ | ||
300 | #define HIFN_PLL_PK_CLK_PLL 0x00000008 /* PK engine PLL clock */ | ||
301 | #define HIFN_PLL_PE_CLK_HBI 0x00000000 /* PE engine HBI clock */ | ||
302 | #define HIFN_PLL_PE_CLK_PLL 0x00000010 /* PE engine PLL clock */ | ||
303 | #define HIFN_PLL_RESERVED_1 0x00000400 /* Reserved bit, must be 1 */ | ||
304 | #define HIFN_PLL_ND_SHIFT 11 /* Clock multiplier shift */ | ||
305 | #define HIFN_PLL_ND_MULT_2 0x00000000 /* PLL clock multiplier 2 */ | ||
306 | #define HIFN_PLL_ND_MULT_4 0x00000800 /* PLL clock multiplier 4 */ | ||
307 | #define HIFN_PLL_ND_MULT_6 0x00001000 /* PLL clock multiplier 6 */ | ||
308 | #define HIFN_PLL_ND_MULT_8 0x00001800 /* PLL clock multiplier 8 */ | ||
309 | #define HIFN_PLL_ND_MULT_10 0x00002000 /* PLL clock multiplier 10 */ | ||
310 | #define HIFN_PLL_ND_MULT_12 0x00002800 /* PLL clock multiplier 12 */ | ||
311 | #define HIFN_PLL_IS_1_8 0x00000000 /* charge pump (mult. 1-8) */ | ||
312 | #define HIFN_PLL_IS_9_12 0x00010000 /* charge pump (mult. 9-12) */ | ||
313 | |||
314 | #define HIFN_PLL_FCK_MAX 266 /* Maximum PLL frequency */ | ||
290 | 315 | ||
291 | /* Public key reset register (HIFN_1_PUB_RESET) */ | 316 | /* Public key reset register (HIFN_1_PUB_RESET) */ |
292 | #define HIFN_PUBRST_RESET 0x00000001 /* reset public/rng unit */ | 317 | #define HIFN_PUBRST_RESET 0x00000001 /* reset public/rng unit */ |
@@ -871,6 +896,64 @@ static void hifn_init_dma(struct hifn_device *dev) | |||
871 | dma->cmdk = dma->srck = dma->dstk = dma->resk = 0; | 896 | dma->cmdk = dma->srck = dma->dstk = dma->resk = 0; |
872 | } | 897 | } |
873 | 898 | ||
899 | /* | ||
900 | * Initialize the PLL. We need to know the frequency of the reference clock | ||
901 | * to calculate the optimal multiplier. For PCI we assume 66MHz, since that | ||
902 | * allows us to operate without the risk of overclocking the chip. If it | ||
903 | * actually uses 33MHz, the chip will operate at half the speed, this can be | ||
904 | * overriden by specifying the frequency as module parameter (pci33). | ||
905 | * | ||
906 | * Unfortunately the PCI clock is not very suitable since the HIFN needs a | ||
907 | * stable clock and the PCI clock frequency may vary, so the default is the | ||
908 | * external clock. There is no way to find out its frequency, we default to | ||
909 | * 66MHz since according to Mike Ham of HiFn, almost every board in existence | ||
910 | * has an external crystal populated at 66MHz. | ||
911 | */ | ||
912 | static void hifn_init_pll(struct hifn_device *dev) | ||
913 | { | ||
914 | unsigned int freq, m; | ||
915 | u32 pllcfg; | ||
916 | |||
917 | pllcfg = HIFN_1_PLL | HIFN_PLL_RESERVED_1; | ||
918 | |||
919 | if (strncmp(hifn_pll_ref, "ext", 3) == 0) | ||
920 | pllcfg |= HIFN_PLL_REF_CLK_PLL; | ||
921 | else | ||
922 | pllcfg |= HIFN_PLL_REF_CLK_HBI; | ||
923 | |||
924 | if (hifn_pll_ref[3] != '\0') | ||
925 | freq = simple_strtoul(hifn_pll_ref + 3, NULL, 10); | ||
926 | else { | ||
927 | freq = 66; | ||
928 | printk(KERN_INFO "hifn795x: assuming %uMHz clock speed, " | ||
929 | "override with hifn_pll_ref=%.3s<frequency>\n", | ||
930 | freq, hifn_pll_ref); | ||
931 | } | ||
932 | |||
933 | m = HIFN_PLL_FCK_MAX / freq; | ||
934 | |||
935 | pllcfg |= (m / 2 - 1) << HIFN_PLL_ND_SHIFT; | ||
936 | if (m <= 8) | ||
937 | pllcfg |= HIFN_PLL_IS_1_8; | ||
938 | else | ||
939 | pllcfg |= HIFN_PLL_IS_9_12; | ||
940 | |||
941 | /* Select clock source and enable clock bypass */ | ||
942 | hifn_write_1(dev, HIFN_1_PLL, pllcfg | | ||
943 | HIFN_PLL_PK_CLK_HBI | HIFN_PLL_PE_CLK_HBI | HIFN_PLL_BP); | ||
944 | |||
945 | /* Let the chip lock to the input clock */ | ||
946 | mdelay(10); | ||
947 | |||
948 | /* Disable clock bypass */ | ||
949 | hifn_write_1(dev, HIFN_1_PLL, pllcfg | | ||
950 | HIFN_PLL_PK_CLK_HBI | HIFN_PLL_PE_CLK_HBI); | ||
951 | |||
952 | /* Switch the engines to the PLL */ | ||
953 | hifn_write_1(dev, HIFN_1_PLL, pllcfg | | ||
954 | HIFN_PLL_PK_CLK_PLL | HIFN_PLL_PE_CLK_PLL); | ||
955 | } | ||
956 | |||
874 | static void hifn_init_registers(struct hifn_device *dev) | 957 | static void hifn_init_registers(struct hifn_device *dev) |
875 | { | 958 | { |
876 | u32 dptr = dev->desc_dma; | 959 | u32 dptr = dev->desc_dma; |
@@ -938,7 +1021,7 @@ static void hifn_init_registers(struct hifn_device *dev) | |||
938 | #else | 1021 | #else |
939 | hifn_write_0(dev, HIFN_0_PUCNFG, 0x10342); | 1022 | hifn_write_0(dev, HIFN_0_PUCNFG, 0x10342); |
940 | #endif | 1023 | #endif |
941 | hifn_write_1(dev, HIFN_1_PLL, HIFN_PLL_7956); | 1024 | hifn_init_pll(dev); |
942 | 1025 | ||
943 | hifn_write_0(dev, HIFN_0_PUISR, HIFN_PUISR_DSTOVER); | 1026 | hifn_write_0(dev, HIFN_0_PUISR, HIFN_PUISR_DSTOVER); |
944 | hifn_write_1(dev, HIFN_1_DMA_CNFG, HIFN_DMACNFG_MSTRESET | | 1027 | hifn_write_1(dev, HIFN_1_DMA_CNFG, HIFN_DMACNFG_MSTRESET | |
@@ -2621,8 +2704,31 @@ static struct pci_driver hifn_pci_driver = { | |||
2621 | 2704 | ||
2622 | static int __devinit hifn_init(void) | 2705 | static int __devinit hifn_init(void) |
2623 | { | 2706 | { |
2707 | unsigned int freq; | ||
2624 | int err; | 2708 | int err; |
2625 | 2709 | ||
2710 | if (strncmp(hifn_pll_ref, "ext", 3) && | ||
2711 | strncmp(hifn_pll_ref, "pci", 3)) { | ||
2712 | printk(KERN_ERR "hifn795x: invalid hifn_pll_ref clock, " | ||
2713 | "must be pci or ext"); | ||
2714 | return -EINVAL; | ||
2715 | } | ||
2716 | |||
2717 | /* | ||
2718 | * For the 7955/7956 the reference clock frequency must be in the | ||
2719 | * range of 20MHz-100MHz. For the 7954 the upper bound is 66.67MHz, | ||
2720 | * but this chip is currently not supported. | ||
2721 | */ | ||
2722 | if (hifn_pll_ref[3] != '\0') { | ||
2723 | freq = simple_strtoul(hifn_pll_ref + 3, NULL, 10); | ||
2724 | if (freq < 20 || freq > 100) { | ||
2725 | printk(KERN_ERR "hifn795x: invalid hifn_pll_ref " | ||
2726 | "frequency, must be in the range " | ||
2727 | "of 20-100"); | ||
2728 | return -EINVAL; | ||
2729 | } | ||
2730 | } | ||
2731 | |||
2626 | err = pci_register_driver(&hifn_pci_driver); | 2732 | err = pci_register_driver(&hifn_pci_driver); |
2627 | if (err < 0) { | 2733 | if (err < 0) { |
2628 | dprintk("Failed to register PCI driver for %s device.\n", | 2734 | dprintk("Failed to register PCI driver for %s device.\n", |