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" }, { } }; |