static int zynq_qspi_probe(struct udevice *bus) { struct zynq_qspi_platdata *plat = dev_get_platdata(bus); struct zynq_qspi_priv *priv = dev_get_priv(bus); debug("zynq_qspi_probe: bus:%p, priv:%p \n", bus, priv); #if defined(CONFIG_MARS_ZX) || defined(CONFIG_MERCURY_ZX) zx_set_storage(ZX_QSPI); #endif priv->regs = plat->regs; zynq_qspi_check_is_dual_flash(priv); if (priv->is_dual == -1) { debug("%s: No QSPI device detected based on MIO settings\n", __func__); return -1; } /* init the zynq spi hw */ zynq_qspi_init_hw(priv); return 0; }
struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, unsigned int max_hz, unsigned int mode) { int is_dual; unsigned long lqspi_frequency; struct zynq_qspi_slave *qspi; debug("%s: bus: %d cs: %d max_hz: %d mode: %d\n", __func__, bus, cs, max_hz, mode); if (!spi_cs_is_valid(bus, cs)) return NULL; is_dual = zynq_qspi_check_is_dual_flash(); if (is_dual == MODE_UNKNOWN) { printf("%s: No QSPI device detected based on MIO settings\n", __func__); return NULL; } zynq_qspi_init_hw(is_dual, cs); qspi = spi_alloc_slave(struct zynq_qspi_slave, bus, cs); if (!qspi) { printf("%s: Fail to allocate zynq_qspi_slave\n", __func__); return NULL; } lqspi_frequency = zynq_clk_get_rate(lqspi_clk); if (!lqspi_frequency) { debug("Defaulting to 200000000 Hz qspi clk"); qspi->qspi.master.input_clk_hz = 200000000; } else { qspi->qspi.master.input_clk_hz = lqspi_frequency; debug("Qspi clk frequency set to %ld Hz\n", lqspi_frequency); } qspi->slave.is_dual = is_dual; qspi->slave.rd_cmd = READ_CMD_FULL; qspi->slave.wr_cmd = PAGE_PROGRAM | QUAD_PAGE_PROGRAM; qspi->qspi.master.speed_hz = qspi->qspi.master.input_clk_hz / 2; qspi->qspi.max_speed_hz = qspi->qspi.master.speed_hz; qspi->qspi.master.is_dual = is_dual; qspi->qspi.mode = mode; qspi->qspi.chip_select = 0; qspi->qspi.bits_per_word = 32; zynq_qspi_setup_transfer(&qspi->qspi, NULL); return &qspi->slave; }
static int zynq_qspi_probe(struct udevice *bus) { struct zynq_qspi_platdata *plat = dev_get_platdata(bus); struct zynq_qspi_priv *priv = dev_get_priv(bus); debug("zynq_qspi_probe: bus:%p, priv:%p \n", bus, priv); priv->regs = plat->regs; zynq_qspi_check_is_dual_flash(priv); if (priv->is_dual == -1) { debug("%s: No QSPI device detected based on MIO settings\n", __func__); return -1; } /* init the zynq spi hw */ zynq_qspi_init_hw(priv); return 0; }
/** * zynq_qspi_probe - Probe method for the QSPI driver * @pdev: Pointer to the platform_device structure * * This function initializes the driver data structures and the hardware. * * Return: 0 on success and error value on failure */ static int zynq_qspi_probe(struct platform_device *pdev) { int ret = 0; struct spi_master *master; struct zynq_qspi *xqspi; struct resource *res; u32 num_cs; master = spi_alloc_master(&pdev->dev, sizeof(*xqspi)); if (master == NULL) return -ENOMEM; xqspi = spi_master_get_devdata(master); master->dev.of_node = pdev->dev.of_node; platform_set_drvdata(pdev, master); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); xqspi->regs = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(xqspi->regs)) { ret = PTR_ERR(xqspi->regs); goto remove_master; } if (of_property_read_u32(pdev->dev.of_node, "is-dual", &xqspi->is_dual)) dev_warn(&pdev->dev, "couldn't determine configuration info " "about dual memories. defaulting to single memory\n"); xqspi->pclk = devm_clk_get(&pdev->dev, "pclk"); if (IS_ERR(xqspi->pclk)) { dev_err(&pdev->dev, "pclk clock not found.\n"); ret = PTR_ERR(xqspi->pclk); goto remove_master; } xqspi->refclk = devm_clk_get(&pdev->dev, "ref_clk"); if (IS_ERR(xqspi->refclk)) { dev_err(&pdev->dev, "ref_clk clock not found.\n"); ret = PTR_ERR(xqspi->refclk); goto remove_master; } ret = clk_prepare_enable(xqspi->pclk); if (ret) { dev_err(&pdev->dev, "Unable to enable APB clock.\n"); goto remove_master; } ret = clk_prepare_enable(xqspi->refclk); if (ret) { dev_err(&pdev->dev, "Unable to enable device clock.\n"); goto clk_dis_pclk; } /* QSPI controller initializations */ zynq_qspi_init_hw(xqspi); xqspi->irq = platform_get_irq(pdev, 0); if (xqspi->irq <= 0) { ret = -ENXIO; dev_err(&pdev->dev, "irq resource not found\n"); goto remove_master; } ret = devm_request_irq(&pdev->dev, xqspi->irq, zynq_qspi_irq, 0, pdev->name, master); if (ret != 0) { ret = -ENXIO; dev_err(&pdev->dev, "request_irq failed\n"); goto remove_master; } ret = of_property_read_u32(pdev->dev.of_node, "num-cs", &num_cs); if (ret < 0) master->num_chipselect = ZYNQ_QSPI_DEFAULT_NUM_CS; else master->num_chipselect = num_cs; master->setup = zynq_qspi_setup; master->set_cs = zynq_qspi_chipselect; master->transfer_one = zynq_qspi_start_transfer; master->prepare_transfer_hardware = zynq_prepare_transfer_hardware; master->unprepare_transfer_hardware = zynq_unprepare_transfer_hardware; master->flags = SPI_MASTER_QUAD_MODE; master->max_speed_hz = clk_get_rate(xqspi->refclk) / 2; master->bits_per_word_mask = SPI_BPW_MASK(8); master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_RX_DUAL | SPI_RX_QUAD | SPI_TX_DUAL | SPI_TX_QUAD; ret = spi_register_master(master); if (ret) { dev_err(&pdev->dev, "spi_register_master failed\n"); goto clk_dis_all; } return ret; clk_dis_all: clk_disable_unprepare(xqspi->refclk); clk_dis_pclk: clk_disable_unprepare(xqspi->pclk); remove_master: spi_master_put(master); return ret; }