Lines Matching +full:spi +full:- +full:src +full:- +full:clk
1 // SPDX-License-Identifier: GPL-2.0
10 #include <linux/clk.h>
16 #include <linux/spi/spi-mem.h>
107 /* FIU UMA Write Data Bytes 0-3 Register */
113 /* FIU UMA Write Data Bytes 4-7 Register */
119 /* FIU UMA Write Data Bytes 8-11 Register */
125 /* FIU UMA Write Data Bytes 12-15 Register */
131 /* FIU UMA Read Data Bytes 0-3 Register */
137 /* FIU UMA Read Data Bytes 4-7 Register */
143 /* FIU UMA Read Data Bytes 8-11 Register */
149 /* FIU UMA Read Data Bytes 12-15 Register */
254 struct clk *clk; member
268 regmap_update_bits(fiu->regmap, NPCM_FIU_DRD_CFG, in npcm_fiu_set_drd()
270 ilog2(op->addr.buswidth) << in npcm_fiu_set_drd()
272 fiu->drd_op.addr.buswidth = op->addr.buswidth; in npcm_fiu_set_drd()
273 regmap_update_bits(fiu->regmap, NPCM_FIU_DRD_CFG, in npcm_fiu_set_drd()
275 op->dummy.nbytes << NPCM_FIU_DRD_DBW_SHIFT); in npcm_fiu_set_drd()
276 fiu->drd_op.dummy.nbytes = op->dummy.nbytes; in npcm_fiu_set_drd()
277 regmap_update_bits(fiu->regmap, NPCM_FIU_DRD_CFG, in npcm_fiu_set_drd()
278 NPCM_FIU_DRD_CFG_RDCMD, op->cmd.opcode); in npcm_fiu_set_drd()
279 fiu->drd_op.cmd.opcode = op->cmd.opcode; in npcm_fiu_set_drd()
280 regmap_update_bits(fiu->regmap, NPCM_FIU_DRD_CFG, in npcm_fiu_set_drd()
282 (op->addr.nbytes - 3) << NPCM_FIU_DRD_ADDSIZ_SHIFT); in npcm_fiu_set_drd()
283 fiu->drd_op.addr.nbytes = op->addr.nbytes; in npcm_fiu_set_drd()
290 spi_controller_get_devdata(desc->mem->spi->controller); in npcm_fiu_direct_read()
291 struct npcm_fiu_chip *chip = &fiu->chip[spi_get_chipselect(desc->mem->spi, 0)]; in npcm_fiu_direct_read()
292 void __iomem *src = (void __iomem *)(chip->flash_region_mapped_ptr + in npcm_fiu_direct_read() local
297 if (fiu->spix_mode) { in npcm_fiu_direct_read()
299 *(buf_rx + i) = ioread8(src + i); in npcm_fiu_direct_read()
301 if (desc->info.op_tmpl.addr.buswidth != fiu->drd_op.addr.buswidth || in npcm_fiu_direct_read()
302 desc->info.op_tmpl.dummy.nbytes != fiu->drd_op.dummy.nbytes || in npcm_fiu_direct_read()
303 desc->info.op_tmpl.cmd.opcode != fiu->drd_op.cmd.opcode || in npcm_fiu_direct_read()
304 desc->info.op_tmpl.addr.nbytes != fiu->drd_op.addr.nbytes) in npcm_fiu_direct_read()
305 npcm_fiu_set_drd(fiu, &desc->info.op_tmpl); in npcm_fiu_direct_read()
307 memcpy_fromio(buf_rx, src, len); in npcm_fiu_direct_read()
317 spi_controller_get_devdata(desc->mem->spi->controller); in npcm_fiu_direct_write()
318 struct npcm_fiu_chip *chip = &fiu->chip[spi_get_chipselect(desc->mem->spi, 0)]; in npcm_fiu_direct_write()
319 void __iomem *dst = (void __iomem *)(chip->flash_region_mapped_ptr + in npcm_fiu_direct_write()
324 if (fiu->spix_mode) in npcm_fiu_direct_write()
338 spi_controller_get_devdata(mem->spi->controller); in npcm_fiu_uma_read()
345 regmap_update_bits(fiu->regmap, NPCM_FIU_UMA_CTS, in npcm_fiu_uma_read()
347 (spi_get_chipselect(mem->spi, 0) << in npcm_fiu_uma_read()
349 regmap_update_bits(fiu->regmap, NPCM_FIU_UMA_CMD, in npcm_fiu_uma_read()
350 NPCM_FIU_UMA_CMD_CMD, op->cmd.opcode); in npcm_fiu_uma_read()
353 uma_cfg |= ilog2(op->cmd.buswidth); in npcm_fiu_uma_read()
354 uma_cfg |= ilog2(op->addr.buswidth) in npcm_fiu_uma_read()
356 if (op->dummy.nbytes) in npcm_fiu_uma_read()
357 uma_cfg |= ilog2(op->dummy.buswidth) in npcm_fiu_uma_read()
359 uma_cfg |= ilog2(op->data.buswidth) in npcm_fiu_uma_read()
361 uma_cfg |= op->dummy.nbytes << NPCM_FIU_UMA_CFG_DBSIZ_SHIFT; in npcm_fiu_uma_read()
362 uma_cfg |= op->addr.nbytes << NPCM_FIU_UMA_CFG_ADDSIZ_SHIFT; in npcm_fiu_uma_read()
363 regmap_write(fiu->regmap, NPCM_FIU_UMA_ADDR, addr); in npcm_fiu_uma_read()
365 regmap_write(fiu->regmap, NPCM_FIU_UMA_ADDR, 0x0); in npcm_fiu_uma_read()
369 regmap_write(fiu->regmap, NPCM_FIU_UMA_CFG, uma_cfg); in npcm_fiu_uma_read()
370 regmap_write_bits(fiu->regmap, NPCM_FIU_UMA_CTS, in npcm_fiu_uma_read()
373 ret = regmap_read_poll_timeout(fiu->regmap, NPCM_FIU_UMA_CTS, val, in npcm_fiu_uma_read()
381 regmap_read(fiu->regmap, NPCM_FIU_UMA_DR0 + (i * 4), in npcm_fiu_uma_read()
394 spi_controller_get_devdata(mem->spi->controller); in npcm_fiu_uma_write()
400 regmap_update_bits(fiu->regmap, NPCM_FIU_UMA_CTS, in npcm_fiu_uma_write()
402 (spi_get_chipselect(mem->spi, 0) << in npcm_fiu_uma_write()
405 regmap_update_bits(fiu->regmap, NPCM_FIU_UMA_CMD, in npcm_fiu_uma_write()
411 regmap_write(fiu->regmap, NPCM_FIU_UMA_DW0 + (i * 4), in npcm_fiu_uma_write()
416 uma_cfg |= ilog2(op->cmd.buswidth); in npcm_fiu_uma_write()
417 uma_cfg |= ilog2(op->addr.buswidth) << in npcm_fiu_uma_write()
419 uma_cfg |= ilog2(op->data.buswidth) << in npcm_fiu_uma_write()
421 uma_cfg |= op->addr.nbytes << NPCM_FIU_UMA_CFG_ADDSIZ_SHIFT; in npcm_fiu_uma_write()
422 regmap_write(fiu->regmap, NPCM_FIU_UMA_ADDR, op->addr.val); in npcm_fiu_uma_write()
424 regmap_write(fiu->regmap, NPCM_FIU_UMA_ADDR, 0x0); in npcm_fiu_uma_write()
428 regmap_write(fiu->regmap, NPCM_FIU_UMA_CFG, uma_cfg); in npcm_fiu_uma_write()
430 regmap_write_bits(fiu->regmap, NPCM_FIU_UMA_CTS, in npcm_fiu_uma_write()
434 return regmap_read_poll_timeout(fiu->regmap, NPCM_FIU_UMA_CTS, val, in npcm_fiu_uma_write()
443 spi_controller_get_devdata(mem->spi->controller); in npcm_fiu_manualwrite()
444 u8 *data = (u8 *)op->data.buf.out; in npcm_fiu_manualwrite()
450 num_data_chunks = op->data.nbytes / CHUNK_SIZE; in npcm_fiu_manualwrite()
451 remain_data = op->data.nbytes % CHUNK_SIZE; in npcm_fiu_manualwrite()
453 regmap_update_bits(fiu->regmap, NPCM_FIU_UMA_CTS, in npcm_fiu_manualwrite()
455 (spi_get_chipselect(mem->spi, 0) << in npcm_fiu_manualwrite()
457 regmap_update_bits(fiu->regmap, NPCM_FIU_UMA_CTS, in npcm_fiu_manualwrite()
460 ret = npcm_fiu_uma_write(mem, op, op->cmd.opcode, true, NULL, 0); in npcm_fiu_manualwrite()
467 &data[1], CHUNK_SIZE - 1); in npcm_fiu_manualwrite()
477 &data[1], remain_data - 1); in npcm_fiu_manualwrite()
482 regmap_update_bits(fiu->regmap, NPCM_FIU_UMA_CTS, in npcm_fiu_manualwrite()
490 u8 *data = op->data.buf.in; in npcm_fiu_read()
497 currlen = op->data.nbytes; in npcm_fiu_read()
500 addr = ((u32)op->addr.val + i); in npcm_fiu_read()
513 currlen -= 16; in npcm_fiu_read()
521 regmap_write(fiu->regmap, NPCM_FIU_DWR_CFG, in npcm_fiux_set_direct_wr()
523 regmap_update_bits(fiu->regmap, NPCM_FIU_DWR_CFG, in npcm_fiux_set_direct_wr()
526 regmap_update_bits(fiu->regmap, NPCM_FIU_DWR_CFG, in npcm_fiux_set_direct_wr()
535 regmap_write(fiu->regmap, NPCM_FIU_DRD_CFG, in npcm_fiux_set_direct_rd()
537 regmap_update_bits(fiu->regmap, NPCM_FIU_DRD_CFG, in npcm_fiux_set_direct_rd()
540 regmap_update_bits(fiu->regmap, NPCM_FIU_DRD_CFG, in npcm_fiux_set_direct_rd()
548 spi_controller_get_devdata(mem->spi->controller); in npcm_fiu_exec_op()
549 struct npcm_fiu_chip *chip = &fiu->chip[spi_get_chipselect(mem->spi, 0)]; in npcm_fiu_exec_op()
553 dev_dbg(fiu->dev, "cmd:%#x mode:%d.%d.%d.%d addr:%#llx len:%#x\n", in npcm_fiu_exec_op()
554 op->cmd.opcode, op->cmd.buswidth, op->addr.buswidth, in npcm_fiu_exec_op()
555 op->dummy.buswidth, op->data.buswidth, op->addr.val, in npcm_fiu_exec_op()
556 op->data.nbytes); in npcm_fiu_exec_op()
558 if (fiu->spix_mode || op->addr.nbytes > 4) in npcm_fiu_exec_op()
559 return -EOPNOTSUPP; in npcm_fiu_exec_op()
561 if (fiu->clkrate != chip->clkrate) { in npcm_fiu_exec_op()
562 ret = clk_set_rate(fiu->clk, chip->clkrate); in npcm_fiu_exec_op()
564 dev_warn(fiu->dev, "Failed setting %lu frequency, stay at %lu frequency\n", in npcm_fiu_exec_op()
565 chip->clkrate, fiu->clkrate); in npcm_fiu_exec_op()
567 fiu->clkrate = chip->clkrate; in npcm_fiu_exec_op()
570 if (op->data.dir == SPI_MEM_DATA_IN) { in npcm_fiu_exec_op()
571 if (!op->addr.nbytes) { in npcm_fiu_exec_op()
572 buf = op->data.buf.in; in npcm_fiu_exec_op()
573 ret = npcm_fiu_uma_read(mem, op, op->addr.val, false, in npcm_fiu_exec_op()
574 buf, op->data.nbytes); in npcm_fiu_exec_op()
579 if (!op->addr.nbytes && !op->data.nbytes) in npcm_fiu_exec_op()
580 ret = npcm_fiu_uma_write(mem, op, op->cmd.opcode, false, in npcm_fiu_exec_op()
582 if (op->addr.nbytes && !op->data.nbytes) { in npcm_fiu_exec_op()
585 u32 addr = op->addr.val; in npcm_fiu_exec_op()
587 for (i = op->addr.nbytes - 1; i >= 0; i--) { in npcm_fiu_exec_op()
591 ret = npcm_fiu_uma_write(mem, op, op->cmd.opcode, false, in npcm_fiu_exec_op()
592 buf_addr, op->addr.nbytes); in npcm_fiu_exec_op()
594 if (!op->addr.nbytes && op->data.nbytes) in npcm_fiu_exec_op()
595 ret = npcm_fiu_uma_write(mem, op, op->cmd.opcode, false, in npcm_fiu_exec_op()
596 (u8 *)op->data.buf.out, in npcm_fiu_exec_op()
597 op->data.nbytes); in npcm_fiu_exec_op()
598 if (op->addr.nbytes && op->data.nbytes) in npcm_fiu_exec_op()
608 spi_controller_get_devdata(desc->mem->spi->controller); in npcm_fiu_dirmap_create()
609 struct npcm_fiu_chip *chip = &fiu->chip[spi_get_chipselect(desc->mem->spi, 0)]; in npcm_fiu_dirmap_create()
612 if (!fiu->res_mem) { in npcm_fiu_dirmap_create()
613 dev_warn(fiu->dev, "Reserved memory not defined, direct read disabled\n"); in npcm_fiu_dirmap_create()
614 desc->nodirmap = true; in npcm_fiu_dirmap_create()
618 if (!fiu->spix_mode && in npcm_fiu_dirmap_create()
619 desc->info.op_tmpl.data.dir == SPI_MEM_DATA_OUT) { in npcm_fiu_dirmap_create()
620 desc->nodirmap = true; in npcm_fiu_dirmap_create()
624 if (!chip->flash_region_mapped_ptr) { in npcm_fiu_dirmap_create()
625 chip->flash_region_mapped_ptr = in npcm_fiu_dirmap_create()
626 devm_ioremap(fiu->dev, (fiu->res_mem->start + in npcm_fiu_dirmap_create()
627 (fiu->info->max_map_size * in npcm_fiu_dirmap_create()
628 spi_get_chipselect(desc->mem->spi, 0))), in npcm_fiu_dirmap_create()
629 (u32)desc->info.length); in npcm_fiu_dirmap_create()
630 if (!chip->flash_region_mapped_ptr) { in npcm_fiu_dirmap_create()
631 dev_warn(fiu->dev, "Error mapping memory region, direct read disabled\n"); in npcm_fiu_dirmap_create()
632 desc->nodirmap = true; in npcm_fiu_dirmap_create()
637 if (of_device_is_compatible(fiu->dev->of_node, "nuvoton,npcm750-fiu")) { in npcm_fiu_dirmap_create()
639 syscon_regmap_lookup_by_compatible("nuvoton,npcm750-gcr"); in npcm_fiu_dirmap_create()
641 dev_warn(fiu->dev, "Didn't find nuvoton,npcm750-gcr, direct read disabled\n"); in npcm_fiu_dirmap_create()
642 desc->nodirmap = true; in npcm_fiu_dirmap_create()
649 regmap_update_bits(fiu->regmap, NPCM_FIU_CFG, in npcm_fiu_dirmap_create()
654 if (desc->info.op_tmpl.data.dir == SPI_MEM_DATA_IN) { in npcm_fiu_dirmap_create()
655 if (!fiu->spix_mode) in npcm_fiu_dirmap_create()
656 npcm_fiu_set_drd(fiu, &desc->info.op_tmpl); in npcm_fiu_dirmap_create()
667 static int npcm_fiu_setup(struct spi_device *spi) in npcm_fiu_setup() argument
669 struct spi_controller *ctrl = spi->controller; in npcm_fiu_setup()
673 chip = &fiu->chip[spi_get_chipselect(spi, 0)]; in npcm_fiu_setup()
674 chip->fiu = fiu; in npcm_fiu_setup()
675 chip->chipselect = spi_get_chipselect(spi, 0); in npcm_fiu_setup()
676 chip->clkrate = spi->max_speed_hz; in npcm_fiu_setup()
678 fiu->clkrate = clk_get_rate(fiu->clk); in npcm_fiu_setup()
691 { .compatible = "nuvoton,npcm750-fiu", .data = &npcm7xx_fiu_data },
692 { .compatible = "nuvoton,npcm845-fiu", .data = &npxm8xx_fiu_data },
699 struct device *dev = &pdev->dev; in npcm_fiu_probe()
707 return -ENOMEM; in npcm_fiu_probe()
714 return -ENODEV; in npcm_fiu_probe()
717 id = of_alias_get_id(dev->of_node, "fiu"); in npcm_fiu_probe()
718 if (id < 0 || id >= fiu_data_match->fiu_max) { in npcm_fiu_probe()
720 return -EINVAL; in npcm_fiu_probe()
723 fiu->info = &fiu_data_match->npcm_fiu_data_info[id]; in npcm_fiu_probe()
726 fiu->dev = dev; in npcm_fiu_probe()
732 fiu->regmap = devm_regmap_init_mmio(dev, regbase, in npcm_fiu_probe()
734 if (IS_ERR(fiu->regmap)) { in npcm_fiu_probe()
736 return PTR_ERR(fiu->regmap); in npcm_fiu_probe()
739 fiu->res_mem = platform_get_resource_byname(pdev, IORESOURCE_MEM, in npcm_fiu_probe()
741 fiu->clk = devm_clk_get_enabled(dev, NULL); in npcm_fiu_probe()
742 if (IS_ERR(fiu->clk)) in npcm_fiu_probe()
743 return PTR_ERR(fiu->clk); in npcm_fiu_probe()
745 fiu->spix_mode = of_property_read_bool(dev->of_node, in npcm_fiu_probe()
746 "nuvoton,spix-mode"); in npcm_fiu_probe()
750 ctrl->mode_bits = SPI_RX_DUAL | SPI_RX_QUAD in npcm_fiu_probe()
752 ctrl->setup = npcm_fiu_setup; in npcm_fiu_probe()
753 ctrl->bus_num = -1; in npcm_fiu_probe()
754 ctrl->mem_ops = &npcm_fiu_mem_ops; in npcm_fiu_probe()
755 ctrl->num_chipselect = fiu->info->max_cs; in npcm_fiu_probe()
756 ctrl->dev.of_node = dev->of_node; in npcm_fiu_probe()
769 .name = "NPCM-FIU",
778 MODULE_DESCRIPTION("Nuvoton FLASH Interface Unit SPI Controller Driver");