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