1 // SPDX-License-Identifier: GPL-2.0-only
3 * Cavium ThunderX SPI driver.
5 * Copyright (C) 2016 Cavium Inc.
6 * Authors: Jan Glauber <jglauber@cavium.com>
9 #include <linux/module.h>
10 #include <linux/pci.h>
11 #include <linux/spi/spi.h>
13 #include "spi-cavium.h"
15 #define DRV_NAME "spi-thunderx"
17 #define SYS_FREQ_DEFAULT 700000000 /* 700 Mhz */
19 static int thunderx_spi_probe(struct pci_dev
*pdev
,
20 const struct pci_device_id
*ent
)
22 struct device
*dev
= &pdev
->dev
;
23 struct spi_master
*master
;
27 master
= spi_alloc_master(dev
, sizeof(struct octeon_spi
));
31 p
= spi_master_get_devdata(master
);
33 ret
= pcim_enable_device(pdev
);
37 ret
= pci_request_regions(pdev
, DRV_NAME
);
41 p
->register_base
= pcim_iomap(pdev
, 0, pci_resource_len(pdev
, 0));
42 if (!p
->register_base
) {
47 p
->regs
.config
= 0x1000;
48 p
->regs
.status
= 0x1008;
50 p
->regs
.data
= 0x1080;
52 p
->clk
= devm_clk_get(dev
, NULL
);
54 ret
= PTR_ERR(p
->clk
);
58 ret
= clk_prepare_enable(p
->clk
);
62 p
->sys_freq
= clk_get_rate(p
->clk
);
64 p
->sys_freq
= SYS_FREQ_DEFAULT
;
65 dev_info(dev
, "Set system clock to %u\n", p
->sys_freq
);
67 master
->flags
= SPI_MASTER_HALF_DUPLEX
;
68 master
->num_chipselect
= 4;
69 master
->mode_bits
= SPI_CPHA
| SPI_CPOL
| SPI_CS_HIGH
|
70 SPI_LSB_FIRST
| SPI_3WIRE
;
71 master
->transfer_one_message
= octeon_spi_transfer_one_message
;
72 master
->bits_per_word_mask
= SPI_BPW_MASK(8);
73 master
->max_speed_hz
= OCTEON_SPI_MAX_CLOCK_HZ
;
74 master
->dev
.of_node
= pdev
->dev
.of_node
;
76 pci_set_drvdata(pdev
, master
);
78 ret
= devm_spi_register_master(dev
, master
);
85 clk_disable_unprepare(p
->clk
);
86 pci_release_regions(pdev
);
87 spi_master_put(master
);
91 static void thunderx_spi_remove(struct pci_dev
*pdev
)
93 struct spi_master
*master
= pci_get_drvdata(pdev
);
96 p
= spi_master_get_devdata(master
);
100 clk_disable_unprepare(p
->clk
);
101 pci_release_regions(pdev
);
102 /* Put everything in a known state. */
103 writeq(0, p
->register_base
+ OCTEON_SPI_CFG(p
));
106 static const struct pci_device_id thunderx_spi_pci_id_table
[] = {
107 { PCI_DEVICE(PCI_VENDOR_ID_CAVIUM
, 0xa00b) },
111 MODULE_DEVICE_TABLE(pci
, thunderx_spi_pci_id_table
);
113 static struct pci_driver thunderx_spi_driver
= {
115 .id_table
= thunderx_spi_pci_id_table
,
116 .probe
= thunderx_spi_probe
,
117 .remove
= thunderx_spi_remove
,
120 module_pci_driver(thunderx_spi_driver
);
122 MODULE_DESCRIPTION("Cavium, Inc. ThunderX SPI bus driver");
123 MODULE_AUTHOR("Jan Glauber");
124 MODULE_LICENSE("GPL");