Lines Matching +full:cs +full:- +full:x
1 // SPDX-License-Identifier: GPL-2.0-or-later
5 * Copyright (c) 2015-2022, IBM Corporation.
15 #include <linux/spi/spi-mem.h>
17 #define DEVICE_NAME "spi-aspeed-smc"
64 u32 cs; member
108 switch (op->data.buswidth) { in aspeed_spi_get_io_mode()
125 ctl = readl(chip->ctl) & ~CTRL_IO_MODE_MASK; in aspeed_spi_set_io_mode()
127 writel(ctl, chip->ctl); in aspeed_spi_set_io_mode()
133 u32 ctl = chip->ctl_val[ASPEED_SPI_BASE]; in aspeed_spi_start_user()
136 writel(ctl, chip->ctl); in aspeed_spi_start_user()
139 writel(ctl, chip->ctl); in aspeed_spi_start_user()
144 u32 ctl = chip->ctl_val[ASPEED_SPI_READ] | in aspeed_spi_stop_user()
147 writel(ctl, chip->ctl); in aspeed_spi_stop_user()
150 writel(chip->ctl_val[ASPEED_SPI_READ], chip->ctl); in aspeed_spi_stop_user()
161 len -= offset; in aspeed_spi_read_from_ahb()
175 len -= offset; in aspeed_spi_write_to_ahb()
193 aspeed_spi_write_to_ahb(chip->ahb_base, &temp, 4); in aspeed_spi_send_cmd_addr()
197 aspeed_spi_write_to_ahb(chip->ahb_base, &opcode, 1); in aspeed_spi_send_cmd_addr()
198 aspeed_spi_write_to_ahb(chip->ahb_base, &temp, 4); in aspeed_spi_send_cmd_addr()
202 return -EOPNOTSUPP; in aspeed_spi_send_cmd_addr()
211 aspeed_spi_write_to_ahb(chip->ahb_base, &op->cmd.opcode, 1); in aspeed_spi_read_reg()
212 aspeed_spi_read_from_ahb(op->data.buf.in, in aspeed_spi_read_reg()
213 chip->ahb_base, op->data.nbytes); in aspeed_spi_read_reg()
222 aspeed_spi_write_to_ahb(chip->ahb_base, &op->cmd.opcode, 1); in aspeed_spi_write_reg()
223 aspeed_spi_write_to_ahb(chip->ahb_base, op->data.buf.out, in aspeed_spi_write_reg()
224 op->data.nbytes); in aspeed_spi_write_reg()
240 ret = aspeed_spi_send_cmd_addr(chip, op->addr.nbytes, offset, op->cmd.opcode); in aspeed_spi_read_user()
244 if (op->dummy.buswidth && op->dummy.nbytes) { in aspeed_spi_read_user()
245 for (i = 0; i < op->dummy.nbytes / op->dummy.buswidth; i++) in aspeed_spi_read_user()
246 aspeed_spi_write_to_ahb(chip->ahb_base, &dummy, sizeof(dummy)); in aspeed_spi_read_user()
251 aspeed_spi_read_from_ahb(buf, chip->ahb_base, len); in aspeed_spi_read_user()
263 ret = aspeed_spi_send_cmd_addr(chip, op->addr.nbytes, op->addr.val, op->cmd.opcode); in aspeed_spi_write_user()
266 aspeed_spi_write_to_ahb(chip->ahb_base, op->data.buf.out, op->data.nbytes); in aspeed_spi_write_user()
272 /* support for 1-1-1, 1-1-2 or 1-1-4 */
275 if (op->cmd.buswidth > 1) in aspeed_spi_supports_op()
278 if (op->addr.nbytes != 0) { in aspeed_spi_supports_op()
279 if (op->addr.buswidth > 1) in aspeed_spi_supports_op()
281 if (op->addr.nbytes < 3 || op->addr.nbytes > 4) in aspeed_spi_supports_op()
285 if (op->dummy.nbytes != 0) { in aspeed_spi_supports_op()
286 if (op->dummy.buswidth > 1 || op->dummy.nbytes > 7) in aspeed_spi_supports_op()
290 if (op->data.nbytes != 0 && op->data.buswidth > 4) in aspeed_spi_supports_op()
300 struct aspeed_spi *aspi = spi_controller_get_devdata(mem->spi->controller); in do_aspeed_spi_exec_op()
301 struct aspeed_spi_chip *chip = &aspi->chips[spi_get_chipselect(mem->spi, 0)]; in do_aspeed_spi_exec_op()
306 dev_dbg(aspi->dev, in do_aspeed_spi_exec_op()
307 "CE%d %s OP %#x mode:%d.%d.%d.%d naddr:%#x ndummies:%#x len:%#x", in do_aspeed_spi_exec_op()
308 chip->cs, op->data.dir == SPI_MEM_DATA_IN ? "read" : "write", in do_aspeed_spi_exec_op()
309 op->cmd.opcode, op->cmd.buswidth, op->addr.buswidth, in do_aspeed_spi_exec_op()
310 op->dummy.buswidth, op->data.buswidth, in do_aspeed_spi_exec_op()
311 op->addr.nbytes, op->dummy.nbytes, op->data.nbytes); in do_aspeed_spi_exec_op()
313 addr_mode = readl(aspi->regs + CE_CTRL_REG); in do_aspeed_spi_exec_op()
316 ctl_val = chip->ctl_val[ASPEED_SPI_BASE]; in do_aspeed_spi_exec_op()
319 ctl_val |= op->cmd.opcode << CTRL_COMMAND_SHIFT; in do_aspeed_spi_exec_op()
322 if (op->addr.nbytes) { in do_aspeed_spi_exec_op()
323 if (op->addr.nbytes == 4) in do_aspeed_spi_exec_op()
324 addr_mode |= (0x11 << chip->cs); in do_aspeed_spi_exec_op()
326 addr_mode &= ~(0x11 << chip->cs); in do_aspeed_spi_exec_op()
328 if (op->addr.nbytes == 4 && chip->aspi->data == &ast2400_spi_data) in do_aspeed_spi_exec_op()
332 if (op->dummy.nbytes) in do_aspeed_spi_exec_op()
333 ctl_val |= CTRL_IO_DUMMY_SET(op->dummy.nbytes / op->dummy.buswidth); in do_aspeed_spi_exec_op()
335 if (op->data.nbytes) in do_aspeed_spi_exec_op()
338 if (op->data.dir == SPI_MEM_DATA_OUT) in do_aspeed_spi_exec_op()
344 writel(addr_mode, aspi->regs + CE_CTRL_REG); in do_aspeed_spi_exec_op()
345 writel(ctl_val, chip->ctl); in do_aspeed_spi_exec_op()
347 if (op->data.dir == SPI_MEM_DATA_IN) { in do_aspeed_spi_exec_op()
348 if (!op->addr.nbytes) in do_aspeed_spi_exec_op()
351 ret = aspeed_spi_read_user(chip, op, op->addr.val, in do_aspeed_spi_exec_op()
352 op->data.nbytes, op->data.buf.in); in do_aspeed_spi_exec_op()
354 if (!op->addr.nbytes) in do_aspeed_spi_exec_op()
362 writel(addr_mode_backup, aspi->regs + CE_CTRL_REG); in do_aspeed_spi_exec_op()
363 writel(chip->ctl_val[ASPEED_SPI_READ], chip->ctl); in do_aspeed_spi_exec_op()
373 dev_err(&mem->spi->dev, "operation failed: %d\n", ret); in aspeed_spi_exec_op()
379 struct aspeed_spi *aspi = spi_controller_get_devdata(mem->spi->controller); in aspeed_spi_get_name()
380 struct device *dev = aspi->dev; in aspeed_spi_get_name()
383 spi_get_chipselect(mem->spi, 0)); in aspeed_spi_get_name()
387 u32 cs; member
395 const struct aspeed_spi_data *data = aspi->data; in aspeed_spi_get_windows()
397 u32 cs; in aspeed_spi_get_windows() local
399 for (cs = 0; cs < aspi->data->max_cs; cs++) { in aspeed_spi_get_windows()
400 reg_val = readl(aspi->regs + CE0_SEGMENT_ADDR_REG + cs * 4); in aspeed_spi_get_windows()
401 windows[cs].cs = cs; in aspeed_spi_get_windows()
402 windows[cs].size = data->segment_end(aspi, reg_val) - in aspeed_spi_get_windows()
403 data->segment_start(aspi, reg_val); in aspeed_spi_get_windows()
404 windows[cs].offset = data->segment_start(aspi, reg_val) - aspi->ahb_base_phy; in aspeed_spi_get_windows()
405 dev_vdbg(aspi->dev, "CE%d offset=0x%.8x size=0x%x\n", cs, in aspeed_spi_get_windows()
406 windows[cs].offset, windows[cs].size); in aspeed_spi_get_windows()
412 * U-Boot should open all.
416 struct aspeed_spi *aspi = chip->aspi; in aspeed_spi_chip_set_default_window()
418 struct aspeed_spi_window *win = &windows[chip->cs]; in aspeed_spi_chip_set_default_window()
421 if (aspi->data == &ast2400_spi_data) { in aspeed_spi_chip_set_default_window()
422 win->offset = 0; in aspeed_spi_chip_set_default_window()
423 win->size = aspi->ahb_window_size; in aspeed_spi_chip_set_default_window()
428 chip->ahb_base = aspi->ahb_base + win->offset; in aspeed_spi_chip_set_default_window()
429 chip->ahb_window_size = win->size; in aspeed_spi_chip_set_default_window()
431 dev_dbg(aspi->dev, "CE%d default window [ 0x%.8x - 0x%.8x ] %dMB", in aspeed_spi_chip_set_default_window()
432 chip->cs, aspi->ahb_base_phy + win->offset, in aspeed_spi_chip_set_default_window()
433 aspi->ahb_base_phy + win->offset + win->size - 1, in aspeed_spi_chip_set_default_window()
434 win->size >> 20); in aspeed_spi_chip_set_default_window()
436 return chip->ahb_window_size ? 0 : -1; in aspeed_spi_chip_set_default_window()
442 u32 start = aspi->ahb_base_phy + win->offset; in aspeed_spi_set_window()
443 u32 end = start + win->size; in aspeed_spi_set_window()
444 void __iomem *seg_reg = aspi->regs + CE0_SEGMENT_ADDR_REG + win->cs * 4; in aspeed_spi_set_window()
446 u32 seg_val = aspi->data->segment_reg(aspi, start, end); in aspeed_spi_set_window()
458 dev_err(aspi->dev, "CE%d invalid window [ 0x%.8x - 0x%.8x ] %dMB", in aspeed_spi_set_window()
459 win->cs, start, end - 1, win->size >> 20); in aspeed_spi_set_window()
461 return -EIO; in aspeed_spi_set_window()
464 if (win->size) in aspeed_spi_set_window()
465 dev_dbg(aspi->dev, "CE%d new window [ 0x%.8x - 0x%.8x ] %dMB", in aspeed_spi_set_window()
466 win->cs, start, end - 1, win->size >> 20); in aspeed_spi_set_window()
468 dev_dbg(aspi->dev, "CE%d window closed", win->cs); in aspeed_spi_set_window()
475 * - Align mappings on flash size (we don't have the info)
476 * - ioremap each window, not strictly necessary since the overall window
486 struct aspeed_spi *aspi = chip->aspi; in aspeed_spi_chip_adjust_window()
488 struct aspeed_spi_window *win = &windows[chip->cs]; in aspeed_spi_chip_adjust_window()
492 if (aspi->data == &ast2400_spi_data) in aspeed_spi_chip_adjust_window()
499 if (aspi->data == &ast2500_spi_data && chip->cs == 0 && size == SZ_128M) { in aspeed_spi_chip_adjust_window()
501 dev_info(aspi->dev, "CE%d window resized to %dMB (AST2500 HW quirk)", in aspeed_spi_chip_adjust_window()
502 chip->cs, size >> 20); in aspeed_spi_chip_adjust_window()
509 if ((aspi->data == &ast2600_spi_data || aspi->data == &ast2600_fmc_data) && in aspeed_spi_chip_adjust_window()
512 dev_info(aspi->dev, "CE%d window resized to %dMB (AST2600 Decoding)", in aspeed_spi_chip_adjust_window()
513 chip->cs, size >> 20); in aspeed_spi_chip_adjust_window()
519 win->offset += local_offset; in aspeed_spi_chip_adjust_window()
520 win->size = size; in aspeed_spi_chip_adjust_window()
522 if (win->offset + win->size > aspi->ahb_window_size) { in aspeed_spi_chip_adjust_window()
523 win->size = aspi->ahb_window_size - win->offset; in aspeed_spi_chip_adjust_window()
524 dev_warn(aspi->dev, "CE%d window resized to %dMB", chip->cs, win->size >> 20); in aspeed_spi_chip_adjust_window()
532 chip->ahb_base = aspi->ahb_base + win->offset; in aspeed_spi_chip_adjust_window()
533 chip->ahb_window_size = win->size; in aspeed_spi_chip_adjust_window()
539 if (chip->cs < aspi->data->max_cs - 1) { in aspeed_spi_chip_adjust_window()
540 struct aspeed_spi_window *next = &windows[chip->cs + 1]; in aspeed_spi_chip_adjust_window()
543 if ((next->offset + next->size) > (win->offset + win->size)) in aspeed_spi_chip_adjust_window()
544 next->size = (next->offset + next->size) - (win->offset + win->size); in aspeed_spi_chip_adjust_window()
546 next->size = 0; in aspeed_spi_chip_adjust_window()
547 next->offset = win->offset + win->size; in aspeed_spi_chip_adjust_window()
558 struct aspeed_spi *aspi = spi_controller_get_devdata(desc->mem->spi->controller); in aspeed_spi_dirmap_create()
559 struct aspeed_spi_chip *chip = &aspi->chips[spi_get_chipselect(desc->mem->spi, 0)]; in aspeed_spi_dirmap_create()
560 struct spi_mem_op *op = &desc->info.op_tmpl; in aspeed_spi_dirmap_create()
564 dev_dbg(aspi->dev, in aspeed_spi_dirmap_create()
565 "CE%d %s dirmap [ 0x%.8llx - 0x%.8llx ] OP %#x mode:%d.%d.%d.%d naddr:%#x ndummies:%#x\n", in aspeed_spi_dirmap_create()
566 chip->cs, op->data.dir == SPI_MEM_DATA_IN ? "read" : "write", in aspeed_spi_dirmap_create()
567 desc->info.offset, desc->info.offset + desc->info.length, in aspeed_spi_dirmap_create()
568 op->cmd.opcode, op->cmd.buswidth, op->addr.buswidth, in aspeed_spi_dirmap_create()
569 op->dummy.buswidth, op->data.buswidth, in aspeed_spi_dirmap_create()
570 op->addr.nbytes, op->dummy.nbytes); in aspeed_spi_dirmap_create()
572 chip->clk_freq = desc->mem->spi->max_speed_hz; in aspeed_spi_dirmap_create()
575 if (op->data.dir != SPI_MEM_DATA_IN) in aspeed_spi_dirmap_create()
576 return -EOPNOTSUPP; in aspeed_spi_dirmap_create()
578 aspeed_spi_chip_adjust_window(chip, desc->info.offset, desc->info.length); in aspeed_spi_dirmap_create()
580 if (desc->info.length > chip->ahb_window_size) in aspeed_spi_dirmap_create()
581 dev_warn(aspi->dev, "CE%d window (%dMB) too small for mapping", in aspeed_spi_dirmap_create()
582 chip->cs, chip->ahb_window_size >> 20); in aspeed_spi_dirmap_create()
585 ctl_val = readl(chip->ctl) & ~CTRL_IO_CMD_MASK; in aspeed_spi_dirmap_create()
587 op->cmd.opcode << CTRL_COMMAND_SHIFT | in aspeed_spi_dirmap_create()
590 if (op->dummy.nbytes) in aspeed_spi_dirmap_create()
591 ctl_val |= CTRL_IO_DUMMY_SET(op->dummy.nbytes / op->dummy.buswidth); in aspeed_spi_dirmap_create()
594 if (op->addr.nbytes) { in aspeed_spi_dirmap_create()
595 u32 addr_mode = readl(aspi->regs + CE_CTRL_REG); in aspeed_spi_dirmap_create()
597 if (op->addr.nbytes == 4) in aspeed_spi_dirmap_create()
598 addr_mode |= (0x11 << chip->cs); in aspeed_spi_dirmap_create()
600 addr_mode &= ~(0x11 << chip->cs); in aspeed_spi_dirmap_create()
601 writel(addr_mode, aspi->regs + CE_CTRL_REG); in aspeed_spi_dirmap_create()
606 if (op->addr.nbytes == 4 && chip->aspi->data == &ast2400_spi_data) in aspeed_spi_dirmap_create()
611 chip->ctl_val[ASPEED_SPI_READ] = ctl_val; in aspeed_spi_dirmap_create()
612 writel(chip->ctl_val[ASPEED_SPI_READ], chip->ctl); in aspeed_spi_dirmap_create()
616 dev_info(aspi->dev, "CE%d read buswidth:%d [0x%08x]\n", in aspeed_spi_dirmap_create()
617 chip->cs, op->data.buswidth, chip->ctl_val[ASPEED_SPI_READ]); in aspeed_spi_dirmap_create()
625 struct aspeed_spi *aspi = spi_controller_get_devdata(desc->mem->spi->controller); in aspeed_spi_dirmap_read()
626 struct aspeed_spi_chip *chip = &aspi->chips[spi_get_chipselect(desc->mem->spi, 0)]; in aspeed_spi_dirmap_read()
629 if (chip->ahb_window_size < offset + len) { in aspeed_spi_dirmap_read()
632 ret = aspeed_spi_read_user(chip, &desc->info.op_tmpl, offset, len, buf); in aspeed_spi_dirmap_read()
636 memcpy_fromio(buf, chip->ahb_base + offset, len); in aspeed_spi_dirmap_read()
650 static void aspeed_spi_chip_set_type(struct aspeed_spi *aspi, unsigned int cs, int type) in aspeed_spi_chip_set_type() argument
654 reg = readl(aspi->regs + CONFIG_REG); in aspeed_spi_chip_set_type()
655 reg &= ~(0x3 << (cs * 2)); in aspeed_spi_chip_set_type()
656 reg |= type << (cs * 2); in aspeed_spi_chip_set_type()
657 writel(reg, aspi->regs + CONFIG_REG); in aspeed_spi_chip_set_type()
660 static void aspeed_spi_chip_enable(struct aspeed_spi *aspi, unsigned int cs, bool enable) in aspeed_spi_chip_enable() argument
662 u32 we_bit = BIT(aspi->data->we0 + cs); in aspeed_spi_chip_enable()
663 u32 reg = readl(aspi->regs + CONFIG_REG); in aspeed_spi_chip_enable()
669 writel(reg, aspi->regs + CONFIG_REG); in aspeed_spi_chip_enable()
674 struct aspeed_spi *aspi = spi_controller_get_devdata(spi->controller); in aspeed_spi_setup()
675 const struct aspeed_spi_data *data = aspi->data; in aspeed_spi_setup()
676 unsigned int cs = spi_get_chipselect(spi, 0); in aspeed_spi_setup() local
677 struct aspeed_spi_chip *chip = &aspi->chips[cs]; in aspeed_spi_setup()
679 chip->aspi = aspi; in aspeed_spi_setup()
680 chip->cs = cs; in aspeed_spi_setup()
681 chip->ctl = aspi->regs + data->ctl0 + cs * 4; in aspeed_spi_setup()
684 if (data->hastype) in aspeed_spi_setup()
685 aspeed_spi_chip_set_type(aspi, cs, CONFIG_TYPE_SPI); in aspeed_spi_setup()
688 dev_warn(aspi->dev, "CE%d window invalid", cs); in aspeed_spi_setup()
689 return -EINVAL; in aspeed_spi_setup()
692 aspeed_spi_chip_enable(aspi, cs, true); in aspeed_spi_setup()
694 chip->ctl_val[ASPEED_SPI_BASE] = CTRL_CE_STOP_ACTIVE | CTRL_IO_MODE_USER; in aspeed_spi_setup()
696 dev_dbg(aspi->dev, "CE%d setup done\n", cs); in aspeed_spi_setup()
702 struct aspeed_spi *aspi = spi_controller_get_devdata(spi->controller); in aspeed_spi_cleanup()
703 unsigned int cs = spi_get_chipselect(spi, 0); in aspeed_spi_cleanup() local
705 aspeed_spi_chip_enable(aspi, cs, false); in aspeed_spi_cleanup()
707 dev_dbg(aspi->dev, "CE%d cleanup done\n", cs); in aspeed_spi_cleanup()
712 int cs; in aspeed_spi_enable() local
714 for (cs = 0; cs < aspi->data->max_cs; cs++) in aspeed_spi_enable()
715 aspeed_spi_chip_enable(aspi, cs, enable); in aspeed_spi_enable()
720 struct device *dev = &pdev->dev; in aspeed_spi_probe()
727 data = of_device_get_match_data(&pdev->dev); in aspeed_spi_probe()
729 return -ENODEV; in aspeed_spi_probe()
733 return -ENOMEM; in aspeed_spi_probe()
737 aspi->data = data; in aspeed_spi_probe()
738 aspi->dev = dev; in aspeed_spi_probe()
740 aspi->regs = devm_platform_ioremap_resource(pdev, 0); in aspeed_spi_probe()
741 if (IS_ERR(aspi->regs)) in aspeed_spi_probe()
742 return PTR_ERR(aspi->regs); in aspeed_spi_probe()
744 aspi->ahb_base = devm_platform_get_and_ioremap_resource(pdev, 1, &res); in aspeed_spi_probe()
745 if (IS_ERR(aspi->ahb_base)) { in aspeed_spi_probe()
747 return PTR_ERR(aspi->ahb_base); in aspeed_spi_probe()
750 aspi->ahb_window_size = resource_size(res); in aspeed_spi_probe()
751 aspi->ahb_base_phy = res->start; in aspeed_spi_probe()
753 aspi->clk = devm_clk_get_enabled(&pdev->dev, NULL); in aspeed_spi_probe()
754 if (IS_ERR(aspi->clk)) { in aspeed_spi_probe()
756 return PTR_ERR(aspi->clk); in aspeed_spi_probe()
759 aspi->clk_freq = clk_get_rate(aspi->clk); in aspeed_spi_probe()
760 if (!aspi->clk_freq) { in aspeed_spi_probe()
762 return -EINVAL; in aspeed_spi_probe()
767 ctlr->mode_bits = SPI_RX_DUAL | SPI_TX_DUAL | data->mode_bits; in aspeed_spi_probe()
768 ctlr->bus_num = pdev->id; in aspeed_spi_probe()
769 ctlr->mem_ops = &aspeed_spi_mem_ops; in aspeed_spi_probe()
770 ctlr->setup = aspeed_spi_setup; in aspeed_spi_probe()
771 ctlr->cleanup = aspeed_spi_cleanup; in aspeed_spi_probe()
772 ctlr->num_chipselect = data->max_cs; in aspeed_spi_probe()
773 ctlr->dev.of_node = dev->of_node; in aspeed_spi_probe()
777 dev_err(&pdev->dev, "spi_register_controller failed\n"); in aspeed_spi_probe()
825 return aspi->ahb_base_phy + start_offset; in aspeed_spi_segment_ast2600_start()
835 return aspi->ahb_base_phy; in aspeed_spi_segment_ast2600_end()
837 return aspi->ahb_base_phy + end_offset + 0x100000; in aspeed_spi_segment_ast2600_end()
848 ((end - 1) & AST2600_SEG_ADDR_MASK); in aspeed_spi_segment_ast2600_reg()
863 memcpy_fromio(test_buf, chip->ahb_base, CALIBRATE_BUF_SIZE); in aspeed_spi_check_reads()
883 struct aspeed_spi *aspi = chip->aspi; in aspeed_spi_calibrate()
884 const struct aspeed_spi_data *data = aspi->data; in aspeed_spi_calibrate()
886 int good_pass = -1, pass_count = 0; in aspeed_spi_calibrate()
887 u32 shift = (hdiv - 1) << 2; in aspeed_spi_calibrate()
897 if (chip->cs == 0) { in aspeed_spi_calibrate()
900 writel(fread_timing_val, aspi->regs + data->timing); in aspeed_spi_calibrate()
903 dev_dbg(aspi->dev, in aspeed_spi_calibrate()
904 " * [%08x] %d HCLK delay, %dns DI delay : %s", in aspeed_spi_calibrate()
910 good_pass = i - 1; in aspeed_spi_calibrate()
920 return -1; in aspeed_spi_calibrate()
923 if (chip->cs == 0) { in aspeed_spi_calibrate()
926 writel(fread_timing_val, aspi->regs + data->timing); in aspeed_spi_calibrate()
928 dev_dbg(aspi->dev, " * -> good is pass %d [0x%08x]", in aspeed_spi_calibrate()
960 (aspeed_spi_hclk_divs[(i) - 1] << CTRL_FREQ_SEL_SHIFT)
964 struct aspeed_spi *aspi = chip->aspi; in aspeed_spi_do_calibration()
965 const struct aspeed_spi_data *data = aspi->data; in aspeed_spi_do_calibration()
966 u32 ahb_freq = aspi->clk_freq; in aspeed_spi_do_calibration()
967 u32 max_freq = chip->clk_freq; in aspeed_spi_do_calibration()
971 int i, rc, best_div = -1; in aspeed_spi_do_calibration()
973 dev_dbg(aspi->dev, "calculate timing compensation - AHB freq: %d MHz", in aspeed_spi_do_calibration()
980 ctl_val = chip->ctl_val[ASPEED_SPI_READ] & data->hclk_mask; in aspeed_spi_do_calibration()
981 writel(ctl_val, chip->ctl); in aspeed_spi_do_calibration()
985 return -ENOMEM; in aspeed_spi_do_calibration()
989 memcpy_fromio(golden_buf, chip->ahb_base, CALIBRATE_BUF_SIZE); in aspeed_spi_do_calibration()
991 dev_info(aspi->dev, "Calibration area too uniform, using low speed"); in aspeed_spi_do_calibration()
1001 for (i = ARRAY_SIZE(aspeed_spi_hclk_divs); i > data->hdiv_max - 1; i--) { in aspeed_spi_do_calibration()
1009 tv = chip->ctl_val[ASPEED_SPI_READ] | ASPEED_SPI_HCLK_DIV(i); in aspeed_spi_do_calibration()
1010 writel(tv, chip->ctl); in aspeed_spi_do_calibration()
1011 dev_dbg(aspi->dev, "Trying HCLK/%d [%08x] ...", i, tv); in aspeed_spi_do_calibration()
1012 rc = data->calibrate(chip, i, golden_buf, test_buf); in aspeed_spi_do_calibration()
1019 dev_warn(aspi->dev, "No good frequency, using dumb slow"); in aspeed_spi_do_calibration()
1021 dev_dbg(aspi->dev, "Found good read timings at HCLK/%d", best_div); in aspeed_spi_do_calibration()
1025 chip->ctl_val[i] = (chip->ctl_val[i] & data->hclk_mask) | in aspeed_spi_do_calibration()
1030 writel(chip->ctl_val[ASPEED_SPI_READ], chip->ctl); in aspeed_spi_do_calibration()
1038 ((chip)->aspi->regs + (chip)->aspi->data->timing + \
1039 (chip)->cs * 4)
1044 struct aspeed_spi *aspi = chip->aspi; in aspeed_spi_ast2600_calibrate()
1046 u32 shift = (hdiv - 2) << 3; in aspeed_spi_ast2600_calibrate()
1060 dev_dbg(aspi->dev, in aspeed_spi_ast2600_calibrate()
1061 " * [%08x] %d HCLK delay, DI delay none : %s", in aspeed_spi_ast2600_calibrate()
1076 dev_dbg(aspi->dev, in aspeed_spi_ast2600_calibrate()
1077 " * [%08x] %d HCLK delay, DI delay %d.%dns : %s", in aspeed_spi_ast2600_calibrate()
1091 return -1; in aspeed_spi_ast2600_calibrate()
1182 { .compatible = "aspeed,ast2400-fmc", .data = &ast2400_fmc_data },
1183 { .compatible = "aspeed,ast2400-spi", .data = &ast2400_spi_data },
1184 { .compatible = "aspeed,ast2500-fmc", .data = &ast2500_fmc_data },
1185 { .compatible = "aspeed,ast2500-spi", .data = &ast2500_spi_data },
1186 { .compatible = "aspeed,ast2600-fmc", .data = &ast2600_fmc_data },
1187 { .compatible = "aspeed,ast2600-spi", .data = &ast2600_spi_data },
1204 MODULE_AUTHOR("Chin-Ting Kuo <chin-ting_kuo@aspeedtech.com>");