Lines Matching +full:op +full:- +full:mode

1 // SPDX-License-Identifier: GPL-2.0
21 #include <linux/spi/spi-mem.h>
80 #define SPIFC_A1_USER_CMD(op) ( \ argument
82 FIELD_PREP(SPIFC_A1_USER_CMD_CODE, (op)->cmd.opcode) | \
83 FIELD_PREP(SPIFC_A1_USER_CMD_MODE, ilog2((op)->cmd.buswidth)))
85 #define SPIFC_A1_USER_ADDR(op) ( \ argument
87 FIELD_PREP(SPIFC_A1_USER_ADDR_MODE, ilog2((op)->addr.buswidth)) | \
88 FIELD_PREP(SPIFC_A1_USER_ADDR_BYTES, (op)->addr.nbytes - 1))
90 #define SPIFC_A1_USER_DUMMY(op) ( \ argument
92 FIELD_PREP(SPIFC_A1_USER_DUMMY_MODE, ilog2((op)->dummy.buswidth)) | \
93 FIELD_PREP(SPIFC_A1_USER_DUMMY_CLK_SYCLES, (op)->dummy.nbytes << 3))
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()
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()
140 memcpy(buf + len - pad, &data, pad); in amlogic_spifc_a1_drain_buffer()
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()
156 memcpy(&data, buf + len - pad, pad); in amlogic_spifc_a1_fill_buffer()
157 writel(data, spifc->base + SPIFC_A1_DBUF_DATA_REG); in amlogic_spifc_a1_fill_buffer()
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()
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()
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()
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()
204 u32 size, u32 mode) in amlogic_spifc_a1_read() argument
206 u32 val = readl(spifc->base + SPIFC_A1_USER_CTRL3_REG); in amlogic_spifc_a1_read()
211 val |= FIELD_PREP(SPIFC_A1_USER_DIN_MODE, mode); in amlogic_spifc_a1_read()
213 writel(val, spifc->base + SPIFC_A1_USER_CTRL3_REG); in amlogic_spifc_a1_read()
223 const void *buf, u32 size, u32 mode) in amlogic_spifc_a1_write() argument
229 val = readl(spifc->base + SPIFC_A1_USER_CTRL1_REG); in amlogic_spifc_a1_write()
231 val |= FIELD_PREP(SPIFC_A1_USER_DOUT_MODE, mode); in amlogic_spifc_a1_write()
234 writel(val, spifc->base + SPIFC_A1_USER_CTRL1_REG); in amlogic_spifc_a1_write()
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()
255 const struct spi_mem_op *op) in amlogic_spifc_a1_exec_op() argument
258 spi_controller_get_devdata(mem->spi->controller); in amlogic_spifc_a1_exec_op()
259 size_t data_size = op->data.nbytes; in amlogic_spifc_a1_exec_op()
262 ret = amlogic_spifc_a1_set_freq(spifc, op->max_freq); in amlogic_spifc_a1_exec_op()
267 amlogic_spifc_a1_set_cmd(spifc, SPIFC_A1_USER_CMD(op)); in amlogic_spifc_a1_exec_op()
269 if (op->addr.nbytes) in amlogic_spifc_a1_exec_op()
270 amlogic_spifc_a1_set_addr(spifc, op->addr.val, in amlogic_spifc_a1_exec_op()
271 SPIFC_A1_USER_ADDR(op)); in amlogic_spifc_a1_exec_op()
273 if (op->dummy.nbytes) in amlogic_spifc_a1_exec_op()
274 amlogic_spifc_a1_set_dummy(spifc, SPIFC_A1_USER_DUMMY(op)); in amlogic_spifc_a1_exec_op()
277 u32 mode = ilog2(op->data.buswidth); in amlogic_spifc_a1_exec_op() local
279 writel(0, spifc->base + SPIFC_A1_USER_DBUF_ADDR_REG); in amlogic_spifc_a1_exec_op()
281 if (op->data.dir == SPI_MEM_DATA_IN) in amlogic_spifc_a1_exec_op()
282 ret = amlogic_spifc_a1_read(spifc, op->data.buf.in, in amlogic_spifc_a1_exec_op()
283 data_size, mode); in amlogic_spifc_a1_exec_op()
285 ret = amlogic_spifc_a1_write(spifc, op->data.buf.out, in amlogic_spifc_a1_exec_op()
286 data_size, mode); in amlogic_spifc_a1_exec_op()
295 struct spi_mem_op *op) in amlogic_spifc_a1_adjust_op_size() argument
297 op->data.nbytes = min(op->data.nbytes, SPIFC_A1_BUFFER_SIZE); in amlogic_spifc_a1_adjust_op_size()
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()
333 ctrl = devm_spi_alloc_host(&pdev->dev, sizeof(*spifc)); in amlogic_spifc_a1_probe()
335 return -ENOMEM; in amlogic_spifc_a1_probe()
340 spifc->dev = &pdev->dev; in amlogic_spifc_a1_probe()
341 spifc->ctrl = ctrl; in amlogic_spifc_a1_probe()
343 spifc->base = devm_platform_ioremap_resource(pdev, 0); in amlogic_spifc_a1_probe()
344 if (IS_ERR(spifc->base)) in amlogic_spifc_a1_probe()
345 return PTR_ERR(spifc->base); in amlogic_spifc_a1_probe()
347 spifc->clk = devm_clk_get_enabled(spifc->dev, NULL); in amlogic_spifc_a1_probe()
348 if (IS_ERR(spifc->clk)) in amlogic_spifc_a1_probe()
349 return dev_err_probe(spifc->dev, PTR_ERR(spifc->clk), in amlogic_spifc_a1_probe()
354 pm_runtime_set_autosuspend_delay(spifc->dev, 500); in amlogic_spifc_a1_probe()
355 pm_runtime_use_autosuspend(spifc->dev); in amlogic_spifc_a1_probe()
356 devm_pm_runtime_enable(spifc->dev); in amlogic_spifc_a1_probe()
358 ctrl->num_chipselect = 1; in amlogic_spifc_a1_probe()
359 ctrl->dev.of_node = pdev->dev.of_node; in amlogic_spifc_a1_probe()
360 ctrl->bits_per_word_mask = SPI_BPW_MASK(8); in amlogic_spifc_a1_probe()
361 ctrl->auto_runtime_pm = true; in amlogic_spifc_a1_probe()
362 ctrl->mem_ops = &amlogic_spifc_a1_mem_ops; in amlogic_spifc_a1_probe()
363 ctrl->mem_caps = &amlogic_spifc_a1_mem_caps; in amlogic_spifc_a1_probe()
364 ctrl->min_speed_hz = SPIFC_A1_MIN_HZ; in amlogic_spifc_a1_probe()
365 ctrl->max_speed_hz = SPIFC_A1_MAX_HZ; in amlogic_spifc_a1_probe()
366 ctrl->mode_bits = (SPI_RX_DUAL | SPI_TX_DUAL | in amlogic_spifc_a1_probe()
369 ret = devm_spi_register_controller(spifc->dev, ctrl); in amlogic_spifc_a1_probe()
371 return dev_err_probe(spifc->dev, ret, in amlogic_spifc_a1_probe()
383 ret = spi_controller_suspend(spifc->ctrl); in amlogic_spifc_a1_suspend()
388 clk_disable_unprepare(spifc->clk); in amlogic_spifc_a1_suspend()
399 ret = clk_prepare_enable(spifc->clk); in amlogic_spifc_a1_resume()
406 ret = spi_controller_resume(spifc->ctrl); in amlogic_spifc_a1_resume()
408 clk_disable_unprepare(spifc->clk); in amlogic_spifc_a1_resume()
419 clk_disable_unprepare(spifc->clk); in amlogic_spifc_a1_runtime_suspend()
429 ret = clk_prepare_enable(spifc->clk); in amlogic_spifc_a1_runtime_resume()
447 { .compatible = "amlogic,a1-spifc", },
456 .name = "amlogic-spifc-a1",