Lines Matching +full:cs +full:- +full:2
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"
35 (((((dummy) >> 2) & 0x1) << 14) | (((dummy) & 0x3) << 6))
38 #define CTRL_CE_STOP_ACTIVE BIT(2)
64 u32 cs; member
108 switch (op->data.buswidth) { in aspeed_spi_get_io_mode()
111 case 2: 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()
159 ioread32_rep(src, buf, len >> 2); in aspeed_spi_read_from_ahb()
161 len -= offset; in aspeed_spi_read_from_ahb()
173 iowrite32_rep(dst, buf, len >> 2); in aspeed_spi_write_to_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 addr_mode = readl(aspi->regs + CE_CTRL_REG); in do_aspeed_spi_exec_op()
309 ctl_val = chip->ctl_val[ASPEED_SPI_BASE]; in do_aspeed_spi_exec_op()
312 ctl_val |= op->cmd.opcode << CTRL_COMMAND_SHIFT; in do_aspeed_spi_exec_op()
315 if (op->addr.nbytes) { in do_aspeed_spi_exec_op()
316 if (op->addr.nbytes == 4) in do_aspeed_spi_exec_op()
317 addr_mode |= (0x11 << chip->cs); in do_aspeed_spi_exec_op()
319 addr_mode &= ~(0x11 << chip->cs); in do_aspeed_spi_exec_op()
321 if (op->addr.nbytes == 4 && chip->aspi->data == &ast2400_spi_data) in do_aspeed_spi_exec_op()
325 if (op->dummy.nbytes) in do_aspeed_spi_exec_op()
326 ctl_val |= CTRL_IO_DUMMY_SET(op->dummy.nbytes / op->dummy.buswidth); in do_aspeed_spi_exec_op()
328 if (op->data.nbytes) in do_aspeed_spi_exec_op()
331 if (op->data.dir == SPI_MEM_DATA_OUT) in do_aspeed_spi_exec_op()
337 writel(addr_mode, aspi->regs + CE_CTRL_REG); in do_aspeed_spi_exec_op()
338 writel(ctl_val, chip->ctl); in do_aspeed_spi_exec_op()
340 if (op->data.dir == SPI_MEM_DATA_IN) { in do_aspeed_spi_exec_op()
341 if (!op->addr.nbytes) in do_aspeed_spi_exec_op()
344 ret = aspeed_spi_read_user(chip, op, op->addr.val, in do_aspeed_spi_exec_op()
345 op->data.nbytes, op->data.buf.in); in do_aspeed_spi_exec_op()
347 if (!op->addr.nbytes) in do_aspeed_spi_exec_op()
355 writel(addr_mode_backup, aspi->regs + CE_CTRL_REG); in do_aspeed_spi_exec_op()
356 writel(chip->ctl_val[ASPEED_SPI_READ], chip->ctl); in do_aspeed_spi_exec_op()
366 dev_err(&mem->spi->dev, "operation failed: %d\n", ret); in aspeed_spi_exec_op()
372 struct aspeed_spi *aspi = spi_controller_get_devdata(mem->spi->controller); in aspeed_spi_get_name()
373 struct device *dev = aspi->dev; in aspeed_spi_get_name()
376 spi_get_chipselect(mem->spi, 0)); in aspeed_spi_get_name()
380 u32 cs; member
388 const struct aspeed_spi_data *data = aspi->data; in aspeed_spi_get_windows()
390 u32 cs; in aspeed_spi_get_windows() local
392 for (cs = 0; cs < aspi->data->max_cs; cs++) { in aspeed_spi_get_windows()
393 reg_val = readl(aspi->regs + CE0_SEGMENT_ADDR_REG + cs * 4); in aspeed_spi_get_windows()
394 windows[cs].cs = cs; in aspeed_spi_get_windows()
395 windows[cs].size = data->segment_end(aspi, reg_val) - in aspeed_spi_get_windows()
396 data->segment_start(aspi, reg_val); in aspeed_spi_get_windows()
397 windows[cs].offset = data->segment_start(aspi, reg_val) - aspi->ahb_base_phy; in aspeed_spi_get_windows()
398 dev_vdbg(aspi->dev, "CE%d offset=0x%.8x size=0x%x\n", cs, in aspeed_spi_get_windows()
399 windows[cs].offset, windows[cs].size); in aspeed_spi_get_windows()
405 * U-Boot should open all.
409 struct aspeed_spi *aspi = chip->aspi; in aspeed_spi_chip_set_default_window()
411 struct aspeed_spi_window *win = &windows[chip->cs]; in aspeed_spi_chip_set_default_window()
414 if (aspi->data == &ast2400_spi_data) { in aspeed_spi_chip_set_default_window()
415 win->offset = 0; in aspeed_spi_chip_set_default_window()
416 win->size = aspi->ahb_window_size; in aspeed_spi_chip_set_default_window()
421 chip->ahb_base = aspi->ahb_base + win->offset; in aspeed_spi_chip_set_default_window()
422 chip->ahb_window_size = win->size; in aspeed_spi_chip_set_default_window()
424 dev_dbg(aspi->dev, "CE%d default window [ 0x%.8x - 0x%.8x ] %dMB", in aspeed_spi_chip_set_default_window()
425 chip->cs, aspi->ahb_base_phy + win->offset, in aspeed_spi_chip_set_default_window()
426 aspi->ahb_base_phy + win->offset + win->size - 1, in aspeed_spi_chip_set_default_window()
427 win->size >> 20); in aspeed_spi_chip_set_default_window()
429 return chip->ahb_window_size ? 0 : -1; in aspeed_spi_chip_set_default_window()
435 u32 start = aspi->ahb_base_phy + win->offset; in aspeed_spi_set_window()
436 u32 end = start + win->size; in aspeed_spi_set_window()
437 void __iomem *seg_reg = aspi->regs + CE0_SEGMENT_ADDR_REG + win->cs * 4; in aspeed_spi_set_window()
439 u32 seg_val = aspi->data->segment_reg(aspi, start, end); in aspeed_spi_set_window()
451 dev_err(aspi->dev, "CE%d invalid window [ 0x%.8x - 0x%.8x ] %dMB", in aspeed_spi_set_window()
452 win->cs, start, end - 1, win->size >> 20); in aspeed_spi_set_window()
454 return -EIO; in aspeed_spi_set_window()
457 if (win->size) in aspeed_spi_set_window()
458 dev_dbg(aspi->dev, "CE%d new 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 dev_dbg(aspi->dev, "CE%d window closed", win->cs); in aspeed_spi_set_window()
468 * - Align mappings on flash size (we don't have the info)
469 * - ioremap each window, not strictly necessary since the overall window
479 struct aspeed_spi *aspi = chip->aspi; in aspeed_spi_chip_adjust_window()
481 struct aspeed_spi_window *win = &windows[chip->cs]; in aspeed_spi_chip_adjust_window()
485 if (aspi->data == &ast2400_spi_data) in aspeed_spi_chip_adjust_window()
492 if (aspi->data == &ast2500_spi_data && chip->cs == 0 && size == SZ_128M) { in aspeed_spi_chip_adjust_window()
494 dev_info(aspi->dev, "CE%d window resized to %dMB (AST2500 HW quirk)", in aspeed_spi_chip_adjust_window()
495 chip->cs, size >> 20); in aspeed_spi_chip_adjust_window()
500 * least 2MB. in aspeed_spi_chip_adjust_window()
502 if ((aspi->data == &ast2600_spi_data || aspi->data == &ast2600_fmc_data) && in aspeed_spi_chip_adjust_window()
505 dev_info(aspi->dev, "CE%d window resized to %dMB (AST2600 Decoding)", in aspeed_spi_chip_adjust_window()
506 chip->cs, size >> 20); in aspeed_spi_chip_adjust_window()
512 win->offset += local_offset; in aspeed_spi_chip_adjust_window()
513 win->size = size; in aspeed_spi_chip_adjust_window()
515 if (win->offset + win->size > aspi->ahb_window_size) { in aspeed_spi_chip_adjust_window()
516 win->size = aspi->ahb_window_size - win->offset; in aspeed_spi_chip_adjust_window()
517 dev_warn(aspi->dev, "CE%d window resized to %dMB", chip->cs, win->size >> 20); in aspeed_spi_chip_adjust_window()
525 chip->ahb_base = aspi->ahb_base + win->offset; in aspeed_spi_chip_adjust_window()
526 chip->ahb_window_size = win->size; in aspeed_spi_chip_adjust_window()
532 if (chip->cs < aspi->data->max_cs - 1) { in aspeed_spi_chip_adjust_window()
533 struct aspeed_spi_window *next = &windows[chip->cs + 1]; in aspeed_spi_chip_adjust_window()
536 if ((next->offset + next->size) > (win->offset + win->size)) in aspeed_spi_chip_adjust_window()
537 next->size = (next->offset + next->size) - (win->offset + win->size); in aspeed_spi_chip_adjust_window()
539 next->size = 0; in aspeed_spi_chip_adjust_window()
540 next->offset = win->offset + win->size; in aspeed_spi_chip_adjust_window()
551 struct aspeed_spi *aspi = spi_controller_get_devdata(desc->mem->spi->controller); in aspeed_spi_dirmap_create()
552 struct aspeed_spi_chip *chip = &aspi->chips[spi_get_chipselect(desc->mem->spi, 0)]; in aspeed_spi_dirmap_create()
553 struct spi_mem_op *op = &desc->info.op_tmpl; in aspeed_spi_dirmap_create()
557 dev_dbg(aspi->dev, in aspeed_spi_dirmap_create()
558 "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()
559 chip->cs, op->data.dir == SPI_MEM_DATA_IN ? "read" : "write", in aspeed_spi_dirmap_create()
560 desc->info.offset, desc->info.offset + desc->info.length, in aspeed_spi_dirmap_create()
561 op->cmd.opcode, op->cmd.buswidth, op->addr.buswidth, in aspeed_spi_dirmap_create()
562 op->dummy.buswidth, op->data.buswidth, in aspeed_spi_dirmap_create()
563 op->addr.nbytes, op->dummy.nbytes); in aspeed_spi_dirmap_create()
565 chip->clk_freq = desc->mem->spi->max_speed_hz; in aspeed_spi_dirmap_create()
568 if (op->data.dir != SPI_MEM_DATA_IN) in aspeed_spi_dirmap_create()
569 return -EOPNOTSUPP; in aspeed_spi_dirmap_create()
571 aspeed_spi_chip_adjust_window(chip, desc->info.offset, desc->info.length); in aspeed_spi_dirmap_create()
573 if (desc->info.length > chip->ahb_window_size) in aspeed_spi_dirmap_create()
574 dev_warn(aspi->dev, "CE%d window (%dMB) too small for mapping", in aspeed_spi_dirmap_create()
575 chip->cs, chip->ahb_window_size >> 20); in aspeed_spi_dirmap_create()
578 ctl_val = readl(chip->ctl) & ~CTRL_IO_CMD_MASK; in aspeed_spi_dirmap_create()
580 op->cmd.opcode << CTRL_COMMAND_SHIFT | in aspeed_spi_dirmap_create()
583 if (op->dummy.nbytes) in aspeed_spi_dirmap_create()
584 ctl_val |= CTRL_IO_DUMMY_SET(op->dummy.nbytes / op->dummy.buswidth); in aspeed_spi_dirmap_create()
587 if (op->addr.nbytes) { in aspeed_spi_dirmap_create()
588 u32 addr_mode = readl(aspi->regs + CE_CTRL_REG); in aspeed_spi_dirmap_create()
590 if (op->addr.nbytes == 4) in aspeed_spi_dirmap_create()
591 addr_mode |= (0x11 << chip->cs); in aspeed_spi_dirmap_create()
593 addr_mode &= ~(0x11 << chip->cs); in aspeed_spi_dirmap_create()
594 writel(addr_mode, aspi->regs + CE_CTRL_REG); in aspeed_spi_dirmap_create()
599 if (op->addr.nbytes == 4 && chip->aspi->data == &ast2400_spi_data) in aspeed_spi_dirmap_create()
604 chip->ctl_val[ASPEED_SPI_READ] = ctl_val; in aspeed_spi_dirmap_create()
605 writel(chip->ctl_val[ASPEED_SPI_READ], chip->ctl); in aspeed_spi_dirmap_create()
609 dev_info(aspi->dev, "CE%d read buswidth:%d [0x%08x]\n", in aspeed_spi_dirmap_create()
610 chip->cs, op->data.buswidth, chip->ctl_val[ASPEED_SPI_READ]); in aspeed_spi_dirmap_create()
618 struct aspeed_spi *aspi = spi_controller_get_devdata(desc->mem->spi->controller); in aspeed_spi_dirmap_read()
619 struct aspeed_spi_chip *chip = &aspi->chips[spi_get_chipselect(desc->mem->spi, 0)]; in aspeed_spi_dirmap_read()
622 if (chip->ahb_window_size < offset + len) { in aspeed_spi_dirmap_read()
625 ret = aspeed_spi_read_user(chip, &desc->info.op_tmpl, offset, len, buf); in aspeed_spi_dirmap_read()
629 memcpy_fromio(buf, chip->ahb_base + offset, len); in aspeed_spi_dirmap_read()
643 static void aspeed_spi_chip_set_type(struct aspeed_spi *aspi, unsigned int cs, int type) in aspeed_spi_chip_set_type() argument
647 reg = readl(aspi->regs + CONFIG_REG); in aspeed_spi_chip_set_type()
648 reg &= ~(0x3 << (cs * 2)); in aspeed_spi_chip_set_type()
649 reg |= type << (cs * 2); in aspeed_spi_chip_set_type()
650 writel(reg, aspi->regs + CONFIG_REG); in aspeed_spi_chip_set_type()
653 static void aspeed_spi_chip_enable(struct aspeed_spi *aspi, unsigned int cs, bool enable) in aspeed_spi_chip_enable() argument
655 u32 we_bit = BIT(aspi->data->we0 + cs); in aspeed_spi_chip_enable()
656 u32 reg = readl(aspi->regs + CONFIG_REG); in aspeed_spi_chip_enable()
662 writel(reg, aspi->regs + CONFIG_REG); in aspeed_spi_chip_enable()
667 struct aspeed_spi *aspi = spi_controller_get_devdata(spi->controller); in aspeed_spi_setup()
668 const struct aspeed_spi_data *data = aspi->data; in aspeed_spi_setup()
669 unsigned int cs = spi_get_chipselect(spi, 0); in aspeed_spi_setup() local
670 struct aspeed_spi_chip *chip = &aspi->chips[cs]; in aspeed_spi_setup()
672 chip->aspi = aspi; in aspeed_spi_setup()
673 chip->cs = cs; in aspeed_spi_setup()
674 chip->ctl = aspi->regs + data->ctl0 + cs * 4; in aspeed_spi_setup()
677 if (data->hastype) in aspeed_spi_setup()
678 aspeed_spi_chip_set_type(aspi, cs, CONFIG_TYPE_SPI); in aspeed_spi_setup()
681 dev_warn(aspi->dev, "CE%d window invalid", cs); in aspeed_spi_setup()
682 return -EINVAL; in aspeed_spi_setup()
685 aspeed_spi_chip_enable(aspi, cs, true); in aspeed_spi_setup()
687 chip->ctl_val[ASPEED_SPI_BASE] = CTRL_CE_STOP_ACTIVE | CTRL_IO_MODE_USER; in aspeed_spi_setup()
689 dev_dbg(aspi->dev, "CE%d setup done\n", cs); in aspeed_spi_setup()
695 struct aspeed_spi *aspi = spi_controller_get_devdata(spi->controller); in aspeed_spi_cleanup()
696 unsigned int cs = spi_get_chipselect(spi, 0); in aspeed_spi_cleanup() local
698 aspeed_spi_chip_enable(aspi, cs, false); in aspeed_spi_cleanup()
700 dev_dbg(aspi->dev, "CE%d cleanup done\n", cs); in aspeed_spi_cleanup()
705 int cs; in aspeed_spi_enable() local
707 for (cs = 0; cs < aspi->data->max_cs; cs++) in aspeed_spi_enable()
708 aspeed_spi_chip_enable(aspi, cs, enable); in aspeed_spi_enable()
713 struct device *dev = &pdev->dev; in aspeed_spi_probe()
720 data = of_device_get_match_data(&pdev->dev); in aspeed_spi_probe()
722 return -ENODEV; in aspeed_spi_probe()
726 return -ENOMEM; in aspeed_spi_probe()
730 aspi->data = data; in aspeed_spi_probe()
731 aspi->dev = dev; in aspeed_spi_probe()
733 aspi->regs = devm_platform_ioremap_resource(pdev, 0); in aspeed_spi_probe()
734 if (IS_ERR(aspi->regs)) in aspeed_spi_probe()
735 return PTR_ERR(aspi->regs); in aspeed_spi_probe()
737 aspi->ahb_base = devm_platform_get_and_ioremap_resource(pdev, 1, &res); in aspeed_spi_probe()
738 if (IS_ERR(aspi->ahb_base)) { in aspeed_spi_probe()
740 return PTR_ERR(aspi->ahb_base); in aspeed_spi_probe()
743 aspi->ahb_window_size = resource_size(res); in aspeed_spi_probe()
744 aspi->ahb_base_phy = res->start; in aspeed_spi_probe()
746 aspi->clk = devm_clk_get_enabled(&pdev->dev, NULL); in aspeed_spi_probe()
747 if (IS_ERR(aspi->clk)) { in aspeed_spi_probe()
749 return PTR_ERR(aspi->clk); in aspeed_spi_probe()
752 aspi->clk_freq = clk_get_rate(aspi->clk); in aspeed_spi_probe()
753 if (!aspi->clk_freq) { in aspeed_spi_probe()
755 return -EINVAL; in aspeed_spi_probe()
760 ctlr->mode_bits = SPI_RX_DUAL | SPI_TX_DUAL | data->mode_bits; in aspeed_spi_probe()
761 ctlr->bus_num = pdev->id; in aspeed_spi_probe()
762 ctlr->mem_ops = &aspeed_spi_mem_ops; in aspeed_spi_probe()
763 ctlr->setup = aspeed_spi_setup; in aspeed_spi_probe()
764 ctlr->cleanup = aspeed_spi_cleanup; in aspeed_spi_probe()
765 ctlr->num_chipselect = data->max_cs; in aspeed_spi_probe()
766 ctlr->dev.of_node = dev->of_node; in aspeed_spi_probe()
770 dev_err(&pdev->dev, "spi_register_controller failed\n"); in aspeed_spi_probe()
818 return aspi->ahb_base_phy + start_offset; in aspeed_spi_segment_ast2600_start()
828 return aspi->ahb_base_phy; in aspeed_spi_segment_ast2600_end()
830 return aspi->ahb_base_phy + end_offset + 0x100000; in aspeed_spi_segment_ast2600_end()
841 ((end - 1) & AST2600_SEG_ADDR_MASK); in aspeed_spi_segment_ast2600_reg()
856 memcpy_fromio(test_buf, chip->ahb_base, CALIBRATE_BUF_SIZE); in aspeed_spi_check_reads()
868 #define FREAD_TPASS(i) (((i) / 2) | (((i) & 1) ? 0 : 8))
876 struct aspeed_spi *aspi = chip->aspi; in aspeed_spi_calibrate()
877 const struct aspeed_spi_data *data = aspi->data; in aspeed_spi_calibrate()
879 int good_pass = -1, pass_count = 0; in aspeed_spi_calibrate()
880 u32 shift = (hdiv - 1) << 2; in aspeed_spi_calibrate()
890 if (chip->cs == 0) { in aspeed_spi_calibrate()
893 writel(fread_timing_val, aspi->regs + data->timing); in aspeed_spi_calibrate()
896 dev_dbg(aspi->dev, in aspeed_spi_calibrate()
898 fread_timing_val, i / 2, (i & 1) ? 0 : 4, in aspeed_spi_calibrate()
903 good_pass = i - 1; in aspeed_spi_calibrate()
913 return -1; in aspeed_spi_calibrate()
916 if (chip->cs == 0) { in aspeed_spi_calibrate()
919 writel(fread_timing_val, aspi->regs + data->timing); in aspeed_spi_calibrate()
921 dev_dbg(aspi->dev, " * -> good is pass %d [0x%08x]", in aspeed_spi_calibrate()
936 size >>= 2; in aspeed_spi_check_calib_data()
946 0x7, /* HCLK/2 */
953 (aspeed_spi_hclk_divs[(i) - 1] << CTRL_FREQ_SEL_SHIFT)
957 struct aspeed_spi *aspi = chip->aspi; in aspeed_spi_do_calibration()
958 const struct aspeed_spi_data *data = aspi->data; in aspeed_spi_do_calibration()
959 u32 ahb_freq = aspi->clk_freq; in aspeed_spi_do_calibration()
960 u32 max_freq = chip->clk_freq; in aspeed_spi_do_calibration()
964 int i, rc, best_div = -1; in aspeed_spi_do_calibration()
966 dev_dbg(aspi->dev, "calculate timing compensation - AHB freq: %d MHz", in aspeed_spi_do_calibration()
973 ctl_val = chip->ctl_val[ASPEED_SPI_READ] & data->hclk_mask; in aspeed_spi_do_calibration()
974 writel(ctl_val, chip->ctl); in aspeed_spi_do_calibration()
976 test_buf = kzalloc(CALIBRATE_BUF_SIZE * 2, GFP_KERNEL); in aspeed_spi_do_calibration()
978 return -ENOMEM; in aspeed_spi_do_calibration()
982 memcpy_fromio(golden_buf, chip->ahb_base, CALIBRATE_BUF_SIZE); in aspeed_spi_do_calibration()
984 dev_info(aspi->dev, "Calibration area too uniform, using low speed"); in aspeed_spi_do_calibration()
994 for (i = ARRAY_SIZE(aspeed_spi_hclk_divs); i > data->hdiv_max - 1; i--) { in aspeed_spi_do_calibration()
1002 tv = chip->ctl_val[ASPEED_SPI_READ] | ASPEED_SPI_HCLK_DIV(i); in aspeed_spi_do_calibration()
1003 writel(tv, chip->ctl); in aspeed_spi_do_calibration()
1004 dev_dbg(aspi->dev, "Trying HCLK/%d [%08x] ...", i, tv); in aspeed_spi_do_calibration()
1005 rc = data->calibrate(chip, i, golden_buf, test_buf); in aspeed_spi_do_calibration()
1012 dev_warn(aspi->dev, "No good frequency, using dumb slow"); in aspeed_spi_do_calibration()
1014 dev_dbg(aspi->dev, "Found good read timings at HCLK/%d", best_div); in aspeed_spi_do_calibration()
1018 chip->ctl_val[i] = (chip->ctl_val[i] & data->hclk_mask) | in aspeed_spi_do_calibration()
1023 writel(chip->ctl_val[ASPEED_SPI_READ], chip->ctl); in aspeed_spi_do_calibration()
1031 ((chip)->aspi->regs + (chip)->aspi->data->timing + \
1032 (chip)->cs * 4)
1037 struct aspeed_spi *aspi = chip->aspi; in aspeed_spi_ast2600_calibrate()
1039 u32 shift = (hdiv - 2) << 3; in aspeed_spi_ast2600_calibrate()
1053 dev_dbg(aspi->dev, in aspeed_spi_ast2600_calibrate()
1069 dev_dbg(aspi->dev, in aspeed_spi_ast2600_calibrate()
1071 fread_timing_val, hcycle, (delay_ns + 1) / 2, in aspeed_spi_ast2600_calibrate()
1084 return -1; in aspeed_spi_ast2600_calibrate()
1131 .max_cs = 2,
1152 .hdiv_max = 2,
1160 .max_cs = 2,
1167 .hdiv_max = 2,
1175 { .compatible = "aspeed,ast2400-fmc", .data = &ast2400_fmc_data },
1176 { .compatible = "aspeed,ast2400-spi", .data = &ast2400_spi_data },
1177 { .compatible = "aspeed,ast2500-fmc", .data = &ast2500_fmc_data },
1178 { .compatible = "aspeed,ast2500-spi", .data = &ast2500_spi_data },
1179 { .compatible = "aspeed,ast2600-fmc", .data = &ast2600_fmc_data },
1180 { .compatible = "aspeed,ast2600-spi", .data = &ast2600_spi_data },
1197 MODULE_AUTHOR("Chin-Ting Kuo <chin-ting_kuo@aspeedtech.com>");