Skip to content
Snippets Groups Projects
fsl_qspi.c 31.2 KiB
Newer Older
  • Learn to ignore specific revisions
  • 	if (ret) {
    		debug("Error: can't get base addresses (ret = %d)!\n", ret);
    		return -ENOMEM;
    	}
    
    	/* Count flash numbers */
    	fdt_for_each_subnode(blob, subnode, node)
    		++flash_num;
    
    	if (flash_num == 0) {
    		debug("Error: Missing flashes!\n");
    		return -ENODEV;
    	}
    
    	plat->speed_hz = fdtdec_get_int(blob, node, "spi-max-frequency",
    					FSL_QSPI_DEFAULT_SCK_FREQ);
    	plat->num_chipselect = fdtdec_get_int(blob, node, "num-cs",
    					      FSL_QSPI_MAX_CHIPSELECT_NUM);
    
    	plat->reg_base = regs_data[0].addr;
    	plat->amba_base = regs_data[1].addr;
    	plat->amba_total_size = regs_data[1].size;
    	plat->flash_num = flash_num;
    
    	debug("%s: regs=<0x%x> <0x%x, 0x%x>, max-frequency=%d, endianess=%s\n",
    	      __func__,
    	      plat->reg_base,
    	      plat->amba_base,
    	      plat->amba_total_size,
    	      plat->speed_hz,
    	      plat->flags & QSPI_FLAG_REGMAP_ENDIAN_BIG ? "be" : "le"
    	      );
    
    	return 0;
    }
    
    static int fsl_qspi_xfer(struct udevice *dev, unsigned int bitlen,
    		const void *dout, void *din, unsigned long flags)
    {
    	struct fsl_qspi_priv *priv;
    	struct udevice *bus;
    
    	bus = dev->parent;
    	priv = dev_get_priv(bus);
    
    	return qspi_xfer(priv, bitlen, dout, din, flags);
    }
    
    static int fsl_qspi_claim_bus(struct udevice *dev)
    {
    	struct fsl_qspi_priv *priv;
    	struct udevice *bus;
    	struct dm_spi_slave_platdata *slave_plat = dev_get_parent_platdata(dev);
    
    	bus = dev->parent;
    	priv = dev_get_priv(bus);
    
    	priv->cur_amba_base =
    		priv->amba_base[0] + FSL_QSPI_FLASH_SIZE * slave_plat->cs;
    
    	qspi_module_disable(priv, 0);
    
    	return 0;
    }
    
    static int fsl_qspi_release_bus(struct udevice *dev)
    {
    	struct fsl_qspi_priv *priv;
    	struct udevice *bus;
    
    	bus = dev->parent;
    	priv = dev_get_priv(bus);
    
    	qspi_module_disable(priv, 1);
    
    	return 0;
    }
    
    static int fsl_qspi_set_speed(struct udevice *bus, uint speed)
    {
    	/* Nothing to do */
    	return 0;
    }
    
    static int fsl_qspi_set_mode(struct udevice *bus, uint mode)
    {
    	/* Nothing to do */
    	return 0;
    }
    
    static const struct dm_spi_ops fsl_qspi_ops = {
    	.claim_bus	= fsl_qspi_claim_bus,
    	.release_bus	= fsl_qspi_release_bus,
    	.xfer		= fsl_qspi_xfer,
    	.set_speed	= fsl_qspi_set_speed,
    	.set_mode	= fsl_qspi_set_mode,
    };
    
    static const struct udevice_id fsl_qspi_ids[] = {
    	{ .compatible = "fsl,vf610-qspi" },
    	{ .compatible = "fsl,imx6sx-qspi" },
    	{ }
    };
    
    U_BOOT_DRIVER(fsl_qspi) = {
    	.name	= "fsl_qspi",
    	.id	= UCLASS_SPI,
    	.of_match = fsl_qspi_ids,
    	.ops	= &fsl_qspi_ops,
    	.ofdata_to_platdata = fsl_qspi_ofdata_to_platdata,
    	.platdata_auto_alloc_size = sizeof(struct fsl_qspi_platdata),
    	.priv_auto_alloc_size = sizeof(struct fsl_qspi_priv),
    	.probe	= fsl_qspi_probe,
    	.child_pre_probe = fsl_qspi_child_pre_probe,
    };
    #endif