xref: /OK3568_Linux_fs/kernel/drivers/spi/spi-ar934x.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0
2*4882a593Smuzhiyun //
3*4882a593Smuzhiyun // SPI controller driver for Qualcomm Atheros AR934x/QCA95xx SoCs
4*4882a593Smuzhiyun //
5*4882a593Smuzhiyun // Copyright (C) 2020 Chuanhong Guo <gch981213@gmail.com>
6*4882a593Smuzhiyun //
7*4882a593Smuzhiyun // Based on spi-mt7621.c:
8*4882a593Smuzhiyun // Copyright (C) 2011 Sergiy <piratfm@gmail.com>
9*4882a593Smuzhiyun // Copyright (C) 2011-2013 Gabor Juhos <juhosg@openwrt.org>
10*4882a593Smuzhiyun // Copyright (C) 2014-2015 Felix Fietkau <nbd@nbd.name>
11*4882a593Smuzhiyun 
12*4882a593Smuzhiyun #include <linux/clk.h>
13*4882a593Smuzhiyun #include <linux/io.h>
14*4882a593Smuzhiyun #include <linux/iopoll.h>
15*4882a593Smuzhiyun #include <linux/kernel.h>
16*4882a593Smuzhiyun #include <linux/module.h>
17*4882a593Smuzhiyun #include <linux/of_device.h>
18*4882a593Smuzhiyun #include <linux/spi/spi.h>
19*4882a593Smuzhiyun 
20*4882a593Smuzhiyun #define DRIVER_NAME "spi-ar934x"
21*4882a593Smuzhiyun 
22*4882a593Smuzhiyun #define AR934X_SPI_REG_FS		0x00
23*4882a593Smuzhiyun #define AR934X_SPI_ENABLE		BIT(0)
24*4882a593Smuzhiyun 
25*4882a593Smuzhiyun #define AR934X_SPI_REG_IOC		0x08
26*4882a593Smuzhiyun #define AR934X_SPI_IOC_INITVAL		0x70000
27*4882a593Smuzhiyun 
28*4882a593Smuzhiyun #define AR934X_SPI_REG_CTRL		0x04
29*4882a593Smuzhiyun #define AR934X_SPI_CLK_MASK		GENMASK(5, 0)
30*4882a593Smuzhiyun 
31*4882a593Smuzhiyun #define AR934X_SPI_DATAOUT		0x10
32*4882a593Smuzhiyun 
33*4882a593Smuzhiyun #define AR934X_SPI_REG_SHIFT_CTRL	0x14
34*4882a593Smuzhiyun #define AR934X_SPI_SHIFT_EN		BIT(31)
35*4882a593Smuzhiyun #define AR934X_SPI_SHIFT_CS(n)		BIT(28 + (n))
36*4882a593Smuzhiyun #define AR934X_SPI_SHIFT_TERM		26
37*4882a593Smuzhiyun #define AR934X_SPI_SHIFT_VAL(cs, term, count)			\
38*4882a593Smuzhiyun 	(AR934X_SPI_SHIFT_EN | AR934X_SPI_SHIFT_CS(cs) |	\
39*4882a593Smuzhiyun 	(term) << AR934X_SPI_SHIFT_TERM | (count))
40*4882a593Smuzhiyun 
41*4882a593Smuzhiyun #define AR934X_SPI_DATAIN 0x18
42*4882a593Smuzhiyun 
43*4882a593Smuzhiyun struct ar934x_spi {
44*4882a593Smuzhiyun 	struct spi_controller *ctlr;
45*4882a593Smuzhiyun 	void __iomem *base;
46*4882a593Smuzhiyun 	struct clk *clk;
47*4882a593Smuzhiyun 	unsigned int clk_freq;
48*4882a593Smuzhiyun };
49*4882a593Smuzhiyun 
ar934x_spi_clk_div(struct ar934x_spi * sp,unsigned int freq)50*4882a593Smuzhiyun static inline int ar934x_spi_clk_div(struct ar934x_spi *sp, unsigned int freq)
51*4882a593Smuzhiyun {
52*4882a593Smuzhiyun 	int div = DIV_ROUND_UP(sp->clk_freq, freq * 2) - 1;
53*4882a593Smuzhiyun 
54*4882a593Smuzhiyun 	if (div < 0)
55*4882a593Smuzhiyun 		return 0;
56*4882a593Smuzhiyun 	else if (div > AR934X_SPI_CLK_MASK)
57*4882a593Smuzhiyun 		return -EINVAL;
58*4882a593Smuzhiyun 	else
59*4882a593Smuzhiyun 		return div;
60*4882a593Smuzhiyun }
61*4882a593Smuzhiyun 
ar934x_spi_setup(struct spi_device * spi)62*4882a593Smuzhiyun static int ar934x_spi_setup(struct spi_device *spi)
63*4882a593Smuzhiyun {
64*4882a593Smuzhiyun 	struct ar934x_spi *sp = spi_controller_get_devdata(spi->master);
65*4882a593Smuzhiyun 
66*4882a593Smuzhiyun 	if ((spi->max_speed_hz == 0) ||
67*4882a593Smuzhiyun 	    (spi->max_speed_hz > (sp->clk_freq / 2))) {
68*4882a593Smuzhiyun 		spi->max_speed_hz = sp->clk_freq / 2;
69*4882a593Smuzhiyun 	} else if (spi->max_speed_hz < (sp->clk_freq / 128)) {
70*4882a593Smuzhiyun 		dev_err(&spi->dev, "spi clock is too low\n");
71*4882a593Smuzhiyun 		return -EINVAL;
72*4882a593Smuzhiyun 	}
73*4882a593Smuzhiyun 
74*4882a593Smuzhiyun 	return 0;
75*4882a593Smuzhiyun }
76*4882a593Smuzhiyun 
ar934x_spi_transfer_one_message(struct spi_controller * master,struct spi_message * m)77*4882a593Smuzhiyun static int ar934x_spi_transfer_one_message(struct spi_controller *master,
78*4882a593Smuzhiyun 					   struct spi_message *m)
79*4882a593Smuzhiyun {
80*4882a593Smuzhiyun 	struct ar934x_spi *sp = spi_controller_get_devdata(master);
81*4882a593Smuzhiyun 	struct spi_transfer *t = NULL;
82*4882a593Smuzhiyun 	struct spi_device *spi = m->spi;
83*4882a593Smuzhiyun 	unsigned long trx_done, trx_cur;
84*4882a593Smuzhiyun 	int stat = 0;
85*4882a593Smuzhiyun 	u8 term = 0;
86*4882a593Smuzhiyun 	int div, i;
87*4882a593Smuzhiyun 	u32 reg;
88*4882a593Smuzhiyun 	const u8 *tx_buf;
89*4882a593Smuzhiyun 	u8 *buf;
90*4882a593Smuzhiyun 
91*4882a593Smuzhiyun 	m->actual_length = 0;
92*4882a593Smuzhiyun 	list_for_each_entry(t, &m->transfers, transfer_list) {
93*4882a593Smuzhiyun 		if (t->speed_hz)
94*4882a593Smuzhiyun 			div = ar934x_spi_clk_div(sp, t->speed_hz);
95*4882a593Smuzhiyun 		else
96*4882a593Smuzhiyun 			div = ar934x_spi_clk_div(sp, spi->max_speed_hz);
97*4882a593Smuzhiyun 		if (div < 0) {
98*4882a593Smuzhiyun 			stat = -EIO;
99*4882a593Smuzhiyun 			goto msg_done;
100*4882a593Smuzhiyun 		}
101*4882a593Smuzhiyun 
102*4882a593Smuzhiyun 		reg = ioread32(sp->base + AR934X_SPI_REG_CTRL);
103*4882a593Smuzhiyun 		reg &= ~AR934X_SPI_CLK_MASK;
104*4882a593Smuzhiyun 		reg |= div;
105*4882a593Smuzhiyun 		iowrite32(reg, sp->base + AR934X_SPI_REG_CTRL);
106*4882a593Smuzhiyun 		iowrite32(0, sp->base + AR934X_SPI_DATAOUT);
107*4882a593Smuzhiyun 
108*4882a593Smuzhiyun 		for (trx_done = 0; trx_done < t->len; trx_done += 4) {
109*4882a593Smuzhiyun 			trx_cur = t->len - trx_done;
110*4882a593Smuzhiyun 			if (trx_cur > 4)
111*4882a593Smuzhiyun 				trx_cur = 4;
112*4882a593Smuzhiyun 			else if (list_is_last(&t->transfer_list, &m->transfers))
113*4882a593Smuzhiyun 				term = 1;
114*4882a593Smuzhiyun 
115*4882a593Smuzhiyun 			if (t->tx_buf) {
116*4882a593Smuzhiyun 				tx_buf = t->tx_buf + trx_done;
117*4882a593Smuzhiyun 				reg = tx_buf[0];
118*4882a593Smuzhiyun 				for (i = 1; i < trx_cur; i++)
119*4882a593Smuzhiyun 					reg = reg << 8 | tx_buf[i];
120*4882a593Smuzhiyun 				iowrite32(reg, sp->base + AR934X_SPI_DATAOUT);
121*4882a593Smuzhiyun 			}
122*4882a593Smuzhiyun 
123*4882a593Smuzhiyun 			reg = AR934X_SPI_SHIFT_VAL(spi->chip_select, term,
124*4882a593Smuzhiyun 						   trx_cur * 8);
125*4882a593Smuzhiyun 			iowrite32(reg, sp->base + AR934X_SPI_REG_SHIFT_CTRL);
126*4882a593Smuzhiyun 			stat = readl_poll_timeout(
127*4882a593Smuzhiyun 				sp->base + AR934X_SPI_REG_SHIFT_CTRL, reg,
128*4882a593Smuzhiyun 				!(reg & AR934X_SPI_SHIFT_EN), 0, 5);
129*4882a593Smuzhiyun 			if (stat < 0)
130*4882a593Smuzhiyun 				goto msg_done;
131*4882a593Smuzhiyun 
132*4882a593Smuzhiyun 			if (t->rx_buf) {
133*4882a593Smuzhiyun 				reg = ioread32(sp->base + AR934X_SPI_DATAIN);
134*4882a593Smuzhiyun 				buf = t->rx_buf + trx_done;
135*4882a593Smuzhiyun 				for (i = 0; i < trx_cur; i++) {
136*4882a593Smuzhiyun 					buf[trx_cur - i - 1] = reg & 0xff;
137*4882a593Smuzhiyun 					reg >>= 8;
138*4882a593Smuzhiyun 				}
139*4882a593Smuzhiyun 			}
140*4882a593Smuzhiyun 		}
141*4882a593Smuzhiyun 		m->actual_length += t->len;
142*4882a593Smuzhiyun 	}
143*4882a593Smuzhiyun 
144*4882a593Smuzhiyun msg_done:
145*4882a593Smuzhiyun 	m->status = stat;
146*4882a593Smuzhiyun 	spi_finalize_current_message(master);
147*4882a593Smuzhiyun 
148*4882a593Smuzhiyun 	return 0;
149*4882a593Smuzhiyun }
150*4882a593Smuzhiyun 
151*4882a593Smuzhiyun static const struct of_device_id ar934x_spi_match[] = {
152*4882a593Smuzhiyun 	{ .compatible = "qca,ar934x-spi" },
153*4882a593Smuzhiyun 	{},
154*4882a593Smuzhiyun };
155*4882a593Smuzhiyun MODULE_DEVICE_TABLE(of, ar934x_spi_match);
156*4882a593Smuzhiyun 
ar934x_spi_probe(struct platform_device * pdev)157*4882a593Smuzhiyun static int ar934x_spi_probe(struct platform_device *pdev)
158*4882a593Smuzhiyun {
159*4882a593Smuzhiyun 	struct spi_controller *ctlr;
160*4882a593Smuzhiyun 	struct ar934x_spi *sp;
161*4882a593Smuzhiyun 	void __iomem *base;
162*4882a593Smuzhiyun 	struct clk *clk;
163*4882a593Smuzhiyun 	int ret;
164*4882a593Smuzhiyun 
165*4882a593Smuzhiyun 	base = devm_platform_ioremap_resource(pdev, 0);
166*4882a593Smuzhiyun 	if (IS_ERR(base))
167*4882a593Smuzhiyun 		return PTR_ERR(base);
168*4882a593Smuzhiyun 
169*4882a593Smuzhiyun 	clk = devm_clk_get(&pdev->dev, NULL);
170*4882a593Smuzhiyun 	if (IS_ERR(clk)) {
171*4882a593Smuzhiyun 		dev_err(&pdev->dev, "failed to get clock\n");
172*4882a593Smuzhiyun 		return PTR_ERR(clk);
173*4882a593Smuzhiyun 	}
174*4882a593Smuzhiyun 
175*4882a593Smuzhiyun 	ret = clk_prepare_enable(clk);
176*4882a593Smuzhiyun 	if (ret)
177*4882a593Smuzhiyun 		return ret;
178*4882a593Smuzhiyun 
179*4882a593Smuzhiyun 	ctlr = devm_spi_alloc_master(&pdev->dev, sizeof(*sp));
180*4882a593Smuzhiyun 	if (!ctlr) {
181*4882a593Smuzhiyun 		dev_info(&pdev->dev, "failed to allocate spi controller\n");
182*4882a593Smuzhiyun 		ret = -ENOMEM;
183*4882a593Smuzhiyun 		goto err_clk_disable;
184*4882a593Smuzhiyun 	}
185*4882a593Smuzhiyun 
186*4882a593Smuzhiyun 	/* disable flash mapping and expose spi controller registers */
187*4882a593Smuzhiyun 	iowrite32(AR934X_SPI_ENABLE, base + AR934X_SPI_REG_FS);
188*4882a593Smuzhiyun 	/* restore pins to default state: CSn=1 DO=CLK=0 */
189*4882a593Smuzhiyun 	iowrite32(AR934X_SPI_IOC_INITVAL, base + AR934X_SPI_REG_IOC);
190*4882a593Smuzhiyun 
191*4882a593Smuzhiyun 	ctlr->mode_bits = SPI_LSB_FIRST;
192*4882a593Smuzhiyun 	ctlr->setup = ar934x_spi_setup;
193*4882a593Smuzhiyun 	ctlr->transfer_one_message = ar934x_spi_transfer_one_message;
194*4882a593Smuzhiyun 	ctlr->bits_per_word_mask = SPI_BPW_MASK(8);
195*4882a593Smuzhiyun 	ctlr->dev.of_node = pdev->dev.of_node;
196*4882a593Smuzhiyun 	ctlr->num_chipselect = 3;
197*4882a593Smuzhiyun 
198*4882a593Smuzhiyun 	dev_set_drvdata(&pdev->dev, ctlr);
199*4882a593Smuzhiyun 
200*4882a593Smuzhiyun 	sp = spi_controller_get_devdata(ctlr);
201*4882a593Smuzhiyun 	sp->base = base;
202*4882a593Smuzhiyun 	sp->clk = clk;
203*4882a593Smuzhiyun 	sp->clk_freq = clk_get_rate(clk);
204*4882a593Smuzhiyun 	sp->ctlr = ctlr;
205*4882a593Smuzhiyun 
206*4882a593Smuzhiyun 	ret = spi_register_controller(ctlr);
207*4882a593Smuzhiyun 	if (!ret)
208*4882a593Smuzhiyun 		return 0;
209*4882a593Smuzhiyun 
210*4882a593Smuzhiyun err_clk_disable:
211*4882a593Smuzhiyun 	clk_disable_unprepare(clk);
212*4882a593Smuzhiyun 	return ret;
213*4882a593Smuzhiyun }
214*4882a593Smuzhiyun 
ar934x_spi_remove(struct platform_device * pdev)215*4882a593Smuzhiyun static int ar934x_spi_remove(struct platform_device *pdev)
216*4882a593Smuzhiyun {
217*4882a593Smuzhiyun 	struct spi_controller *ctlr;
218*4882a593Smuzhiyun 	struct ar934x_spi *sp;
219*4882a593Smuzhiyun 
220*4882a593Smuzhiyun 	ctlr = dev_get_drvdata(&pdev->dev);
221*4882a593Smuzhiyun 	sp = spi_controller_get_devdata(ctlr);
222*4882a593Smuzhiyun 
223*4882a593Smuzhiyun 	spi_unregister_controller(ctlr);
224*4882a593Smuzhiyun 	clk_disable_unprepare(sp->clk);
225*4882a593Smuzhiyun 
226*4882a593Smuzhiyun 	return 0;
227*4882a593Smuzhiyun }
228*4882a593Smuzhiyun 
229*4882a593Smuzhiyun static struct platform_driver ar934x_spi_driver = {
230*4882a593Smuzhiyun 	.driver = {
231*4882a593Smuzhiyun 		.name = DRIVER_NAME,
232*4882a593Smuzhiyun 		.of_match_table = ar934x_spi_match,
233*4882a593Smuzhiyun 	},
234*4882a593Smuzhiyun 	.probe = ar934x_spi_probe,
235*4882a593Smuzhiyun 	.remove = ar934x_spi_remove,
236*4882a593Smuzhiyun };
237*4882a593Smuzhiyun 
238*4882a593Smuzhiyun module_platform_driver(ar934x_spi_driver);
239*4882a593Smuzhiyun 
240*4882a593Smuzhiyun MODULE_DESCRIPTION("SPI controller driver for Qualcomm Atheros AR934x/QCA95xx");
241*4882a593Smuzhiyun MODULE_AUTHOR("Chuanhong Guo <gch981213@gmail.com>");
242*4882a593Smuzhiyun MODULE_LICENSE("GPL v2");
243*4882a593Smuzhiyun MODULE_ALIAS("platform:" DRIVER_NAME);
244