Lines Matching full:spifc
3 // Driver for Amlogic Meson SPI flash controller (SPIFC)
91 * @spifc: the Meson SPI device
94 static int meson_spifc_wait_ready(struct meson_spifc *spifc) in meson_spifc_wait_ready() argument
100 regmap_read(spifc->regmap, REG_SLAVE, &data); in meson_spifc_wait_ready()
111 * @spifc: the Meson SPI device
115 static void meson_spifc_drain_buffer(struct meson_spifc *spifc, u8 *buf, in meson_spifc_drain_buffer() argument
122 regmap_read(spifc->regmap, REG_C0 + i, &data); in meson_spifc_drain_buffer()
137 * @spifc: the Meson SPI device
141 static void meson_spifc_fill_buffer(struct meson_spifc *spifc, const u8 *buf, in meson_spifc_fill_buffer() argument
153 regmap_write(spifc->regmap, REG_C0 + i, data); in meson_spifc_fill_buffer()
162 * @spifc: the Meson SPI device
165 static void meson_spifc_setup_speed(struct meson_spifc *spifc, u32 speed) in meson_spifc_setup_speed() argument
170 parent = clk_get_rate(spifc->clk); in meson_spifc_setup_speed()
173 dev_dbg(spifc->dev, "parent %lu, speed %u, n %d\n", parent, in meson_spifc_setup_speed()
181 regmap_write(spifc->regmap, REG_CLOCK, value); in meson_spifc_setup_speed()
186 * @spifc: the Meson SPI device
194 static int meson_spifc_txrx(struct meson_spifc *spifc, in meson_spifc_txrx() argument
203 meson_spifc_fill_buffer(spifc, xfer->tx_buf + offset, len); in meson_spifc_txrx()
206 regmap_update_bits(spifc->regmap, REG_USER, USER_UC_MASK, in meson_spifc_txrx()
208 regmap_write(spifc->regmap, REG_USER1, in meson_spifc_txrx()
212 regmap_update_bits(spifc->regmap, REG_USER, USER_DIN_EN_MS, in meson_spifc_txrx()
222 regmap_update_bits(spifc->regmap, REG_USER4, USER4_CS_ACT, in meson_spifc_txrx()
226 regmap_update_bits(spifc->regmap, REG_SLAVE, SLAVE_TRST_DONE, 0); in meson_spifc_txrx()
228 regmap_update_bits(spifc->regmap, REG_CMD, CMD_USER, CMD_USER); in meson_spifc_txrx()
230 ret = meson_spifc_wait_ready(spifc); in meson_spifc_txrx()
233 meson_spifc_drain_buffer(spifc, xfer->rx_buf + offset, len); in meson_spifc_txrx()
249 struct meson_spifc *spifc = spi_master_get_devdata(master); in meson_spifc_transfer_one() local
252 meson_spifc_setup_speed(spifc, xfer->speed_hz); in meson_spifc_transfer_one()
254 regmap_update_bits(spifc->regmap, REG_CTRL, CTRL_ENABLE_AHB, 0); in meson_spifc_transfer_one()
258 ret = meson_spifc_txrx(spifc, xfer, done, len, in meson_spifc_transfer_one()
264 regmap_update_bits(spifc->regmap, REG_CTRL, CTRL_ENABLE_AHB, in meson_spifc_transfer_one()
272 * @spifc: the Meson SPI device
274 static void meson_spifc_hw_init(struct meson_spifc *spifc) in meson_spifc_hw_init() argument
277 regmap_update_bits(spifc->regmap, REG_SLAVE, SLAVE_SW_RST, in meson_spifc_hw_init()
280 regmap_update_bits(spifc->regmap, REG_USER, USER_CMP_MODE, 0); in meson_spifc_hw_init()
282 regmap_update_bits(spifc->regmap, REG_SLAVE, SLAVE_OP_MODE, 0); in meson_spifc_hw_init()
288 struct meson_spifc *spifc; in meson_spifc_probe() local
299 spifc = spi_master_get_devdata(master); in meson_spifc_probe()
300 spifc->dev = &pdev->dev; in meson_spifc_probe()
308 spifc->regmap = devm_regmap_init_mmio(spifc->dev, base, in meson_spifc_probe()
310 if (IS_ERR(spifc->regmap)) { in meson_spifc_probe()
311 ret = PTR_ERR(spifc->regmap); in meson_spifc_probe()
315 spifc->clk = devm_clk_get(spifc->dev, NULL); in meson_spifc_probe()
316 if (IS_ERR(spifc->clk)) { in meson_spifc_probe()
317 dev_err(spifc->dev, "missing clock\n"); in meson_spifc_probe()
318 ret = PTR_ERR(spifc->clk); in meson_spifc_probe()
322 ret = clk_prepare_enable(spifc->clk); in meson_spifc_probe()
324 dev_err(spifc->dev, "can't prepare clock\n"); in meson_spifc_probe()
328 rate = clk_get_rate(spifc->clk); in meson_spifc_probe()
338 meson_spifc_hw_init(spifc); in meson_spifc_probe()
340 pm_runtime_set_active(spifc->dev); in meson_spifc_probe()
341 pm_runtime_enable(spifc->dev); in meson_spifc_probe()
343 ret = devm_spi_register_master(spifc->dev, master); in meson_spifc_probe()
345 dev_err(spifc->dev, "failed to register spi master\n"); in meson_spifc_probe()
351 clk_disable_unprepare(spifc->clk); in meson_spifc_probe()
352 pm_runtime_disable(spifc->dev); in meson_spifc_probe()
361 struct meson_spifc *spifc = spi_master_get_devdata(master); in meson_spifc_remove() local
364 clk_disable_unprepare(spifc->clk); in meson_spifc_remove()
374 struct meson_spifc *spifc = spi_master_get_devdata(master); in meson_spifc_suspend() local
382 clk_disable_unprepare(spifc->clk); in meson_spifc_suspend()
390 struct meson_spifc *spifc = spi_master_get_devdata(master); in meson_spifc_resume() local
394 ret = clk_prepare_enable(spifc->clk); in meson_spifc_resume()
399 meson_spifc_hw_init(spifc); in meson_spifc_resume()
403 clk_disable_unprepare(spifc->clk); in meson_spifc_resume()
413 struct meson_spifc *spifc = spi_master_get_devdata(master); in meson_spifc_runtime_suspend() local
415 clk_disable_unprepare(spifc->clk); in meson_spifc_runtime_suspend()
423 struct meson_spifc *spifc = spi_master_get_devdata(master); in meson_spifc_runtime_resume() local
425 return clk_prepare_enable(spifc->clk); in meson_spifc_runtime_resume()
437 { .compatible = "amlogic,meson6-spifc", },
438 { .compatible = "amlogic,meson-gxbb-spifc", },
447 .name = "meson-spifc",
456 MODULE_DESCRIPTION("Amlogic Meson SPIFC driver");