brintos

brintos / linux-shallow public Read only

0
0
Text · 13.9 KiB · 1605469 Raw
556 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2//3// HiSilicon SPI Controller Driver for Kunpeng SoCs4//5// Copyright (c) 2021 HiSilicon Technologies Co., Ltd.6// Author: Jay Fang <f.fangjian@huawei.com>7//8// This code is based on spi-dw-core.c.9 10#include <linux/acpi.h>11#include <linux/bitfield.h>12#include <linux/debugfs.h>13#include <linux/delay.h>14#include <linux/err.h>15#include <linux/interrupt.h>16#include <linux/module.h>17#include <linux/property.h>18#include <linux/platform_device.h>19#include <linux/slab.h>20#include <linux/spi/spi.h>21 22/* Register offsets */23#define HISI_SPI_CSCR		0x00	/* cs control register */24#define HISI_SPI_CR		0x04	/* spi common control register */25#define HISI_SPI_ENR		0x08	/* spi enable register */26#define HISI_SPI_FIFOC		0x0c	/* fifo level control register */27#define HISI_SPI_IMR		0x10	/* interrupt mask register */28#define HISI_SPI_DIN		0x14	/* data in register */29#define HISI_SPI_DOUT		0x18	/* data out register */30#define HISI_SPI_SR		0x1c	/* status register */31#define HISI_SPI_RISR		0x20	/* raw interrupt status register */32#define HISI_SPI_ISR		0x24	/* interrupt status register */33#define HISI_SPI_ICR		0x28	/* interrupt clear register */34#define HISI_SPI_VERSION	0xe0	/* version register */35 36/* Bit fields in HISI_SPI_CR */37#define CR_LOOP_MASK		GENMASK(1, 1)38#define CR_CPOL_MASK		GENMASK(2, 2)39#define CR_CPHA_MASK		GENMASK(3, 3)40#define CR_DIV_PRE_MASK		GENMASK(11, 4)41#define CR_DIV_POST_MASK	GENMASK(19, 12)42#define CR_BPW_MASK		GENMASK(24, 20)43#define CR_SPD_MODE_MASK	GENMASK(25, 25)44 45/* Bit fields in HISI_SPI_FIFOC */46#define FIFOC_TX_MASK		GENMASK(5, 3)47#define FIFOC_RX_MASK		GENMASK(11, 9)48 49/* Bit fields in HISI_SPI_IMR, 4 bits */50#define IMR_RXOF		BIT(0)		/* Receive Overflow */51#define IMR_RXTO		BIT(1)		/* Receive Timeout */52#define IMR_RX			BIT(2)		/* Receive */53#define IMR_TX			BIT(3)		/* Transmit */54#define IMR_MASK		(IMR_RXOF | IMR_RXTO | IMR_RX | IMR_TX)55 56/* Bit fields in HISI_SPI_SR, 5 bits */57#define SR_TXE			BIT(0)		/* Transmit FIFO empty */58#define SR_TXNF			BIT(1)		/* Transmit FIFO not full */59#define SR_RXNE			BIT(2)		/* Receive FIFO not empty */60#define SR_RXF			BIT(3)		/* Receive FIFO full */61#define SR_BUSY			BIT(4)		/* Busy Flag */62 63/* Bit fields in HISI_SPI_ISR, 4 bits */64#define ISR_RXOF		BIT(0)		/* Receive Overflow */65#define ISR_RXTO		BIT(1)		/* Receive Timeout */66#define ISR_RX			BIT(2)		/* Receive */67#define ISR_TX			BIT(3)		/* Transmit */68#define ISR_MASK		(ISR_RXOF | ISR_RXTO | ISR_RX | ISR_TX)69 70/* Bit fields in HISI_SPI_ICR, 2 bits */71#define ICR_RXOF		BIT(0)		/* Receive Overflow */72#define ICR_RXTO		BIT(1)		/* Receive Timeout */73#define ICR_MASK		(ICR_RXOF | ICR_RXTO)74 75#define DIV_POST_MAX		0xFF76#define DIV_POST_MIN		0x0077#define DIV_PRE_MAX		0xFE78#define DIV_PRE_MIN		0x0279#define CLK_DIV_MAX		((1 + DIV_POST_MAX) * DIV_PRE_MAX)80#define CLK_DIV_MIN		((1 + DIV_POST_MIN) * DIV_PRE_MIN)81 82#define DEFAULT_NUM_CS		183 84#define HISI_SPI_WAIT_TIMEOUT_MS	10UL85 86enum hisi_spi_rx_level_trig {87	HISI_SPI_RX_1,88	HISI_SPI_RX_4,89	HISI_SPI_RX_8,90	HISI_SPI_RX_16,91	HISI_SPI_RX_32,92	HISI_SPI_RX_64,93	HISI_SPI_RX_12894};95 96enum hisi_spi_tx_level_trig {97	HISI_SPI_TX_1_OR_LESS,98	HISI_SPI_TX_4_OR_LESS,99	HISI_SPI_TX_8_OR_LESS,100	HISI_SPI_TX_16_OR_LESS,101	HISI_SPI_TX_32_OR_LESS,102	HISI_SPI_TX_64_OR_LESS,103	HISI_SPI_TX_128_OR_LESS104};105 106enum hisi_spi_frame_n_bytes {107	HISI_SPI_N_BYTES_NULL,108	HISI_SPI_N_BYTES_U8,109	HISI_SPI_N_BYTES_U16,110	HISI_SPI_N_BYTES_U32 = 4111};112 113/* Slave spi_dev related */114struct hisi_chip_data {115	u32 cr;116	u32 speed_hz;	/* baud rate */117	u16 clk_div;	/* baud rate divider */118 119	/* clk_div = (1 + div_post) * div_pre */120	u8 div_post;	/* value from 0 to 255 */121	u8 div_pre;	/* value from 2 to 254 (even only!) */122};123 124struct hisi_spi {125	struct device		*dev;126 127	void __iomem		*regs;128	int			irq;129	u32			fifo_len; /* depth of the FIFO buffer */130 131	/* Current message transfer state info */132	const void		*tx;133	unsigned int		tx_len;134	void			*rx;135	unsigned int		rx_len;136	u8			n_bytes; /* current is a 1/2/4 bytes op */137 138	struct dentry *debugfs;139	struct debugfs_regset32 regset;140};141 142#define HISI_SPI_DBGFS_REG(_name, _off)	\143{					\144	.name = _name,			\145	.offset = _off,			\146}147 148static const struct debugfs_reg32 hisi_spi_regs[] = {149	HISI_SPI_DBGFS_REG("CSCR", HISI_SPI_CSCR),150	HISI_SPI_DBGFS_REG("CR", HISI_SPI_CR),151	HISI_SPI_DBGFS_REG("ENR", HISI_SPI_ENR),152	HISI_SPI_DBGFS_REG("FIFOC", HISI_SPI_FIFOC),153	HISI_SPI_DBGFS_REG("IMR", HISI_SPI_IMR),154	HISI_SPI_DBGFS_REG("SR", HISI_SPI_SR),155	HISI_SPI_DBGFS_REG("RISR", HISI_SPI_RISR),156	HISI_SPI_DBGFS_REG("ISR", HISI_SPI_ISR),157	HISI_SPI_DBGFS_REG("ICR", HISI_SPI_ICR),158	HISI_SPI_DBGFS_REG("VERSION", HISI_SPI_VERSION),159};160 161static int hisi_spi_debugfs_init(struct hisi_spi *hs)162{163	char name[32];164 165	struct spi_controller *host;166 167	host = container_of(hs->dev, struct spi_controller, dev);168	snprintf(name, 32, "hisi_spi%d", host->bus_num);169	hs->debugfs = debugfs_create_dir(name, NULL);170	if (IS_ERR(hs->debugfs))171		return -ENOMEM;172 173	hs->regset.regs = hisi_spi_regs;174	hs->regset.nregs = ARRAY_SIZE(hisi_spi_regs);175	hs->regset.base = hs->regs;176	debugfs_create_regset32("registers", 0400, hs->debugfs, &hs->regset);177 178	return 0;179}180 181static u32 hisi_spi_busy(struct hisi_spi *hs)182{183	return readl(hs->regs + HISI_SPI_SR) & SR_BUSY;184}185 186static u32 hisi_spi_rx_not_empty(struct hisi_spi *hs)187{188	return readl(hs->regs + HISI_SPI_SR) & SR_RXNE;189}190 191static u32 hisi_spi_tx_not_full(struct hisi_spi *hs)192{193	return readl(hs->regs + HISI_SPI_SR) & SR_TXNF;194}195 196static void hisi_spi_flush_fifo(struct hisi_spi *hs)197{198	unsigned long limit = loops_per_jiffy << 1;199 200	do {201		while (hisi_spi_rx_not_empty(hs))202			readl(hs->regs + HISI_SPI_DOUT);203	} while (hisi_spi_busy(hs) && limit--);204}205 206/* Disable the controller and all interrupts */207static void hisi_spi_disable(struct hisi_spi *hs)208{209	writel(0, hs->regs + HISI_SPI_ENR);210	writel(IMR_MASK, hs->regs + HISI_SPI_IMR);211	writel(ICR_MASK, hs->regs + HISI_SPI_ICR);212}213 214static u8 hisi_spi_n_bytes(struct spi_transfer *transfer)215{216	if (transfer->bits_per_word <= 8)217		return HISI_SPI_N_BYTES_U8;218	else if (transfer->bits_per_word <= 16)219		return HISI_SPI_N_BYTES_U16;220	else221		return HISI_SPI_N_BYTES_U32;222}223 224static void hisi_spi_reader(struct hisi_spi *hs)225{226	u32 max = min_t(u32, hs->rx_len, hs->fifo_len);227	u32 rxw;228 229	while (hisi_spi_rx_not_empty(hs) && max--) {230		rxw = readl(hs->regs + HISI_SPI_DOUT);231		/* Check the transfer's original "rx" is not null */232		if (hs->rx) {233			switch (hs->n_bytes) {234			case HISI_SPI_N_BYTES_U8:235				*(u8 *)(hs->rx) = rxw;236				break;237			case HISI_SPI_N_BYTES_U16:238				*(u16 *)(hs->rx) = rxw;239				break;240			case HISI_SPI_N_BYTES_U32:241				*(u32 *)(hs->rx) = rxw;242				break;243			}244			hs->rx += hs->n_bytes;245		}246		--hs->rx_len;247	}248}249 250static void hisi_spi_writer(struct hisi_spi *hs)251{252	u32 max = min_t(u32, hs->tx_len, hs->fifo_len);253	u32 txw = 0;254 255	while (hisi_spi_tx_not_full(hs) && max--) {256		/* Check the transfer's original "tx" is not null */257		if (hs->tx) {258			switch (hs->n_bytes) {259			case HISI_SPI_N_BYTES_U8:260				txw = *(u8 *)(hs->tx);261				break;262			case HISI_SPI_N_BYTES_U16:263				txw = *(u16 *)(hs->tx);264				break;265			case HISI_SPI_N_BYTES_U32:266				txw = *(u32 *)(hs->tx);267				break;268			}269			hs->tx += hs->n_bytes;270		}271		writel(txw, hs->regs + HISI_SPI_DIN);272		--hs->tx_len;273	}274}275 276static void __hisi_calc_div_reg(struct hisi_chip_data *chip)277{278	chip->div_pre = DIV_PRE_MAX;279	while (chip->div_pre >= DIV_PRE_MIN) {280		if (chip->clk_div % chip->div_pre == 0)281			break;282 283		chip->div_pre -= 2;284	}285 286	if (chip->div_pre > chip->clk_div)287		chip->div_pre = chip->clk_div;288 289	chip->div_post = (chip->clk_div / chip->div_pre) - 1;290}291 292static u32 hisi_calc_effective_speed(struct spi_controller *host,293			struct hisi_chip_data *chip, u32 speed_hz)294{295	u32 effective_speed;296 297	/* Note clock divider doesn't support odd numbers */298	chip->clk_div = DIV_ROUND_UP(host->max_speed_hz, speed_hz) + 1;299	chip->clk_div &= 0xfffe;300	if (chip->clk_div > CLK_DIV_MAX)301		chip->clk_div = CLK_DIV_MAX;302 303	effective_speed = host->max_speed_hz / chip->clk_div;304	if (chip->speed_hz != effective_speed) {305		__hisi_calc_div_reg(chip);306		chip->speed_hz = effective_speed;307	}308 309	return effective_speed;310}311 312static u32 hisi_spi_prepare_cr(struct spi_device *spi)313{314	u32 cr = FIELD_PREP(CR_SPD_MODE_MASK, 1);315 316	cr |= FIELD_PREP(CR_CPHA_MASK, (spi->mode & SPI_CPHA) ? 1 : 0);317	cr |= FIELD_PREP(CR_CPOL_MASK, (spi->mode & SPI_CPOL) ? 1 : 0);318	cr |= FIELD_PREP(CR_LOOP_MASK, (spi->mode & SPI_LOOP) ? 1 : 0);319 320	return cr;321}322 323static void hisi_spi_hw_init(struct hisi_spi *hs)324{325	hisi_spi_disable(hs);326 327	/* FIFO default config */328	writel(FIELD_PREP(FIFOC_TX_MASK, HISI_SPI_TX_64_OR_LESS) |329		FIELD_PREP(FIFOC_RX_MASK, HISI_SPI_RX_16),330		hs->regs + HISI_SPI_FIFOC);331 332	hs->fifo_len = 256;333}334 335static irqreturn_t hisi_spi_irq(int irq, void *dev_id)336{337	struct spi_controller *host = dev_id;338	struct hisi_spi *hs = spi_controller_get_devdata(host);339	u32 irq_status = readl(hs->regs + HISI_SPI_ISR) & ISR_MASK;340 341	if (!irq_status)342		return IRQ_NONE;343 344	if (!host->cur_msg)345		return IRQ_HANDLED;346 347	/* Error handling */348	if (irq_status & ISR_RXOF) {349		dev_err(hs->dev, "interrupt_transfer: fifo overflow\n");350		host->cur_msg->status = -EIO;351		goto finalize_transfer;352	}353 354	/*355	 * Read data from the Rx FIFO every time. If there is356	 * nothing left to receive, finalize the transfer.357	 */358	hisi_spi_reader(hs);359	if (!hs->rx_len)360		goto finalize_transfer;361 362	/* Send data out when Tx FIFO IRQ triggered */363	if (irq_status & ISR_TX)364		hisi_spi_writer(hs);365 366	return IRQ_HANDLED;367 368finalize_transfer:369	hisi_spi_disable(hs);370	spi_finalize_current_transfer(host);371	return IRQ_HANDLED;372}373 374static int hisi_spi_transfer_one(struct spi_controller *host,375		struct spi_device *spi, struct spi_transfer *transfer)376{377	struct hisi_spi *hs = spi_controller_get_devdata(host);378	struct hisi_chip_data *chip = spi_get_ctldata(spi);379	u32 cr = chip->cr;380 381	/* Update per transfer options for speed and bpw */382	transfer->effective_speed_hz =383		hisi_calc_effective_speed(host, chip, transfer->speed_hz);384	cr |= FIELD_PREP(CR_DIV_PRE_MASK, chip->div_pre);385	cr |= FIELD_PREP(CR_DIV_POST_MASK, chip->div_post);386	cr |= FIELD_PREP(CR_BPW_MASK, transfer->bits_per_word - 1);387	writel(cr, hs->regs + HISI_SPI_CR);388 389	hisi_spi_flush_fifo(hs);390 391	hs->n_bytes = hisi_spi_n_bytes(transfer);392	hs->tx = transfer->tx_buf;393	hs->tx_len = transfer->len / hs->n_bytes;394	hs->rx = transfer->rx_buf;395	hs->rx_len = hs->tx_len;396 397	/*398	 * Ensure that the transfer data above has been updated399	 * before the interrupt to start.400	 */401	smp_mb();402 403	/* Enable all interrupts and the controller */404	writel(~(u32)IMR_MASK, hs->regs + HISI_SPI_IMR);405	writel(1, hs->regs + HISI_SPI_ENR);406 407	return 1;408}409 410static void hisi_spi_handle_err(struct spi_controller *host,411		struct spi_message *msg)412{413	struct hisi_spi *hs = spi_controller_get_devdata(host);414 415	hisi_spi_disable(hs);416 417	/*418	 * Wait for interrupt handler that is419	 * already in timeout to complete.420	 */421	msleep(HISI_SPI_WAIT_TIMEOUT_MS);422}423 424static int hisi_spi_setup(struct spi_device *spi)425{426	struct hisi_chip_data *chip;427 428	/* Only alloc on first setup */429	chip = spi_get_ctldata(spi);430	if (!chip) {431		chip = kzalloc(sizeof(*chip), GFP_KERNEL);432		if (!chip)433			return -ENOMEM;434		spi_set_ctldata(spi, chip);435	}436 437	chip->cr = hisi_spi_prepare_cr(spi);438 439	return 0;440}441 442static void hisi_spi_cleanup(struct spi_device *spi)443{444	struct hisi_chip_data *chip = spi_get_ctldata(spi);445 446	kfree(chip);447	spi_set_ctldata(spi, NULL);448}449 450static int hisi_spi_probe(struct platform_device *pdev)451{452	struct device *dev = &pdev->dev;453	struct spi_controller *host;454	struct hisi_spi *hs;455	int ret, irq;456 457	irq = platform_get_irq(pdev, 0);458	if (irq < 0)459		return irq;460 461	host = devm_spi_alloc_host(dev, sizeof(*hs));462	if (!host)463		return -ENOMEM;464 465	platform_set_drvdata(pdev, host);466 467	hs = spi_controller_get_devdata(host);468	hs->dev = dev;469	hs->irq = irq;470 471	hs->regs = devm_platform_ioremap_resource(pdev, 0);472	if (IS_ERR(hs->regs))473		return PTR_ERR(hs->regs);474 475	/* Specify maximum SPI clocking speed (host only) by firmware */476	ret = device_property_read_u32(dev, "spi-max-frequency",477					&host->max_speed_hz);478	if (ret) {479		dev_err(dev, "failed to get max SPI clocking speed, ret=%d\n",480			ret);481		return -EINVAL;482	}483 484	if (host->max_speed_hz == 0)485		return dev_err_probe(dev, -EINVAL, "spi-max-frequency can't be 0\n");486 487	ret = device_property_read_u16(dev, "num-cs",488					&host->num_chipselect);489	if (ret)490		host->num_chipselect = DEFAULT_NUM_CS;491 492	host->use_gpio_descriptors = true;493	host->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_LOOP;494	host->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 32);495	host->bus_num = pdev->id;496	host->setup = hisi_spi_setup;497	host->cleanup = hisi_spi_cleanup;498	host->transfer_one = hisi_spi_transfer_one;499	host->handle_err = hisi_spi_handle_err;500	host->dev.fwnode = dev->fwnode;501	host->min_speed_hz = DIV_ROUND_UP(host->max_speed_hz, CLK_DIV_MAX);502 503	hisi_spi_hw_init(hs);504 505	ret = devm_request_irq(dev, hs->irq, hisi_spi_irq, 0, dev_name(dev),506			       host);507	if (ret < 0) {508		dev_err(dev, "failed to get IRQ=%d, ret=%d\n", hs->irq, ret);509		return ret;510	}511 512	ret = spi_register_controller(host);513	if (ret) {514		dev_err(dev, "failed to register spi host, ret=%d\n", ret);515		return ret;516	}517 518	if (hisi_spi_debugfs_init(hs))519		dev_info(dev, "failed to create debugfs dir\n");520 521	dev_info(dev, "hw version:0x%x max-freq:%u kHz\n",522		readl(hs->regs + HISI_SPI_VERSION),523		host->max_speed_hz / 1000);524 525	return 0;526}527 528static void hisi_spi_remove(struct platform_device *pdev)529{530	struct spi_controller *host = platform_get_drvdata(pdev);531	struct hisi_spi *hs = spi_controller_get_devdata(host);532 533	debugfs_remove_recursive(hs->debugfs);534	spi_unregister_controller(host);535}536 537static const struct acpi_device_id hisi_spi_acpi_match[] = {538	{"HISI03E1", 0},539	{}540};541MODULE_DEVICE_TABLE(acpi, hisi_spi_acpi_match);542 543static struct platform_driver hisi_spi_driver = {544	.probe		= hisi_spi_probe,545	.remove_new	= hisi_spi_remove,546	.driver		= {547		.name	= "hisi-kunpeng-spi",548		.acpi_match_table = hisi_spi_acpi_match,549	},550};551module_platform_driver(hisi_spi_driver);552 553MODULE_AUTHOR("Jay Fang <f.fangjian@huawei.com>");554MODULE_DESCRIPTION("HiSilicon SPI Controller Driver for Kunpeng SoCs");555MODULE_LICENSE("GPL v2");556