diff options
Diffstat (limited to 'board/renesas/sh7753evb/sh7753evb.c')
| -rw-r--r-- | board/renesas/sh7753evb/sh7753evb.c | 326 | 
1 files changed, 326 insertions, 0 deletions
| diff --git a/board/renesas/sh7753evb/sh7753evb.c b/board/renesas/sh7753evb/sh7753evb.c new file mode 100644 index 000000000..42b920fb3 --- /dev/null +++ b/board/renesas/sh7753evb/sh7753evb.c @@ -0,0 +1,326 @@ +/* + * Copyright (C) 2012  Renesas Solutions Corp. + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#include <common.h> +#include <malloc.h> +#include <asm/processor.h> +#include <asm/io.h> +#include <asm/mmc.h> +#include <spi_flash.h> + +int checkboard(void) +{ +	puts("BOARD: SH7753 EVB\n"); + +	return 0; +} + +static void init_gpio(void) +{ +	struct gpio_regs *gpio = GPIO_BASE; +	struct sermux_regs *sermux = SERMUX_BASE; + +	/* GPIO */ +	writew(0x0000, &gpio->pacr);	/* GETHER */ +	writew(0x0001, &gpio->pbcr);	/* INTC */ +	writew(0x0000, &gpio->pccr);	/* PWMU, INTC */ +	writew(0x0000, &gpio->pdcr);	/* SPI0 */ +	writew(0xeaff, &gpio->pecr);	/* GPIO */ +	writew(0x0000, &gpio->pfcr);	/* WDT */ +	writew(0x0004, &gpio->pgcr);	/* SPI0, GETHER MDIO gate(PTG1) */ +	writew(0x0000, &gpio->phcr);	/* SPI1 */ +	writew(0x0000, &gpio->picr);	/* SDHI */ +	writew(0x0000, &gpio->pjcr);	/* SCIF4 */ +	writew(0x0003, &gpio->pkcr);	/* SerMux */ +	writew(0x0000, &gpio->plcr);	/* SerMux */ +	writew(0x0000, &gpio->pmcr);	/* RIIC */ +	writew(0x0000, &gpio->pncr);	/* USB, SGPIO */ +	writew(0x0000, &gpio->pocr);	/* SGPIO */ +	writew(0xd555, &gpio->pqcr);	/* GPIO */ +	writew(0x0000, &gpio->prcr);	/* RIIC */ +	writew(0x0000, &gpio->pscr);	/* RIIC */ +	writew(0x0000, &gpio->ptcr);	/* STATUS */ +	writeb(0x00, &gpio->pudr); +	writew(0x5555, &gpio->pucr);	/* Debug LED */ +	writew(0x0000, &gpio->pvcr);	/* RSPI */ +	writew(0x0000, &gpio->pwcr);	/* EVC */ +	writew(0x0000, &gpio->pxcr);	/* LBSC */ +	writew(0x0000, &gpio->pycr);	/* LBSC */ +	writew(0x0000, &gpio->pzcr);	/* eMMC */ +	writew(0xfe00, &gpio->psel0); +	writew(0x0000, &gpio->psel1); +	writew(0x3000, &gpio->psel2); +	writew(0xff00, &gpio->psel3); +	writew(0x771f, &gpio->psel4); +	writew(0x0ffc, &gpio->psel5); +	writew(0x00ff, &gpio->psel6); +	writew(0xfc00, &gpio->psel7); + +	writeb(0x10, &sermux->smr0);	/* SMR0: SerMux mode 0 */ +} + +static void init_usb_phy(void) +{ +	struct usb_common_regs *common0 = USB0_COMMON_BASE; +	struct usb_common_regs *common1 = USB1_COMMON_BASE; +	struct usb0_phy_regs *phy = USB0_PHY_BASE; +	struct usb1_port_regs *port = USB1_PORT_BASE; +	struct usb1_alignment_regs *align = USB1_ALIGNMENT_BASE; + +	writew(0x0100, &phy->reset);		/* set reset */ +	/* port0 = USB0, port1 = USB1 */ +	writew(0x0002, &phy->portsel); +	writel(0x0001, &port->port1sel);	/* port1 = Host */ +	writew(0x0111, &phy->reset);		/* clear reset */ + +	writew(0x4000, &common0->suspmode); +	writew(0x4000, &common1->suspmode); + +#if defined(__LITTLE_ENDIAN) +	writel(0x00000000, &align->ehcidatac); +	writel(0x00000000, &align->ohcidatac); +#endif +} + +static void init_gether_mdio(void) +{ +	struct gpio_regs *gpio = GPIO_BASE; + +	writew(readw(&gpio->pgcr) | 0x0004, &gpio->pgcr); +	writeb(readb(&gpio->pgdr) | 0x02, &gpio->pgdr);	/* Use ET0-MDIO */ +} + +static void set_mac_to_sh_giga_eth_register(int channel, char *mac_string) +{ +	struct ether_mac_regs *ether; +	unsigned char mac[6]; +	unsigned long val; + +	eth_parse_enetaddr(mac_string, mac); + +	if (!channel) +		ether = GETHER0_MAC_BASE; +	else +		ether = GETHER1_MAC_BASE; + +	val = (mac[0] << 24) | (mac[1] << 16) | (mac[2] << 8) | mac[3]; +	writel(val, ðer->mahr); +	val = (mac[4] << 8) | mac[5]; +	writel(val, ðer->malr); +} + +/***************************************************************** + * This PMB must be set on this timing. The lowlevel_init is run on + * Area 0(phys 0x00000000), so we have to map it. + * + * The new PMB table is following: + * ent	virt		phys		v	sz	c	wt + * 0	0xa0000000	0x40000000	1	128M	0	1 + * 1	0xa8000000	0x48000000	1	128M	0	1 + * 2	0xb0000000	0x50000000	1	128M	0	1 + * 3	0xb8000000	0x58000000	1	128M	0	1 + * 4	0x80000000	0x40000000	1	128M	1	1 + * 5	0x88000000	0x48000000	1	128M	1	1 + * 6	0x90000000	0x50000000	1	128M	1	1 + * 7	0x98000000	0x58000000	1	128M	1	1 + */ +static void set_pmb_on_board_init(void) +{ +	struct mmu_regs *mmu = MMU_BASE; + +	/* clear ITLB */ +	writel(0x00000004, &mmu->mmucr); + +	/* delete PMB for SPIBOOT */ +	writel(0, PMB_ADDR_BASE(0)); +	writel(0, PMB_DATA_BASE(0)); + +	/* add PMB for SDRAM(0x40000000 - 0x47ffffff) */ +	/*			ppn  ub v s1 s0  c  wt */ +	writel(mk_pmb_addr_val(0xa0), PMB_ADDR_BASE(0)); +	writel(mk_pmb_data_val(0x40, 1, 1, 1, 0, 0, 1), PMB_DATA_BASE(0)); +	writel(mk_pmb_addr_val(0xb0), PMB_ADDR_BASE(2)); +	writel(mk_pmb_data_val(0x50, 1, 1, 1, 0, 0, 1), PMB_DATA_BASE(2)); +	writel(mk_pmb_addr_val(0xb8), PMB_ADDR_BASE(3)); +	writel(mk_pmb_data_val(0x58, 1, 1, 1, 0, 0, 1), PMB_DATA_BASE(3)); +	writel(mk_pmb_addr_val(0x80), PMB_ADDR_BASE(4)); +	writel(mk_pmb_data_val(0x40, 0, 1, 1, 0, 1, 1), PMB_DATA_BASE(4)); +	writel(mk_pmb_addr_val(0x90), PMB_ADDR_BASE(6)); +	writel(mk_pmb_data_val(0x50, 0, 1, 1, 0, 1, 1), PMB_DATA_BASE(6)); +	writel(mk_pmb_addr_val(0x98), PMB_ADDR_BASE(7)); +	writel(mk_pmb_data_val(0x58, 0, 1, 1, 0, 1, 1), PMB_DATA_BASE(7)); +} + +int board_init(void) +{ +	struct gether_control_regs *gether = GETHER_CONTROL_BASE; + +	init_gpio(); +	set_pmb_on_board_init(); + +	/* Sets TXnDLY to B'010 */ +	writel(0x00000202, &gether->gbecont); + +	init_usb_phy(); +	init_gether_mdio(); + +	return 0; +} + +int dram_init(void) +{ +	DECLARE_GLOBAL_DATA_PTR; + +	gd->bd->bi_memstart = CONFIG_SYS_SDRAM_BASE; +	gd->bd->bi_memsize = CONFIG_SYS_SDRAM_SIZE; +	printf("DRAM:  %dMB\n", CONFIG_SYS_SDRAM_SIZE / (1024 * 1024)); + +	return 0; +} + +int board_mmc_init(bd_t *bis) +{ +	struct gpio_regs *gpio = GPIO_BASE; + +	writew(readw(&gpio->pgcr) | 0x0040, &gpio->pgcr); +	writeb(readb(&gpio->pgdr) & ~0x08, &gpio->pgdr); /* Reset */ +	udelay(1); +	writeb(readb(&gpio->pgdr) | 0x08, &gpio->pgdr);	/* Release reset */ +	udelay(200); + +	return mmcif_mmc_init(); +} + +static int get_sh_eth_mac_raw(unsigned char *buf, int size) +{ +	struct spi_flash *spi; +	int ret; + +	spi = spi_flash_probe(0, 0, 1000000, SPI_MODE_3); +	if (spi == NULL) { +		printf("%s: spi_flash probe failed.\n", __func__); +		return 1; +	} + +	ret = spi_flash_read(spi, SH7753EVB_ETHERNET_MAC_BASE, size, buf); +	if (ret) { +		printf("%s: spi_flash read failed.\n", __func__); +		spi_flash_free(spi); +		return 1; +	} +	spi_flash_free(spi); + +	return 0; +} + +static int get_sh_eth_mac(int channel, char *mac_string, unsigned char *buf) +{ +	memcpy(mac_string, &buf[channel * (SH7753EVB_ETHERNET_MAC_SIZE + 1)], +		SH7753EVB_ETHERNET_MAC_SIZE); +	mac_string[SH7753EVB_ETHERNET_MAC_SIZE] = 0x00;	/* terminate */ + +	return 0; +} + +static void init_ethernet_mac(void) +{ +	char mac_string[64]; +	char env_string[64]; +	int i; +	unsigned char *buf; + +	buf = malloc(256); +	if (!buf) { +		printf("%s: malloc failed.\n", __func__); +		return; +	} +	get_sh_eth_mac_raw(buf, 256); + +	/* Gigabit Ethernet */ +	for (i = 0; i < SH7753EVB_ETHERNET_NUM_CH; i++) { +		get_sh_eth_mac(i, mac_string, buf); +		if (i == 0) +			setenv("ethaddr", mac_string); +		else { +			sprintf(env_string, "eth%daddr", i); +			setenv(env_string, mac_string); +		} +		set_mac_to_sh_giga_eth_register(i, mac_string); +	} + +	free(buf); +} + +int board_late_init(void) +{ +	init_ethernet_mac(); + +	return 0; +} + +int do_write_mac(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ +	int i, ret; +	char mac_string[256]; +	struct spi_flash *spi; +	unsigned char *buf; + +	if (argc != 3) { +		buf = malloc(256); +		if (!buf) { +			printf("%s: malloc failed.\n", __func__); +			return 1; +		} + +		get_sh_eth_mac_raw(buf, 256); + +		/* print current MAC address */ +		for (i = 0; i < SH7753EVB_ETHERNET_NUM_CH; i++) { +			get_sh_eth_mac(i, mac_string, buf); +			printf("GETHERC ch%d = %s\n", i, mac_string); +		} +		free(buf); +		return 0; +	} + +	/* new setting */ +	memset(mac_string, 0xff, sizeof(mac_string)); +	sprintf(mac_string, "%s\t%s", +		argv[1], argv[2]); + +	/* write MAC data to SPI rom */ +	spi = spi_flash_probe(0, 0, 1000000, SPI_MODE_3); +	if (!spi) { +		printf("%s: spi_flash probe failed.\n", __func__); +		return 1; +	} + +	ret = spi_flash_erase(spi, SH7753EVB_ETHERNET_MAC_BASE_SPI, +				SH7753EVB_SPI_SECTOR_SIZE); +	if (ret) { +		printf("%s: spi_flash erase failed.\n", __func__); +		return 1; +	} + +	ret = spi_flash_write(spi, SH7753EVB_ETHERNET_MAC_BASE_SPI, +				sizeof(mac_string), mac_string); +	if (ret) { +		printf("%s: spi_flash write failed.\n", __func__); +		spi_flash_free(spi); +		return 1; +	} +	spi_flash_free(spi); + +	puts("The writing of the MAC address to SPI ROM was completed.\n"); + +	return 0; +} + +U_BOOT_CMD( +	write_mac,	3,	1,	do_write_mac, +	"write MAC address for GETHERC", +	"[GETHERC ch0] [GETHERC ch1]\n" +); |