Lines Matching refs:q

238 static inline int is_vybrid_qspi(struct fsl_qspi *q)  in is_vybrid_qspi()  argument
240 return q->devtype_data->devtype == FSL_QUADSPI_VYBRID; in is_vybrid_qspi()
243 static inline int is_imx6sx_qspi(struct fsl_qspi *q) in is_imx6sx_qspi() argument
245 return q->devtype_data->devtype == FSL_QUADSPI_IMX6SX; in is_imx6sx_qspi()
252 static inline u32 fsl_qspi_endian_xchg(struct fsl_qspi *q, u32 a) in fsl_qspi_endian_xchg() argument
254 return is_vybrid_qspi(q) ? __swab32(a) : a; in fsl_qspi_endian_xchg()
257 static inline void fsl_qspi_unlock_lut(struct fsl_qspi *q) in fsl_qspi_unlock_lut() argument
259 writel(QUADSPI_LUTKEY_VALUE, q->iobase + QUADSPI_LUTKEY); in fsl_qspi_unlock_lut()
260 writel(QUADSPI_LCKER_UNLOCK, q->iobase + QUADSPI_LCKCR); in fsl_qspi_unlock_lut()
263 static inline void fsl_qspi_lock_lut(struct fsl_qspi *q) in fsl_qspi_lock_lut() argument
265 writel(QUADSPI_LUTKEY_VALUE, q->iobase + QUADSPI_LUTKEY); in fsl_qspi_lock_lut()
266 writel(QUADSPI_LCKER_LOCK, q->iobase + QUADSPI_LCKCR); in fsl_qspi_lock_lut()
271 struct fsl_qspi *q = dev_id; in fsl_qspi_irq_handler() local
275 reg = readl(q->iobase + QUADSPI_FR); in fsl_qspi_irq_handler()
276 writel(reg, q->iobase + QUADSPI_FR); in fsl_qspi_irq_handler()
279 complete(&q->c); in fsl_qspi_irq_handler()
281 dev_dbg(q->dev, "QUADSPI_FR : 0x%.8x:0x%.8x\n", q->chip_base_addr, reg); in fsl_qspi_irq_handler()
285 static void fsl_qspi_init_lut(struct fsl_qspi *q) in fsl_qspi_init_lut() argument
287 void __iomem *base = q->iobase; in fsl_qspi_init_lut()
288 int rxfifo = q->devtype_data->rxfifo; in fsl_qspi_init_lut()
293 fsl_qspi_unlock_lut(q); in fsl_qspi_init_lut()
302 if (q->nor_size <= SZ_16M) { in fsl_qspi_init_lut()
325 if (q->nor_size <= SZ_16M) { in fsl_qspi_init_lut()
346 if (q->nor_size <= SZ_16M) { in fsl_qspi_init_lut()
390 fsl_qspi_lock_lut(q); in fsl_qspi_init_lut()
394 static int fsl_qspi_get_seqid(struct fsl_qspi *q, u8 cmd) in fsl_qspi_get_seqid() argument
422 dev_err(q->dev, "Unsupported cmd 0x%.2x\n", cmd); in fsl_qspi_get_seqid()
429 fsl_qspi_runcmd(struct fsl_qspi *q, u8 cmd, unsigned int addr, int len) in fsl_qspi_runcmd() argument
431 void __iomem *base = q->iobase; in fsl_qspi_runcmd()
436 init_completion(&q->c); in fsl_qspi_runcmd()
437 dev_dbg(q->dev, "to 0x%.8x:0x%.8x, len:%d, cmd:%.2x\n", in fsl_qspi_runcmd()
438 q->chip_base_addr, addr, len, cmd); in fsl_qspi_runcmd()
443 writel(q->memmap_phy + q->chip_base_addr + addr, base + QUADSPI_SFAR); in fsl_qspi_runcmd()
452 dev_dbg(q->dev, "The controller is busy, 0x%x\n", reg2); in fsl_qspi_runcmd()
459 seqid = fsl_qspi_get_seqid(q, cmd); in fsl_qspi_runcmd()
463 if (!wait_for_completion_timeout(&q->c, msecs_to_jiffies(1000))) { in fsl_qspi_runcmd()
464 dev_err(q->dev, in fsl_qspi_runcmd()
480 static void fsl_qspi_read_data(struct fsl_qspi *q, int len, u8 *rxbuf) in fsl_qspi_read_data() argument
486 tmp = readl(q->iobase + QUADSPI_RBDR + i * 4); in fsl_qspi_read_data()
487 tmp = fsl_qspi_endian_xchg(q, tmp); in fsl_qspi_read_data()
488 dev_dbg(q->dev, "chip addr:0x%.8x, rcv:0x%.8x\n", in fsl_qspi_read_data()
489 q->chip_base_addr, tmp); in fsl_qspi_read_data()
510 static inline void fsl_qspi_invalid(struct fsl_qspi *q) in fsl_qspi_invalid() argument
514 reg = readl(q->iobase + QUADSPI_MCR); in fsl_qspi_invalid()
516 writel(reg, q->iobase + QUADSPI_MCR); in fsl_qspi_invalid()
525 writel(reg, q->iobase + QUADSPI_MCR); in fsl_qspi_invalid()
528 static int fsl_qspi_nor_write(struct fsl_qspi *q, struct spi_nor *nor, in fsl_qspi_nor_write() argument
535 dev_dbg(q->dev, "to 0x%.8x:0x%.8x, len : %d\n", in fsl_qspi_nor_write()
536 q->chip_base_addr, to, count); in fsl_qspi_nor_write()
539 tmp = readl(q->iobase + QUADSPI_MCR); in fsl_qspi_nor_write()
540 writel(tmp | QUADSPI_MCR_CLR_RXF_MASK, q->iobase + QUADSPI_MCR); in fsl_qspi_nor_write()
544 tmp = fsl_qspi_endian_xchg(q, *txbuf); in fsl_qspi_nor_write()
545 writel(tmp, q->iobase + QUADSPI_TBDR); in fsl_qspi_nor_write()
550 ret = fsl_qspi_runcmd(q, opcode, to, count); in fsl_qspi_nor_write()
558 static void fsl_qspi_set_map_addr(struct fsl_qspi *q) in fsl_qspi_set_map_addr() argument
560 int nor_size = q->nor_size; in fsl_qspi_set_map_addr()
561 void __iomem *base = q->iobase; in fsl_qspi_set_map_addr()
563 writel(nor_size + q->memmap_phy, base + QUADSPI_SFA1AD); in fsl_qspi_set_map_addr()
564 writel(nor_size * 2 + q->memmap_phy, base + QUADSPI_SFA2AD); in fsl_qspi_set_map_addr()
565 writel(nor_size * 3 + q->memmap_phy, base + QUADSPI_SFB1AD); in fsl_qspi_set_map_addr()
566 writel(nor_size * 4 + q->memmap_phy, base + QUADSPI_SFB2AD); in fsl_qspi_set_map_addr()
582 static void fsl_qspi_init_abh_read(struct fsl_qspi *q) in fsl_qspi_init_abh_read() argument
584 void __iomem *base = q->iobase; in fsl_qspi_init_abh_read()
595 writel(QUADSPI_BUF3CR_ALLMST_MASK | ((q->devtype_data->ahb_buf_size / 8) in fsl_qspi_init_abh_read()
604 seqid = fsl_qspi_get_seqid(q, q->nor[0].read_opcode); in fsl_qspi_init_abh_read()
606 q->iobase + QUADSPI_BFGENCR); in fsl_qspi_init_abh_read()
610 static int fsl_qspi_nor_setup(struct fsl_qspi *q) in fsl_qspi_nor_setup() argument
612 void __iomem *base = q->iobase; in fsl_qspi_nor_setup()
617 ret = clk_set_rate(q->clk, 66000000); in fsl_qspi_nor_setup()
622 fsl_qspi_init_lut(q); in fsl_qspi_nor_setup()
639 writel(QUADSPI_RSER_TFIE, q->iobase + QUADSPI_RSER); in fsl_qspi_nor_setup()
644 static int fsl_qspi_nor_setup_last(struct fsl_qspi *q) in fsl_qspi_nor_setup_last() argument
646 unsigned long rate = q->clk_rate; in fsl_qspi_nor_setup_last()
649 if (is_imx6sx_qspi(q)) in fsl_qspi_nor_setup_last()
652 ret = clk_set_rate(q->clk, rate); in fsl_qspi_nor_setup_last()
657 fsl_qspi_init_lut(q); in fsl_qspi_nor_setup_last()
660 fsl_qspi_init_abh_read(q); in fsl_qspi_nor_setup_last()
672 static void fsl_qspi_set_base_addr(struct fsl_qspi *q, struct spi_nor *nor) in fsl_qspi_set_base_addr() argument
674 q->chip_base_addr = q->nor_size * (nor - q->nor); in fsl_qspi_set_base_addr()
680 struct fsl_qspi *q = nor->priv; in fsl_qspi_read_reg() local
682 ret = fsl_qspi_runcmd(q, opcode, 0, len); in fsl_qspi_read_reg()
686 fsl_qspi_read_data(q, len, buf); in fsl_qspi_read_reg()
693 struct fsl_qspi *q = nor->priv; in fsl_qspi_write_reg() local
697 ret = fsl_qspi_runcmd(q, opcode, 0, 1); in fsl_qspi_write_reg()
702 fsl_qspi_invalid(q); in fsl_qspi_write_reg()
705 ret = fsl_qspi_nor_write(q, nor, opcode, 0, in fsl_qspi_write_reg()
708 dev_err(q->dev, "invalid cmd %d\n", opcode); in fsl_qspi_write_reg()
718 struct fsl_qspi *q = nor->priv; in fsl_qspi_write() local
720 fsl_qspi_nor_write(q, nor, nor->program_opcode, to, in fsl_qspi_write()
724 fsl_qspi_invalid(q); in fsl_qspi_write()
730 struct fsl_qspi *q = nor->priv; in fsl_qspi_read() local
733 dev_dbg(q->dev, "cmd [%x],read from (0x%p, 0x%.8x, 0x%.8x),len:%d\n", in fsl_qspi_read()
734 cmd, q->ahb_base, q->chip_base_addr, (unsigned int)from, len); in fsl_qspi_read()
737 memcpy(buf, q->ahb_base + q->chip_base_addr + from, len); in fsl_qspi_read()
745 struct fsl_qspi *q = nor->priv; in fsl_qspi_erase() local
749 nor->mtd->erasesize / 1024, q->chip_base_addr, (u32)offs); in fsl_qspi_erase()
751 ret = fsl_qspi_runcmd(q, nor->erase_opcode, offs, 0); in fsl_qspi_erase()
755 fsl_qspi_invalid(q); in fsl_qspi_erase()
761 struct fsl_qspi *q = nor->priv; in fsl_qspi_prep() local
764 ret = clk_enable(q->clk_en); in fsl_qspi_prep()
768 ret = clk_enable(q->clk); in fsl_qspi_prep()
770 clk_disable(q->clk_en); in fsl_qspi_prep()
774 fsl_qspi_set_base_addr(q, nor); in fsl_qspi_prep()
780 struct fsl_qspi *q = nor->priv; in fsl_qspi_unprep() local
782 clk_disable(q->clk); in fsl_qspi_unprep()
783 clk_disable(q->clk_en); in fsl_qspi_unprep()
791 struct fsl_qspi *q; in fsl_qspi_probe() local
799 q = devm_kzalloc(dev, sizeof(*q), GFP_KERNEL); in fsl_qspi_probe()
800 if (!q) in fsl_qspi_probe()
803 q->nor_num = of_get_child_count(dev->of_node); in fsl_qspi_probe()
804 if (!q->nor_num || q->nor_num > FSL_QSPI_MAX_CHIP) in fsl_qspi_probe()
809 q->iobase = devm_ioremap_resource(dev, res); in fsl_qspi_probe()
810 if (IS_ERR(q->iobase)) in fsl_qspi_probe()
811 return PTR_ERR(q->iobase); in fsl_qspi_probe()
815 q->ahb_base = devm_ioremap_resource(dev, res); in fsl_qspi_probe()
816 if (IS_ERR(q->ahb_base)) in fsl_qspi_probe()
817 return PTR_ERR(q->ahb_base); in fsl_qspi_probe()
819 q->memmap_phy = res->start; in fsl_qspi_probe()
822 q->clk_en = devm_clk_get(dev, "qspi_en"); in fsl_qspi_probe()
823 if (IS_ERR(q->clk_en)) in fsl_qspi_probe()
824 return PTR_ERR(q->clk_en); in fsl_qspi_probe()
826 q->clk = devm_clk_get(dev, "qspi"); in fsl_qspi_probe()
827 if (IS_ERR(q->clk)) in fsl_qspi_probe()
828 return PTR_ERR(q->clk); in fsl_qspi_probe()
830 ret = clk_prepare_enable(q->clk_en); in fsl_qspi_probe()
836 ret = clk_prepare_enable(q->clk); in fsl_qspi_probe()
850 fsl_qspi_irq_handler, 0, pdev->name, q); in fsl_qspi_probe()
856 q->dev = dev; in fsl_qspi_probe()
857 q->devtype_data = (struct fsl_qspi_devtype_data *)of_id->data; in fsl_qspi_probe()
858 platform_set_drvdata(pdev, q); in fsl_qspi_probe()
860 ret = fsl_qspi_nor_setup(q); in fsl_qspi_probe()
865 q->has_second_chip = true; in fsl_qspi_probe()
872 if (!q->has_second_chip) in fsl_qspi_probe()
875 nor = &q->nor[i]; in fsl_qspi_probe()
876 mtd = &q->mtd[i]; in fsl_qspi_probe()
880 nor->priv = q; in fsl_qspi_probe()
898 &q->clk_rate); in fsl_qspi_probe()
903 fsl_qspi_set_base_addr(q, nor); in fsl_qspi_probe()
915 if (q->nor_size == 0) { in fsl_qspi_probe()
916 q->nor_size = mtd->size; in fsl_qspi_probe()
919 fsl_qspi_set_map_addr(q); in fsl_qspi_probe()
931 if (nor->page_size > q->devtype_data->txfifo) in fsl_qspi_probe()
932 nor->page_size = q->devtype_data->txfifo; in fsl_qspi_probe()
938 ret = fsl_qspi_nor_setup_last(q); in fsl_qspi_probe()
942 clk_disable(q->clk); in fsl_qspi_probe()
943 clk_disable(q->clk_en); in fsl_qspi_probe()
947 for (i = 0; i < q->nor_num; i++) { in fsl_qspi_probe()
949 if (!q->has_second_chip) in fsl_qspi_probe()
951 mtd_device_unregister(&q->mtd[i]); in fsl_qspi_probe()
954 clk_disable_unprepare(q->clk); in fsl_qspi_probe()
956 clk_disable_unprepare(q->clk_en); in fsl_qspi_probe()
962 struct fsl_qspi *q = platform_get_drvdata(pdev); in fsl_qspi_remove() local
965 for (i = 0; i < q->nor_num; i++) { in fsl_qspi_remove()
967 if (!q->has_second_chip) in fsl_qspi_remove()
969 mtd_device_unregister(&q->mtd[i]); in fsl_qspi_remove()
973 writel(QUADSPI_MCR_MDIS_MASK, q->iobase + QUADSPI_MCR); in fsl_qspi_remove()
974 writel(0x0, q->iobase + QUADSPI_RSER); in fsl_qspi_remove()
976 clk_unprepare(q->clk); in fsl_qspi_remove()
977 clk_unprepare(q->clk_en); in fsl_qspi_remove()
988 struct fsl_qspi *q = platform_get_drvdata(pdev); in fsl_qspi_resume() local
990 fsl_qspi_nor_setup(q); in fsl_qspi_resume()
991 fsl_qspi_set_map_addr(q); in fsl_qspi_resume()
992 fsl_qspi_nor_setup_last(q); in fsl_qspi_resume()