diff options
Diffstat (limited to 'roms/u-boot/board/synopsys')
| -rw-r--r-- | roms/u-boot/board/synopsys/axs101/Makefile | 8 | ||||
| -rw-r--r-- | roms/u-boot/board/synopsys/axs101/axs101.c | 44 | ||||
| -rw-r--r-- | roms/u-boot/board/synopsys/axs101/nand.c | 234 | 
3 files changed, 286 insertions, 0 deletions
diff --git a/roms/u-boot/board/synopsys/axs101/Makefile b/roms/u-boot/board/synopsys/axs101/Makefile new file mode 100644 index 00000000..f0965f78 --- /dev/null +++ b/roms/u-boot/board/synopsys/axs101/Makefile @@ -0,0 +1,8 @@ +# +# Copyright (C) 2013-2014 Synopsys, Inc. All rights reserved. +# +# SPDX-License-Identifier:	GPL-2.0+ +# + +obj-y	+= axs101.o +obj-$(CONFIG_CMD_NAND) += nand.o diff --git a/roms/u-boot/board/synopsys/axs101/axs101.c b/roms/u-boot/board/synopsys/axs101/axs101.c new file mode 100644 index 00000000..d1271ffc --- /dev/null +++ b/roms/u-boot/board/synopsys/axs101/axs101.c @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2013-2014 Synopsys, Inc. All rights reserved. + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#include <common.h> +#include <dwmmc.h> +#include <malloc.h> +#include <netdev.h> +#include <phy.h> + +DECLARE_GLOBAL_DATA_PTR; + +int board_mmc_init(bd_t *bis) +{ +	struct dwmci_host *host = NULL; + +	host = malloc(sizeof(struct dwmci_host)); +	if (!host) { +		printf("dwmci_host malloc fail!\n"); +		return 1; +	} + +	memset(host, 0, sizeof(struct dwmci_host)); +	host->name = "Synopsys Mobile storage"; +	host->ioaddr = (void *)ARC_DWMMC_BASE; +	host->buswidth = 4; +	host->dev_index = 0; +	host->bus_hz = 25000000; + +	add_dwmci(host, 52000000, 400000); + +	return 0; +} + +int board_eth_init(bd_t *bis) +{ +	if (designware_initialize(ARC_DWGMAC_BASE, +				  PHY_INTERFACE_MODE_RGMII) >= 0) +		return 1; + +	return 0; +} diff --git a/roms/u-boot/board/synopsys/axs101/nand.c b/roms/u-boot/board/synopsys/axs101/nand.c new file mode 100644 index 00000000..c7f90c44 --- /dev/null +++ b/roms/u-boot/board/synopsys/axs101/nand.c @@ -0,0 +1,234 @@ +/* + * Copyright (C) 2013-2014 Synopsys, Inc. All rights reserved. + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#include <bouncebuf.h> +#include <common.h> +#include <malloc.h> +#include <nand.h> +#include <asm/io.h> + +#define BUS_WIDTH	8		/* AXI data bus width in bytes	*/ + +/* DMA buffer descriptor bits & masks */ +#define BD_STAT_OWN			(1 << 31) +#define BD_STAT_BD_FIRST		(1 << 3) +#define BD_STAT_BD_LAST			(1 << 2) +#define BD_SIZES_BUFFER1_MASK		0xfff + +#define BD_STAT_BD_COMPLETE	(BD_STAT_BD_FIRST | BD_STAT_BD_LAST) + +/* Controller command flags */ +#define B_WFR		(1 << 19)	/* 1b - Wait for ready		*/ +#define B_LC		(1 << 18)	/* 1b - Last cycle		*/ +#define B_IWC		(1 << 13)	/* 1b - Interrupt when complete	*/ + +/* NAND cycle types */ +#define B_CT_ADDRESS	(0x0 << 16)	/* Address operation		*/ +#define B_CT_COMMAND	(0x1 << 16)	/* Command operation		*/ +#define B_CT_WRITE	(0x2 << 16)	/* Write operation		*/ +#define B_CT_READ	(0x3 << 16)	/* Write operation		*/ + +enum nand_isr_t { +	NAND_ISR_DATAREQUIRED = 0, +	NAND_ISR_TXUNDERFLOW, +	NAND_ISR_TXOVERFLOW, +	NAND_ISR_DATAAVAILABLE, +	NAND_ISR_RXUNDERFLOW, +	NAND_ISR_RXOVERFLOW, +	NAND_ISR_TXDMACOMPLETE, +	NAND_ISR_RXDMACOMPLETE, +	NAND_ISR_DESCRIPTORUNAVAILABLE, +	NAND_ISR_CMDDONE, +	NAND_ISR_CMDAVAILABLE, +	NAND_ISR_CMDERROR, +	NAND_ISR_DATATRANSFEROVER, +	NAND_ISR_NONE +}; + +enum nand_regs_t { +	AC_FIFO = 0,		/* address and command fifo */ +	IDMAC_BDADDR = 0x18,	/* idmac descriptor list base address */ +	INT_STATUS = 0x118,	/* interrupt status register */ +	INT_CLR_STATUS = 0x120,	/* interrupt clear status register */ +}; + +struct nand_bd { +	uint32_t status;	/* DES0 */ +	uint32_t sizes;		/* DES1 */ +	uint32_t buffer_ptr0;	/* DES2 */ +	uint32_t buffer_ptr1;	/* DES3 */ +}; + +#define NAND_REG_WRITE(r, v)	writel(v, CONFIG_SYS_NAND_BASE + r) +#define NAND_REG_READ(r)	readl(CONFIG_SYS_NAND_BASE + r) + +static struct nand_bd *bd;	/* DMA buffer descriptors	*/ + +/** + * axs101_nand_write_buf -  write buffer to chip + * @mtd:	MTD device structure + * @buf:	data buffer + * @len:	number of bytes to write + */ +static uint32_t nand_flag_is_set(uint32_t flag) +{ +	uint32_t reg = NAND_REG_READ(INT_STATUS); + +	if (reg & (1 << NAND_ISR_CMDERROR)) +		return 0; + +	if (reg & (1 << flag)) { +		NAND_REG_WRITE(INT_CLR_STATUS, 1 << flag); +		return 1; +	} + +	return 0; +} + +/** + * axs101_nand_write_buf -  write buffer to chip + * @mtd:	MTD device structure + * @buf:	data buffer + * @len:	number of bytes to write + */ +static void axs101_nand_write_buf(struct mtd_info *mtd, const u_char *buf, +				   int len) +{ +	struct bounce_buffer bbstate; + +	bounce_buffer_start(&bbstate, (void *)buf, len, GEN_BB_READ); + +	/* Setup buffer descriptor */ +	writel(BD_STAT_OWN | BD_STAT_BD_COMPLETE, &bd->status); +	writel(ALIGN(len, BUS_WIDTH) & BD_SIZES_BUFFER1_MASK, &bd->sizes); +	writel(bbstate.bounce_buffer, &bd->buffer_ptr0); +	writel(0, &bd->buffer_ptr1); + +	/* Flush modified buffer descriptor */ +	flush_dcache_range((unsigned long)bd, +			   (unsigned long)bd + sizeof(struct nand_bd)); + +	/* Issue "write" command */ +	NAND_REG_WRITE(AC_FIFO, B_CT_WRITE | B_WFR | B_IWC | B_LC | (len-1)); + +	/* Wait for NAND command and DMA to complete */ +	while (!nand_flag_is_set(NAND_ISR_CMDDONE)) +		; +	while (!nand_flag_is_set(NAND_ISR_TXDMACOMPLETE)) +		; + +	bounce_buffer_stop(&bbstate); +} + +/** + * axs101_nand_read_buf -  read chip data into buffer + * @mtd:	MTD device structure + * @buf:	buffer to store data + * @len:	number of bytes to read + */ +static void axs101_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len) +{ +	struct bounce_buffer bbstate; + +	bounce_buffer_start(&bbstate, buf, len, GEN_BB_WRITE); + +	/* Setup buffer descriptor */ +	writel(BD_STAT_OWN | BD_STAT_BD_COMPLETE, &bd->status); +	writel(ALIGN(len, BUS_WIDTH) & BD_SIZES_BUFFER1_MASK, &bd->sizes); +	writel(bbstate.bounce_buffer, &bd->buffer_ptr0); +	writel(0, &bd->buffer_ptr1); + +	/* Flush modified buffer descriptor */ +	flush_dcache_range((unsigned long)bd, +			   (unsigned long)bd + sizeof(struct nand_bd)); + +	/* Issue "read" command */ +	NAND_REG_WRITE(AC_FIFO, B_CT_READ | B_WFR | B_IWC | B_LC | (len - 1)); + +	/* Wait for NAND command and DMA to complete */ +	while (!nand_flag_is_set(NAND_ISR_CMDDONE)) +		; +	while (!nand_flag_is_set(NAND_ISR_RXDMACOMPLETE)) +		; + +	bounce_buffer_stop(&bbstate); +} + +/** + * axs101_nand_read_byte -  read one byte from the chip + * @mtd:	MTD device structure + */ +static u_char axs101_nand_read_byte(struct mtd_info *mtd) +{ +	u8 byte; + +	axs101_nand_read_buf(mtd, (uchar *)&byte, sizeof(byte)); +	return byte; +} + +/** + * axs101_nand_read_word -  read one word from the chip + * @mtd:	MTD device structure + */ +static u16 axs101_nand_read_word(struct mtd_info *mtd) +{ +	u16 word; + +	axs101_nand_read_buf(mtd, (uchar *)&word, sizeof(word)); +	return word; +} + +/** + * axs101_nand_hwcontrol - NAND control functions wrapper. + * @mtd:	MTD device structure + * @cmd:	Command + */ +static void axs101_nand_hwcontrol(struct mtd_info *mtdinfo, int cmd, +				   unsigned int ctrl) +{ +	if (cmd == NAND_CMD_NONE) +		return; + +	cmd = cmd & 0xff; + +	switch (ctrl & (NAND_ALE | NAND_CLE)) { +	/* Address */ +	case NAND_ALE: +		cmd |= B_CT_ADDRESS; +		break; + +	/* Command */ +	case NAND_CLE: +		cmd |= B_CT_COMMAND | B_WFR; + +		break; + +	default: +		debug("%s: unknown ctrl %#x\n", __func__, ctrl); +	} + +	NAND_REG_WRITE(AC_FIFO, cmd | B_LC); +	while (!nand_flag_is_set(NAND_ISR_CMDDONE)) +		; +} + +int board_nand_init(struct nand_chip *nand) +{ +	bd = (struct nand_bd *)memalign(ARCH_DMA_MINALIGN, +					sizeof(struct nand_bd)); + +	/* Set buffer descriptor address in IDMAC */ +	NAND_REG_WRITE(IDMAC_BDADDR, bd); + +	nand->ecc.mode = NAND_ECC_SOFT; +	nand->cmd_ctrl = axs101_nand_hwcontrol; +	nand->read_byte = axs101_nand_read_byte; +	nand->read_word = axs101_nand_read_word; +	nand->write_buf = axs101_nand_write_buf; +	nand->read_buf = axs101_nand_read_buf; + +	return 0; +}  | 
