Lines Matching +full:spi +full:- +full:nor
1 // SPDX-License-Identifier: GPL-2.0-or-later
5 * Copyright (c) 2015-2016, IBM Corporation.
15 #include <linux/mtd/spi-nor.h>
21 #define DEVICE_NAME "aspeed-smc"
24 * The driver only support SPI flash
100 struct spi_nor nor; member
109 void __iomem *ahb_base; /* per-chip windows resource */
116 * SPI Flash Configuration Register (AST2500 SPI)
119 * CE0 and CE1 can only be of type SPI. CE2 can be of type NOR but the
156 #define CONTROL_IO_ADDRESS_4B BIT(13) /* AST2400 SPI */
186 * and the end address of the mapping window of a flash SPI slave :
189 * +--------+--------+--------+--------+
198 ((controller)->regs + SEGMENT_ADDR_REG0 + (cs) * 4)
202 * range are transferred to or from the SPI bus. The range is treated as a
205 * sending bytes to the SPI bus.
235 len -= offset; in aspeed_smc_read_from_ahb()
250 len -= offset; in aspeed_smc_write_to_ahb()
258 return BIT(chip->controller->info->we0 + chip->cs); in aspeed_smc_chip_write_bit()
263 struct aspeed_smc_controller *controller = chip->controller; in aspeed_smc_chip_check_config()
266 reg = readl(controller->regs + CONFIG_REG); in aspeed_smc_chip_check_config()
271 dev_dbg(controller->dev, "config write is not set ! @%p: 0x%08x\n", in aspeed_smc_chip_check_config()
272 controller->regs + CONFIG_REG, reg); in aspeed_smc_chip_check_config()
274 writel(reg, controller->regs + CONFIG_REG); in aspeed_smc_chip_check_config()
277 static void aspeed_smc_start_user(struct spi_nor *nor) in aspeed_smc_start_user() argument
279 struct aspeed_smc_chip *chip = nor->priv; in aspeed_smc_start_user()
280 u32 ctl = chip->ctl_val[smc_base]; in aspeed_smc_start_user()
290 writel(ctl, chip->ctl); in aspeed_smc_start_user()
293 writel(ctl, chip->ctl); in aspeed_smc_start_user()
296 static void aspeed_smc_stop_user(struct spi_nor *nor) in aspeed_smc_stop_user() argument
298 struct aspeed_smc_chip *chip = nor->priv; in aspeed_smc_stop_user()
300 u32 ctl = chip->ctl_val[smc_read]; in aspeed_smc_stop_user()
304 writel(ctl2, chip->ctl); /* stop user CE control */ in aspeed_smc_stop_user()
305 writel(ctl, chip->ctl); /* default to fread or read mode */ in aspeed_smc_stop_user()
308 static int aspeed_smc_prep(struct spi_nor *nor) in aspeed_smc_prep() argument
310 struct aspeed_smc_chip *chip = nor->priv; in aspeed_smc_prep()
312 mutex_lock(&chip->controller->mutex); in aspeed_smc_prep()
316 static void aspeed_smc_unprep(struct spi_nor *nor) in aspeed_smc_unprep() argument
318 struct aspeed_smc_chip *chip = nor->priv; in aspeed_smc_unprep()
320 mutex_unlock(&chip->controller->mutex); in aspeed_smc_unprep()
323 static int aspeed_smc_read_reg(struct spi_nor *nor, u8 opcode, u8 *buf, in aspeed_smc_read_reg() argument
326 struct aspeed_smc_chip *chip = nor->priv; in aspeed_smc_read_reg()
328 aspeed_smc_start_user(nor); in aspeed_smc_read_reg()
329 aspeed_smc_write_to_ahb(chip->ahb_base, &opcode, 1); in aspeed_smc_read_reg()
330 aspeed_smc_read_from_ahb(buf, chip->ahb_base, len); in aspeed_smc_read_reg()
331 aspeed_smc_stop_user(nor); in aspeed_smc_read_reg()
335 static int aspeed_smc_write_reg(struct spi_nor *nor, u8 opcode, const u8 *buf, in aspeed_smc_write_reg() argument
338 struct aspeed_smc_chip *chip = nor->priv; in aspeed_smc_write_reg()
340 aspeed_smc_start_user(nor); in aspeed_smc_write_reg()
341 aspeed_smc_write_to_ahb(chip->ahb_base, &opcode, 1); in aspeed_smc_write_reg()
342 aspeed_smc_write_to_ahb(chip->ahb_base, buf, len); in aspeed_smc_write_reg()
343 aspeed_smc_stop_user(nor); in aspeed_smc_write_reg()
347 static void aspeed_smc_send_cmd_addr(struct spi_nor *nor, u8 cmd, u32 addr) in aspeed_smc_send_cmd_addr() argument
349 struct aspeed_smc_chip *chip = nor->priv; in aspeed_smc_send_cmd_addr()
353 switch (nor->addr_width) { in aspeed_smc_send_cmd_addr()
356 nor->addr_width); in aspeed_smc_send_cmd_addr()
363 aspeed_smc_write_to_ahb(chip->ahb_base, &temp, 4); in aspeed_smc_send_cmd_addr()
367 aspeed_smc_write_to_ahb(chip->ahb_base, &cmd, 1); in aspeed_smc_send_cmd_addr()
368 aspeed_smc_write_to_ahb(chip->ahb_base, &temp, 4); in aspeed_smc_send_cmd_addr()
373 static ssize_t aspeed_smc_read_user(struct spi_nor *nor, loff_t from, in aspeed_smc_read_user() argument
376 struct aspeed_smc_chip *chip = nor->priv; in aspeed_smc_read_user()
380 aspeed_smc_start_user(nor); in aspeed_smc_read_user()
381 aspeed_smc_send_cmd_addr(nor, nor->read_opcode, from); in aspeed_smc_read_user()
382 for (i = 0; i < chip->nor.read_dummy / 8; i++) in aspeed_smc_read_user()
383 aspeed_smc_write_to_ahb(chip->ahb_base, &dummy, sizeof(dummy)); in aspeed_smc_read_user()
385 aspeed_smc_read_from_ahb(read_buf, chip->ahb_base, len); in aspeed_smc_read_user()
386 aspeed_smc_stop_user(nor); in aspeed_smc_read_user()
390 static ssize_t aspeed_smc_write_user(struct spi_nor *nor, loff_t to, in aspeed_smc_write_user() argument
393 struct aspeed_smc_chip *chip = nor->priv; in aspeed_smc_write_user()
395 aspeed_smc_start_user(nor); in aspeed_smc_write_user()
396 aspeed_smc_send_cmd_addr(nor, nor->program_opcode, to); in aspeed_smc_write_user()
397 aspeed_smc_write_to_ahb(chip->ahb_base, write_buf, len); in aspeed_smc_write_user()
398 aspeed_smc_stop_user(nor); in aspeed_smc_write_user()
407 for (n = 0; n < controller->info->nce; n++) { in aspeed_smc_unregister()
408 chip = controller->chips[n]; in aspeed_smc_unregister()
410 mtd_device_unregister(&chip->nor.mtd); in aspeed_smc_unregister()
422 { .compatible = "aspeed,ast2400-fmc", .data = &fmc_2400_info },
423 { .compatible = "aspeed,ast2400-spi", .data = &spi_2400_info },
424 { .compatible = "aspeed,ast2500-fmc", .data = &fmc_2500_info },
425 { .compatible = "aspeed,ast2500-spi", .data = &spi_2500_info },
440 struct aspeed_smc_controller *controller = chip->controller; in aspeed_smc_chip_base()
444 if (controller->info->nce > 1) { in aspeed_smc_chip_base()
445 reg = readl(SEGMENT_ADDR_REG(controller, chip->cs)); in aspeed_smc_chip_base()
450 offset = SEGMENT_ADDR_START(reg) - res->start; in aspeed_smc_chip_base()
453 return controller->ahb_base + offset; in aspeed_smc_chip_base()
466 struct aspeed_smc_controller *controller = chip->controller; in chip_set_segment()
481 size = SEGMENT_ADDR_END(seg_oldval) - start; in chip_set_segment()
487 if (start + size > ahb_base_phy + controller->ahb_window_size) { in chip_set_segment()
488 size = ahb_base_phy + controller->ahb_window_size - start; in chip_set_segment()
489 dev_warn(chip->nor.dev, "CE%d window resized to %dMB", in chip_set_segment()
503 dev_err(chip->nor.dev, "CE%d window invalid", cs); in chip_set_segment()
507 size = end - start; in chip_set_segment()
510 dev_info(chip->nor.dev, "CE%d window [ 0x%.8x - 0x%.8x ] %dMB", in chip_set_segment()
526 struct aspeed_smc_controller *controller = chip->controller; in aspeed_smc_chip_set_segment()
528 u32 size = chip->nor.mtd.size; in aspeed_smc_chip_set_segment()
534 if (size > controller->info->maxsize) in aspeed_smc_chip_set_segment()
535 size = controller->info->maxsize; in aspeed_smc_chip_set_segment()
538 * The AST2400 SPI controller only handles one chip and does in aspeed_smc_chip_set_segment()
542 if (controller->info == &spi_2400_info) in aspeed_smc_chip_set_segment()
546 * The AST2500 SPI controller has a HW bug when the CE0 chip in aspeed_smc_chip_set_segment()
551 if (chip->cs == 0 && controller->info == &spi_2500_info && in aspeed_smc_chip_set_segment()
554 dev_info(chip->nor.dev, in aspeed_smc_chip_set_segment()
556 chip->cs, size >> 20); in aspeed_smc_chip_set_segment()
566 if (chip->cs) { in aspeed_smc_chip_set_segment()
567 u32 prev = readl(SEGMENT_ADDR_REG(controller, chip->cs - 1)); in aspeed_smc_chip_set_segment()
574 size = chip_set_segment(chip, chip->cs, start, size); in aspeed_smc_chip_set_segment()
577 chip->ahb_base = controller->ahb_base + (start - ahb_base_phy); in aspeed_smc_chip_set_segment()
584 if (chip->cs < controller->info->nce - 1) in aspeed_smc_chip_set_segment()
585 chip_set_segment(chip, chip->cs + 1, start + size, 0); in aspeed_smc_chip_set_segment()
588 if (size < chip->nor.mtd.size) in aspeed_smc_chip_set_segment()
589 dev_warn(chip->nor.dev, in aspeed_smc_chip_set_segment()
591 chip->cs, (u32)chip->nor.mtd.size >> 20); in aspeed_smc_chip_set_segment()
598 struct aspeed_smc_controller *controller = chip->controller; in aspeed_smc_chip_enable_write()
601 reg = readl(controller->regs + CONFIG_REG); in aspeed_smc_chip_enable_write()
604 writel(reg, controller->regs + CONFIG_REG); in aspeed_smc_chip_enable_write()
609 struct aspeed_smc_controller *controller = chip->controller; in aspeed_smc_chip_set_type()
612 chip->type = type; in aspeed_smc_chip_set_type()
614 reg = readl(controller->regs + CONFIG_REG); in aspeed_smc_chip_set_type()
615 reg &= ~(3 << (chip->cs * 2)); in aspeed_smc_chip_set_type()
616 reg |= chip->type << (chip->cs * 2); in aspeed_smc_chip_set_type()
617 writel(reg, controller->regs + CONFIG_REG); in aspeed_smc_chip_set_type()
627 struct aspeed_smc_controller *controller = chip->controller; in aspeed_smc_chip_set_4b()
630 reg = readl(controller->regs + CE_CONTROL_REG); in aspeed_smc_chip_set_4b()
631 reg |= 1 << chip->cs; in aspeed_smc_chip_set_4b()
632 writel(reg, controller->regs + CE_CONTROL_REG); in aspeed_smc_chip_set_4b()
636 * The AST2400 SPI flash controller does not have a CE Control
642 chip->ctl_val[smc_base] |= CONTROL_IO_ADDRESS_4B; in aspeed_smc_chip_set_4b_spi_2400()
643 chip->ctl_val[smc_read] |= CONTROL_IO_ADDRESS_4B; in aspeed_smc_chip_set_4b_spi_2400()
649 struct aspeed_smc_controller *controller = chip->controller; in aspeed_smc_chip_setup_init()
650 const struct aspeed_smc_info *info = controller->info; in aspeed_smc_chip_setup_init()
659 /* The driver only supports SPI type flash */ in aspeed_smc_chip_setup_init()
660 if (info->hastype) in aspeed_smc_chip_setup_init()
666 chip->ahb_base = aspeed_smc_chip_base(chip, res); in aspeed_smc_chip_setup_init()
667 if (!chip->ahb_base) { in aspeed_smc_chip_setup_init()
668 dev_warn(chip->nor.dev, "CE%d window closed", chip->cs); in aspeed_smc_chip_setup_init()
669 return -EINVAL; in aspeed_smc_chip_setup_init()
673 * Get value of the inherited control register. U-Boot usually in aspeed_smc_chip_setup_init()
678 reg = readl(chip->ctl); in aspeed_smc_chip_setup_init()
679 dev_dbg(controller->dev, "control register: %08x\n", reg); in aspeed_smc_chip_setup_init()
683 dev_dbg(controller->dev, in aspeed_smc_chip_setup_init()
687 chip->ctl_val[smc_base] = base_reg; in aspeed_smc_chip_setup_init()
696 chip->ctl_val[smc_read] = reg; in aspeed_smc_chip_setup_init()
698 chip->ctl_val[smc_read] = chip->ctl_val[smc_base] | in aspeed_smc_chip_setup_init()
701 dev_dbg(controller->dev, "default control register: %08x\n", in aspeed_smc_chip_setup_init()
702 chip->ctl_val[smc_read]); in aspeed_smc_chip_setup_init()
708 struct aspeed_smc_controller *controller = chip->controller; in aspeed_smc_chip_setup_finish()
709 const struct aspeed_smc_info *info = controller->info; in aspeed_smc_chip_setup_finish()
712 if (chip->nor.addr_width == 4 && info->set_4b) in aspeed_smc_chip_setup_finish()
713 info->set_4b(chip); in aspeed_smc_chip_setup_finish()
716 chip->ahb_window_size = aspeed_smc_chip_set_segment(chip); in aspeed_smc_chip_setup_finish()
721 chip->ctl_val[smc_write] = chip->ctl_val[smc_base] | in aspeed_smc_chip_setup_finish()
722 chip->nor.program_opcode << CONTROL_COMMAND_SHIFT | in aspeed_smc_chip_setup_finish()
725 dev_dbg(controller->dev, "write control register: %08x\n", in aspeed_smc_chip_setup_finish()
726 chip->ctl_val[smc_write]); in aspeed_smc_chip_setup_finish()
730 * SPI NOR flags to adjust controller settings. in aspeed_smc_chip_setup_finish()
732 if (chip->nor.read_proto == SNOR_PROTO_1_1_1) { in aspeed_smc_chip_setup_finish()
733 if (chip->nor.read_dummy == 0) in aspeed_smc_chip_setup_finish()
738 dev_err(chip->nor.dev, "unsupported SPI read mode\n"); in aspeed_smc_chip_setup_finish()
739 return -EINVAL; in aspeed_smc_chip_setup_finish()
742 chip->ctl_val[smc_read] |= cmd | in aspeed_smc_chip_setup_finish()
743 CONTROL_IO_DUMMY_SET(chip->nor.read_dummy / 8); in aspeed_smc_chip_setup_finish()
745 dev_dbg(controller->dev, "base control register: %08x\n", in aspeed_smc_chip_setup_finish()
746 chip->ctl_val[smc_read]); in aspeed_smc_chip_setup_finish()
767 const struct aspeed_smc_info *info = controller->info; in aspeed_smc_setup_flash()
768 struct device *dev = controller->dev; in aspeed_smc_setup_flash()
771 int ret = -ENODEV; in aspeed_smc_setup_flash()
775 struct spi_nor *nor; in aspeed_smc_setup_flash() local
778 /* This driver does not support NAND or NOR flash devices. */ in aspeed_smc_setup_flash()
779 if (!of_device_is_compatible(child, "jedec,spi-nor")) in aspeed_smc_setup_flash()
788 if (cs >= info->nce) { in aspeed_smc_setup_flash()
791 ret = -ERANGE; in aspeed_smc_setup_flash()
795 if (controller->chips[cs]) { in aspeed_smc_setup_flash()
797 cs, dev_name(controller->chips[cs]->nor.dev)); in aspeed_smc_setup_flash()
798 ret = -EBUSY; in aspeed_smc_setup_flash()
802 chip = devm_kzalloc(controller->dev, sizeof(*chip), GFP_KERNEL); in aspeed_smc_setup_flash()
804 ret = -ENOMEM; in aspeed_smc_setup_flash()
808 chip->controller = controller; in aspeed_smc_setup_flash()
809 chip->ctl = controller->regs + info->ctl0 + cs * 4; in aspeed_smc_setup_flash()
810 chip->cs = cs; in aspeed_smc_setup_flash()
812 nor = &chip->nor; in aspeed_smc_setup_flash()
813 mtd = &nor->mtd; in aspeed_smc_setup_flash()
815 nor->dev = dev; in aspeed_smc_setup_flash()
816 nor->priv = chip; in aspeed_smc_setup_flash()
817 spi_nor_set_flash_node(nor, child); in aspeed_smc_setup_flash()
818 nor->controller_ops = &aspeed_smc_controller_ops; in aspeed_smc_setup_flash()
825 * TODO: Add support for Dual and Quad SPI protocols in aspeed_smc_setup_flash()
829 ret = spi_nor_scan(nor, NULL, &hwcaps); in aspeed_smc_setup_flash()
841 controller->chips[cs] = chip; in aspeed_smc_setup_flash()
854 struct device_node *np = pdev->dev.of_node; in aspeed_smc_probe()
855 struct device *dev = &pdev->dev; in aspeed_smc_probe()
862 match = of_match_device(aspeed_smc_matches, &pdev->dev); in aspeed_smc_probe()
863 if (!match || !match->data) in aspeed_smc_probe()
864 return -ENODEV; in aspeed_smc_probe()
865 info = match->data; in aspeed_smc_probe()
867 controller = devm_kzalloc(&pdev->dev, in aspeed_smc_probe()
868 struct_size(controller, chips, info->nce), in aspeed_smc_probe()
871 return -ENOMEM; in aspeed_smc_probe()
872 controller->info = info; in aspeed_smc_probe()
873 controller->dev = dev; in aspeed_smc_probe()
875 mutex_init(&controller->mutex); in aspeed_smc_probe()
879 controller->regs = devm_ioremap_resource(dev, res); in aspeed_smc_probe()
880 if (IS_ERR(controller->regs)) in aspeed_smc_probe()
881 return PTR_ERR(controller->regs); in aspeed_smc_probe()
884 controller->ahb_base = devm_ioremap_resource(dev, res); in aspeed_smc_probe()
885 if (IS_ERR(controller->ahb_base)) in aspeed_smc_probe()
886 return PTR_ERR(controller->ahb_base); in aspeed_smc_probe()
888 controller->ahb_window_size = resource_size(res); in aspeed_smc_probe()