Lines Matching full:spifc
3 * Driver for Amlogic A1 SPI flash controller (SPIFC)
113 static int amlogic_spifc_a1_request(struct amlogic_spifc_a1 *spifc, bool read) in amlogic_spifc_a1_request() argument
120 spifc->base + SPIFC_A1_USER_CTRL0_REG); in amlogic_spifc_a1_request()
122 return readl_poll_timeout(spifc->base + SPIFC_A1_USER_CTRL0_REG, in amlogic_spifc_a1_request()
127 static void amlogic_spifc_a1_drain_buffer(struct amlogic_spifc_a1 *spifc, in amlogic_spifc_a1_drain_buffer() argument
135 spifc->base + SPIFC_A1_DBUF_CTRL_REG); in amlogic_spifc_a1_drain_buffer()
136 ioread32_rep(spifc->base + SPIFC_A1_DBUF_DATA_REG, buf, count); in amlogic_spifc_a1_drain_buffer()
139 data = readl(spifc->base + SPIFC_A1_DBUF_DATA_REG); in amlogic_spifc_a1_drain_buffer()
144 static void amlogic_spifc_a1_fill_buffer(struct amlogic_spifc_a1 *spifc, in amlogic_spifc_a1_fill_buffer() argument
152 spifc->base + SPIFC_A1_DBUF_CTRL_REG); in amlogic_spifc_a1_fill_buffer()
153 iowrite32_rep(spifc->base + SPIFC_A1_DBUF_DATA_REG, buf, count); in amlogic_spifc_a1_fill_buffer()
157 writel(data, spifc->base + SPIFC_A1_DBUF_DATA_REG); in amlogic_spifc_a1_fill_buffer()
161 static void amlogic_spifc_a1_user_init(struct amlogic_spifc_a1 *spifc) in amlogic_spifc_a1_user_init() argument
163 writel(0, spifc->base + SPIFC_A1_USER_CTRL0_REG); in amlogic_spifc_a1_user_init()
164 writel(0, spifc->base + SPIFC_A1_USER_CTRL1_REG); in amlogic_spifc_a1_user_init()
165 writel(0, spifc->base + SPIFC_A1_USER_CTRL2_REG); in amlogic_spifc_a1_user_init()
166 writel(0, spifc->base + SPIFC_A1_USER_CTRL3_REG); in amlogic_spifc_a1_user_init()
169 static void amlogic_spifc_a1_set_cmd(struct amlogic_spifc_a1 *spifc, in amlogic_spifc_a1_set_cmd() argument
174 val = readl(spifc->base + SPIFC_A1_USER_CTRL1_REG); in amlogic_spifc_a1_set_cmd()
177 writel(val, spifc->base + SPIFC_A1_USER_CTRL1_REG); in amlogic_spifc_a1_set_cmd()
180 static void amlogic_spifc_a1_set_addr(struct amlogic_spifc_a1 *spifc, u32 addr, in amlogic_spifc_a1_set_addr() argument
185 writel(addr, spifc->base + SPIFC_A1_USER_ADDR_REG); in amlogic_spifc_a1_set_addr()
187 val = readl(spifc->base + SPIFC_A1_USER_CTRL1_REG); in amlogic_spifc_a1_set_addr()
190 writel(val, spifc->base + SPIFC_A1_USER_CTRL1_REG); in amlogic_spifc_a1_set_addr()
193 static void amlogic_spifc_a1_set_dummy(struct amlogic_spifc_a1 *spifc, in amlogic_spifc_a1_set_dummy() argument
196 u32 val = readl(spifc->base + SPIFC_A1_USER_CTRL2_REG); in amlogic_spifc_a1_set_dummy()
200 writel(val, spifc->base + SPIFC_A1_USER_CTRL2_REG); in amlogic_spifc_a1_set_dummy()
203 static int amlogic_spifc_a1_read(struct amlogic_spifc_a1 *spifc, void *buf, in amlogic_spifc_a1_read() argument
206 u32 val = readl(spifc->base + SPIFC_A1_USER_CTRL3_REG); in amlogic_spifc_a1_read()
213 writel(val, spifc->base + SPIFC_A1_USER_CTRL3_REG); in amlogic_spifc_a1_read()
215 ret = amlogic_spifc_a1_request(spifc, true); in amlogic_spifc_a1_read()
217 amlogic_spifc_a1_drain_buffer(spifc, buf, size); in amlogic_spifc_a1_read()
222 static int amlogic_spifc_a1_write(struct amlogic_spifc_a1 *spifc, in amlogic_spifc_a1_write() argument
227 amlogic_spifc_a1_fill_buffer(spifc, buf, size); in amlogic_spifc_a1_write()
229 val = readl(spifc->base + SPIFC_A1_USER_CTRL1_REG); in amlogic_spifc_a1_write()
234 writel(val, spifc->base + SPIFC_A1_USER_CTRL1_REG); in amlogic_spifc_a1_write()
236 return amlogic_spifc_a1_request(spifc, false); in amlogic_spifc_a1_write()
239 static int amlogic_spifc_a1_set_freq(struct amlogic_spifc_a1 *spifc, u32 freq) in amlogic_spifc_a1_set_freq() argument
243 if (freq == spifc->curr_speed_hz) in amlogic_spifc_a1_set_freq()
246 ret = clk_set_rate(spifc->clk, freq); in amlogic_spifc_a1_set_freq()
250 spifc->curr_speed_hz = freq; in amlogic_spifc_a1_set_freq()
257 struct amlogic_spifc_a1 *spifc = in amlogic_spifc_a1_exec_op() local
262 ret = amlogic_spifc_a1_set_freq(spifc, mem->spi->max_speed_hz); in amlogic_spifc_a1_exec_op()
266 amlogic_spifc_a1_user_init(spifc); in amlogic_spifc_a1_exec_op()
267 amlogic_spifc_a1_set_cmd(spifc, SPIFC_A1_USER_CMD(op)); in amlogic_spifc_a1_exec_op()
270 amlogic_spifc_a1_set_addr(spifc, op->addr.val, in amlogic_spifc_a1_exec_op()
274 amlogic_spifc_a1_set_dummy(spifc, SPIFC_A1_USER_DUMMY(op)); in amlogic_spifc_a1_exec_op()
279 writel(0, spifc->base + SPIFC_A1_USER_DBUF_ADDR_REG); in amlogic_spifc_a1_exec_op()
282 ret = amlogic_spifc_a1_read(spifc, op->data.buf.in, in amlogic_spifc_a1_exec_op()
285 ret = amlogic_spifc_a1_write(spifc, op->data.buf.out, in amlogic_spifc_a1_exec_op()
288 ret = amlogic_spifc_a1_request(spifc, false); in amlogic_spifc_a1_exec_op()
301 static void amlogic_spifc_a1_hw_init(struct amlogic_spifc_a1 *spifc) in amlogic_spifc_a1_hw_init() argument
305 regv = readl(spifc->base + SPIFC_A1_AHB_REQ_CTRL_REG); in amlogic_spifc_a1_hw_init()
307 writel(regv, spifc->base + SPIFC_A1_AHB_REQ_CTRL_REG); in amlogic_spifc_a1_hw_init()
309 regv = readl(spifc->base + SPIFC_A1_AHB_CTRL_REG); in amlogic_spifc_a1_hw_init()
311 writel(regv, spifc->base + SPIFC_A1_AHB_CTRL_REG); in amlogic_spifc_a1_hw_init()
313 writel(SPIFC_A1_ACTIMING0_VAL, spifc->base + SPIFC_A1_ACTIMING0_REG); in amlogic_spifc_a1_hw_init()
315 writel(0, spifc->base + SPIFC_A1_USER_DBUF_ADDR_REG); in amlogic_spifc_a1_hw_init()
326 struct amlogic_spifc_a1 *spifc; in amlogic_spifc_a1_probe() local
329 ctrl = devm_spi_alloc_host(&pdev->dev, sizeof(*spifc)); in amlogic_spifc_a1_probe()
333 spifc = spi_controller_get_devdata(ctrl); in amlogic_spifc_a1_probe()
334 platform_set_drvdata(pdev, spifc); in amlogic_spifc_a1_probe()
336 spifc->dev = &pdev->dev; in amlogic_spifc_a1_probe()
337 spifc->ctrl = ctrl; in amlogic_spifc_a1_probe()
339 spifc->base = devm_platform_ioremap_resource(pdev, 0); in amlogic_spifc_a1_probe()
340 if (IS_ERR(spifc->base)) in amlogic_spifc_a1_probe()
341 return PTR_ERR(spifc->base); in amlogic_spifc_a1_probe()
343 spifc->clk = devm_clk_get_enabled(spifc->dev, NULL); in amlogic_spifc_a1_probe()
344 if (IS_ERR(spifc->clk)) in amlogic_spifc_a1_probe()
345 return dev_err_probe(spifc->dev, PTR_ERR(spifc->clk), in amlogic_spifc_a1_probe()
348 amlogic_spifc_a1_hw_init(spifc); in amlogic_spifc_a1_probe()
350 pm_runtime_set_autosuspend_delay(spifc->dev, 500); in amlogic_spifc_a1_probe()
351 pm_runtime_use_autosuspend(spifc->dev); in amlogic_spifc_a1_probe()
352 devm_pm_runtime_enable(spifc->dev); in amlogic_spifc_a1_probe()
364 ret = devm_spi_register_controller(spifc->dev, ctrl); in amlogic_spifc_a1_probe()
366 return dev_err_probe(spifc->dev, ret, in amlogic_spifc_a1_probe()
375 struct amlogic_spifc_a1 *spifc = dev_get_drvdata(dev); in amlogic_spifc_a1_suspend() local
378 ret = spi_controller_suspend(spifc->ctrl); in amlogic_spifc_a1_suspend()
383 clk_disable_unprepare(spifc->clk); in amlogic_spifc_a1_suspend()
390 struct amlogic_spifc_a1 *spifc = dev_get_drvdata(dev); in amlogic_spifc_a1_resume() local
394 ret = clk_prepare_enable(spifc->clk); in amlogic_spifc_a1_resume()
399 amlogic_spifc_a1_hw_init(spifc); in amlogic_spifc_a1_resume()
401 ret = spi_controller_resume(spifc->ctrl); in amlogic_spifc_a1_resume()
403 clk_disable_unprepare(spifc->clk); in amlogic_spifc_a1_resume()
412 struct amlogic_spifc_a1 *spifc = dev_get_drvdata(dev); in amlogic_spifc_a1_runtime_suspend() local
414 clk_disable_unprepare(spifc->clk); in amlogic_spifc_a1_runtime_suspend()
421 struct amlogic_spifc_a1 *spifc = dev_get_drvdata(dev); in amlogic_spifc_a1_runtime_resume() local
424 ret = clk_prepare_enable(spifc->clk); in amlogic_spifc_a1_runtime_resume()
426 amlogic_spifc_a1_hw_init(spifc); in amlogic_spifc_a1_runtime_resume()
442 { .compatible = "amlogic,a1-spifc", },
451 .name = "amlogic-spifc-a1",
459 MODULE_DESCRIPTION("Amlogic A1 SPIFC driver");