mirror of
				https://github.com/smaeul/u-boot.git
				synced 2025-10-31 12:08:19 +00:00 
			
		
		
		
	Merge git://git.denx.de/u-boot-nds32
This commit is contained in:
		
						commit
						d36a27adbb
					
				| @ -69,6 +69,14 @@ | ||||
| 		interrupts = <25 4>; | ||||
| 	}; | ||||
| 
 | ||||
| 	mmc0: mmc@f0e00000 { | ||||
| 		compatible = "andestech,atsdc010"; | ||||
| 		max-frequency = <100000000>; | ||||
| 		fifo-depth = <0x10>; | ||||
| 		reg = <0xf0e00000 0x1000>; | ||||
| 		interrupts = <17 4>; | ||||
| 	}; | ||||
| 
 | ||||
| 	nor@0,0 { | ||||
| 		compatible = "cfi-flash"; | ||||
| 		reg = <0x88000000 0x1000>; | ||||
|  | ||||
| @ -60,4 +60,12 @@ | ||||
| 		reg = <0x90900000 0x1000>; | ||||
| 		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) | ||||
| { | ||||
| #ifndef CONFIG_DM_MMC | ||||
| #ifdef CONFIG_FTSDC010 | ||||
| 	ftsdc010_mmc_init(0); | ||||
| #endif | ||||
| #endif | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| @ -27,12 +27,15 @@ CONFIG_CFI_FLASH=y | ||||
| CONFIG_DM_SPI_FLASH=y | ||||
| CONFIG_SPI_FLASH=y | ||||
| CONFIG_SPI_FLASH_MACRONIX=y | ||||
| CONFIG_DM_MMC=y | ||||
| CONFIG_MMC_NDS32=y | ||||
| CONFIG_FTSDC010=y | ||||
| CONFIG_DM_ETH=y | ||||
| CONFIG_FTMAC100=y | ||||
| CONFIG_BAUDRATE=38400 | ||||
| CONFIG_DM_SERIAL=y | ||||
| CONFIG_SYS_NS16550=y | ||||
| CONFIG_DM_SPI=y | ||||
| CONFIG_NDS_AE3XX_SPI=y | ||||
| CONFIG_ATCSPI200_SPI=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_DM=y | ||||
| CONFIG_MMC=y | ||||
| CONFIG_DM_MMC=y | ||||
| CONFIG_MMC_NDS32=y | ||||
| CONFIG_FTSDC010=y | ||||
| CONFIG_MTD_NOR_FLASH=y | ||||
| CONFIG_DM_ETH=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, | ||||
| 	  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 | ||||
| 
 | ||||
| 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_SDHI) += sh_sdhi.o | ||||
| obj-$(CONFIG_STM32_SDMMC2) += stm32_sdmmc2.o | ||||
| obj-$(CONFIG_MMC_NDS32) += nds32_mmc.o | ||||
| 
 | ||||
| # SDHCI
 | ||||
| obj-$(CONFIG_MMC_SDHCI)			+= sdhci.o | ||||
|  | ||||
| @ -12,24 +12,15 @@ | ||||
| #include <part.h> | ||||
| #include <mmc.h> | ||||
| 
 | ||||
| #include <asm/io.h> | ||||
| #include <linux/io.h> | ||||
| #include <linux/errno.h> | ||||
| #include <asm/byteorder.h> | ||||
| #include <faraday/ftsdc010.h> | ||||
| #include "ftsdc010_mci.h" | ||||
| 
 | ||||
| #define CFG_CMD_TIMEOUT (CONFIG_SYS_HZ >> 4) /* 250 ms */ | ||||
| #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) | ||||
| { | ||||
| 	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) | ||||
| { | ||||
| 	int ret = -ETIMEDOUT; | ||||
| 	uint32_t st, ts; | ||||
| 
 | ||||
| 	for (ts = get_timer(0); get_timer(ts) < CFG_CMD_TIMEOUT; ) { | ||||
| 	uint32_t st, timeout = 10000000; | ||||
| 	while (timeout--) { | ||||
| 		st = readl(®s->status); | ||||
| 		if (!(st & mask)) | ||||
| 			continue; | ||||
| @ -138,8 +128,9 @@ static int ftsdc010_wait(struct ftsdc010_mmc __iomem *regs, uint32_t mask) | ||||
| 		break; | ||||
| 	} | ||||
| 
 | ||||
| 	if (ret) | ||||
| 	if (ret){ | ||||
| 		debug("ftsdc010: wait st(0x%x) timeout\n", mask); | ||||
| 	} | ||||
| 
 | ||||
| 	return ret; | ||||
| } | ||||
| @ -147,10 +138,16 @@ static int ftsdc010_wait(struct ftsdc010_mmc __iomem *regs, uint32_t mask) | ||||
| /*
 | ||||
|  * 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, | ||||
| 	struct mmc_data *data) | ||||
| { | ||||
| #endif | ||||
| 	int ret = -EOPNOTSUPP; | ||||
| 	uint32_t len = 0; | ||||
| 	struct ftsdc010_chip *chip = mmc->priv; | ||||
| @ -245,14 +242,20 @@ static int ftsdc010_request(struct mmc *mmc, struct mmc_cmd *cmd, | ||||
| 
 | ||||
| 	if (!ret) { | ||||
| 		ret = ftsdc010_wait(regs, | ||||
| 			FTSDC010_STATUS_DATA_END | FTSDC010_STATUS_DATA_ERROR); | ||||
| 			FTSDC010_STATUS_DATA_END | FTSDC010_STATUS_DATA_CRC_OK); | ||||
| 	} | ||||
| 
 | ||||
| 	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) | ||||
| { | ||||
| #endif | ||||
| 	struct ftsdc010_chip *chip = mmc->priv; | ||||
| 	struct ftsdc010_mmc __iomem *regs = chip->regs; | ||||
| 
 | ||||
| @ -274,20 +277,43 @@ static int ftsdc010_set_ios(struct mmc *mmc) | ||||
| 	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) | ||||
| { | ||||
| 	struct ftsdc010_chip *chip = mmc->priv; | ||||
| 	struct ftsdc010_mmc __iomem *regs = chip->regs; | ||||
| 	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; | ||||
| 
 | ||||
| 	/* 1. chip reset */ | ||||
| @ -311,11 +337,69 @@ static int ftsdc010_init(struct mmc *mmc) | ||||
| 	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 = { | ||||
| 	.send_cmd	= ftsdc010_request, | ||||
| 	.set_ios	= ftsdc010_set_ios, | ||||
| 	.getcd		= ftsdc010_get_cd, | ||||
| 	.getwp		= ftsdc010_get_wp, | ||||
| 	.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) | ||||
| { | ||||
| @ -345,19 +429,11 @@ int ftsdc010_mmc_init(int devid) | ||||
| #endif | ||||
| 
 | ||||
| 	chip->cfg.name = "ftsdc010"; | ||||
| #ifndef CONFIG_DM_MMC | ||||
| 	chip->cfg.ops = &ftsdc010_ops; | ||||
| #endif | ||||
| 	chip->cfg.host_caps = MMC_MODE_HS | MMC_MODE_HS_52MHz; | ||||
| 	switch (readl(®s->bwr) & FTSDC010_BWR_CAPS_MASK) { | ||||
| 	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; | ||||
| 	} | ||||
| 
 | ||||
| 	set_bus_width(regs , &chip->cfg); | ||||
| 	chip->cfg.voltages  = MMC_VDD_32_33 | MMC_VDD_33_34; | ||||
| 	chip->cfg.f_max     = chip->sclk / 2; | ||||
| 	chip->cfg.f_min     = chip->sclk / 0x100; | ||||
| @ -373,3 +449,4 @@ int ftsdc010_mmc_init(int devid) | ||||
| 
 | ||||
| 	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 | ||||
| 	  Freescale IP core. | ||||
| 
 | ||||
| config NDS_AE3XX_SPI | ||||
| 	bool "Andestech AE3XX SPI driver" | ||||
| config ATCSPI200_SPI | ||||
| 	bool "Andestech ATCSPI200 SPI driver" | ||||
| 	help | ||||
| 	  Enable the Andestech AE3XX SPI driver. This driver can be | ||||
| 	  used to access the SPI flash on platforms embedding this | ||||
| 	  Andestech IP core. | ||||
| 	  Enable the Andestech ATCSPI200 SPI driver. This driver can be | ||||
| 	  used to access the SPI flash on AE3XX and AE250 platforms embedding | ||||
| 	  this Andestech IP core. | ||||
| 
 | ||||
| config TI_QSPI | ||||
| 	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_MXC_SPI) += mxc_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_PIC32_SPI) += pic32_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. | ||||
|  * Author: Rick Chen (rick@andestech.com) | ||||
| @ -25,7 +25,7 @@ DECLARE_GLOBAL_DATA_PTR; | ||||
| #define SPI1_BASE		0xf0f00000 | ||||
| #define NSPI_MAX_CS_NUM		1 | ||||
| 
 | ||||
| struct ae3xx_spi_regs { | ||||
| struct atcspi200_spi_regs { | ||||
| 	u32	rev; | ||||
| 	u32	reserve1[3]; | ||||
| 	u32	format;		/* 0x10 */ | ||||
| @ -78,7 +78,7 @@ struct nds_spi_slave { | ||||
| #ifndef CONFIG_DM_SPI | ||||
| 	struct spi_slave slave; | ||||
| #endif | ||||
| 	volatile struct ae3xx_spi_regs *regs; | ||||
| 	volatile struct atcspi200_spi_regs *regs; | ||||
| 	int		to; | ||||
| 	unsigned int	freq; | ||||
| 	ulong		clock; | ||||
| @ -94,7 +94,7 @@ struct nds_spi_slave { | ||||
| 	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; | ||||
| 	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; | ||||
| 		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; | ||||
| 		format = ns->mode|DATA_LENGTH(8); | ||||
| 		ns->regs->format = format; | ||||
| 		__ae3xx_spi_set_speed(ns); | ||||
| 		__atcspi200_spi_set_speed(ns); | ||||
| 
 | ||||
| 		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 */ | ||||
| 	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 tc = ns->regs->tctrl; | ||||
| @ -168,7 +168,7 @@ static int __ae3xx_spi_start(struct nds_spi_slave *ns) | ||||
| 	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; | ||||
| 	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 long flags) | ||||
| { | ||||
| @ -230,7 +230,7 @@ static int __ae3xx_spi_xfer(struct nds_spi_slave *ns, | ||||
| 			memcpy(cmd_buf, data_out, cmd_len); | ||||
| 			data_out = 0; | ||||
| 			data_len = 0; | ||||
| 			__ae3xx_spi_start(ns); | ||||
| 			__atcspi200_spi_start(ns); | ||||
| 			break; | ||||
| 		} | ||||
| 		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; | ||||
| 			if(num_bytes == 0) | ||||
| 				num_bytes = CHUNK_SIZE; | ||||
| 			__ae3xx_spi_start(ns); | ||||
| 			__atcspi200_spi_start(ns); | ||||
| 
 | ||||
| 			while (num_blks) { | ||||
| 				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->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; | ||||
| } | ||||
| @ -300,11 +300,11 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, | ||||
| 
 | ||||
| 	switch (bus) { | ||||
| 	case SPI0_BUS: | ||||
| 			ns->regs = (struct ae3xx_spi_regs *)SPI0_BASE; | ||||
| 			ns->regs = (struct atcspi200_spi_regs *)SPI0_BASE; | ||||
| 			break; | ||||
| 
 | ||||
| 		case SPI1_BUS: | ||||
| 			ns->regs = (struct ae3xx_spi_regs *)SPI1_BASE; | ||||
| 			ns->regs = (struct atcspi200_spi_regs *)SPI1_BASE; | ||||
| 			break; | ||||
| 
 | ||||
| 		default: | ||||
| @ -336,20 +336,20 @@ void spi_init(void) | ||||
| int spi_claim_bus(struct 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) | ||||
| { | ||||
| 	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, | ||||
| 		void *data_in, unsigned long flags) | ||||
| { | ||||
| 	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) | ||||
| @ -360,28 +360,28 @@ int spi_cs_is_valid(unsigned int bus, unsigned int cs) | ||||
| void spi_cs_activate(struct 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) | ||||
| { | ||||
| 	struct nds_spi_slave *ns = to_nds_spi_slave(slave); | ||||
| 	__ae3xx_spi_stop(ns); | ||||
| 	__atcspi200_spi_stop(ns); | ||||
| } | ||||
| #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); | ||||
| 
 | ||||
| 	debug("%s speed %u\n", __func__, max_hz); | ||||
| 
 | ||||
| 	ns->freq = max_hz; | ||||
| 	__ae3xx_spi_set_speed(ns); | ||||
| 	__atcspi200_spi_set_speed(ns); | ||||
| 
 | ||||
| 	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); | ||||
| 
 | ||||
| @ -391,7 +391,7 @@ static int ae3xx_spi_set_mode(struct udevice *bus, uint mode) | ||||
| 	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 = | ||||
| 		dev_get_parent_platdata(dev); | ||||
| @ -403,27 +403,27 @@ static int ae3xx_spi_claim_bus(struct udevice *dev) | ||||
| 		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); | ||||
| 
 | ||||
| 	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, | ||||
| 			    unsigned long flags) | ||||
| { | ||||
| 	struct udevice *bus = dev->parent; | ||||
| 	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 clk clk; | ||||
| @ -444,26 +444,26 @@ static int ae3xx_spi_get_clk(struct udevice *bus) | ||||
| 	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); | ||||
| 
 | ||||
| 	ns->to = SPI_TIMEOUT; | ||||
| 	ns->max_transfer_length = MAX_TRANSFER_LEN; | ||||
| 	ns->mtiming = ns->regs->timing; | ||||
| 	ae3xx_spi_get_clk(bus); | ||||
| 	atcspi200_spi_get_clk(bus); | ||||
| 
 | ||||
| 	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); | ||||
| 	const void *blob = gd->fdt_blob; | ||||
| 	int node = dev_of_offset(bus); | ||||
| 
 | ||||
| 	ns->regs = map_physmem(devfdt_get_addr(bus), | ||||
| 				 sizeof(struct ae3xx_spi_regs), | ||||
| 				 sizeof(struct atcspi200_spi_regs), | ||||
| 				 MAP_NOCACHE); | ||||
| 	if (!ns->regs) { | ||||
| 		printf("%s: could not map device address\n", __func__); | ||||
| @ -474,26 +474,26 @@ static int ae3xx_ofdata_to_platadata(struct udevice *bus) | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static const struct dm_spi_ops ae3xx_spi_ops = { | ||||
| 	.claim_bus	= ae3xx_spi_claim_bus, | ||||
| 	.release_bus	= ae3xx_spi_release_bus, | ||||
| 	.xfer		= ae3xx_spi_xfer, | ||||
| 	.set_speed	= ae3xx_spi_set_speed, | ||||
| 	.set_mode	= ae3xx_spi_set_mode, | ||||
| static const struct dm_spi_ops atcspi200_spi_ops = { | ||||
| 	.claim_bus	= atcspi200_spi_claim_bus, | ||||
| 	.release_bus	= atcspi200_spi_release_bus, | ||||
| 	.xfer		= atcspi200_spi_xfer, | ||||
| 	.set_speed	= atcspi200_spi_set_speed, | ||||
| 	.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" }, | ||||
| 	{ } | ||||
| }; | ||||
| 
 | ||||
| U_BOOT_DRIVER(ae3xx_spi) = { | ||||
| 	.name = "ae3xx_spi", | ||||
| U_BOOT_DRIVER(atcspi200_spi) = { | ||||
| 	.name = "atcspi200_spi", | ||||
| 	.id = UCLASS_SPI, | ||||
| 	.of_match = ae3xx_spi_ids, | ||||
| 	.ops = &ae3xx_spi_ops, | ||||
| 	.ofdata_to_platdata = ae3xx_ofdata_to_platadata, | ||||
| 	.of_match = atcspi200_spi_ids, | ||||
| 	.ops = &atcspi200_spi_ops, | ||||
| 	.ofdata_to_platdata = atcspi200_ofdata_to_platadata, | ||||
| 	.priv_auto_alloc_size = sizeof(struct nds_spi_slave), | ||||
| 	.probe = ae3xx_spi_probe, | ||||
| 	.probe = atcspi200_spi_probe, | ||||
| }; | ||||
| #endif | ||||
| @ -105,11 +105,12 @@ config AG101P_TIMER | ||||
| 	help | ||||
| 	  Select this to enable a timer for AG01P devices. | ||||
| 
 | ||||
| config AE3XX_TIMER | ||||
| 	bool "AE3XX timer support" | ||||
| 	depends on TIMER && NDS32 | ||||
| config ATCPIT100_TIMER | ||||
| 	bool "ATCPIT100 timer support" | ||||
| 	depends on TIMER | ||||
| 	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 | ||||
|         bool "Rockchip timer support" | ||||
|  | ||||
| @ -13,6 +13,6 @@ obj-$(CONFIG_AST_TIMER)	+= ast_timer.o | ||||
| obj-$(CONFIG_STI_TIMER)		+= sti-timer.o | ||||
| obj-$(CONFIG_ARC_TIMER)	+= arc_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_ATMEL_PIT_TIMER) += atmel_pit_timer.o | ||||
|  | ||||
| @ -14,7 +14,7 @@ | ||||
| 
 | ||||
| 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 | ||||
| @ -67,51 +67,51 @@ struct atctmr_timer_regs { | ||||
| 	u32	int_mask;	/* 0x38 */ | ||||
| }; | ||||
| 
 | ||||
| struct atftmr_timer_platdata { | ||||
| 	unsigned long *regs; | ||||
| struct atcpit_timer_platdata { | ||||
| 	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; | ||||
| 	val = ~(REG32_TMR(CH_CNT(1))+0xffffffff); | ||||
| 	*count = timer_conv_64(val); | ||||
| 	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_CTL(1)) = APB_CLK|TMR_32; | ||||
| 	REG32_TMR(CH_EN) |= CH_TMR_EN(1 , 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); | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static const struct timer_ops ag101p_timer_ops = { | ||||
| 	.get_count = atftmr_timer_get_count, | ||||
| static const struct timer_ops atcpit_timer_ops = { | ||||
| 	.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" }, | ||||
| 	{} | ||||
| }; | ||||
| 
 | ||||
| U_BOOT_DRIVER(altera_timer) = { | ||||
| 	.name	= "ae3xx_timer", | ||||
| U_BOOT_DRIVER(atcpit100_timer) = { | ||||
| 	.name	= "atcpit100_timer", | ||||
| 	.id	= UCLASS_TIMER, | ||||
| 	.of_match = ag101p_timer_ids, | ||||
| 	.ofdata_to_platdata = atctme_timer_ofdata_to_platdata, | ||||
| 	.platdata_auto_alloc_size = sizeof(struct atftmr_timer_platdata), | ||||
| 	.probe = atctmr_timer_probe, | ||||
| 	.ops	= &ag101p_timer_ops, | ||||
| 	.of_match = atcpit_timer_ids, | ||||
| 	.ofdata_to_platdata = atcpit_timer_ofdata_to_platdata, | ||||
| 	.platdata_auto_alloc_size = sizeof(struct atcpit_timer_platdata), | ||||
| 	.probe = atcpit_timer_probe, | ||||
| 	.ops	= &atcpit_timer_ops, | ||||
| 	.flags = DM_FLAG_PRE_RELOC, | ||||
| }; | ||||
| @ -91,7 +91,6 @@ | ||||
| /*
 | ||||
|  * SD (MMC) controller | ||||
|  */ | ||||
| #define CONFIG_FTSDC010 | ||||
| #define CONFIG_FTSDC010_NUMBER		1 | ||||
| #define CONFIG_FTSDC010_SDIO | ||||
| 
 | ||||
|  | ||||
| @ -97,7 +97,6 @@ | ||||
| /*
 | ||||
|  * SD (MMC) controller | ||||
|  */ | ||||
| #define CONFIG_FTSDC010 | ||||
| #define CONFIG_FTSDC010_NUMBER		1 | ||||
| #define CONFIG_FTSDC010_SDIO | ||||
| 
 | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user