1 // SPDX-License-Identifier: GPL-2.0+
3 // Driver for Amlogic Meson SPI flash controller (SPIFC)
5 // Copyright (C) 2014 Beniamino Galvani <b.galvani@gmail.com>
9 #include <linux/delay.h>
10 #include <linux/device.h>
12 #include <linux/kernel.h>
13 #include <linux/module.h>
15 #include <linux/platform_device.h>
16 #include <linux/pm_runtime.h>
17 #include <linux/regmap.h>
18 #include <linux/spi/spi.h>
19 #include <linux/types.h>
25 #define REG_CTRL1 0x0c
26 #define REG_STATUS 0x10
27 #define REG_CTRL2 0x14
28 #define REG_CLOCK 0x18
30 #define REG_USER1 0x20
31 #define REG_USER2 0x24
32 #define REG_USER3 0x28
33 #define REG_USER4 0x2c
34 #define REG_SLAVE 0x30
35 #define REG_SLAVE1 0x34
36 #define REG_SLAVE2 0x38
37 #define REG_SLAVE3 0x3c
43 #define CMD_USER BIT(18)
44 #define CTRL_ENABLE_AHB BIT(17)
45 #define CLOCK_SOURCE BIT(31)
46 #define CLOCK_DIV_SHIFT 12
47 #define CLOCK_DIV_MASK (0x3f << CLOCK_DIV_SHIFT)
48 #define CLOCK_CNT_HIGH_SHIFT 6
49 #define CLOCK_CNT_HIGH_MASK (0x3f << CLOCK_CNT_HIGH_SHIFT)
50 #define CLOCK_CNT_LOW_SHIFT 0
51 #define CLOCK_CNT_LOW_MASK (0x3f << CLOCK_CNT_LOW_SHIFT)
52 #define USER_DIN_EN_MS BIT(0)
53 #define USER_CMP_MODE BIT(2)
54 #define USER_UC_DOUT_SEL BIT(27)
55 #define USER_UC_DIN_SEL BIT(28)
56 #define USER_UC_MASK ((BIT(5) - 1) << 27)
57 #define USER1_BN_UC_DOUT_SHIFT 17
58 #define USER1_BN_UC_DOUT_MASK (0xff << 16)
59 #define USER1_BN_UC_DIN_SHIFT 8
60 #define USER1_BN_UC_DIN_MASK (0xff << 8)
61 #define USER4_CS_ACT BIT(30)
62 #define SLAVE_TRST_DONE BIT(4)
63 #define SLAVE_OP_MODE BIT(30)
64 #define SLAVE_SW_RST BIT(31)
66 #define SPIFC_BUFFER_SIZE 64
70 * @master: the SPI master
71 * @regmap: regmap for device registers
72 * @clk: input clock of the built-in baud rate generator
73 * @dev: the device structure
76 struct spi_master
*master
;
77 struct regmap
*regmap
;
82 static const struct regmap_config spifc_regmap_config
= {
86 .max_register
= REG_MAX
,
90 * meson_spifc_wait_ready() - wait for the current operation to terminate
91 * @spifc: the Meson SPI device
92 * Return: 0 on success, a negative value on error
94 static int meson_spifc_wait_ready(struct meson_spifc
*spifc
)
96 unsigned long deadline
= jiffies
+ msecs_to_jiffies(5);
100 regmap_read(spifc
->regmap
, REG_SLAVE
, &data
);
101 if (data
& SLAVE_TRST_DONE
)
104 } while (!time_after(jiffies
, deadline
));
110 * meson_spifc_drain_buffer() - copy data from device buffer to memory
111 * @spifc: the Meson SPI device
112 * @buf: the destination buffer
113 * @len: number of bytes to copy
115 static void meson_spifc_drain_buffer(struct meson_spifc
*spifc
, u8
*buf
,
122 regmap_read(spifc
->regmap
, REG_C0
+ i
, &data
);
125 *((u32
*)buf
) = data
;
128 memcpy(buf
, &data
, len
- i
);
136 * meson_spifc_fill_buffer() - copy data from memory to device buffer
137 * @spifc: the Meson SPI device
138 * @buf: the source buffer
139 * @len: number of bytes to copy
141 static void meson_spifc_fill_buffer(struct meson_spifc
*spifc
, const u8
*buf
,
151 memcpy(&data
, buf
, len
- i
);
153 regmap_write(spifc
->regmap
, REG_C0
+ i
, data
);
161 * meson_spifc_setup_speed() - program the clock divider
162 * @spifc: the Meson SPI device
163 * @speed: desired speed in Hz
165 static void meson_spifc_setup_speed(struct meson_spifc
*spifc
, u32 speed
)
167 unsigned long parent
, value
;
170 parent
= clk_get_rate(spifc
->clk
);
171 n
= max_t(int, parent
/ speed
- 1, 1);
173 dev_dbg(spifc
->dev
, "parent %lu, speed %u, n %d\n", parent
,
176 value
= (n
<< CLOCK_DIV_SHIFT
) & CLOCK_DIV_MASK
;
177 value
|= (n
<< CLOCK_CNT_LOW_SHIFT
) & CLOCK_CNT_LOW_MASK
;
178 value
|= (((n
+ 1) / 2 - 1) << CLOCK_CNT_HIGH_SHIFT
) &
181 regmap_write(spifc
->regmap
, REG_CLOCK
, value
);
185 * meson_spifc_txrx() - transfer a chunk of data
186 * @spifc: the Meson SPI device
187 * @xfer: the current SPI transfer
188 * @offset: offset of the data to transfer
189 * @len: length of the data to transfer
190 * @last_xfer: whether this is the last transfer of the message
191 * @last_chunk: whether this is the last chunk of the transfer
192 * Return: 0 on success, a negative value on error
194 static int meson_spifc_txrx(struct meson_spifc
*spifc
,
195 struct spi_transfer
*xfer
,
196 int offset
, int len
, bool last_xfer
,
203 meson_spifc_fill_buffer(spifc
, xfer
->tx_buf
+ offset
, len
);
205 /* enable DOUT stage */
206 regmap_update_bits(spifc
->regmap
, REG_USER
, USER_UC_MASK
,
208 regmap_write(spifc
->regmap
, REG_USER1
,
209 (8 * len
- 1) << USER1_BN_UC_DOUT_SHIFT
);
211 /* enable data input during DOUT */
212 regmap_update_bits(spifc
->regmap
, REG_USER
, USER_DIN_EN_MS
,
217 keep_cs
= xfer
->cs_change
;
219 keep_cs
= !xfer
->cs_change
;
222 regmap_update_bits(spifc
->regmap
, REG_USER4
, USER4_CS_ACT
,
223 keep_cs
? USER4_CS_ACT
: 0);
225 /* clear transition done bit */
226 regmap_update_bits(spifc
->regmap
, REG_SLAVE
, SLAVE_TRST_DONE
, 0);
228 regmap_update_bits(spifc
->regmap
, REG_CMD
, CMD_USER
, CMD_USER
);
230 ret
= meson_spifc_wait_ready(spifc
);
232 if (!ret
&& xfer
->rx_buf
)
233 meson_spifc_drain_buffer(spifc
, xfer
->rx_buf
+ offset
, len
);
239 * meson_spifc_transfer_one() - perform a single transfer
240 * @master: the SPI master
241 * @spi: the SPI device
242 * @xfer: the current SPI transfer
243 * Return: 0 on success, a negative value on error
245 static int meson_spifc_transfer_one(struct spi_master
*master
,
246 struct spi_device
*spi
,
247 struct spi_transfer
*xfer
)
249 struct meson_spifc
*spifc
= spi_master_get_devdata(master
);
250 int len
, done
= 0, ret
= 0;
252 meson_spifc_setup_speed(spifc
, xfer
->speed_hz
);
254 regmap_update_bits(spifc
->regmap
, REG_CTRL
, CTRL_ENABLE_AHB
, 0);
256 while (done
< xfer
->len
&& !ret
) {
257 len
= min_t(int, xfer
->len
- done
, SPIFC_BUFFER_SIZE
);
258 ret
= meson_spifc_txrx(spifc
, xfer
, done
, len
,
259 spi_transfer_is_last(master
, xfer
),
260 done
+ len
>= xfer
->len
);
264 regmap_update_bits(spifc
->regmap
, REG_CTRL
, CTRL_ENABLE_AHB
,
271 * meson_spifc_hw_init() - reset and initialize the SPI controller
272 * @spifc: the Meson SPI device
274 static void meson_spifc_hw_init(struct meson_spifc
*spifc
)
277 regmap_update_bits(spifc
->regmap
, REG_SLAVE
, SLAVE_SW_RST
,
279 /* disable compatible mode */
280 regmap_update_bits(spifc
->regmap
, REG_USER
, USER_CMP_MODE
, 0);
281 /* set master mode */
282 regmap_update_bits(spifc
->regmap
, REG_SLAVE
, SLAVE_OP_MODE
, 0);
285 static int meson_spifc_probe(struct platform_device
*pdev
)
287 struct spi_master
*master
;
288 struct meson_spifc
*spifc
;
293 master
= spi_alloc_master(&pdev
->dev
, sizeof(struct meson_spifc
));
297 platform_set_drvdata(pdev
, master
);
299 spifc
= spi_master_get_devdata(master
);
300 spifc
->dev
= &pdev
->dev
;
302 base
= devm_platform_ioremap_resource(pdev
, 0);
308 spifc
->regmap
= devm_regmap_init_mmio(spifc
->dev
, base
,
309 &spifc_regmap_config
);
310 if (IS_ERR(spifc
->regmap
)) {
311 ret
= PTR_ERR(spifc
->regmap
);
315 spifc
->clk
= devm_clk_get(spifc
->dev
, NULL
);
316 if (IS_ERR(spifc
->clk
)) {
317 dev_err(spifc
->dev
, "missing clock\n");
318 ret
= PTR_ERR(spifc
->clk
);
322 ret
= clk_prepare_enable(spifc
->clk
);
324 dev_err(spifc
->dev
, "can't prepare clock\n");
328 rate
= clk_get_rate(spifc
->clk
);
330 master
->num_chipselect
= 1;
331 master
->dev
.of_node
= pdev
->dev
.of_node
;
332 master
->bits_per_word_mask
= SPI_BPW_MASK(8);
333 master
->auto_runtime_pm
= true;
334 master
->transfer_one
= meson_spifc_transfer_one
;
335 master
->min_speed_hz
= rate
>> 6;
336 master
->max_speed_hz
= rate
>> 1;
338 meson_spifc_hw_init(spifc
);
340 pm_runtime_set_active(spifc
->dev
);
341 pm_runtime_enable(spifc
->dev
);
343 ret
= devm_spi_register_master(spifc
->dev
, master
);
345 dev_err(spifc
->dev
, "failed to register spi master\n");
351 clk_disable_unprepare(spifc
->clk
);
353 spi_master_put(master
);
357 static int meson_spifc_remove(struct platform_device
*pdev
)
359 struct spi_master
*master
= platform_get_drvdata(pdev
);
360 struct meson_spifc
*spifc
= spi_master_get_devdata(master
);
362 pm_runtime_get_sync(&pdev
->dev
);
363 clk_disable_unprepare(spifc
->clk
);
364 pm_runtime_disable(&pdev
->dev
);
369 #ifdef CONFIG_PM_SLEEP
370 static int meson_spifc_suspend(struct device
*dev
)
372 struct spi_master
*master
= dev_get_drvdata(dev
);
373 struct meson_spifc
*spifc
= spi_master_get_devdata(master
);
376 ret
= spi_master_suspend(master
);
380 if (!pm_runtime_suspended(dev
))
381 clk_disable_unprepare(spifc
->clk
);
386 static int meson_spifc_resume(struct device
*dev
)
388 struct spi_master
*master
= dev_get_drvdata(dev
);
389 struct meson_spifc
*spifc
= spi_master_get_devdata(master
);
392 if (!pm_runtime_suspended(dev
)) {
393 ret
= clk_prepare_enable(spifc
->clk
);
398 meson_spifc_hw_init(spifc
);
400 ret
= spi_master_resume(master
);
402 clk_disable_unprepare(spifc
->clk
);
406 #endif /* CONFIG_PM_SLEEP */
409 static int meson_spifc_runtime_suspend(struct device
*dev
)
411 struct spi_master
*master
= dev_get_drvdata(dev
);
412 struct meson_spifc
*spifc
= spi_master_get_devdata(master
);
414 clk_disable_unprepare(spifc
->clk
);
419 static int meson_spifc_runtime_resume(struct device
*dev
)
421 struct spi_master
*master
= dev_get_drvdata(dev
);
422 struct meson_spifc
*spifc
= spi_master_get_devdata(master
);
424 return clk_prepare_enable(spifc
->clk
);
426 #endif /* CONFIG_PM */
428 static const struct dev_pm_ops meson_spifc_pm_ops
= {
429 SET_SYSTEM_SLEEP_PM_OPS(meson_spifc_suspend
, meson_spifc_resume
)
430 SET_RUNTIME_PM_OPS(meson_spifc_runtime_suspend
,
431 meson_spifc_runtime_resume
,
435 static const struct of_device_id meson_spifc_dt_match
[] = {
436 { .compatible
= "amlogic,meson6-spifc", },
437 { .compatible
= "amlogic,meson-gxbb-spifc", },
440 MODULE_DEVICE_TABLE(of
, meson_spifc_dt_match
);
442 static struct platform_driver meson_spifc_driver
= {
443 .probe
= meson_spifc_probe
,
444 .remove
= meson_spifc_remove
,
446 .name
= "meson-spifc",
447 .of_match_table
= of_match_ptr(meson_spifc_dt_match
),
448 .pm
= &meson_spifc_pm_ops
,
452 module_platform_driver(meson_spifc_driver
);
454 MODULE_AUTHOR("Beniamino Galvani <b.galvani@gmail.com>");
455 MODULE_DESCRIPTION("Amlogic Meson SPIFC driver");
456 MODULE_LICENSE("GPL v2");