xref: /openbmc/linux/drivers/spi/spi-gxp.c (revision 8eab9be5)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /* Copyright (C) 2022 Hewlett-Packard Development Company, L.P. */
3 
4 #include <linux/iopoll.h>
5 #include <linux/of.h>
6 #include <linux/of_device.h>
7 #include <linux/platform_device.h>
8 #include <linux/spi/spi.h>
9 #include <linux/spi/spi-mem.h>
10 
11 #define GXP_SPI0_MAX_CHIPSELECT	2
12 #define GXP_SPI_SLEEP_TIME	1
13 #define GXP_SPI_TIMEOUT (130 * 1000000 / GXP_SPI_SLEEP_TIME)
14 
15 #define MANUAL_MODE		0
16 #define DIRECT_MODE		1
17 #define SPILDAT_LEN		256
18 
19 #define OFFSET_SPIMCFG		0x0
20 #define OFFSET_SPIMCTRL		0x4
21 #define OFFSET_SPICMD		0x5
22 #define OFFSET_SPIDCNT		0x6
23 #define OFFSET_SPIADDR		0x8
24 #define OFFSET_SPIINTSTS	0xc
25 
26 #define SPIMCTRL_START		0x01
27 #define SPIMCTRL_BUSY		0x02
28 #define SPIMCTRL_DIR		0x08
29 
30 struct gxp_spi;
31 
32 struct gxp_spi_chip {
33 	struct gxp_spi *spifi;
34 	u32 cs;
35 };
36 
37 struct gxp_spi_data {
38 	u32 max_cs;
39 	u32 mode_bits;
40 };
41 
42 struct gxp_spi {
43 	const struct gxp_spi_data *data;
44 	void __iomem *reg_base;
45 	void __iomem *dat_base;
46 	void __iomem *dir_base;
47 	struct device *dev;
48 	struct gxp_spi_chip chips[GXP_SPI0_MAX_CHIPSELECT];
49 };
50 
51 static void gxp_spi_set_mode(struct gxp_spi *spifi, int mode)
52 {
53 	u8 value;
54 	void __iomem *reg_base = spifi->reg_base;
55 
56 	value = readb(reg_base + OFFSET_SPIMCTRL);
57 
58 	if (mode == MANUAL_MODE) {
59 		writeb(0x55, reg_base + OFFSET_SPICMD);
60 		writeb(0xaa, reg_base + OFFSET_SPICMD);
61 		value &= ~0x30;
62 	} else {
63 		value |= 0x30;
64 	}
65 	writeb(value, reg_base + OFFSET_SPIMCTRL);
66 }
67 
68 static int gxp_spi_read_reg(struct gxp_spi_chip *chip, const struct spi_mem_op *op)
69 {
70 	int ret;
71 	struct gxp_spi *spifi = chip->spifi;
72 	void __iomem *reg_base = spifi->reg_base;
73 	u32 value;
74 
75 	value = readl(reg_base + OFFSET_SPIMCFG);
76 	value &= ~(1 << 24);
77 	value |= (chip->cs << 24);
78 	value &= ~(0x07 << 16);
79 	value &= ~(0x1f << 19);
80 	writel(value, reg_base + OFFSET_SPIMCFG);
81 
82 	writel(0, reg_base + OFFSET_SPIADDR);
83 
84 	writeb(op->cmd.opcode, reg_base + OFFSET_SPICMD);
85 
86 	writew(op->data.nbytes, reg_base + OFFSET_SPIDCNT);
87 
88 	value = readb(reg_base + OFFSET_SPIMCTRL);
89 	value &= ~SPIMCTRL_DIR;
90 	value |= SPIMCTRL_START;
91 
92 	writeb(value, reg_base + OFFSET_SPIMCTRL);
93 
94 	ret = readb_poll_timeout(reg_base + OFFSET_SPIMCTRL, value,
95 				 !(value & SPIMCTRL_BUSY),
96 				 GXP_SPI_SLEEP_TIME, GXP_SPI_TIMEOUT);
97 	if (ret) {
98 		dev_warn(spifi->dev, "read reg busy time out\n");
99 		return ret;
100 	}
101 
102 	memcpy_fromio(op->data.buf.in, spifi->dat_base, op->data.nbytes);
103 	return ret;
104 }
105 
106 static int gxp_spi_write_reg(struct gxp_spi_chip *chip, const struct spi_mem_op *op)
107 {
108 	int ret;
109 	struct gxp_spi *spifi = chip->spifi;
110 	void __iomem *reg_base = spifi->reg_base;
111 	u32 value;
112 
113 	value = readl(reg_base + OFFSET_SPIMCFG);
114 	value &= ~(1 << 24);
115 	value |= (chip->cs << 24);
116 	value &= ~(0x07 << 16);
117 	value &= ~(0x1f << 19);
118 	writel(value, reg_base + OFFSET_SPIMCFG);
119 
120 	writel(0, reg_base + OFFSET_SPIADDR);
121 
122 	writeb(op->cmd.opcode, reg_base + OFFSET_SPICMD);
123 
124 	memcpy_toio(spifi->dat_base, op->data.buf.in, op->data.nbytes);
125 
126 	writew(op->data.nbytes, reg_base + OFFSET_SPIDCNT);
127 
128 	value = readb(reg_base + OFFSET_SPIMCTRL);
129 	value |= SPIMCTRL_DIR;
130 	value |= SPIMCTRL_START;
131 
132 	writeb(value, reg_base + OFFSET_SPIMCTRL);
133 
134 	ret = readb_poll_timeout(reg_base + OFFSET_SPIMCTRL, value,
135 				 !(value & SPIMCTRL_BUSY),
136 				 GXP_SPI_SLEEP_TIME, GXP_SPI_TIMEOUT);
137 	if (ret)
138 		dev_warn(spifi->dev, "write reg busy time out\n");
139 
140 	return ret;
141 }
142 
143 static ssize_t gxp_spi_read(struct gxp_spi_chip *chip, const struct spi_mem_op *op)
144 {
145 	struct gxp_spi *spifi = chip->spifi;
146 	u32 offset = op->addr.val;
147 
148 	if (chip->cs == 0)
149 		offset += 0x4000000;
150 
151 	memcpy_fromio(op->data.buf.in, spifi->dir_base + offset, op->data.nbytes);
152 
153 	return 0;
154 }
155 
156 static ssize_t gxp_spi_write(struct gxp_spi_chip *chip, const struct spi_mem_op *op)
157 {
158 	struct gxp_spi *spifi = chip->spifi;
159 	void __iomem *reg_base = spifi->reg_base;
160 	u32 write_len;
161 	u32 value;
162 	int ret;
163 
164 	write_len = op->data.nbytes;
165 	if (write_len > SPILDAT_LEN)
166 		write_len = SPILDAT_LEN;
167 
168 	value = readl(reg_base + OFFSET_SPIMCFG);
169 	value &= ~(1 << 24);
170 	value |= (chip->cs << 24);
171 	value &= ~(0x07 << 16);
172 	value |= (op->addr.nbytes << 16);
173 	value &= ~(0x1f << 19);
174 	writel(value, reg_base + OFFSET_SPIMCFG);
175 
176 	writel(op->addr.val, reg_base + OFFSET_SPIADDR);
177 
178 	writeb(op->cmd.opcode, reg_base + OFFSET_SPICMD);
179 
180 	writew(write_len, reg_base + OFFSET_SPIDCNT);
181 
182 	memcpy_toio(spifi->dat_base, op->data.buf.in, write_len);
183 
184 	value = readb(reg_base + OFFSET_SPIMCTRL);
185 	value |= SPIMCTRL_DIR;
186 	value |= SPIMCTRL_START;
187 
188 	writeb(value, reg_base + OFFSET_SPIMCTRL);
189 
190 	ret = readb_poll_timeout(reg_base + OFFSET_SPIMCTRL, value,
191 				 !(value & SPIMCTRL_BUSY),
192 				 GXP_SPI_SLEEP_TIME, GXP_SPI_TIMEOUT);
193 	if (ret) {
194 		dev_warn(spifi->dev, "write busy time out\n");
195 		return ret;
196 	}
197 
198 	return write_len;
199 }
200 
201 static int do_gxp_exec_mem_op(struct spi_mem *mem, const struct spi_mem_op *op)
202 {
203 	struct gxp_spi *spifi = spi_controller_get_devdata(mem->spi->master);
204 	struct gxp_spi_chip *chip = &spifi->chips[mem->spi->chip_select];
205 	int ret;
206 
207 	if (op->data.dir == SPI_MEM_DATA_IN) {
208 		if (!op->addr.nbytes)
209 			ret = gxp_spi_read_reg(chip, op);
210 		else
211 			ret = gxp_spi_read(chip, op);
212 	} else {
213 		if (!op->addr.nbytes)
214 			ret = gxp_spi_write_reg(chip, op);
215 		else
216 			ret = gxp_spi_write(chip, op);
217 	}
218 
219 	return ret;
220 }
221 
222 static int gxp_exec_mem_op(struct spi_mem *mem, const struct spi_mem_op *op)
223 {
224 	int ret;
225 
226 	ret = do_gxp_exec_mem_op(mem, op);
227 	if (ret)
228 		dev_err(&mem->spi->dev, "operation failed: %d", ret);
229 
230 	return ret;
231 }
232 
233 static const struct spi_controller_mem_ops gxp_spi_mem_ops = {
234 	.exec_op = gxp_exec_mem_op,
235 };
236 
237 static int gxp_spi_setup(struct spi_device *spi)
238 {
239 	struct gxp_spi *spifi = spi_controller_get_devdata(spi->master);
240 	unsigned int cs = spi->chip_select;
241 	struct gxp_spi_chip *chip = &spifi->chips[cs];
242 
243 	chip->spifi = spifi;
244 	chip->cs = cs;
245 
246 	gxp_spi_set_mode(spifi, MANUAL_MODE);
247 
248 	return 0;
249 }
250 
251 static int gxp_spifi_probe(struct platform_device *pdev)
252 {
253 	struct device *dev = &pdev->dev;
254 	const struct gxp_spi_data *data;
255 	struct spi_controller *ctlr;
256 	struct gxp_spi *spifi;
257 	int ret;
258 
259 	data = of_device_get_match_data(&pdev->dev);
260 
261 	ctlr = devm_spi_alloc_master(dev, sizeof(*spifi));
262 	if (!ctlr)
263 		return -ENOMEM;
264 
265 	spifi = spi_controller_get_devdata(ctlr);
266 
267 	platform_set_drvdata(pdev, spifi);
268 	spifi->data = data;
269 	spifi->dev = dev;
270 
271 	spifi->reg_base = devm_platform_ioremap_resource(pdev, 0);
272 	if (IS_ERR(spifi->reg_base))
273 		return PTR_ERR(spifi->reg_base);
274 
275 	spifi->dat_base = devm_platform_ioremap_resource(pdev, 1);
276 	if (IS_ERR(spifi->dat_base))
277 		return PTR_ERR(spifi->dat_base);
278 
279 	spifi->dir_base = devm_platform_ioremap_resource(pdev, 2);
280 	if (IS_ERR(spifi->dir_base))
281 		return PTR_ERR(spifi->dir_base);
282 
283 	ctlr->mode_bits = data->mode_bits;
284 	ctlr->bus_num = pdev->id;
285 	ctlr->mem_ops = &gxp_spi_mem_ops;
286 	ctlr->setup = gxp_spi_setup;
287 	ctlr->num_chipselect = data->max_cs;
288 	ctlr->dev.of_node = dev->of_node;
289 
290 	ret = devm_spi_register_controller(dev, ctlr);
291 	if (ret) {
292 		return dev_err_probe(&pdev->dev, ret,
293 				     "failed to register spi controller\n");
294 	}
295 
296 	return 0;
297 }
298 
299 static const struct gxp_spi_data gxp_spifi_data = {
300 	.max_cs	= 2,
301 	.mode_bits = 0,
302 };
303 
304 static const struct of_device_id gxp_spifi_match[] = {
305 	{.compatible = "hpe,gxp-spifi", .data = &gxp_spifi_data },
306 	{ /* null */ }
307 };
308 MODULE_DEVICE_TABLE(of, gxp_spifi_match);
309 
310 static struct platform_driver gxp_spifi_driver = {
311 	.probe = gxp_spifi_probe,
312 	.driver = {
313 		.name = "gxp-spifi",
314 		.of_match_table = gxp_spifi_match,
315 	},
316 };
317 module_platform_driver(gxp_spifi_driver);
318 
319 MODULE_DESCRIPTION("HPE GXP SPI Flash Interface driver");
320 MODULE_AUTHOR("Nick Hawkins <nick.hawkins@hpe.com>");
321 MODULE_LICENSE("GPL");
322