diff options
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/ata/Kconfig | 11 | ||||
| -rw-r--r-- | drivers/ata/Makefile | 1 | ||||
| -rw-r--r-- | drivers/ata/ahci_mvebu.c | 58 | ||||
| -rw-r--r-- | drivers/mmc/ftsdc010_mci.c | 2 | ||||
| -rw-r--r-- | drivers/mtd/Makefile | 1 | ||||
| -rw-r--r-- | drivers/mtd/ftsmc020.c | 37 | ||||
| -rw-r--r-- | drivers/mtd/spi/spi_flash.c | 11 | ||||
| -rw-r--r-- | drivers/mtd/spi/spi_flash_ids.c | 6 | ||||
| -rw-r--r-- | drivers/mtd/ubi/fastmap-wl.c | 29 | ||||
| -rw-r--r-- | drivers/net/ftmac100.c | 14 | ||||
| -rw-r--r-- | drivers/pinctrl/mvebu/pinctrl-mvebu.c | 67 | ||||
| -rw-r--r-- | drivers/spi/atcspi200_spi.c | 10 | ||||
| -rw-r--r-- | drivers/spi/fsl_qspi.c | 2 | ||||
| -rw-r--r-- | drivers/spi/lpc32xx_ssp.c | 2 | ||||
| -rw-r--r-- | drivers/spi/stm32_qspi.c | 91 | 
15 files changed, 248 insertions, 94 deletions
| diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index 86ec628104b..49a056e9416 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig @@ -99,4 +99,15 @@ config SATA_SIL3114  	help  	  Enable this driver to support the SIL3114 SATA controllers. +config AHCI_MVEBU +	bool "Marvell EBU AHCI SATA support" +	depends on ARCH_MVEBU +	depends on AHCI +	select SCSI_AHCI +	select DM_SCSI +	help +	  This option enables support for the Marvell EBU SoC's +	  onboard AHCI SATA. + +	  If unsure, say N.  endmenu diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile index 02f02c8e8dd..10bed53bb3f 100644 --- a/drivers/ata/Makefile +++ b/drivers/ata/Makefile @@ -17,3 +17,4 @@ obj-$(CONFIG_SATA_MV) += sata_mv.o  obj-$(CONFIG_SATA_SIL3114) += sata_sil3114.o  obj-$(CONFIG_SATA_SIL) += sata_sil.o  obj-$(CONFIG_SANDBOX) += sata_sandbox.o +obj-$(CONFIG_AHCI_MVEBU) += ahci_mvebu.o diff --git a/drivers/ata/ahci_mvebu.c b/drivers/ata/ahci_mvebu.c new file mode 100644 index 00000000000..6e3f17ee276 --- /dev/null +++ b/drivers/ata/ahci_mvebu.c @@ -0,0 +1,58 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2016 Stefan Roese <sr@denx.de> + */ + +#include <common.h> +#include <ahci.h> +#include <dm.h> + +/* + * Dummy implementation that can be overwritten by a board + * specific function + */ +__weak int board_ahci_enable(void) +{ +	return 0; +} + +static int mvebu_ahci_bind(struct udevice *dev) +{ +	struct udevice *scsi_dev; +	int ret; + +	ret = ahci_bind_scsi(dev, &scsi_dev); +	if (ret) { +		debug("%s: Failed to bind (err=%d\n)", __func__, ret); +		return ret; +	} + +	return 0; +} + +static int mvebu_ahci_probe(struct udevice *dev) +{ +	/* +	 * Board specific SATA / AHCI enable code, e.g. enable the +	 * AHCI power or deassert reset +	 */ +	board_ahci_enable(); + +	ahci_probe_scsi(dev, (ulong)devfdt_get_addr_ptr(dev)); + +	return 0; +} + +static const struct udevice_id mvebu_ahci_ids[] = { +	{ .compatible = "marvell,armada-3700-ahci" }, +	{ .compatible = "marvell,armada-8k-ahci" }, +	{ } +}; + +U_BOOT_DRIVER(ahci_mvebu_drv) = { +	.name		= "ahci_mvebu", +	.id		= UCLASS_AHCI, +	.of_match	= mvebu_ahci_ids, +	.bind		= mvebu_ahci_bind, +	.probe		= mvebu_ahci_probe, +}; diff --git a/drivers/mmc/ftsdc010_mci.c b/drivers/mmc/ftsdc010_mci.c index 00209e33889..9c15eb36d64 100644 --- a/drivers/mmc/ftsdc010_mci.c +++ b/drivers/mmc/ftsdc010_mci.c @@ -463,7 +463,7 @@ int ftsdc010_mmc_bind(struct udevice *dev)  }  static const struct udevice_id ftsdc010_mmc_ids[] = { -	{ .compatible = "andestech,atsdc010" }, +	{ .compatible = "andestech,atfsdc010" },  	{ }  }; diff --git a/drivers/mtd/Makefile b/drivers/mtd/Makefile index eb593c90d75..9cec06510c3 100644 --- a/drivers/mtd/Makefile +++ b/drivers/mtd/Makefile @@ -12,7 +12,6 @@ obj-$(CONFIG_MTD_CONCAT) += mtdconcat.o  obj-$(CONFIG_ALTERA_QSPI) += altera_qspi.o  obj-$(CONFIG_FLASH_CFI_DRIVER) += cfi_flash.o  obj-$(CONFIG_FLASH_CFI_MTD) += cfi_mtd.o -obj-$(CONFIG_FTSMC020) += ftsmc020.o  obj-$(CONFIG_FLASH_CFI_LEGACY) += jedec_flash.o  obj-$(CONFIG_MW_EEPROM) += mw_eeprom.o  obj-$(CONFIG_FLASH_PIC32) += pic32_flash.o diff --git a/drivers/mtd/ftsmc020.c b/drivers/mtd/ftsmc020.c deleted file mode 100644 index 41cdd0e59b7..00000000000 --- a/drivers/mtd/ftsmc020.c +++ /dev/null @@ -1,37 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * (C) Copyright 2009 Faraday Technology - * Po-Yu Chuang <ratbert@faraday-tech.com> - */ - -#include <config.h> -#include <common.h> -#include <asm/io.h> -#include <faraday/ftsmc020.h> - -struct ftsmc020_config { -	unsigned int	config; -	unsigned int	timing; -}; - -static void ftsmc020_setup_bank(unsigned int bank, struct ftsmc020_config *cfg) -{ -	struct ftsmc020 *smc = (struct ftsmc020 *)CONFIG_FTSMC020_BASE; - -	if (bank > 3) { -		printf("bank # %u invalid\n", bank); -		return; -	} - -	writel(cfg->config, &smc->bank[bank].cr); -	writel(cfg->timing, &smc->bank[bank].tpr); -} - -void ftsmc020_init(void) -{ -	struct ftsmc020_config config[] = CONFIG_SYS_FTSMC020_CONFIGS; -	int i; - -	for (i = 0; i < ARRAY_SIZE(config); i++) -		ftsmc020_setup_bank(i, &config[i]); -} diff --git a/drivers/mtd/spi/spi_flash.c b/drivers/mtd/spi/spi_flash.c index 2911729b289..0ed23175547 100644 --- a/drivers/mtd/spi/spi_flash.c +++ b/drivers/mtd/spi/spi_flash.c @@ -1202,14 +1202,15 @@ int spi_flash_scan(struct spi_flash *flash)  	flash->shift = (flash->dual_flash & SF_DUAL_PARALLEL_FLASH) ? 1 : 0;  	flash->page_size = info->page_size;  	/* -	 * The Spansion S25FL032P and S25FL064P have 256b pages, yet use the -	 * 0x4d00 Extended JEDEC code. The rest of the Spansion flashes with -	 * the 0x4d00 Extended JEDEC code have 512b pages. All of the others -	 * have 256b pages. +	 * The Spansion S25FS512S, S25FL032P and S25FL064P have 256b pages, +	 * yet use the 0x4d00 Extended JEDEC code. The rest of the Spansion +	 * flashes with the 0x4d00 Extended JEDEC code have 512b pages. +	 * All of the others have 256b pages.  	 */  	if (JEDEC_EXT(info) == 0x4d00) {  		if ((JEDEC_ID(info) != 0x0215) && -		    (JEDEC_ID(info) != 0x0216)) +		    (JEDEC_ID(info) != 0x0216) && +		    (JEDEC_ID(info) != 0x0220))  			flash->page_size = 512;  	}  	flash->page_size <<= flash->shift; diff --git a/drivers/mtd/spi/spi_flash_ids.c b/drivers/mtd/spi/spi_flash_ids.c index 41879d662a8..5d146e36c64 100644 --- a/drivers/mtd/spi/spi_flash_ids.c +++ b/drivers/mtd/spi/spi_flash_ids.c @@ -71,6 +71,9 @@ const struct spi_flash_info spi_flash_ids[] = {  	{"is25lp064",	   INFO(0x9d6017, 0x0, 64 * 1024,   128, 0) },  	{"is25lp128",	   INFO(0x9d6018, 0x0, 64 * 1024,   256, 0) },  	{"is25lp256",	   INFO(0x9d6019, 0x0, 64 * 1024,   512, 0) }, +	{"is25wp032",	   INFO(0x9d7016, 0x0, 64 * 1024,    64, RD_FULL | SECT_4K) }, +	{"is25wp064",	   INFO(0x9d7017, 0x0, 64 * 1024,   128, RD_FULL | SECT_4K) }, +	{"is25wp128",	   INFO(0x9d7018, 0x0, 64 * 1024,   256, RD_FULL | SECT_4K) },  #endif  #ifdef CONFIG_SPI_FLASH_MACRONIX	/* MACRONIX */  	{"mx25l2006e",	   INFO(0xc22012, 0x0, 64 * 1024,     4, 0) }, @@ -85,6 +88,7 @@ const struct spi_flash_info spi_flash_ids[] = {  	{"mx25u6435f",	   INFO(0xc22537, 0x0, 64 * 1024,   128, RD_FULL | WR_QPP) },  	{"mx25l12855e",	   INFO(0xc22618, 0x0, 64 * 1024,   256, RD_FULL | WR_QPP) },  	{"mx25u1635e",     INFO(0xc22535, 0x0, 64 * 1024,  32, SECT_4K) }, +	{"mx25u25635f",    INFO(0xc22539, 0x0, 64 * 1024,   512, RD_FULL | WR_QPP) },  	{"mx66u51235f",    INFO(0xc2253a, 0x0, 64 * 1024,  1024, RD_FULL | WR_QPP) },  	{"mx66l1g45g",     INFO(0xc2201b, 0x0, 64 * 1024,  2048, RD_FULL | WR_QPP) },  #endif @@ -174,6 +178,7 @@ const struct spi_flash_info spi_flash_ids[] = {  	{"w25q32dw",	   INFO(0xef6016, 0x0,	64 * 1024,    64, RD_FULL | WR_QPP | SECT_4K) },  	{"w25q64dw",	   INFO(0xef6017, 0x0,	64 * 1024,   128, RD_FULL | WR_QPP | SECT_4K) },  	{"w25q128fw",	   INFO(0xef6018, 0x0,	64 * 1024,   256, RD_FULL | WR_QPP | SECT_4K) }, +	{"w25q256fw",	   INFO(0xef6019, 0x0,	64 * 1024,   512, RD_FULL | WR_QPP | SECT_4K) },  #endif  	{},	/* Empty entry to terminate the list */  	/* @@ -188,5 +193,6 @@ const struct spi_flash_info spi_flash_ids[] = {  	 * (w25q32dw, w25q32fv_qpi)  	 * (w25q64dw, w25q64fv_qpi)  	 * (w25q128fw, w25q128fv_qpi) +	 * (w25q256fw, w25q256fv_qpi)  	 */  }; diff --git a/drivers/mtd/ubi/fastmap-wl.c b/drivers/mtd/ubi/fastmap-wl.c index 675e487ae8c..4cb1377c425 100644 --- a/drivers/mtd/ubi/fastmap-wl.c +++ b/drivers/mtd/ubi/fastmap-wl.c @@ -170,6 +170,30 @@ void ubi_refill_pools(struct ubi_device *ubi)  }  /** + * produce_free_peb - produce a free physical eraseblock. + * @ubi: UBI device description object + * + * This function tries to make a free PEB by means of synchronous execution of + * pending works. This may be needed if, for example the background thread is + * disabled. Returns zero in case of success and a negative error code in case + * of failure. + */ +static int produce_free_peb(struct ubi_device *ubi) +{ +	int err; + +	while (!ubi->free.rb_node && ubi->works_count) { +		dbg_wl("do one work synchronously"); +		err = do_work(ubi); + +		if (err) +			return err; +	} + +	return 0; +} + +/**   * ubi_wl_get_peb - get a physical eraseblock.   * @ubi: UBI device description object   * @@ -211,6 +235,11 @@ again:  		}  		retried = 1;  		up_read(&ubi->fm_eba_sem); +		ret = produce_free_peb(ubi); +		if (ret < 0) { +			down_read(&ubi->fm_eba_sem); +			goto out; +		}  		goto again;  	} diff --git a/drivers/net/ftmac100.c b/drivers/net/ftmac100.c index 6c8474893d2..c08889c4b11 100644 --- a/drivers/net/ftmac100.c +++ b/drivers/net/ftmac100.c @@ -104,18 +104,18 @@ static int _ftmac100_init(struct ftmac100_data *priv, unsigned char enetaddr[6])  	for (i = 0; i < PKTBUFSRX; i++) {  		/* RXBUF_BADR */ -		rxdes[i].rxdes2 = (unsigned int)net_rx_packets[i]; +		rxdes[i].rxdes2 = (unsigned int)(unsigned long)net_rx_packets[i];  		rxdes[i].rxdes1 |= FTMAC100_RXDES1_RXBUF_SIZE (PKTSIZE_ALIGN);  		rxdes[i].rxdes0 = FTMAC100_RXDES0_RXDMA_OWN;  	}  	/* transmit ring */ -	writel ((unsigned int)txdes, &ftmac100->txr_badr); +	writel ((unsigned long)txdes, &ftmac100->txr_badr);  	/* receive ring */ -	writel ((unsigned int)rxdes, &ftmac100->rxr_badr); +	writel ((unsigned long)rxdes, &ftmac100->rxr_badr);  	/* poll receive descriptor automatically */ @@ -192,14 +192,14 @@ static int _ftmac100_send(struct ftmac100_data *priv, void *packet, int length)  		return -1;  	} -	debug ("%s(%x, %x)\n", __func__, (int)packet, length); +	debug ("%s(%lx, %x)\n", __func__, (unsigned long)packet, length);  	length = (length < ETH_ZLEN) ? ETH_ZLEN : length;  	/* initiate a transmit sequence */ -	flush_dcache_range((u32)packet,(u32)packet+length); -	curr_des->txdes2 = (unsigned int)packet;	/* TXBUF_BADR */ +	flush_dcache_range((unsigned long)packet,(unsigned long)packet+length); +	curr_des->txdes2 = (unsigned int)(unsigned long)packet;	/* TXBUF_BADR */  	curr_des->txdes1 &= FTMAC100_TXDES1_EDOTR;  	curr_des->txdes1 |= FTMAC100_TXDES1_FTS | @@ -343,7 +343,7 @@ static int ftmac100_recv(struct udevice *dev, int flags, uchar **packetp)  	int len;  	len = __ftmac100_recv(priv);  	if (len) -		*packetp = (void *)curr_des->rxdes2; +		*packetp = (uchar *)(unsigned long)curr_des->rxdes2;  	return len ? len : -EAGAIN;  } diff --git a/drivers/pinctrl/mvebu/pinctrl-mvebu.c b/drivers/pinctrl/mvebu/pinctrl-mvebu.c index d4f2970a692..0b9c9e1d6a9 100644 --- a/drivers/pinctrl/mvebu/pinctrl-mvebu.c +++ b/drivers/pinctrl/mvebu/pinctrl-mvebu.c @@ -16,8 +16,48 @@  #include <asm/arch-armada8k/soc-info.h>  #include "pinctrl-mvebu.h" +#define AP_EMMC_PHY_CTRL_REG		0x100 +#define CP_EMMC_PHY_CTRL_REG		0x424 +#define EMMC_PHY_CTRL_SDPHY_EN		BIT(0) + +#define AP806_EMMC_CLK_PIN_ID		0 +#define AP806_EMMC_CLK_FUNC		0x1 +#define CP110_EMMC_CLK_PIN_ID		56 +#define CP110_EMMC_CLK_FUNC		0xe +  DECLARE_GLOBAL_DATA_PTR; +/* mvebu_pinctl_emmc_set_mux: configure sd/mmc PHY mux + * To enable SDIO/eMMC in Armada-APN806/CP110, need to configure PHY mux. + * eMMC/SD PHY register responsible for muxing between MPPs and SD/eMMC + * controller: + * - Bit0 enabled SDIO/eMMC PHY is used as a MPP muxltiplexer, + * - Bit0 disabled SDIO/eMMC PHY is connected to SDIO/eMMC controller + * If pin function is set to eMMC/SD, then configure the eMMC/SD PHY + * muxltiplexer register to be on SDIO/eMMC controller + */ +void mvebu_pinctl_emmc_set_mux(struct udevice *dev, u32 pin, u32 func) +{ +	const void *blob = gd->fdt_blob; +	int node = dev_of_offset(dev); +	struct mvebu_pinctrl_priv *priv = dev_get_priv(dev); + +	if (!fdt_node_check_compatible(blob, node, "marvell,ap806-pinctrl")) { +		if ((pin == AP806_EMMC_CLK_PIN_ID) && +		    (func == AP806_EMMC_CLK_FUNC)) { +			clrbits_le32(priv->base_reg + AP_EMMC_PHY_CTRL_REG, +				     EMMC_PHY_CTRL_SDPHY_EN); +		} +	} else if (!fdt_node_check_compatible(blob, node, +					"marvell,armada-8k-cpm-pinctrl")) { +		if ((pin == CP110_EMMC_CLK_PIN_ID) && +		    (func == CP110_EMMC_CLK_FUNC)) { +			clrbits_le32(priv->base_reg + CP_EMMC_PHY_CTRL_REG, +				     EMMC_PHY_CTRL_SDPHY_EN); +		} +	} +} +  /*   * mvebu_pinctrl_set_state: configure pin functions.   * @dev: the pinctrl device to be configured. @@ -47,9 +87,16 @@ int mvebu_pinctrl_set_state(struct udevice *dev, struct udevice *config)  	function = fdtdec_get_int(blob, node, "marvell,function", 0xff); +	/* +	 * Check if setup of PHY mux is needed for this pins group. +	 * Only the first pin id in array is tested, all the rest use the same +	 * pin function. +	 */ +	mvebu_pinctl_emmc_set_mux(dev, pin_arr[0], function); +  	for (i = 0; i < pin_count; i++) { -	int reg_offset; -	int field_offset; +		int reg_offset; +		int field_offset;  		int pin = pin_arr[i];  		if (function > priv->max_func) { @@ -96,6 +143,14 @@ static int mvebu_pinctrl_set_state_all(struct udevice *dev,  		return -EINVAL;  	} +	/* Check if setup of PHY mux is needed for this pins group. */ +	if (priv->pin_cnt < CP110_EMMC_CLK_PIN_ID) +		mvebu_pinctl_emmc_set_mux(dev, AP806_EMMC_CLK_PIN_ID, +					  func_arr[AP806_EMMC_CLK_PIN_ID]); +	else +		mvebu_pinctl_emmc_set_mux(dev, CP110_EMMC_CLK_PIN_ID, +					  func_arr[CP110_EMMC_CLK_PIN_ID]); +  	for (pin = 0; pin < priv->pin_cnt; pin++) {  		int reg_offset;  		int field_offset; @@ -161,10 +216,10 @@ static struct pinctrl_ops mvebu_pinctrl_ops = {  static const struct udevice_id mvebu_pinctrl_ids[] = {  	{ .compatible = "marvell,mvebu-pinctrl" }, -	{ .compatible = "marvell,armada-ap806-pinctrl" }, -	{ .compatible = "marvell,a70x0-pinctrl" }, -	{ .compatible = "marvell,a80x0-cp0-pinctrl" }, -	{ .compatible = "marvell,a80x0-cp1-pinctrl" }, +	{ .compatible = "marvell,ap806-pinctrl" }, +	{ .compatible = "marvell,armada-7k-pinctrl" }, +	{ .compatible = "marvell,armada-8k-cpm-pinctrl" }, +	{ .compatible = "marvell,armada-8k-cps-pinctrl" },  	{ }  }; diff --git a/drivers/spi/atcspi200_spi.c b/drivers/spi/atcspi200_spi.c index 2c1d36ee673..af96c6d21e5 100644 --- a/drivers/spi/atcspi200_spi.c +++ b/drivers/spi/atcspi200_spi.c @@ -197,7 +197,7 @@ static int __atcspi200_spi_xfer(struct nds_spi_slave *ns,  		int num_bytes;  		u8 *cmd_buf = ns->cmd_buf;  		size_t cmd_len = ns->cmd_len; -		size_t data_len = bitlen / 8; +		unsigned long data_len = bitlen / 8;  		int rf_cnt;  		int ret = 0; @@ -229,13 +229,15 @@ static int __atcspi200_spi_xfer(struct nds_spi_slave *ns,  			__atcspi200_spi_start(ns);  			break;  		} -		debug("spi_xfer: data_out %08X(%p) data_in %08X(%p) data_len %u\n", -		      *(uint *)data_out, data_out, *(uint *)data_in, data_in, data_len); +		if (data_out) +			debug("spi_xfer: data_out %08X(%p) data_in %08X(%p) data_len %lu\n", +			      *(uint *)data_out, data_out, *(uint *)data_in, +			      data_in, data_len);  		num_chunks = DIV_ROUND_UP(data_len, max_tran_len);  		din = data_in;  		dout = data_out;  		while (num_chunks--) { -			tran_len = min(data_len, (size_t)max_tran_len); +			tran_len = min((size_t)data_len, (size_t)max_tran_len);  			ns->tran_len = tran_len;  			num_blks = DIV_ROUND_UP(tran_len , CHUNK_SIZE);  			num_bytes = (tran_len) % CHUNK_SIZE; diff --git a/drivers/spi/fsl_qspi.c b/drivers/spi/fsl_qspi.c index 36842494847..197f41f9db0 100644 --- a/drivers/spi/fsl_qspi.c +++ b/drivers/spi/fsl_qspi.c @@ -407,7 +407,7 @@ static inline void qspi_ahb_read(struct fsl_qspi_priv *priv, u8 *rxbuf, int len)  {  	struct fsl_qspi_regs *regs = priv->regs;  	u32 mcr_reg; -	void *rx_addr = NULL; +	void *rx_addr;  	mcr_reg = qspi_read32(priv->flags, ®s->mcr); diff --git a/drivers/spi/lpc32xx_ssp.c b/drivers/spi/lpc32xx_ssp.c index e6c876da07b..ce12eee6571 100644 --- a/drivers/spi/lpc32xx_ssp.c +++ b/drivers/spi/lpc32xx_ssp.c @@ -129,7 +129,7 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen,  		int status = readl(&lslave->regs->sr);  		if ((idx_out < bytelen) && (status & SSP_SR_TNF))  			writel(((u8 *)dout)[idx_out++], &lslave->regs->data); -		if ((idx_in < bytelen) && (status & status & SSP_SR_RNE)) +		if ((idx_in < bytelen) && (status & SSP_SR_RNE))  			((u8 *)din)[idx_in++] = readl(&lslave->regs->data);  		if (get_timer(start_time) >= CONFIG_LPC32XX_SSP_TIMEOUT)  			return -1; diff --git a/drivers/spi/stm32_qspi.c b/drivers/spi/stm32_qspi.c index 7d180128077..f6cc3533632 100644 --- a/drivers/spi/stm32_qspi.c +++ b/drivers/spi/stm32_qspi.c @@ -8,16 +8,16 @@   */  #include <common.h> +#include <clk.h> +#include <dm.h> +#include <errno.h>  #include <malloc.h> +#include <reset.h>  #include <spi.h>  #include <spi_flash.h>  #include <asm/io.h> -#include <dm.h> -#include <errno.h>  #include <asm/arch/stm32.h> -#include <clk.h> - -DECLARE_GLOBAL_DATA_PTR; +#include <linux/ioport.h>  struct stm32_qspi_regs {  	u32 cr;		/* 0x00 */ @@ -155,6 +155,8 @@ enum STM32_QSPI_CCR_FMODE {  /* default SCK frequency, unit: HZ */  #define STM32_QSPI_DEFAULT_SCK_FREQ 108000000 +#define STM32_MAX_NORCHIP 2 +  struct stm32_qspi_platdata {  	u32 base;  	u32 memory_map; @@ -206,11 +208,18 @@ static void _stm32_qspi_wait_for_ftf(struct stm32_qspi_priv *priv)  static void _stm32_qspi_set_flash_size(struct stm32_qspi_priv *priv, u32 size)  {  	u32 fsize = fls(size) - 1; +  	clrsetbits_le32(&priv->regs->dcr,  			STM32_QSPI_DCR_FSIZE_MASK << STM32_QSPI_DCR_FSIZE_SHIFT,  			fsize << STM32_QSPI_DCR_FSIZE_SHIFT);  } +static void _stm32_qspi_set_cs(struct stm32_qspi_priv *priv, unsigned int cs) +{ +	clrsetbits_le32(&priv->regs->cr, STM32_QSPI_CR_FSEL, +			cs ? STM32_QSPI_CR_FSEL : 0); +} +  static unsigned int _stm32_qspi_gen_ccr(struct stm32_qspi_priv *priv)  {  	unsigned int ccr_reg = 0; @@ -255,13 +264,15 @@ static unsigned int _stm32_qspi_gen_ccr(struct stm32_qspi_priv *priv)  }  static void _stm32_qspi_enable_mmap(struct stm32_qspi_priv *priv, -		struct spi_flash *flash) +				    struct spi_flash *flash)  { +	unsigned int ccr_reg; +  	priv->command = flash->read_cmd | CMD_HAS_ADR | CMD_HAS_DATA  			| CMD_HAS_DUMMY;  	priv->dummycycles = flash->dummy_byte * 8; -	unsigned int ccr_reg = _stm32_qspi_gen_ccr(priv); +	ccr_reg = _stm32_qspi_gen_ccr(priv);  	ccr_reg |= (STM32_QSPI_CCR_MEM_MAP << STM32_QSPI_CCR_FMODE_SHIFT);  	_stm32_qspi_wait_for_not_busy(priv); @@ -291,10 +302,12 @@ static void _stm32_qspi_start_xfer(struct stm32_qspi_priv *priv, u32 cr_reg)  }  static int _stm32_qspi_xfer(struct stm32_qspi_priv *priv, -		struct spi_flash *flash, unsigned int bitlen, -		const u8 *dout, u8 *din, unsigned long flags) +			    struct spi_flash *flash, unsigned int bitlen, +			    const u8 *dout, u8 *din, unsigned long flags)  {  	unsigned int words = bitlen / 8; +	u32 ccr_reg; +	int i;  	if (flags & SPI_XFER_MMAP) {  		_stm32_qspi_enable_mmap(priv, flash); @@ -346,7 +359,7 @@ static int _stm32_qspi_xfer(struct stm32_qspi_priv *priv,  		}  		if (flags & SPI_XFER_END) { -			u32 ccr_reg = _stm32_qspi_gen_ccr(priv); +			ccr_reg = _stm32_qspi_gen_ccr(priv);  			ccr_reg |= STM32_QSPI_CCR_IND_WRITE  					<< STM32_QSPI_CCR_FMODE_SHIFT; @@ -365,7 +378,7 @@ static int _stm32_qspi_xfer(struct stm32_qspi_priv *priv,  				debug("%s: words:%d data:", __func__, words); -				int i = 0; +				i = 0;  				while (words > i) {  					writeb(dout[i], &priv->regs->dr);  					debug("%02x ", dout[i]); @@ -379,7 +392,7 @@ static int _stm32_qspi_xfer(struct stm32_qspi_priv *priv,  			}  		}  	} else if (din) { -		u32 ccr_reg = _stm32_qspi_gen_ccr(priv); +		ccr_reg = _stm32_qspi_gen_ccr(priv);  		ccr_reg |= STM32_QSPI_CCR_IND_READ  				<< STM32_QSPI_CCR_FMODE_SHIFT; @@ -394,7 +407,7 @@ static int _stm32_qspi_xfer(struct stm32_qspi_priv *priv,  		debug("%s: data:", __func__); -		int i = 0; +		i = 0;  		while (words > i) {  			din[i] = readb(&priv->regs->dr);  			debug("%02x ", din[i]); @@ -408,27 +421,23 @@ static int _stm32_qspi_xfer(struct stm32_qspi_priv *priv,  static int stm32_qspi_ofdata_to_platdata(struct udevice *bus)  { -	struct fdt_resource res_regs, res_mem; +	struct resource res_regs, res_mem;  	struct stm32_qspi_platdata *plat = bus->platdata; -	const void *blob = gd->fdt_blob; -	int node = dev_of_offset(bus);  	int ret; -	ret = fdt_get_named_resource(blob, node, "reg", "reg-names", -				     "QuadSPI", &res_regs); +	ret = dev_read_resource_byname(bus, "qspi", &res_regs);  	if (ret) {  		debug("Error: can't get regs base addresses(ret = %d)!\n", ret);  		return -ENOMEM;  	} -	ret = fdt_get_named_resource(blob, node, "reg", "reg-names", -				     "QuadSPI-memory", &res_mem); +	ret = dev_read_resource_byname(bus, "qspi_mm", &res_mem);  	if (ret) {  		debug("Error: can't get mmap base address(ret = %d)!\n", ret);  		return -ENOMEM;  	} -	plat->max_hz = fdtdec_get_int(blob, node, "spi-max-frequency", -					STM32_QSPI_DEFAULT_SCK_FREQ); +	plat->max_hz = dev_read_u32_default(bus, "spi-max-frequency", +					    STM32_QSPI_DEFAULT_SCK_FREQ);  	plat->base = res_regs.start;  	plat->memory_map = res_mem.start; @@ -448,6 +457,9 @@ static int stm32_qspi_probe(struct udevice *bus)  	struct stm32_qspi_platdata *plat = dev_get_platdata(bus);  	struct stm32_qspi_priv *priv = dev_get_priv(bus);  	struct dm_spi_bus *dm_spi_bus; +	struct clk clk; +	struct reset_ctl reset_ctl; +	int ret;  	dm_spi_bus = bus->uclass_priv; @@ -457,9 +469,6 @@ static int stm32_qspi_probe(struct udevice *bus)  	priv->max_hz = plat->max_hz; -#ifdef CONFIG_CLK -	int ret; -	struct clk clk;  	ret = clk_get_by_index(bus, 0, &clk);  	if (ret < 0)  		return ret; @@ -477,7 +486,19 @@ static int stm32_qspi_probe(struct udevice *bus)  		return priv->clock_rate;  	} -#endif +	ret = reset_get_by_index(bus, 0, &reset_ctl); +	if (ret) { +		if (ret != -ENOENT) { +			dev_err(bus, "failed to get reset\n"); +			clk_disable(&clk); +			return ret; +		} +	} else { +		/* Reset QSPI controller */ +		reset_assert(&reset_ctl); +		udelay(2); +		reset_deassert(&reset_ctl); +	}  	setbits_le32(&priv->regs->cr, STM32_QSPI_CR_SSHIFT); @@ -494,10 +515,17 @@ static int stm32_qspi_claim_bus(struct udevice *dev)  	struct stm32_qspi_priv *priv;  	struct udevice *bus;  	struct spi_flash *flash; +	struct dm_spi_slave_platdata *slave_plat;  	bus = dev->parent;  	priv = dev_get_priv(bus);  	flash = dev_get_uclass_priv(dev); +	slave_plat = dev_get_parent_platdata(dev); + +	if (slave_plat->cs >= STM32_MAX_NORCHIP) +		return -ENODEV; + +	_stm32_qspi_set_cs(priv, slave_plat->cs);  	_stm32_qspi_set_flash_size(priv, flash->size); @@ -520,7 +548,7 @@ static int stm32_qspi_release_bus(struct udevice *dev)  }  static int stm32_qspi_xfer(struct udevice *dev, unsigned int bitlen, -		const void *dout, void *din, unsigned long flags) +			   const void *dout, void *din, unsigned long flags)  {  	struct stm32_qspi_priv *priv;  	struct udevice *bus; @@ -538,12 +566,13 @@ static int stm32_qspi_set_speed(struct udevice *bus, uint speed)  {  	struct stm32_qspi_platdata *plat = bus->platdata;  	struct stm32_qspi_priv *priv = dev_get_priv(bus); +	u32 qspi_clk = priv->clock_rate; +	u32 prescaler = 255; +	u32 csht;  	if (speed > plat->max_hz)  		speed = plat->max_hz; -	u32 qspi_clk = priv->clock_rate; -	u32 prescaler = 255;  	if (speed > 0) {  		prescaler = DIV_ROUND_UP(qspi_clk, speed) - 1;  		if (prescaler > 255) @@ -552,7 +581,7 @@ static int stm32_qspi_set_speed(struct udevice *bus, uint speed)  			prescaler = 0;  	} -	u32 csht = DIV_ROUND_UP((5 * qspi_clk) / (prescaler + 1), 100000000); +	csht = DIV_ROUND_UP((5 * qspi_clk) / (prescaler + 1), 100000000);  	csht = (csht - 1) & STM32_QSPI_DCR_CSHT_MASK;  	_stm32_qspi_wait_for_not_busy(priv); @@ -562,7 +591,6 @@ static int stm32_qspi_set_speed(struct udevice *bus, uint speed)  			STM32_QSPI_CR_PRESCALER_SHIFT,  			prescaler << STM32_QSPI_CR_PRESCALER_SHIFT); -  	clrsetbits_le32(&priv->regs->dcr,  			STM32_QSPI_DCR_CSHT_MASK << STM32_QSPI_DCR_CSHT_SHIFT,  			csht << STM32_QSPI_DCR_CSHT_SHIFT); @@ -632,6 +660,7 @@ static const struct dm_spi_ops stm32_qspi_ops = {  static const struct udevice_id stm32_qspi_ids[] = {  	{ .compatible = "st,stm32-qspi" }, +	{ .compatible = "st,stm32f469-qspi" },  	{ }  }; | 
