Beispiel #1
0
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;
}
Beispiel #2
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;
}
Beispiel #3
0
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;
}
Beispiel #4
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;
}