1*83d290c5STom Rini // SPDX-License-Identifier: GPL-2.0+
25fb17030SIlya Yanok /*
35fb17030SIlya Yanok  * Copyright (C) 2010 Freescale Semiconductor, Inc.
45fb17030SIlya Yanok  * Copyright (C) 2010 Ilya Yanok, Emcraft Systems, yanok@emcraft.com
55fb17030SIlya Yanok  */
65fb17030SIlya Yanok 
75fb17030SIlya Yanok #include <common.h>
85fb17030SIlya Yanok #include <hwconfig.h>
95fb17030SIlya Yanok #include <i2c.h>
10ea1ea54eSIra W. Snyder #include <spi.h>
11b08c8c48SMasahiro Yamada #include <linux/libfdt.h>
125fb17030SIlya Yanok #include <fdt_support.h>
135fb17030SIlya Yanok #include <pci.h>
145fb17030SIlya Yanok #include <mpc83xx.h>
155fb17030SIlya Yanok #include <vsc7385.h>
165fb17030SIlya Yanok #include <netdev.h>
17db1fc7d2SIra W. Snyder #include <fsl_esdhc.h>
185fb17030SIlya Yanok #include <asm/io.h>
195fb17030SIlya Yanok #include <asm/fsl_serdes.h>
205fb17030SIlya Yanok #include <asm/fsl_mpc83xx_serdes.h>
215fb17030SIlya Yanok 
22ea1ea54eSIra W. Snyder /*
23ea1ea54eSIra W. Snyder  * The following are used to control the SPI chip selects for the SPI command.
24ea1ea54eSIra W. Snyder  */
25ea1ea54eSIra W. Snyder #ifdef CONFIG_MPC8XXX_SPI
26ea1ea54eSIra W. Snyder 
27ea1ea54eSIra W. Snyder #define SPI_CS_MASK	0x00400000
28ea1ea54eSIra W. Snyder 
spi_cs_is_valid(unsigned int bus,unsigned int cs)29ea1ea54eSIra W. Snyder int spi_cs_is_valid(unsigned int bus, unsigned int cs)
30ea1ea54eSIra W. Snyder {
31ea1ea54eSIra W. Snyder 	return bus == 0 && cs == 0;
32ea1ea54eSIra W. Snyder }
33ea1ea54eSIra W. Snyder 
spi_cs_activate(struct spi_slave * slave)34ea1ea54eSIra W. Snyder void spi_cs_activate(struct spi_slave *slave)
35ea1ea54eSIra W. Snyder {
36ea1ea54eSIra W. Snyder 	immap_t *immr = (immap_t *)CONFIG_SYS_IMMR;
37ea1ea54eSIra W. Snyder 
38ea1ea54eSIra W. Snyder 	/* active low */
39ea1ea54eSIra W. Snyder 	clrbits_be32(&immr->gpio[0].dat, SPI_CS_MASK);
40ea1ea54eSIra W. Snyder }
41ea1ea54eSIra W. Snyder 
spi_cs_deactivate(struct spi_slave * slave)42ea1ea54eSIra W. Snyder void spi_cs_deactivate(struct spi_slave *slave)
43ea1ea54eSIra W. Snyder {
44ea1ea54eSIra W. Snyder 	immap_t *immr = (immap_t *)CONFIG_SYS_IMMR;
45ea1ea54eSIra W. Snyder 
46ea1ea54eSIra W. Snyder 	/* inactive high */
47ea1ea54eSIra W. Snyder 	setbits_be32(&immr->gpio[0].dat, SPI_CS_MASK);
48ea1ea54eSIra W. Snyder }
49ea1ea54eSIra W. Snyder #endif /* CONFIG_MPC8XXX_SPI */
50ea1ea54eSIra W. Snyder 
51db1fc7d2SIra W. Snyder #ifdef CONFIG_FSL_ESDHC
board_mmc_init(bd_t * bd)52db1fc7d2SIra W. Snyder int board_mmc_init(bd_t *bd)
53db1fc7d2SIra W. Snyder {
54db1fc7d2SIra W. Snyder 	return fsl_esdhc_mmc_init(bd);
55db1fc7d2SIra W. Snyder }
56db1fc7d2SIra W. Snyder #endif
57db1fc7d2SIra W. Snyder 
read_board_info(void)585fb17030SIlya Yanok static u8 read_board_info(void)
595fb17030SIlya Yanok {
605fb17030SIlya Yanok 	u8 val8;
615fb17030SIlya Yanok 	i2c_set_bus_num(0);
625fb17030SIlya Yanok 
635fb17030SIlya Yanok 	if (i2c_read(CONFIG_SYS_I2C_PCF8574A_ADDR, 0, 0, &val8, 1) == 0)
645fb17030SIlya Yanok 		return val8;
655fb17030SIlya Yanok 	else
665fb17030SIlya Yanok 		return 0;
675fb17030SIlya Yanok }
685fb17030SIlya Yanok 
checkboard(void)695fb17030SIlya Yanok int checkboard(void)
705fb17030SIlya Yanok {
715fb17030SIlya Yanok 	static const char * const rev_str[] = {
725fb17030SIlya Yanok 		"1.0",
735fb17030SIlya Yanok 		"<reserved>",
745fb17030SIlya Yanok 		"<reserved>",
755fb17030SIlya Yanok 		"<reserved>",
765fb17030SIlya Yanok 		"<unknown>",
775fb17030SIlya Yanok 	};
785fb17030SIlya Yanok 	u8 info;
795fb17030SIlya Yanok 	int i;
805fb17030SIlya Yanok 
815fb17030SIlya Yanok 	info = read_board_info();
825fb17030SIlya Yanok 	i = (!info) ? 4 : info & 0x03;
835fb17030SIlya Yanok 
845fb17030SIlya Yanok 	printf("Board: Freescale MPC8308RDB Rev %s\n", rev_str[i]);
855fb17030SIlya Yanok 
865fb17030SIlya Yanok 	return 0;
875fb17030SIlya Yanok }
885fb17030SIlya Yanok 
895fb17030SIlya Yanok static struct pci_region pcie_regions_0[] = {
905fb17030SIlya Yanok 	{
915fb17030SIlya Yanok 		.bus_start = CONFIG_SYS_PCIE1_MEM_BASE,
925fb17030SIlya Yanok 		.phys_start = CONFIG_SYS_PCIE1_MEM_PHYS,
935fb17030SIlya Yanok 		.size = CONFIG_SYS_PCIE1_MEM_SIZE,
945fb17030SIlya Yanok 		.flags = PCI_REGION_MEM,
955fb17030SIlya Yanok 	},
965fb17030SIlya Yanok 	{
975fb17030SIlya Yanok 		.bus_start = CONFIG_SYS_PCIE1_IO_BASE,
985fb17030SIlya Yanok 		.phys_start = CONFIG_SYS_PCIE1_IO_PHYS,
995fb17030SIlya Yanok 		.size = CONFIG_SYS_PCIE1_IO_SIZE,
1005fb17030SIlya Yanok 		.flags = PCI_REGION_IO,
1015fb17030SIlya Yanok 	},
1025fb17030SIlya Yanok };
1035fb17030SIlya Yanok 
pci_init_board(void)1045fb17030SIlya Yanok void pci_init_board(void)
1055fb17030SIlya Yanok {
1065fb17030SIlya Yanok 	immap_t *immr = (immap_t *)CONFIG_SYS_IMMR;
1075fb17030SIlya Yanok 	sysconf83xx_t *sysconf = &immr->sysconf;
1085fb17030SIlya Yanok 	law83xx_t *pcie_law = sysconf->pcielaw;
1095fb17030SIlya Yanok 	struct pci_region *pcie_reg[] = { pcie_regions_0 };
1105fb17030SIlya Yanok 
1115fb17030SIlya Yanok 	fsl_setup_serdes(CONFIG_FSL_SERDES1, FSL_SERDES_PROTO_PEX,
1125fb17030SIlya Yanok 					FSL_SERDES_CLK_100, FSL_SERDES_VDD_1V);
1135fb17030SIlya Yanok 
1145fb17030SIlya Yanok 	/* Deassert the resets in the control register */
1155fb17030SIlya Yanok 	out_be32(&sysconf->pecr1, 0xE0008000);
1165fb17030SIlya Yanok 	udelay(2000);
1175fb17030SIlya Yanok 
1185fb17030SIlya Yanok 	/* Configure PCI Express Local Access Windows */
1195fb17030SIlya Yanok 	out_be32(&pcie_law[0].bar, CONFIG_SYS_PCIE1_BASE & LAWBAR_BAR);
1205fb17030SIlya Yanok 	out_be32(&pcie_law[0].ar, LBLAWAR_EN | LBLAWAR_512MB);
1215fb17030SIlya Yanok 
1226aa3d3bfSPeter Tyser 	mpc83xx_pcie_init(1, pcie_reg);
1235fb17030SIlya Yanok }
1245fb17030SIlya Yanok /*
1255fb17030SIlya Yanok  * Miscellaneous late-boot configurations
1265fb17030SIlya Yanok  *
1275fb17030SIlya Yanok  * If a VSC7385 microcode image is present, then upload it.
1285fb17030SIlya Yanok */
misc_init_r(void)1295fb17030SIlya Yanok int misc_init_r(void)
1305fb17030SIlya Yanok {
131ea1ea54eSIra W. Snyder #ifdef CONFIG_MPC8XXX_SPI
132ea1ea54eSIra W. Snyder 	immap_t *immr = (immap_t *)CONFIG_SYS_IMMR;
133ea1ea54eSIra W. Snyder 	sysconf83xx_t *sysconf = &immr->sysconf;
134ea1ea54eSIra W. Snyder 
135ea1ea54eSIra W. Snyder 	/*
136ea1ea54eSIra W. Snyder 	 * Set proper bits in SICRH to allow SPI on header J8
137ea1ea54eSIra W. Snyder 	 *
138ea1ea54eSIra W. Snyder 	 * NOTE: this breaks the TSEC2 interface, attached to the Vitesse
139ea1ea54eSIra W. Snyder 	 * switch. The pinmux configuration does not have a fine enough
140ea1ea54eSIra W. Snyder 	 * granularity to support both simultaneously.
141ea1ea54eSIra W. Snyder 	 */
142ea1ea54eSIra W. Snyder 	clrsetbits_be32(&sysconf->sicrh, SICRH_GPIO_A_TSEC2, SICRH_GPIO_A_GPIO);
143ea1ea54eSIra W. Snyder 	puts("WARNING: SPI enabled, TSEC2 support is broken\n");
144ea1ea54eSIra W. Snyder 
145ea1ea54eSIra W. Snyder 	/* Set header J8 SPI chip select output, disabled */
146ea1ea54eSIra W. Snyder 	setbits_be32(&immr->gpio[0].dir, SPI_CS_MASK);
147ea1ea54eSIra W. Snyder 	setbits_be32(&immr->gpio[0].dat, SPI_CS_MASK);
148ea1ea54eSIra W. Snyder #endif
149ea1ea54eSIra W. Snyder 
1505fb17030SIlya Yanok #ifdef CONFIG_VSC7385_IMAGE
1515fb17030SIlya Yanok 	if (vsc7385_upload_firmware((void *) CONFIG_VSC7385_IMAGE,
1525fb17030SIlya Yanok 		CONFIG_VSC7385_IMAGE_SIZE)) {
1535fb17030SIlya Yanok 		puts("Failure uploading VSC7385 microcode.\n");
1545fb17030SIlya Yanok 		return 1;
1555fb17030SIlya Yanok 	}
1565fb17030SIlya Yanok #endif
1575fb17030SIlya Yanok 
1585fb17030SIlya Yanok 	return 0;
1595fb17030SIlya Yanok }
1605fb17030SIlya Yanok #if defined(CONFIG_OF_BOARD_SETUP)
ft_board_setup(void * blob,bd_t * bd)161e895a4b0SSimon Glass int ft_board_setup(void *blob, bd_t *bd)
1625fb17030SIlya Yanok {
1635fb17030SIlya Yanok 	ft_cpu_setup(blob, bd);
164a5c289b9SSriram Dash 	fsl_fdt_fixup_dr_usb(blob, bd);
165db1fc7d2SIra W. Snyder 	fdt_fixup_esdhc(blob, bd);
166e895a4b0SSimon Glass 
167e895a4b0SSimon Glass 	return 0;
1685fb17030SIlya Yanok }
1695fb17030SIlya Yanok #endif
1705fb17030SIlya Yanok 
board_eth_init(bd_t * bis)1715fb17030SIlya Yanok int board_eth_init(bd_t *bis)
1725fb17030SIlya Yanok {
1735fb17030SIlya Yanok 	int rv, num_if = 0;
1745fb17030SIlya Yanok 
1755fb17030SIlya Yanok 	/* Initialize TSECs first */
17665ea7589SIlya Yanok 	rv = cpu_eth_init(bis);
17765ea7589SIlya Yanok 	if (rv >= 0)
1785fb17030SIlya Yanok 		num_if += rv;
1795fb17030SIlya Yanok 	else
1805fb17030SIlya Yanok 		printf("ERROR: failed to initialize TSECs.\n");
1815fb17030SIlya Yanok 
18265ea7589SIlya Yanok 	rv = pci_eth_init(bis);
18365ea7589SIlya Yanok 	if (rv >= 0)
1845fb17030SIlya Yanok 		num_if += rv;
1855fb17030SIlya Yanok 	else
1865fb17030SIlya Yanok 		printf("ERROR: failed to initialize PCI Ethernet.\n");
1875fb17030SIlya Yanok 
1885fb17030SIlya Yanok 	return num_if;
1895fb17030SIlya Yanok }
190