Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.1.
  1// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
  2//
  3// AMD SPI controller driver
  4//
  5// Copyright (c) 2020, Advanced Micro Devices, Inc.
  6//
  7// Author: Sanjay R Mehta <sanju.mehta@amd.com>
  8
  9#include <linux/acpi.h>
 10#include <linux/init.h>
 11#include <linux/module.h>
 12#include <linux/platform_device.h>
 13#include <linux/delay.h>
 14#include <linux/spi/spi.h>
 15
 16#define AMD_SPI_CTRL0_REG	0x00
 17#define AMD_SPI_EXEC_CMD	BIT(16)
 18#define AMD_SPI_FIFO_CLEAR	BIT(20)
 19#define AMD_SPI_BUSY		BIT(31)
 20
 21#define AMD_SPI_OPCODE_MASK	0xFF
 22
 23#define AMD_SPI_ALT_CS_REG	0x1D
 24#define AMD_SPI_ALT_CS_MASK	0x3
 25
 26#define AMD_SPI_FIFO_BASE	0x80
 27#define AMD_SPI_TX_COUNT_REG	0x48
 28#define AMD_SPI_RX_COUNT_REG	0x4B
 29#define AMD_SPI_STATUS_REG	0x4C
 30
 31#define AMD_SPI_MEM_SIZE	200
 32
 33/* M_CMD OP codes for SPI */
 34#define AMD_SPI_XFER_TX		1
 35#define AMD_SPI_XFER_RX		2
 36
 37struct amd_spi {
 38	void __iomem *io_remap_addr;
 39	unsigned long io_base_addr;
 40	u32 rom_addr;
 41	u8 chip_select;
 42};
 43
 44static inline u8 amd_spi_readreg8(struct spi_master *master, int idx)
 45{
 46	struct amd_spi *amd_spi = spi_master_get_devdata(master);
 47
 48	return ioread8((u8 __iomem *)amd_spi->io_remap_addr + idx);
 49}
 50
 51static inline void amd_spi_writereg8(struct spi_master *master, int idx,
 52				     u8 val)
 53{
 54	struct amd_spi *amd_spi = spi_master_get_devdata(master);
 55
 56	iowrite8(val, ((u8 __iomem *)amd_spi->io_remap_addr + idx));
 57}
 58
 59static inline void amd_spi_setclear_reg8(struct spi_master *master, int idx,
 60					 u8 set, u8 clear)
 61{
 62	u8 tmp = amd_spi_readreg8(master, idx);
 63
 64	tmp = (tmp & ~clear) | set;
 65	amd_spi_writereg8(master, idx, tmp);
 66}
 67
 68static inline u32 amd_spi_readreg32(struct spi_master *master, int idx)
 69{
 70	struct amd_spi *amd_spi = spi_master_get_devdata(master);
 71
 72	return ioread32((u8 __iomem *)amd_spi->io_remap_addr + idx);
 73}
 74
 75static inline void amd_spi_writereg32(struct spi_master *master, int idx,
 76				      u32 val)
 77{
 78	struct amd_spi *amd_spi = spi_master_get_devdata(master);
 79
 80	iowrite32(val, ((u8 __iomem *)amd_spi->io_remap_addr + idx));
 81}
 82
 83static inline void amd_spi_setclear_reg32(struct spi_master *master, int idx,
 84					  u32 set, u32 clear)
 85{
 86	u32 tmp = amd_spi_readreg32(master, idx);
 87
 88	tmp = (tmp & ~clear) | set;
 89	amd_spi_writereg32(master, idx, tmp);
 90}
 91
 92static void amd_spi_select_chip(struct spi_master *master)
 93{
 94	struct amd_spi *amd_spi = spi_master_get_devdata(master);
 95	u8 chip_select = amd_spi->chip_select;
 96
 97	amd_spi_setclear_reg8(master, AMD_SPI_ALT_CS_REG, chip_select,
 98			      AMD_SPI_ALT_CS_MASK);
 99}
100
101static void amd_spi_clear_fifo_ptr(struct spi_master *master)
102{
103	amd_spi_setclear_reg32(master, AMD_SPI_CTRL0_REG, AMD_SPI_FIFO_CLEAR,
104			       AMD_SPI_FIFO_CLEAR);
105}
106
107static void amd_spi_set_opcode(struct spi_master *master, u8 cmd_opcode)
108{
109	amd_spi_setclear_reg32(master, AMD_SPI_CTRL0_REG, cmd_opcode,
110			       AMD_SPI_OPCODE_MASK);
111}
112
113static inline void amd_spi_set_rx_count(struct spi_master *master,
114					u8 rx_count)
115{
116	amd_spi_setclear_reg8(master, AMD_SPI_RX_COUNT_REG, rx_count, 0xff);
117}
118
119static inline void amd_spi_set_tx_count(struct spi_master *master,
120					u8 tx_count)
121{
122	amd_spi_setclear_reg8(master, AMD_SPI_TX_COUNT_REG, tx_count, 0xff);
123}
124
125static inline int amd_spi_busy_wait(struct amd_spi *amd_spi)
126{
127	bool spi_busy;
128	int timeout = 100000;
129
130	/* poll for SPI bus to become idle */
131	spi_busy = (ioread32((u8 __iomem *)amd_spi->io_remap_addr +
132		    AMD_SPI_CTRL0_REG) & AMD_SPI_BUSY) == AMD_SPI_BUSY;
133	while (spi_busy) {
134		usleep_range(10, 20);
135		if (timeout-- < 0)
136			return -ETIMEDOUT;
137
138		spi_busy = (ioread32((u8 __iomem *)amd_spi->io_remap_addr +
139			    AMD_SPI_CTRL0_REG) & AMD_SPI_BUSY) == AMD_SPI_BUSY;
140	}
141
142	return 0;
143}
144
145static void amd_spi_execute_opcode(struct spi_master *master)
146{
147	struct amd_spi *amd_spi = spi_master_get_devdata(master);
148
149	/* Set ExecuteOpCode bit in the CTRL0 register */
150	amd_spi_setclear_reg32(master, AMD_SPI_CTRL0_REG, AMD_SPI_EXEC_CMD,
151			       AMD_SPI_EXEC_CMD);
152
153	amd_spi_busy_wait(amd_spi);
154}
155
156static int amd_spi_master_setup(struct spi_device *spi)
157{
158	struct spi_master *master = spi->master;
159
160	amd_spi_clear_fifo_ptr(master);
161
162	return 0;
163}
164
165static inline int amd_spi_fifo_xfer(struct amd_spi *amd_spi,
166				    struct spi_master *master,
167				    struct spi_message *message)
168{
169	struct spi_transfer *xfer = NULL;
170	u8 cmd_opcode;
171	u8 *buf = NULL;
172	u32 m_cmd = 0;
173	u32 i = 0;
174	u32 tx_len = 0, rx_len = 0;
175
176	list_for_each_entry(xfer, &message->transfers,
177			    transfer_list) {
178		if (xfer->rx_buf)
179			m_cmd = AMD_SPI_XFER_RX;
180		if (xfer->tx_buf)
181			m_cmd = AMD_SPI_XFER_TX;
182
183		if (m_cmd & AMD_SPI_XFER_TX) {
184			buf = (u8 *)xfer->tx_buf;
185			tx_len = xfer->len - 1;
186			cmd_opcode = *(u8 *)xfer->tx_buf;
187			buf++;
188			amd_spi_set_opcode(master, cmd_opcode);
189
190			/* Write data into the FIFO. */
191			for (i = 0; i < tx_len; i++) {
192				iowrite8(buf[i],
193					 ((u8 __iomem *)amd_spi->io_remap_addr +
194					 AMD_SPI_FIFO_BASE + i));
195			}
196
197			amd_spi_set_tx_count(master, tx_len);
198			amd_spi_clear_fifo_ptr(master);
199			/* Execute command */
200			amd_spi_execute_opcode(master);
201		}
202		if (m_cmd & AMD_SPI_XFER_RX) {
203			/*
204			 * Store no. of bytes to be received from
205			 * FIFO
206			 */
207			rx_len = xfer->len;
208			buf = (u8 *)xfer->rx_buf;
209			amd_spi_set_rx_count(master, rx_len);
210			amd_spi_clear_fifo_ptr(master);
211			/* Execute command */
212			amd_spi_execute_opcode(master);
213			/* Read data from FIFO to receive buffer  */
214			for (i = 0; i < rx_len; i++)
215				buf[i] = amd_spi_readreg8(master,
216							  AMD_SPI_FIFO_BASE +
217							  tx_len + i);
218		}
219	}
220
221	/* Update statistics */
222	message->actual_length = tx_len + rx_len + 1;
223	/* complete the transaction */
224	message->status = 0;
225	spi_finalize_current_message(master);
226
227	return 0;
228}
229
230static int amd_spi_master_transfer(struct spi_master *master,
231				   struct spi_message *msg)
232{
233	struct amd_spi *amd_spi = spi_master_get_devdata(master);
234	struct spi_device *spi = msg->spi;
235
236	amd_spi->chip_select = spi->chip_select;
237	amd_spi_select_chip(master);
238
239	/*
240	 * Extract spi_transfers from the spi message and
241	 * program the controller.
242	 */
243	amd_spi_fifo_xfer(amd_spi, master, msg);
244
245	return 0;
246}
247
248static int amd_spi_probe(struct platform_device *pdev)
249{
250	struct device *dev = &pdev->dev;
251	struct spi_master *master;
252	struct amd_spi *amd_spi;
253	struct resource *res;
254	int err = 0;
255
256	/* Allocate storage for spi_master and driver private data */
257	master = spi_alloc_master(dev, sizeof(struct amd_spi));
258	if (!master) {
259		dev_err(dev, "Error allocating SPI master\n");
260		return -ENOMEM;
261	}
262
263	amd_spi = spi_master_get_devdata(master);
264
265	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
266	amd_spi->io_remap_addr = devm_ioremap_resource(&pdev->dev, res);
267	if (IS_ERR(amd_spi->io_remap_addr)) {
268		err = PTR_ERR(amd_spi->io_remap_addr);
269		dev_err(dev, "error %d ioremap of SPI registers failed\n", err);
270		goto err_free_master;
271	}
272	dev_dbg(dev, "io_remap_address: %p\n", amd_spi->io_remap_addr);
273
274	/* Initialize the spi_master fields */
275	master->bus_num = 0;
276	master->num_chipselect = 4;
277	master->mode_bits = 0;
278	master->flags = SPI_MASTER_HALF_DUPLEX;
279	master->setup = amd_spi_master_setup;
280	master->transfer_one_message = amd_spi_master_transfer;
281
282	/* Register the controller with SPI framework */
283	err = devm_spi_register_master(dev, master);
284	if (err) {
285		dev_err(dev, "error %d registering SPI controller\n", err);
286		goto err_free_master;
287	}
288
289	return 0;
290
291err_free_master:
292	spi_master_put(master);
293
294	return err;
295}
296
297#ifdef CONFIG_ACPI
298static const struct acpi_device_id spi_acpi_match[] = {
299	{ "AMDI0061", 0 },
300	{},
301};
302MODULE_DEVICE_TABLE(acpi, spi_acpi_match);
303#endif
304
305static struct platform_driver amd_spi_driver = {
306	.driver = {
307		.name = "amd_spi",
308		.acpi_match_table = ACPI_PTR(spi_acpi_match),
309	},
310	.probe = amd_spi_probe,
311};
312
313module_platform_driver(amd_spi_driver);
314
315MODULE_LICENSE("Dual BSD/GPL");
316MODULE_AUTHOR("Sanjay Mehta <sanju.mehta@amd.com>");
317MODULE_DESCRIPTION("AMD SPI Master Controller Driver");