mirror of
				https://github.com/smaeul/u-boot.git
				synced 2025-11-03 21:48:15 +00:00 
			
		
		
		
	Merge git://git.denx.de/u-boot-nds32
This commit is contained in:
		
						commit
						d36a27adbb
					
				@ -69,6 +69,14 @@
 | 
				
			|||||||
		interrupts = <25 4>;
 | 
							interrupts = <25 4>;
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						mmc0: mmc@f0e00000 {
 | 
				
			||||||
 | 
							compatible = "andestech,atsdc010";
 | 
				
			||||||
 | 
							max-frequency = <100000000>;
 | 
				
			||||||
 | 
							fifo-depth = <0x10>;
 | 
				
			||||||
 | 
							reg = <0xf0e00000 0x1000>;
 | 
				
			||||||
 | 
							interrupts = <17 4>;
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	nor@0,0 {
 | 
						nor@0,0 {
 | 
				
			||||||
		compatible = "cfi-flash";
 | 
							compatible = "cfi-flash";
 | 
				
			||||||
		reg = <0x88000000 0x1000>;
 | 
							reg = <0x88000000 0x1000>;
 | 
				
			||||||
 | 
				
			|||||||
@ -60,4 +60,12 @@
 | 
				
			|||||||
		reg = <0x90900000 0x1000>;
 | 
							reg = <0x90900000 0x1000>;
 | 
				
			||||||
		interrupts = <25 4>;
 | 
							interrupts = <25 4>;
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						mmc0: mmc@98e00000 {
 | 
				
			||||||
 | 
							compatible = "andestech,atsdc010";
 | 
				
			||||||
 | 
							max-frequency = <30000000>;
 | 
				
			||||||
 | 
							fifo-depth = <0x10>;
 | 
				
			||||||
 | 
							reg = <0x98e00000 0x1000>;
 | 
				
			||||||
 | 
							interrupts = <5 4>;
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
				
			|||||||
@ -85,8 +85,10 @@ ulong board_flash_get_legacy(ulong base, int banknum, flash_info_t *info)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
int board_mmc_init(bd_t *bis)
 | 
					int board_mmc_init(bd_t *bis)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					#ifndef CONFIG_DM_MMC
 | 
				
			||||||
#ifdef CONFIG_FTSDC010
 | 
					#ifdef CONFIG_FTSDC010
 | 
				
			||||||
	ftsdc010_mmc_init(0);
 | 
						ftsdc010_mmc_init(0);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -27,12 +27,15 @@ CONFIG_CFI_FLASH=y
 | 
				
			|||||||
CONFIG_DM_SPI_FLASH=y
 | 
					CONFIG_DM_SPI_FLASH=y
 | 
				
			||||||
CONFIG_SPI_FLASH=y
 | 
					CONFIG_SPI_FLASH=y
 | 
				
			||||||
CONFIG_SPI_FLASH_MACRONIX=y
 | 
					CONFIG_SPI_FLASH_MACRONIX=y
 | 
				
			||||||
 | 
					CONFIG_DM_MMC=y
 | 
				
			||||||
 | 
					CONFIG_MMC_NDS32=y
 | 
				
			||||||
 | 
					CONFIG_FTSDC010=y
 | 
				
			||||||
CONFIG_DM_ETH=y
 | 
					CONFIG_DM_ETH=y
 | 
				
			||||||
CONFIG_FTMAC100=y
 | 
					CONFIG_FTMAC100=y
 | 
				
			||||||
CONFIG_BAUDRATE=38400
 | 
					CONFIG_BAUDRATE=38400
 | 
				
			||||||
CONFIG_DM_SERIAL=y
 | 
					CONFIG_DM_SERIAL=y
 | 
				
			||||||
CONFIG_SYS_NS16550=y
 | 
					CONFIG_SYS_NS16550=y
 | 
				
			||||||
CONFIG_DM_SPI=y
 | 
					CONFIG_DM_SPI=y
 | 
				
			||||||
CONFIG_NDS_AE3XX_SPI=y
 | 
					CONFIG_ATCSPI200_SPI=y
 | 
				
			||||||
CONFIG_TIMER=y
 | 
					CONFIG_TIMER=y
 | 
				
			||||||
CONFIG_AE3XX_TIMER=y
 | 
					CONFIG_ATCPIT100_TIMER=y
 | 
				
			||||||
 | 
				
			|||||||
@ -18,6 +18,9 @@ CONFIG_ENV_IS_IN_FLASH=y
 | 
				
			|||||||
CONFIG_NET_RANDOM_ETHADDR=y
 | 
					CONFIG_NET_RANDOM_ETHADDR=y
 | 
				
			||||||
CONFIG_DM=y
 | 
					CONFIG_DM=y
 | 
				
			||||||
CONFIG_MMC=y
 | 
					CONFIG_MMC=y
 | 
				
			||||||
 | 
					CONFIG_DM_MMC=y
 | 
				
			||||||
 | 
					CONFIG_MMC_NDS32=y
 | 
				
			||||||
 | 
					CONFIG_FTSDC010=y
 | 
				
			||||||
CONFIG_MTD_NOR_FLASH=y
 | 
					CONFIG_MTD_NOR_FLASH=y
 | 
				
			||||||
CONFIG_DM_ETH=y
 | 
					CONFIG_DM_ETH=y
 | 
				
			||||||
CONFIG_FTMAC100=y
 | 
					CONFIG_FTMAC100=y
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										37
									
								
								doc/device-tree-bindings/spi/spi-atcspi200.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								doc/device-tree-bindings/spi/spi-atcspi200.txt
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,37 @@
 | 
				
			|||||||
 | 
					Andestech ATCSPI200 SPI controller Device Tree Bindings
 | 
				
			||||||
 | 
					-------------------------------------------------------
 | 
				
			||||||
 | 
					ATCSPI200 is a Serial Peripheral Interface (SPI) controller
 | 
				
			||||||
 | 
					which serves as a SPI master or a SPI slave.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					It is often be embedded in AE3XX and AE250 platforms.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Required properties:
 | 
				
			||||||
 | 
					- compatible: has to be "andestech,atcspi200".
 | 
				
			||||||
 | 
					- reg: Base address and size of the controllers memory area.
 | 
				
			||||||
 | 
					- #address-cells: <1>, as required by generic SPI binding.
 | 
				
			||||||
 | 
					- #size-cells: <0>, also as required by generic SPI binding.
 | 
				
			||||||
 | 
					- interrupts: Property with a value describing the interrupt number.
 | 
				
			||||||
 | 
					- clocks: Clock phandles (see clock bindings for details).
 | 
				
			||||||
 | 
					- spi-max-frequency: Maximum SPI clocking speed of device in Hz.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Optional properties:
 | 
				
			||||||
 | 
					- num-cs: Number of chip selects used.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Example:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						spi: spi@f0b00000 {
 | 
				
			||||||
 | 
							compatible = "andestech,atcspi200";
 | 
				
			||||||
 | 
							reg = <0xf0b00000 0x1000>;
 | 
				
			||||||
 | 
							#address-cells = <1>;
 | 
				
			||||||
 | 
							#size-cells = <0>;
 | 
				
			||||||
 | 
							num-cs = <1>;
 | 
				
			||||||
 | 
							clocks = <&spiclk>;
 | 
				
			||||||
 | 
							interrupts = <3 4>;
 | 
				
			||||||
 | 
							flash@0 {
 | 
				
			||||||
 | 
								compatible = "spi-flash";
 | 
				
			||||||
 | 
								spi-max-frequency = <50000000>;
 | 
				
			||||||
 | 
								reg = <0>;
 | 
				
			||||||
 | 
								spi-cpol;
 | 
				
			||||||
 | 
								spi-cpha;
 | 
				
			||||||
 | 
							};
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
							
								
								
									
										31
									
								
								doc/device-tree-bindings/timer/atcpit100_timer.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								doc/device-tree-bindings/timer/atcpit100_timer.txt
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,31 @@
 | 
				
			|||||||
 | 
					Andestech ATCPIT100 timer
 | 
				
			||||||
 | 
					------------------------------------------------------------------
 | 
				
			||||||
 | 
					ATCPIT100 is a generic IP block from Andes Technology, embedded in
 | 
				
			||||||
 | 
					Andestech AE3XX, AE250 platforms and other designs.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This timer is a set of compact multi-function timers, which can be
 | 
				
			||||||
 | 
					used as pulse width modulators (PWM) as well as simple timers.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					It supports up to 4 PIT channels. Each PIT channel is a
 | 
				
			||||||
 | 
					multi-function timer and provide the following usage scenarios:
 | 
				
			||||||
 | 
					One 32-bit timer
 | 
				
			||||||
 | 
					Two 16-bit timers
 | 
				
			||||||
 | 
					Four 8-bit timers
 | 
				
			||||||
 | 
					One 16-bit PWM
 | 
				
			||||||
 | 
					One 16-bit timer and one 8-bit PWM
 | 
				
			||||||
 | 
					Two 8-bit timer and one 8-bit PWM
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Required properties:
 | 
				
			||||||
 | 
					- compatible	: Should be "andestech,atcpit100"
 | 
				
			||||||
 | 
					- reg		: Address and length of the register set
 | 
				
			||||||
 | 
					- interrupts	: Reference to the timer interrupt
 | 
				
			||||||
 | 
					- clock-frequency : The rate in HZ in input of the Andestech ATCPIT100 timer
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Examples:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					timer0: timer@f0400000 {
 | 
				
			||||||
 | 
						compatible = "andestech,atcpit100";
 | 
				
			||||||
 | 
						reg = <0xf0400000 0x1000>;
 | 
				
			||||||
 | 
						interrupts = <2 4>;
 | 
				
			||||||
 | 
						clock-frequency = <30000000>;
 | 
				
			||||||
 | 
					}:
 | 
				
			||||||
@ -401,6 +401,18 @@ config STM32_SDMMC2
 | 
				
			|||||||
	  If you have a board based on such a SoC and with a SD/MMC slot,
 | 
						  If you have a board based on such a SoC and with a SD/MMC slot,
 | 
				
			||||||
	  say Y or M here.
 | 
						  say Y or M here.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					config MMC_NDS32
 | 
				
			||||||
 | 
						bool "Andestech SD/MMC controller support"
 | 
				
			||||||
 | 
						depends on DM_MMC && OF_CONTROL && BLK && FTSDC010
 | 
				
			||||||
 | 
						help
 | 
				
			||||||
 | 
						  This enables support for the Andestech SD/MMM controller, which is
 | 
				
			||||||
 | 
						  based on Faraday IP.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					config FTSDC010
 | 
				
			||||||
 | 
						bool "Ftsdc010 SD/MMC controller Support"
 | 
				
			||||||
 | 
						help
 | 
				
			||||||
 | 
						  This SD/MMC controller is present in Andestech SoCs which is based on Faraday IP.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
endif
 | 
					endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
config TEGRA124_MMC_DISABLE_EXT_LOOPBACK
 | 
					config TEGRA124_MMC_DISABLE_EXT_LOOPBACK
 | 
				
			||||||
 | 
				
			|||||||
@ -44,6 +44,7 @@ obj-$(CONFIG_MMC_SANDBOX)		+= sandbox_mmc.o
 | 
				
			|||||||
obj-$(CONFIG_SH_MMCIF) += sh_mmcif.o
 | 
					obj-$(CONFIG_SH_MMCIF) += sh_mmcif.o
 | 
				
			||||||
obj-$(CONFIG_SH_SDHI) += sh_sdhi.o
 | 
					obj-$(CONFIG_SH_SDHI) += sh_sdhi.o
 | 
				
			||||||
obj-$(CONFIG_STM32_SDMMC2) += stm32_sdmmc2.o
 | 
					obj-$(CONFIG_STM32_SDMMC2) += stm32_sdmmc2.o
 | 
				
			||||||
 | 
					obj-$(CONFIG_MMC_NDS32) += nds32_mmc.o
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# SDHCI
 | 
					# SDHCI
 | 
				
			||||||
obj-$(CONFIG_MMC_SDHCI)			+= sdhci.o
 | 
					obj-$(CONFIG_MMC_SDHCI)			+= sdhci.o
 | 
				
			||||||
 | 
				
			|||||||
@ -12,24 +12,15 @@
 | 
				
			|||||||
#include <part.h>
 | 
					#include <part.h>
 | 
				
			||||||
#include <mmc.h>
 | 
					#include <mmc.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <asm/io.h>
 | 
					#include <linux/io.h>
 | 
				
			||||||
#include <linux/errno.h>
 | 
					#include <linux/errno.h>
 | 
				
			||||||
#include <asm/byteorder.h>
 | 
					#include <asm/byteorder.h>
 | 
				
			||||||
#include <faraday/ftsdc010.h>
 | 
					#include <faraday/ftsdc010.h>
 | 
				
			||||||
 | 
					#include "ftsdc010_mci.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define CFG_CMD_TIMEOUT (CONFIG_SYS_HZ >> 4) /* 250 ms */
 | 
					#define CFG_CMD_TIMEOUT (CONFIG_SYS_HZ >> 4) /* 250 ms */
 | 
				
			||||||
#define CFG_RST_TIMEOUT CONFIG_SYS_HZ /* 1 sec reset timeout */
 | 
					#define CFG_RST_TIMEOUT CONFIG_SYS_HZ /* 1 sec reset timeout */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct ftsdc010_chip {
 | 
					 | 
				
			||||||
	void __iomem *regs;
 | 
					 | 
				
			||||||
	uint32_t wprot;   /* write protected (locked) */
 | 
					 | 
				
			||||||
	uint32_t rate;    /* actual SD clock in Hz */
 | 
					 | 
				
			||||||
	uint32_t sclk;    /* FTSDC010 source clock in Hz */
 | 
					 | 
				
			||||||
	uint32_t fifo;    /* fifo depth in bytes */
 | 
					 | 
				
			||||||
	uint32_t acmd;
 | 
					 | 
				
			||||||
	struct mmc_config cfg;	/* mmc configuration */
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static inline int ftsdc010_send_cmd(struct mmc *mmc, struct mmc_cmd *mmc_cmd)
 | 
					static inline int ftsdc010_send_cmd(struct mmc *mmc, struct mmc_cmd *mmc_cmd)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct ftsdc010_chip *chip = mmc->priv;
 | 
						struct ftsdc010_chip *chip = mmc->priv;
 | 
				
			||||||
@ -127,9 +118,8 @@ static void ftsdc010_clkset(struct mmc *mmc, uint32_t rate)
 | 
				
			|||||||
static int ftsdc010_wait(struct ftsdc010_mmc __iomem *regs, uint32_t mask)
 | 
					static int ftsdc010_wait(struct ftsdc010_mmc __iomem *regs, uint32_t mask)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int ret = -ETIMEDOUT;
 | 
						int ret = -ETIMEDOUT;
 | 
				
			||||||
	uint32_t st, ts;
 | 
						uint32_t st, timeout = 10000000;
 | 
				
			||||||
 | 
						while (timeout--) {
 | 
				
			||||||
	for (ts = get_timer(0); get_timer(ts) < CFG_CMD_TIMEOUT; ) {
 | 
					 | 
				
			||||||
		st = readl(®s->status);
 | 
							st = readl(®s->status);
 | 
				
			||||||
		if (!(st & mask))
 | 
							if (!(st & mask))
 | 
				
			||||||
			continue;
 | 
								continue;
 | 
				
			||||||
@ -138,8 +128,9 @@ static int ftsdc010_wait(struct ftsdc010_mmc __iomem *regs, uint32_t mask)
 | 
				
			|||||||
		break;
 | 
							break;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (ret)
 | 
						if (ret){
 | 
				
			||||||
		debug("ftsdc010: wait st(0x%x) timeout\n", mask);
 | 
							debug("ftsdc010: wait st(0x%x) timeout\n", mask);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return ret;
 | 
						return ret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -147,10 +138,16 @@ static int ftsdc010_wait(struct ftsdc010_mmc __iomem *regs, uint32_t mask)
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 * u-boot mmc api
 | 
					 * u-boot mmc api
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					#ifdef CONFIG_DM_MMC
 | 
				
			||||||
 | 
					static int ftsdc010_request(struct udevice *dev, struct mmc_cmd *cmd,
 | 
				
			||||||
 | 
						struct mmc_data *data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct mmc *mmc = mmc_get_mmc_dev(dev);
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
static int ftsdc010_request(struct mmc *mmc, struct mmc_cmd *cmd,
 | 
					static int ftsdc010_request(struct mmc *mmc, struct mmc_cmd *cmd,
 | 
				
			||||||
	struct mmc_data *data)
 | 
						struct mmc_data *data)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
	int ret = -EOPNOTSUPP;
 | 
						int ret = -EOPNOTSUPP;
 | 
				
			||||||
	uint32_t len = 0;
 | 
						uint32_t len = 0;
 | 
				
			||||||
	struct ftsdc010_chip *chip = mmc->priv;
 | 
						struct ftsdc010_chip *chip = mmc->priv;
 | 
				
			||||||
@ -245,14 +242,20 @@ static int ftsdc010_request(struct mmc *mmc, struct mmc_cmd *cmd,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	if (!ret) {
 | 
						if (!ret) {
 | 
				
			||||||
		ret = ftsdc010_wait(regs,
 | 
							ret = ftsdc010_wait(regs,
 | 
				
			||||||
			FTSDC010_STATUS_DATA_END | FTSDC010_STATUS_DATA_ERROR);
 | 
								FTSDC010_STATUS_DATA_END | FTSDC010_STATUS_DATA_CRC_OK);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return ret;
 | 
						return ret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef CONFIG_DM_MMC
 | 
				
			||||||
 | 
					static int ftsdc010_set_ios(struct udevice *dev)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct mmc *mmc = mmc_get_mmc_dev(dev);
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
static int ftsdc010_set_ios(struct mmc *mmc)
 | 
					static int ftsdc010_set_ios(struct mmc *mmc)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
	struct ftsdc010_chip *chip = mmc->priv;
 | 
						struct ftsdc010_chip *chip = mmc->priv;
 | 
				
			||||||
	struct ftsdc010_mmc __iomem *regs = chip->regs;
 | 
						struct ftsdc010_mmc __iomem *regs = chip->regs;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -274,20 +277,43 @@ static int ftsdc010_set_ios(struct mmc *mmc)
 | 
				
			|||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef CONFIG_DM_MMC
 | 
				
			||||||
 | 
					static int ftsdc010_get_cd(struct udevice *dev)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct mmc *mmc = mmc_get_mmc_dev(dev);
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					static int ftsdc010_get_cd(struct mmc *mmc)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
						struct ftsdc010_chip *chip = mmc->priv;
 | 
				
			||||||
 | 
						struct ftsdc010_mmc __iomem *regs = chip->regs;
 | 
				
			||||||
 | 
						return !(readl(®s->status) & FTSDC010_STATUS_CARD_DETECT);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef CONFIG_DM_MMC
 | 
				
			||||||
 | 
					static int ftsdc010_get_wp(struct udevice *dev)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct mmc *mmc = mmc_get_mmc_dev(dev);
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					static int ftsdc010_get_wp(struct mmc *mmc)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
						struct ftsdc010_chip *chip = mmc->priv;
 | 
				
			||||||
 | 
						struct ftsdc010_mmc __iomem *regs = chip->regs;
 | 
				
			||||||
 | 
						if (readl(®s->status) & FTSDC010_STATUS_WRITE_PROT) {
 | 
				
			||||||
 | 
							printf("ftsdc010: write protected\n");
 | 
				
			||||||
 | 
							chip->wprot = 1;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int ftsdc010_init(struct mmc *mmc)
 | 
					static int ftsdc010_init(struct mmc *mmc)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct ftsdc010_chip *chip = mmc->priv;
 | 
						struct ftsdc010_chip *chip = mmc->priv;
 | 
				
			||||||
	struct ftsdc010_mmc __iomem *regs = chip->regs;
 | 
						struct ftsdc010_mmc __iomem *regs = chip->regs;
 | 
				
			||||||
	uint32_t ts;
 | 
						uint32_t ts;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (readl(®s->status) & FTSDC010_STATUS_CARD_DETECT)
 | 
					 | 
				
			||||||
		return -ENOMEDIUM;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (readl(®s->status) & FTSDC010_STATUS_WRITE_PROT) {
 | 
					 | 
				
			||||||
		printf("ftsdc010: write protected\n");
 | 
					 | 
				
			||||||
		chip->wprot = 1;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	chip->fifo = (readl(®s->feature) & 0xff) << 2;
 | 
						chip->fifo = (readl(®s->feature) & 0xff) << 2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* 1. chip reset */
 | 
						/* 1. chip reset */
 | 
				
			||||||
@ -311,11 +337,69 @@ static int ftsdc010_init(struct mmc *mmc)
 | 
				
			|||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef CONFIG_DM_MMC
 | 
				
			||||||
 | 
					int ftsdc010_probe(struct udevice *dev)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct mmc *mmc = mmc_get_mmc_dev(dev);
 | 
				
			||||||
 | 
						return ftsdc010_init(mmc);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const struct dm_mmc_ops dm_ftsdc010_ops = {
 | 
				
			||||||
 | 
						.send_cmd	= ftsdc010_request,
 | 
				
			||||||
 | 
						.set_ios	= ftsdc010_set_ios,
 | 
				
			||||||
 | 
						.get_cd		= ftsdc010_get_cd,
 | 
				
			||||||
 | 
						.get_wp		= ftsdc010_get_wp,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
static const struct mmc_ops ftsdc010_ops = {
 | 
					static const struct mmc_ops ftsdc010_ops = {
 | 
				
			||||||
	.send_cmd	= ftsdc010_request,
 | 
						.send_cmd	= ftsdc010_request,
 | 
				
			||||||
	.set_ios	= ftsdc010_set_ios,
 | 
						.set_ios	= ftsdc010_set_ios,
 | 
				
			||||||
 | 
						.getcd		= ftsdc010_get_cd,
 | 
				
			||||||
 | 
						.getwp		= ftsdc010_get_wp,
 | 
				
			||||||
	.init		= ftsdc010_init,
 | 
						.init		= ftsdc010_init,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ftsdc_setup_cfg(struct mmc_config *cfg, const char *name, int buswidth,
 | 
				
			||||||
 | 
							     uint caps, u32 max_clk, u32 min_clk)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						cfg->name = name;
 | 
				
			||||||
 | 
						cfg->f_min = min_clk;
 | 
				
			||||||
 | 
						cfg->f_max = max_clk;
 | 
				
			||||||
 | 
						cfg->voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195;
 | 
				
			||||||
 | 
						cfg->host_caps = caps;
 | 
				
			||||||
 | 
						if (buswidth == 8) {
 | 
				
			||||||
 | 
							cfg->host_caps |= MMC_MODE_8BIT;
 | 
				
			||||||
 | 
							cfg->host_caps &= ~MMC_MODE_4BIT;
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							cfg->host_caps |= MMC_MODE_4BIT;
 | 
				
			||||||
 | 
							cfg->host_caps &= ~MMC_MODE_8BIT;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						cfg->part_type = PART_TYPE_DOS;
 | 
				
			||||||
 | 
						cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void set_bus_width(struct ftsdc010_mmc __iomem *regs, struct mmc_config *cfg)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						switch (readl(®s->bwr) & FTSDC010_BWR_CAPS_MASK) {
 | 
				
			||||||
 | 
						case FTSDC010_BWR_CAPS_4BIT:
 | 
				
			||||||
 | 
							cfg->host_caps |= MMC_MODE_4BIT;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case FTSDC010_BWR_CAPS_8BIT:
 | 
				
			||||||
 | 
							cfg->host_caps |= MMC_MODE_4BIT | MMC_MODE_8BIT;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef CONFIG_BLK
 | 
				
			||||||
 | 
					int ftsdc010_bind(struct udevice *dev, struct mmc *mmc, struct mmc_config *cfg)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return mmc_bind(dev, mmc, cfg);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int ftsdc010_mmc_init(int devid)
 | 
					int ftsdc010_mmc_init(int devid)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@ -345,19 +429,11 @@ int ftsdc010_mmc_init(int devid)
 | 
				
			|||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	chip->cfg.name = "ftsdc010";
 | 
						chip->cfg.name = "ftsdc010";
 | 
				
			||||||
 | 
					#ifndef CONFIG_DM_MMC
 | 
				
			||||||
	chip->cfg.ops = &ftsdc010_ops;
 | 
						chip->cfg.ops = &ftsdc010_ops;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
	chip->cfg.host_caps = MMC_MODE_HS | MMC_MODE_HS_52MHz;
 | 
						chip->cfg.host_caps = MMC_MODE_HS | MMC_MODE_HS_52MHz;
 | 
				
			||||||
	switch (readl(®s->bwr) & FTSDC010_BWR_CAPS_MASK) {
 | 
						set_bus_width(regs , &chip->cfg);
 | 
				
			||||||
	case FTSDC010_BWR_CAPS_4BIT:
 | 
					 | 
				
			||||||
		chip->cfg.host_caps |= MMC_MODE_4BIT;
 | 
					 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
	case FTSDC010_BWR_CAPS_8BIT:
 | 
					 | 
				
			||||||
		chip->cfg.host_caps |= MMC_MODE_4BIT | MMC_MODE_8BIT;
 | 
					 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
	default:
 | 
					 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	chip->cfg.voltages  = MMC_VDD_32_33 | MMC_VDD_33_34;
 | 
						chip->cfg.voltages  = MMC_VDD_32_33 | MMC_VDD_33_34;
 | 
				
			||||||
	chip->cfg.f_max     = chip->sclk / 2;
 | 
						chip->cfg.f_max     = chip->sclk / 2;
 | 
				
			||||||
	chip->cfg.f_min     = chip->sclk / 0x100;
 | 
						chip->cfg.f_min     = chip->sclk / 0x100;
 | 
				
			||||||
@ -373,3 +449,4 @@ int ftsdc010_mmc_init(int devid)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										53
									
								
								drivers/mmc/ftsdc010_mci.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								drivers/mmc/ftsdc010_mci.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,53 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Faraday FTSDC010 Secure Digital Memory Card Host Controller
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Copyright (C) 2011 Andes Technology Corporation
 | 
				
			||||||
 | 
					 * Macpaul Lin, Andes Technology Corporation <macpaul@andestech.com>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * SPDX-License-Identifier:	GPL-2.0+
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#include <mmc.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef __FTSDC010_MCI_H
 | 
				
			||||||
 | 
					#define __FTSDC010_MCI_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct ftsdc010_chip {
 | 
				
			||||||
 | 
						void __iomem *regs;
 | 
				
			||||||
 | 
						uint32_t wprot;   /* write protected (locked) */
 | 
				
			||||||
 | 
						uint32_t rate;    /* actual SD clock in Hz */
 | 
				
			||||||
 | 
						uint32_t sclk;    /* FTSDC010 source clock in Hz */
 | 
				
			||||||
 | 
						uint32_t fifo;    /* fifo depth in bytes */
 | 
				
			||||||
 | 
						uint32_t acmd;
 | 
				
			||||||
 | 
						struct mmc_config cfg;	/* mmc configuration */
 | 
				
			||||||
 | 
						const char *name;
 | 
				
			||||||
 | 
						void *ioaddr;
 | 
				
			||||||
 | 
						unsigned int caps;
 | 
				
			||||||
 | 
						unsigned int version;
 | 
				
			||||||
 | 
						unsigned int clock;
 | 
				
			||||||
 | 
						unsigned int bus_hz;
 | 
				
			||||||
 | 
						unsigned int div;
 | 
				
			||||||
 | 
						int dev_index;
 | 
				
			||||||
 | 
						int dev_id;
 | 
				
			||||||
 | 
						int buswidth;
 | 
				
			||||||
 | 
						u32 fifoth_val;
 | 
				
			||||||
 | 
						struct mmc *mmc;
 | 
				
			||||||
 | 
						void *priv;
 | 
				
			||||||
 | 
						bool fifo_mode;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef CONFIG_DM_MMC
 | 
				
			||||||
 | 
					/* Export the operations to drivers */
 | 
				
			||||||
 | 
					int ftsdc010_probe(struct udevice *dev);
 | 
				
			||||||
 | 
					extern const struct dm_mmc_ops dm_ftsdc010_ops;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					void ftsdc_setup_cfg(struct mmc_config *cfg, const char *name, int buswidth,
 | 
				
			||||||
 | 
							     uint caps, u32 max_clk, u32 min_clk);
 | 
				
			||||||
 | 
					void set_bus_width(struct ftsdc010_mmc __iomem *regs, struct mmc_config *cfg);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef CONFIG_BLK
 | 
				
			||||||
 | 
					int ftsdc010_bind(struct udevice *dev, struct mmc *mmc, struct mmc_config *cfg);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif /* __FTSDC010_MCI_H */
 | 
				
			||||||
							
								
								
									
										136
									
								
								drivers/mmc/nds32_mmc.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										136
									
								
								drivers/mmc/nds32_mmc.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,136 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Andestech ATFSDC010 SD/MMC driver
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * (C) Copyright 2017
 | 
				
			||||||
 | 
					 * Rick Chen, NDS32 Software Engineering, rick@andestech.com
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 * SPDX-License-Identifier:	GPL-2.0+
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <common.h>
 | 
				
			||||||
 | 
					#include <clk.h>
 | 
				
			||||||
 | 
					#include <dm.h>
 | 
				
			||||||
 | 
					#include <dt-structs.h>
 | 
				
			||||||
 | 
					#include <errno.h>
 | 
				
			||||||
 | 
					#include <mapmem.h>
 | 
				
			||||||
 | 
					#include <mmc.h>
 | 
				
			||||||
 | 
					#include <pwrseq.h>
 | 
				
			||||||
 | 
					#include <syscon.h>
 | 
				
			||||||
 | 
					#include <linux/err.h>
 | 
				
			||||||
 | 
					#include <faraday/ftsdc010.h>
 | 
				
			||||||
 | 
					#include "ftsdc010_mci.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					DECLARE_GLOBAL_DATA_PTR;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if CONFIG_IS_ENABLED(OF_PLATDATA)
 | 
				
			||||||
 | 
					struct nds_mmc {
 | 
				
			||||||
 | 
						fdt32_t		bus_width;
 | 
				
			||||||
 | 
						bool		cap_mmc_highspeed;
 | 
				
			||||||
 | 
						bool		cap_sd_highspeed;
 | 
				
			||||||
 | 
						fdt32_t		clock_freq_min_max[2];
 | 
				
			||||||
 | 
						struct phandle_2_cell	clocks[4];
 | 
				
			||||||
 | 
						fdt32_t		fifo_depth;
 | 
				
			||||||
 | 
						fdt32_t		reg[2];
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct nds_mmc_plat {
 | 
				
			||||||
 | 
					#if CONFIG_IS_ENABLED(OF_PLATDATA)
 | 
				
			||||||
 | 
						struct nds_mmc dtplat;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
						struct mmc_config cfg;
 | 
				
			||||||
 | 
						struct mmc mmc;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct ftsdc_priv {
 | 
				
			||||||
 | 
						struct clk clk;
 | 
				
			||||||
 | 
						struct ftsdc010_chip chip;
 | 
				
			||||||
 | 
						int fifo_depth;
 | 
				
			||||||
 | 
						bool fifo_mode;
 | 
				
			||||||
 | 
						u32 minmax[2];
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int nds32_mmc_ofdata_to_platdata(struct udevice *dev)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					#if !CONFIG_IS_ENABLED(OF_PLATDATA)
 | 
				
			||||||
 | 
						struct ftsdc_priv *priv = dev_get_priv(dev);
 | 
				
			||||||
 | 
						struct ftsdc010_chip *chip = &priv->chip;
 | 
				
			||||||
 | 
						chip->name = dev->name;
 | 
				
			||||||
 | 
						chip->ioaddr = (void *)devfdt_get_addr(dev);
 | 
				
			||||||
 | 
						chip->buswidth = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
 | 
				
			||||||
 | 
										"bus-width", 4);
 | 
				
			||||||
 | 
						chip->priv = dev;
 | 
				
			||||||
 | 
						priv->fifo_depth = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
 | 
				
			||||||
 | 
									    "fifo-depth", 0);
 | 
				
			||||||
 | 
						priv->fifo_mode = fdtdec_get_bool(gd->fdt_blob, dev_of_offset(dev),
 | 
				
			||||||
 | 
										  "fifo-mode");
 | 
				
			||||||
 | 
						if (fdtdec_get_int_array(gd->fdt_blob, dev_of_offset(dev),
 | 
				
			||||||
 | 
								 "clock-freq-min-max", priv->minmax, 2)) {
 | 
				
			||||||
 | 
							int val = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
 | 
				
			||||||
 | 
									  "max-frequency", -EINVAL);
 | 
				
			||||||
 | 
							if (val < 0)
 | 
				
			||||||
 | 
								return val;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							priv->minmax[0] = 400000;  /* 400 kHz */
 | 
				
			||||||
 | 
							priv->minmax[1] = val;
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							debug("%s: 'clock-freq-min-max' property was deprecated.\n",
 | 
				
			||||||
 | 
							__func__);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
						chip->sclk = priv->minmax[1];
 | 
				
			||||||
 | 
						chip->regs = chip->ioaddr;
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int nds32_mmc_probe(struct udevice *dev)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct nds_mmc_plat *plat = dev_get_platdata(dev);
 | 
				
			||||||
 | 
						struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
 | 
				
			||||||
 | 
						struct ftsdc_priv *priv = dev_get_priv(dev);
 | 
				
			||||||
 | 
						struct ftsdc010_chip *chip = &priv->chip;
 | 
				
			||||||
 | 
						struct udevice *pwr_dev __maybe_unused;
 | 
				
			||||||
 | 
					#if CONFIG_IS_ENABLED(OF_PLATDATA)
 | 
				
			||||||
 | 
						int ret;
 | 
				
			||||||
 | 
						struct nds_mmc *dtplat = &plat->dtplat;
 | 
				
			||||||
 | 
						chip->name = dev->name;
 | 
				
			||||||
 | 
						chip->ioaddr = map_sysmem(dtplat->reg[0], dtplat->reg[1]);
 | 
				
			||||||
 | 
						chip->buswidth = dtplat->bus_width;
 | 
				
			||||||
 | 
						chip->priv = dev;
 | 
				
			||||||
 | 
						chip->dev_index = 1;
 | 
				
			||||||
 | 
						memcpy(priv->minmax, dtplat->clock_freq_min_max, sizeof(priv->minmax));
 | 
				
			||||||
 | 
						ret = clk_get_by_index_platdata(dev, 0, dtplat->clocks, &priv->clk);
 | 
				
			||||||
 | 
						if (ret < 0)
 | 
				
			||||||
 | 
							return ret;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
						ftsdc_setup_cfg(&plat->cfg, dev->name, chip->buswidth, chip->caps,
 | 
				
			||||||
 | 
								priv->minmax[1] , priv->minmax[0]);
 | 
				
			||||||
 | 
						chip->mmc = &plat->mmc;
 | 
				
			||||||
 | 
						chip->mmc->priv = &priv->chip;
 | 
				
			||||||
 | 
						chip->mmc->dev = dev;
 | 
				
			||||||
 | 
						upriv->mmc = chip->mmc;
 | 
				
			||||||
 | 
						return ftsdc010_probe(dev);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int nds32_mmc_bind(struct udevice *dev)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct nds_mmc_plat *plat = dev_get_platdata(dev);
 | 
				
			||||||
 | 
						return ftsdc010_bind(dev, &plat->mmc, &plat->cfg);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const struct udevice_id nds32_mmc_ids[] = {
 | 
				
			||||||
 | 
						{ .compatible = "andestech,atsdc010" },
 | 
				
			||||||
 | 
						{ }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					U_BOOT_DRIVER(nds32_mmc_drv) = {
 | 
				
			||||||
 | 
						.name		= "nds32_mmc",
 | 
				
			||||||
 | 
						.id		= UCLASS_MMC,
 | 
				
			||||||
 | 
						.of_match	= nds32_mmc_ids,
 | 
				
			||||||
 | 
						.ofdata_to_platdata = nds32_mmc_ofdata_to_platdata,
 | 
				
			||||||
 | 
						.ops		= &dm_ftsdc010_ops,
 | 
				
			||||||
 | 
						.bind		= nds32_mmc_bind,
 | 
				
			||||||
 | 
						.probe		= nds32_mmc_probe,
 | 
				
			||||||
 | 
						.priv_auto_alloc_size = sizeof(struct ftsdc_priv),
 | 
				
			||||||
 | 
						.platdata_auto_alloc_size = sizeof(struct nds_mmc_plat),
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
@ -210,12 +210,12 @@ config FSL_QSPI
 | 
				
			|||||||
	  used to access the SPI NOR flash on platforms embedding this
 | 
						  used to access the SPI NOR flash on platforms embedding this
 | 
				
			||||||
	  Freescale IP core.
 | 
						  Freescale IP core.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
config NDS_AE3XX_SPI
 | 
					config ATCSPI200_SPI
 | 
				
			||||||
	bool "Andestech AE3XX SPI driver"
 | 
						bool "Andestech ATCSPI200 SPI driver"
 | 
				
			||||||
	help
 | 
						help
 | 
				
			||||||
	  Enable the Andestech AE3XX SPI driver. This driver can be
 | 
						  Enable the Andestech ATCSPI200 SPI driver. This driver can be
 | 
				
			||||||
	  used to access the SPI flash on platforms embedding this
 | 
						  used to access the SPI flash on AE3XX and AE250 platforms embedding
 | 
				
			||||||
	  Andestech IP core.
 | 
						  this Andestech IP core.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
config TI_QSPI
 | 
					config TI_QSPI
 | 
				
			||||||
	bool "TI QSPI driver"
 | 
						bool "TI QSPI driver"
 | 
				
			||||||
 | 
				
			|||||||
@ -34,7 +34,7 @@ obj-$(CONFIG_MPC8XXX_SPI) += mpc8xxx_spi.o
 | 
				
			|||||||
obj-$(CONFIG_MVEBU_A3700_SPI) += mvebu_a3700_spi.o
 | 
					obj-$(CONFIG_MVEBU_A3700_SPI) += mvebu_a3700_spi.o
 | 
				
			||||||
obj-$(CONFIG_MXC_SPI) += mxc_spi.o
 | 
					obj-$(CONFIG_MXC_SPI) += mxc_spi.o
 | 
				
			||||||
obj-$(CONFIG_MXS_SPI) += mxs_spi.o
 | 
					obj-$(CONFIG_MXS_SPI) += mxs_spi.o
 | 
				
			||||||
obj-$(CONFIG_NDS_AE3XX_SPI) += nds_ae3xx_spi.o
 | 
					obj-$(CONFIG_ATCSPI200_SPI) += atcspi200_spi.o
 | 
				
			||||||
obj-$(CONFIG_OMAP3_SPI) += omap3_spi.o
 | 
					obj-$(CONFIG_OMAP3_SPI) += omap3_spi.o
 | 
				
			||||||
obj-$(CONFIG_PIC32_SPI) += pic32_spi.o
 | 
					obj-$(CONFIG_PIC32_SPI) += pic32_spi.o
 | 
				
			||||||
obj-$(CONFIG_ROCKCHIP_SPI) += rk_spi.o
 | 
					obj-$(CONFIG_ROCKCHIP_SPI) += rk_spi.o
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,5 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 * NDS SPI controller driver.
 | 
					 * Andestech ATCSPI200 SPI controller driver.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * Copyright 2017 Andes Technology, Inc.
 | 
					 * Copyright 2017 Andes Technology, Inc.
 | 
				
			||||||
 * Author: Rick Chen (rick@andestech.com)
 | 
					 * Author: Rick Chen (rick@andestech.com)
 | 
				
			||||||
@ -25,7 +25,7 @@ DECLARE_GLOBAL_DATA_PTR;
 | 
				
			|||||||
#define SPI1_BASE		0xf0f00000
 | 
					#define SPI1_BASE		0xf0f00000
 | 
				
			||||||
#define NSPI_MAX_CS_NUM		1
 | 
					#define NSPI_MAX_CS_NUM		1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct ae3xx_spi_regs {
 | 
					struct atcspi200_spi_regs {
 | 
				
			||||||
	u32	rev;
 | 
						u32	rev;
 | 
				
			||||||
	u32	reserve1[3];
 | 
						u32	reserve1[3];
 | 
				
			||||||
	u32	format;		/* 0x10 */
 | 
						u32	format;		/* 0x10 */
 | 
				
			||||||
@ -78,7 +78,7 @@ struct nds_spi_slave {
 | 
				
			|||||||
#ifndef CONFIG_DM_SPI
 | 
					#ifndef CONFIG_DM_SPI
 | 
				
			||||||
	struct spi_slave slave;
 | 
						struct spi_slave slave;
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
	volatile struct ae3xx_spi_regs *regs;
 | 
						volatile struct atcspi200_spi_regs *regs;
 | 
				
			||||||
	int		to;
 | 
						int		to;
 | 
				
			||||||
	unsigned int	freq;
 | 
						unsigned int	freq;
 | 
				
			||||||
	ulong		clock;
 | 
						ulong		clock;
 | 
				
			||||||
@ -94,7 +94,7 @@ struct nds_spi_slave {
 | 
				
			|||||||
	unsigned int    max_transfer_length;
 | 
						unsigned int    max_transfer_length;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int __ae3xx_spi_set_speed(struct nds_spi_slave *ns)
 | 
					static int __atcspi200_spi_set_speed(struct nds_spi_slave *ns)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	u32 tm;
 | 
						u32 tm;
 | 
				
			||||||
	u8 div;
 | 
						u8 div;
 | 
				
			||||||
@ -117,7 +117,7 @@ static int __ae3xx_spi_set_speed(struct nds_spi_slave *ns)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int __ae3xx_spi_claim_bus(struct nds_spi_slave *ns)
 | 
					static int __atcspi200_spi_claim_bus(struct nds_spi_slave *ns)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
		unsigned int format=0;
 | 
							unsigned int format=0;
 | 
				
			||||||
		ns->regs->ctrl |= (TXFRST|RXFRST|SPIRST);
 | 
							ns->regs->ctrl |= (TXFRST|RXFRST|SPIRST);
 | 
				
			||||||
@ -128,18 +128,18 @@ static int __ae3xx_spi_claim_bus(struct nds_spi_slave *ns)
 | 
				
			|||||||
		ns->cmd_len = 0;
 | 
							ns->cmd_len = 0;
 | 
				
			||||||
		format = ns->mode|DATA_LENGTH(8);
 | 
							format = ns->mode|DATA_LENGTH(8);
 | 
				
			||||||
		ns->regs->format = format;
 | 
							ns->regs->format = format;
 | 
				
			||||||
		__ae3xx_spi_set_speed(ns);
 | 
							__atcspi200_spi_set_speed(ns);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		return 0;
 | 
							return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int __ae3xx_spi_release_bus(struct nds_spi_slave *ns)
 | 
					static int __atcspi200_spi_release_bus(struct nds_spi_slave *ns)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/* do nothing */
 | 
						/* do nothing */
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int __ae3xx_spi_start(struct nds_spi_slave *ns)
 | 
					static int __atcspi200_spi_start(struct nds_spi_slave *ns)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int i,olen=0;
 | 
						int i,olen=0;
 | 
				
			||||||
	int tc = ns->regs->tctrl;
 | 
						int tc = ns->regs->tctrl;
 | 
				
			||||||
@ -168,7 +168,7 @@ static int __ae3xx_spi_start(struct nds_spi_slave *ns)
 | 
				
			|||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int __ae3xx_spi_stop(struct nds_spi_slave *ns)
 | 
					static int __atcspi200_spi_stop(struct nds_spi_slave *ns)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	ns->regs->timing = ns->mtiming;
 | 
						ns->regs->timing = ns->mtiming;
 | 
				
			||||||
	while ((ns->regs->status & SPIBSY)&&(ns->to--))
 | 
						while ((ns->regs->status & SPIBSY)&&(ns->to--))
 | 
				
			||||||
@ -190,7 +190,7 @@ static int __nspi_espi_rx(struct nds_spi_slave *ns, void *din, unsigned int byte
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int __ae3xx_spi_xfer(struct nds_spi_slave *ns,
 | 
					static int __atcspi200_spi_xfer(struct nds_spi_slave *ns,
 | 
				
			||||||
		unsigned int bitlen,  const void *data_out, void *data_in,
 | 
							unsigned int bitlen,  const void *data_out, void *data_in,
 | 
				
			||||||
		unsigned long flags)
 | 
							unsigned long flags)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@ -230,7 +230,7 @@ static int __ae3xx_spi_xfer(struct nds_spi_slave *ns,
 | 
				
			|||||||
			memcpy(cmd_buf, data_out, cmd_len);
 | 
								memcpy(cmd_buf, data_out, cmd_len);
 | 
				
			||||||
			data_out = 0;
 | 
								data_out = 0;
 | 
				
			||||||
			data_len = 0;
 | 
								data_len = 0;
 | 
				
			||||||
			__ae3xx_spi_start(ns);
 | 
								__atcspi200_spi_start(ns);
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		debug("spi_xfer: data_out %08X(%p) data_in %08X(%p) data_len %u\n",
 | 
							debug("spi_xfer: data_out %08X(%p) data_in %08X(%p) data_len %u\n",
 | 
				
			||||||
@ -245,7 +245,7 @@ static int __ae3xx_spi_xfer(struct nds_spi_slave *ns,
 | 
				
			|||||||
			num_bytes = (tran_len) % CHUNK_SIZE;
 | 
								num_bytes = (tran_len) % CHUNK_SIZE;
 | 
				
			||||||
			if(num_bytes == 0)
 | 
								if(num_bytes == 0)
 | 
				
			||||||
				num_bytes = CHUNK_SIZE;
 | 
									num_bytes = CHUNK_SIZE;
 | 
				
			||||||
			__ae3xx_spi_start(ns);
 | 
								__atcspi200_spi_start(ns);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			while (num_blks) {
 | 
								while (num_blks) {
 | 
				
			||||||
				event = in_le32(&ns->regs->status);
 | 
									event = in_le32(&ns->regs->status);
 | 
				
			||||||
@ -279,9 +279,9 @@ static int __ae3xx_spi_xfer(struct nds_spi_slave *ns,
 | 
				
			|||||||
				ns->cmd_buf[3] += ((tran_len)&0xff);
 | 
									ns->cmd_buf[3] += ((tran_len)&0xff);
 | 
				
			||||||
				ns->data_len = data_len;
 | 
									ns->data_len = data_len;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			ret = __ae3xx_spi_stop(ns);
 | 
								ret = __atcspi200_spi_stop(ns);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		ret = __ae3xx_spi_stop(ns);
 | 
							ret = __atcspi200_spi_stop(ns);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		return ret;
 | 
							return ret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -300,11 +300,11 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	switch (bus) {
 | 
						switch (bus) {
 | 
				
			||||||
	case SPI0_BUS:
 | 
						case SPI0_BUS:
 | 
				
			||||||
			ns->regs = (struct ae3xx_spi_regs *)SPI0_BASE;
 | 
								ns->regs = (struct atcspi200_spi_regs *)SPI0_BASE;
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		case SPI1_BUS:
 | 
							case SPI1_BUS:
 | 
				
			||||||
			ns->regs = (struct ae3xx_spi_regs *)SPI1_BASE;
 | 
								ns->regs = (struct atcspi200_spi_regs *)SPI1_BASE;
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		default:
 | 
							default:
 | 
				
			||||||
@ -336,20 +336,20 @@ void spi_init(void)
 | 
				
			|||||||
int spi_claim_bus(struct spi_slave *slave)
 | 
					int spi_claim_bus(struct spi_slave *slave)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct nds_spi_slave *ns = to_nds_spi_slave(slave);
 | 
						struct nds_spi_slave *ns = to_nds_spi_slave(slave);
 | 
				
			||||||
	return __ae3xx_spi_claim_bus(ns);
 | 
						return __atcspi200_spi_claim_bus(ns);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void spi_release_bus(struct spi_slave *slave)
 | 
					void spi_release_bus(struct spi_slave *slave)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct nds_spi_slave *ns = to_nds_spi_slave(slave);
 | 
						struct nds_spi_slave *ns = to_nds_spi_slave(slave);
 | 
				
			||||||
	__ae3xx_spi_release_bus(ns);
 | 
						__atcspi200_spi_release_bus(ns);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *data_out,
 | 
					int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *data_out,
 | 
				
			||||||
		void *data_in, unsigned long flags)
 | 
							void *data_in, unsigned long flags)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct nds_spi_slave *ns = to_nds_spi_slave(slave);
 | 
						struct nds_spi_slave *ns = to_nds_spi_slave(slave);
 | 
				
			||||||
	return __ae3xx_spi_xfer(ns, bitlen, data_out, data_in, flags);
 | 
						return __atcspi200_spi_xfer(ns, bitlen, data_out, data_in, flags);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int spi_cs_is_valid(unsigned int bus, unsigned int cs)
 | 
					int spi_cs_is_valid(unsigned int bus, unsigned int cs)
 | 
				
			||||||
@ -360,28 +360,28 @@ int spi_cs_is_valid(unsigned int bus, unsigned int cs)
 | 
				
			|||||||
void spi_cs_activate(struct spi_slave *slave)
 | 
					void spi_cs_activate(struct spi_slave *slave)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct nds_spi_slave *ns = to_nds_spi_slave(slave);
 | 
						struct nds_spi_slave *ns = to_nds_spi_slave(slave);
 | 
				
			||||||
	__ae3xx_spi_start(ns);
 | 
						__atcspi200_spi_start(ns);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void spi_cs_deactivate(struct spi_slave *slave)
 | 
					void spi_cs_deactivate(struct spi_slave *slave)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct nds_spi_slave *ns = to_nds_spi_slave(slave);
 | 
						struct nds_spi_slave *ns = to_nds_spi_slave(slave);
 | 
				
			||||||
	__ae3xx_spi_stop(ns);
 | 
						__atcspi200_spi_stop(ns);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
static int ae3xx_spi_set_speed(struct udevice *bus, uint max_hz)
 | 
					static int atcspi200_spi_set_speed(struct udevice *bus, uint max_hz)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct nds_spi_slave *ns = dev_get_priv(bus);
 | 
						struct nds_spi_slave *ns = dev_get_priv(bus);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	debug("%s speed %u\n", __func__, max_hz);
 | 
						debug("%s speed %u\n", __func__, max_hz);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ns->freq = max_hz;
 | 
						ns->freq = max_hz;
 | 
				
			||||||
	__ae3xx_spi_set_speed(ns);
 | 
						__atcspi200_spi_set_speed(ns);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int ae3xx_spi_set_mode(struct udevice *bus, uint mode)
 | 
					static int atcspi200_spi_set_mode(struct udevice *bus, uint mode)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct nds_spi_slave *ns = dev_get_priv(bus);
 | 
						struct nds_spi_slave *ns = dev_get_priv(bus);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -391,7 +391,7 @@ static int ae3xx_spi_set_mode(struct udevice *bus, uint mode)
 | 
				
			|||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int ae3xx_spi_claim_bus(struct udevice *dev)
 | 
					static int atcspi200_spi_claim_bus(struct udevice *dev)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct dm_spi_slave_platdata *slave_plat =
 | 
						struct dm_spi_slave_platdata *slave_plat =
 | 
				
			||||||
		dev_get_parent_platdata(dev);
 | 
							dev_get_parent_platdata(dev);
 | 
				
			||||||
@ -403,27 +403,27 @@ static int ae3xx_spi_claim_bus(struct udevice *dev)
 | 
				
			|||||||
		return -EINVAL;
 | 
							return -EINVAL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return __ae3xx_spi_claim_bus(ns);
 | 
						return __atcspi200_spi_claim_bus(ns);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int ae3xx_spi_release_bus(struct udevice *dev)
 | 
					static int atcspi200_spi_release_bus(struct udevice *dev)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct nds_spi_slave *ns = dev_get_priv(dev->parent);
 | 
						struct nds_spi_slave *ns = dev_get_priv(dev->parent);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return __ae3xx_spi_release_bus(ns);
 | 
						return __atcspi200_spi_release_bus(ns);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int ae3xx_spi_xfer(struct udevice *dev, unsigned int bitlen,
 | 
					static int atcspi200_spi_xfer(struct udevice *dev, unsigned int bitlen,
 | 
				
			||||||
			    const void *dout, void *din,
 | 
								    const void *dout, void *din,
 | 
				
			||||||
			    unsigned long flags)
 | 
								    unsigned long flags)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct udevice *bus = dev->parent;
 | 
						struct udevice *bus = dev->parent;
 | 
				
			||||||
	struct nds_spi_slave *ns = dev_get_priv(bus);
 | 
						struct nds_spi_slave *ns = dev_get_priv(bus);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return __ae3xx_spi_xfer(ns, bitlen, dout, din, flags);
 | 
						return __atcspi200_spi_xfer(ns, bitlen, dout, din, flags);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int ae3xx_spi_get_clk(struct udevice *bus)
 | 
					static int atcspi200_spi_get_clk(struct udevice *bus)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct nds_spi_slave *ns = dev_get_priv(bus);
 | 
						struct nds_spi_slave *ns = dev_get_priv(bus);
 | 
				
			||||||
	struct clk clk;
 | 
						struct clk clk;
 | 
				
			||||||
@ -444,26 +444,26 @@ static int ae3xx_spi_get_clk(struct udevice *bus)
 | 
				
			|||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int ae3xx_spi_probe(struct udevice *bus)
 | 
					static int atcspi200_spi_probe(struct udevice *bus)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct nds_spi_slave *ns = dev_get_priv(bus);
 | 
						struct nds_spi_slave *ns = dev_get_priv(bus);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ns->to = SPI_TIMEOUT;
 | 
						ns->to = SPI_TIMEOUT;
 | 
				
			||||||
	ns->max_transfer_length = MAX_TRANSFER_LEN;
 | 
						ns->max_transfer_length = MAX_TRANSFER_LEN;
 | 
				
			||||||
	ns->mtiming = ns->regs->timing;
 | 
						ns->mtiming = ns->regs->timing;
 | 
				
			||||||
	ae3xx_spi_get_clk(bus);
 | 
						atcspi200_spi_get_clk(bus);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int ae3xx_ofdata_to_platadata(struct udevice *bus)
 | 
					static int atcspi200_ofdata_to_platadata(struct udevice *bus)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct nds_spi_slave *ns = dev_get_priv(bus);
 | 
						struct nds_spi_slave *ns = dev_get_priv(bus);
 | 
				
			||||||
	const void *blob = gd->fdt_blob;
 | 
						const void *blob = gd->fdt_blob;
 | 
				
			||||||
	int node = dev_of_offset(bus);
 | 
						int node = dev_of_offset(bus);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ns->regs = map_physmem(devfdt_get_addr(bus),
 | 
						ns->regs = map_physmem(devfdt_get_addr(bus),
 | 
				
			||||||
				 sizeof(struct ae3xx_spi_regs),
 | 
									 sizeof(struct atcspi200_spi_regs),
 | 
				
			||||||
				 MAP_NOCACHE);
 | 
									 MAP_NOCACHE);
 | 
				
			||||||
	if (!ns->regs) {
 | 
						if (!ns->regs) {
 | 
				
			||||||
		printf("%s: could not map device address\n", __func__);
 | 
							printf("%s: could not map device address\n", __func__);
 | 
				
			||||||
@ -474,26 +474,26 @@ static int ae3xx_ofdata_to_platadata(struct udevice *bus)
 | 
				
			|||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const struct dm_spi_ops ae3xx_spi_ops = {
 | 
					static const struct dm_spi_ops atcspi200_spi_ops = {
 | 
				
			||||||
	.claim_bus	= ae3xx_spi_claim_bus,
 | 
						.claim_bus	= atcspi200_spi_claim_bus,
 | 
				
			||||||
	.release_bus	= ae3xx_spi_release_bus,
 | 
						.release_bus	= atcspi200_spi_release_bus,
 | 
				
			||||||
	.xfer		= ae3xx_spi_xfer,
 | 
						.xfer		= atcspi200_spi_xfer,
 | 
				
			||||||
	.set_speed	= ae3xx_spi_set_speed,
 | 
						.set_speed	= atcspi200_spi_set_speed,
 | 
				
			||||||
	.set_mode	= ae3xx_spi_set_mode,
 | 
						.set_mode	= atcspi200_spi_set_mode,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const struct udevice_id ae3xx_spi_ids[] = {
 | 
					static const struct udevice_id atcspi200_spi_ids[] = {
 | 
				
			||||||
	{ .compatible = "andestech,atcspi200" },
 | 
						{ .compatible = "andestech,atcspi200" },
 | 
				
			||||||
	{ }
 | 
						{ }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
U_BOOT_DRIVER(ae3xx_spi) = {
 | 
					U_BOOT_DRIVER(atcspi200_spi) = {
 | 
				
			||||||
	.name = "ae3xx_spi",
 | 
						.name = "atcspi200_spi",
 | 
				
			||||||
	.id = UCLASS_SPI,
 | 
						.id = UCLASS_SPI,
 | 
				
			||||||
	.of_match = ae3xx_spi_ids,
 | 
						.of_match = atcspi200_spi_ids,
 | 
				
			||||||
	.ops = &ae3xx_spi_ops,
 | 
						.ops = &atcspi200_spi_ops,
 | 
				
			||||||
	.ofdata_to_platdata = ae3xx_ofdata_to_platadata,
 | 
						.ofdata_to_platdata = atcspi200_ofdata_to_platadata,
 | 
				
			||||||
	.priv_auto_alloc_size = sizeof(struct nds_spi_slave),
 | 
						.priv_auto_alloc_size = sizeof(struct nds_spi_slave),
 | 
				
			||||||
	.probe = ae3xx_spi_probe,
 | 
						.probe = atcspi200_spi_probe,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
@ -105,11 +105,12 @@ config AG101P_TIMER
 | 
				
			|||||||
	help
 | 
						help
 | 
				
			||||||
	  Select this to enable a timer for AG01P devices.
 | 
						  Select this to enable a timer for AG01P devices.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
config AE3XX_TIMER
 | 
					config ATCPIT100_TIMER
 | 
				
			||||||
	bool "AE3XX timer support"
 | 
						bool "ATCPIT100 timer support"
 | 
				
			||||||
	depends on TIMER && NDS32
 | 
						depends on TIMER
 | 
				
			||||||
	help
 | 
						help
 | 
				
			||||||
	  Select this to enable a timer for AE3XX devices.
 | 
						  Select this to enable a ATCPIT100 timer which will be embeded
 | 
				
			||||||
 | 
							in AE3XX, AE250 boards.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
config ROCKCHIP_TIMER
 | 
					config ROCKCHIP_TIMER
 | 
				
			||||||
        bool "Rockchip timer support"
 | 
					        bool "Rockchip timer support"
 | 
				
			||||||
 | 
				
			|||||||
@ -13,6 +13,6 @@ obj-$(CONFIG_AST_TIMER)	+= ast_timer.o
 | 
				
			|||||||
obj-$(CONFIG_STI_TIMER)		+= sti-timer.o
 | 
					obj-$(CONFIG_STI_TIMER)		+= sti-timer.o
 | 
				
			||||||
obj-$(CONFIG_ARC_TIMER)	+= arc_timer.o
 | 
					obj-$(CONFIG_ARC_TIMER)	+= arc_timer.o
 | 
				
			||||||
obj-$(CONFIG_AG101P_TIMER) += ag101p_timer.o
 | 
					obj-$(CONFIG_AG101P_TIMER) += ag101p_timer.o
 | 
				
			||||||
obj-$(CONFIG_AE3XX_TIMER) += ae3xx_timer.o
 | 
					obj-$(CONFIG_ATCPIT100_TIMER) += atcpit100_timer.o
 | 
				
			||||||
obj-$(CONFIG_ROCKCHIP_TIMER) += rockchip_timer.o
 | 
					obj-$(CONFIG_ROCKCHIP_TIMER) += rockchip_timer.o
 | 
				
			||||||
obj-$(CONFIG_ATMEL_PIT_TIMER) += atmel_pit_timer.o
 | 
					obj-$(CONFIG_ATMEL_PIT_TIMER) += atmel_pit_timer.o
 | 
				
			||||||
 | 
				
			|||||||
@ -14,7 +14,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
DECLARE_GLOBAL_DATA_PTR;
 | 
					DECLARE_GLOBAL_DATA_PTR;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define REG32_TMR(x)	(*(unsigned long *)	((plat->regs) + (x>>2)))
 | 
					#define REG32_TMR(x)	(*(u32 *)	((plat->regs) + (x>>2)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * Definition of register offsets
 | 
					 * Definition of register offsets
 | 
				
			||||||
@ -67,51 +67,51 @@ struct atctmr_timer_regs {
 | 
				
			|||||||
	u32	int_mask;	/* 0x38 */
 | 
						u32	int_mask;	/* 0x38 */
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct atftmr_timer_platdata {
 | 
					struct atcpit_timer_platdata {
 | 
				
			||||||
	unsigned long *regs;
 | 
						u32 *regs;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int atftmr_timer_get_count(struct udevice *dev, u64 *count)
 | 
					static int atcpit_timer_get_count(struct udevice *dev, u64 *count)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct atftmr_timer_platdata *plat = dev->platdata;
 | 
						struct atcpit_timer_platdata *plat = dev_get_platdata(dev);
 | 
				
			||||||
	u32 val;
 | 
						u32 val;
 | 
				
			||||||
	val = ~(REG32_TMR(CH_CNT(1))+0xffffffff);
 | 
						val = ~(REG32_TMR(CH_CNT(1))+0xffffffff);
 | 
				
			||||||
	*count = timer_conv_64(val);
 | 
						*count = timer_conv_64(val);
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int atctmr_timer_probe(struct udevice *dev)
 | 
					static int atcpit_timer_probe(struct udevice *dev)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct atftmr_timer_platdata *plat = dev->platdata;
 | 
						struct atcpit_timer_platdata *plat = dev_get_platdata(dev);
 | 
				
			||||||
	REG32_TMR(CH_REL(1)) = 0xffffffff;
 | 
						REG32_TMR(CH_REL(1)) = 0xffffffff;
 | 
				
			||||||
	REG32_TMR(CH_CTL(1)) = APB_CLK|TMR_32;
 | 
						REG32_TMR(CH_CTL(1)) = APB_CLK|TMR_32;
 | 
				
			||||||
	REG32_TMR(CH_EN) |= CH_TMR_EN(1 , 0);
 | 
						REG32_TMR(CH_EN) |= CH_TMR_EN(1 , 0);
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int atctme_timer_ofdata_to_platdata(struct udevice *dev)
 | 
					static int atcpit_timer_ofdata_to_platdata(struct udevice *dev)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct atftmr_timer_platdata *plat = dev_get_platdata(dev);
 | 
						struct atcpit_timer_platdata *plat = dev_get_platdata(dev);
 | 
				
			||||||
	plat->regs = map_physmem(devfdt_get_addr(dev) , 0x100 , MAP_NOCACHE);
 | 
						plat->regs = map_physmem(devfdt_get_addr(dev) , 0x100 , MAP_NOCACHE);
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const struct timer_ops ag101p_timer_ops = {
 | 
					static const struct timer_ops atcpit_timer_ops = {
 | 
				
			||||||
	.get_count = atftmr_timer_get_count,
 | 
						.get_count = atcpit_timer_get_count,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const struct udevice_id ag101p_timer_ids[] = {
 | 
					static const struct udevice_id atcpit_timer_ids[] = {
 | 
				
			||||||
	{ .compatible = "andestech,atcpit100" },
 | 
						{ .compatible = "andestech,atcpit100" },
 | 
				
			||||||
	{}
 | 
						{}
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
U_BOOT_DRIVER(altera_timer) = {
 | 
					U_BOOT_DRIVER(atcpit100_timer) = {
 | 
				
			||||||
	.name	= "ae3xx_timer",
 | 
						.name	= "atcpit100_timer",
 | 
				
			||||||
	.id	= UCLASS_TIMER,
 | 
						.id	= UCLASS_TIMER,
 | 
				
			||||||
	.of_match = ag101p_timer_ids,
 | 
						.of_match = atcpit_timer_ids,
 | 
				
			||||||
	.ofdata_to_platdata = atctme_timer_ofdata_to_platdata,
 | 
						.ofdata_to_platdata = atcpit_timer_ofdata_to_platdata,
 | 
				
			||||||
	.platdata_auto_alloc_size = sizeof(struct atftmr_timer_platdata),
 | 
						.platdata_auto_alloc_size = sizeof(struct atcpit_timer_platdata),
 | 
				
			||||||
	.probe = atctmr_timer_probe,
 | 
						.probe = atcpit_timer_probe,
 | 
				
			||||||
	.ops	= &ag101p_timer_ops,
 | 
						.ops	= &atcpit_timer_ops,
 | 
				
			||||||
	.flags = DM_FLAG_PRE_RELOC,
 | 
						.flags = DM_FLAG_PRE_RELOC,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
@ -91,7 +91,6 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 * SD (MMC) controller
 | 
					 * SD (MMC) controller
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
#define CONFIG_FTSDC010
 | 
					 | 
				
			||||||
#define CONFIG_FTSDC010_NUMBER		1
 | 
					#define CONFIG_FTSDC010_NUMBER		1
 | 
				
			||||||
#define CONFIG_FTSDC010_SDIO
 | 
					#define CONFIG_FTSDC010_SDIO
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -97,7 +97,6 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 * SD (MMC) controller
 | 
					 * SD (MMC) controller
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
#define CONFIG_FTSDC010
 | 
					 | 
				
			||||||
#define CONFIG_FTSDC010_NUMBER		1
 | 
					#define CONFIG_FTSDC010_NUMBER		1
 | 
				
			||||||
#define CONFIG_FTSDC010_SDIO
 | 
					#define CONFIG_FTSDC010_SDIO
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user