aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/crypto/hifn_795x.c110
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
51static char hifn_pll_ref[sizeof("extNNN")] = "ext";
52module_param_string(hifn_pll_ref, hifn_pll_ref, sizeof(hifn_pll_ref), 0444);
53MODULE_PARM_DESC(hifn_pll_ref,
54 "PLL reference clock (pci[freq] or ext[freq], default ext)");
55
50static atomic_t hifn_dev_number; 56static 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 */
912static 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
874static void hifn_init_registers(struct hifn_device *dev) 957static 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
2622static int __devinit hifn_init(void) 2705static 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",