204 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			204 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/*
 | 
						|
 * arch/sh/boards/st/mb671/setup.c
 | 
						|
 *
 | 
						|
 * Copyright (C) 2007 STMicroelectronics Limited
 | 
						|
 * Author: Stuart Menefy (stuart.menefy@st.com)
 | 
						|
 *
 | 
						|
 * May be copied or modified under the terms of the GNU General Public
 | 
						|
 * License.  See linux/COPYING for more information.
 | 
						|
 *
 | 
						|
 * STMicroelectronics STx7200 Mboard support.
 | 
						|
 */
 | 
						|
 | 
						|
#include <linux/init.h>
 | 
						|
#include <linux/platform_device.h>
 | 
						|
#include <linux/delay.h>
 | 
						|
#include <linux/io.h>
 | 
						|
#include <linux/phy.h>
 | 
						|
#include <linux/stm/emi.h>
 | 
						|
#include <linux/stm/platform.h>
 | 
						|
#include <linux/stm/stx7200.h>
 | 
						|
#include <linux/mtd/mtd.h>
 | 
						|
#include <linux/mtd/physmap.h>
 | 
						|
#include <linux/irq.h>
 | 
						|
#include <asm/irq-ilc.h>
 | 
						|
#include <mach/epld.h>
 | 
						|
#include <mach/common.h>
 | 
						|
 | 
						|
static void __init mb671_setup(char **cmdline_p)
 | 
						|
{
 | 
						|
	printk(KERN_NOTICE "STMicroelectronics STx7200 Mboard "
 | 
						|
			"initialisation\n");
 | 
						|
 | 
						|
	stx7200_early_device_init();
 | 
						|
 | 
						|
	stx7200_configure_asc(2, &(struct stx7200_asc_config) {
 | 
						|
			.hw_flow_control = 1,
 | 
						|
			.is_console = 1 });
 | 
						|
	stx7200_configure_asc(3, &(struct stx7200_asc_config) {
 | 
						|
			.hw_flow_control = 1,
 | 
						|
			.is_console = 0 });
 | 
						|
}
 | 
						|
 | 
						|
/* NOR Flash */
 | 
						|
static void mb671_nor_vpp(struct map_info *map, int vpp)
 | 
						|
{
 | 
						|
	/* Bit 0: VPP enable
 | 
						|
	 * Bit 1: Reset (not used in later EPLD versions)
 | 
						|
	 */
 | 
						|
 | 
						|
	if (vpp) {
 | 
						|
		epld_write(3, EPLD_FLASH);
 | 
						|
	} else {
 | 
						|
		epld_write(2, EPLD_FLASH);
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
static struct platform_device mb671_nor_flash = {
 | 
						|
	.name		= "physmap-flash",
 | 
						|
	.id		= -1,
 | 
						|
	.num_resources	= 1,
 | 
						|
	.resource	= (struct resource[]) {
 | 
						|
		STM_PLAT_RESOURCE_MEM(0, 32*1024*1024),
 | 
						|
	},
 | 
						|
	.dev.platform_data = &(struct physmap_flash_data) {
 | 
						|
		.width		= 2,
 | 
						|
		.set_vpp	= mb671_nor_vpp,
 | 
						|
		.nr_parts	= 3,
 | 
						|
		.parts		= (struct mtd_partition []) {
 | 
						|
			{
 | 
						|
				.name = "NOR Flash 1",
 | 
						|
				.size = 0x00080000,
 | 
						|
				.offset = 0x00000000,
 | 
						|
			}, {
 | 
						|
				.name = "NOR Flash 2",
 | 
						|
				.size = 0x00200000,
 | 
						|
				.offset = MTDPART_OFS_NXTBLK,
 | 
						|
			}, {
 | 
						|
				.name = "NOR Flash 3",
 | 
						|
				.size = MTDPART_SIZ_FULL,
 | 
						|
				.offset = MTDPART_OFS_NXTBLK,
 | 
						|
			},
 | 
						|
		},
 | 
						|
	},
 | 
						|
};
 | 
						|
 | 
						|
static struct stmmac_mdio_bus_data stmmac0_mdio_bus = {
 | 
						|
	.bus_id = 0,
 | 
						|
	.phy_mask = 0,
 | 
						|
};
 | 
						|
 | 
						|
#ifdef CONFIG_SH_ST_MB671_STMMAC1
 | 
						|
static struct stmmac_mdio_bus_data stmmac1_mdio_bus = {
 | 
						|
	.bus_id = 1,
 | 
						|
	.phy_mask = 0,
 | 
						|
	.probed_phy_irq = ILC_IRQ(95),
 | 
						|
};
 | 
						|
#endif
 | 
						|
 | 
						|
static struct platform_device mb671_epld_device = {
 | 
						|
	.name		= "epld",
 | 
						|
	.id		= -1,
 | 
						|
	.num_resources	= 1,
 | 
						|
	.resource	= (struct resource[]) {
 | 
						|
		{
 | 
						|
			.start	= EPLD_BASE,
 | 
						|
			.end	= EPLD_BASE + EPLD_SIZE - 1,
 | 
						|
			.flags	= IORESOURCE_MEM,
 | 
						|
		}
 | 
						|
	},
 | 
						|
	.dev.platform_data = &(struct plat_epld_data) {
 | 
						|
		.opsize = 16,
 | 
						|
	},
 | 
						|
};
 | 
						|
 | 
						|
static struct platform_device *mb671_devices[] __initdata = {
 | 
						|
	&mb671_epld_device,
 | 
						|
	&mb671_nor_flash,
 | 
						|
};
 | 
						|
 | 
						|
static int __init mb671_devices_init(void)
 | 
						|
{
 | 
						|
	unsigned int epld_rev;
 | 
						|
	unsigned int pcb_rev;
 | 
						|
 | 
						|
	epld_rev = epld_read(EPLD_EPLDVER);
 | 
						|
	pcb_rev = epld_read(EPLD_PCBVER);
 | 
						|
	printk(KERN_NOTICE "mb671 PCB rev %X EPLD rev %dr%d\n",
 | 
						|
			pcb_rev, epld_rev >> 4, epld_rev & 0xf);
 | 
						|
 | 
						|
	stx7200_configure_ssc_i2c(0); /* HDMI */
 | 
						|
	/* Usage of the remaining SSC is defined by the peripheral
 | 
						|
	 * board (eg. MB520) */
 | 
						|
 | 
						|
	stx7200_configure_usb(0);
 | 
						|
	stx7200_configure_usb(1);
 | 
						|
	stx7200_configure_usb(2);
 | 
						|
 | 
						|
	stx7200_configure_sata();
 | 
						|
 | 
						|
	/* On-board PHY (MII0) in RMII mode, using MII_CLK */
 | 
						|
	stx7200_configure_ethernet(0, &(struct stx7200_ethernet_config) {
 | 
						|
			.mode = stx7200_ethernet_mode_rmii,
 | 
						|
			.ext_clk = 0,
 | 
						|
			.phy_bus = 0,
 | 
						|
			.phy_addr = -1,
 | 
						|
			.mdio_bus_data = &stmmac0_mdio_bus,
 | 
						|
		});
 | 
						|
#ifdef CONFIG_SH_ST_MB671_STMMAC1
 | 
						|
	/* External PHY board (MB539B) on MII1 in MII mode,
 | 
						|
	   using its own clock */
 | 
						|
	stx7200_configure_ethernet(1, &(struct stx7200_ethernet_config) {
 | 
						|
			.mode = stx7200_ethernet_mode_mii,
 | 
						|
			.ext_clk = 1,
 | 
						|
			.phy_bus = 1,
 | 
						|
			.phy_addr = -1,
 | 
						|
			.mdio_bus_data = &stmmac1_mdio_bus,
 | 
						|
		});
 | 
						|
#endif
 | 
						|
 | 
						|
	return platform_add_devices(mb671_devices, ARRAY_SIZE(mb671_devices));
 | 
						|
}
 | 
						|
arch_initcall(mb671_devices_init);
 | 
						|
 | 
						|
static void __iomem *mb671_ioport_map(unsigned long port, unsigned int size)
 | 
						|
{
 | 
						|
	/* However picking somewhere safe isn't as easy as you might think.
 | 
						|
	 * I used to use external ROM, but that can cause problems if you are
 | 
						|
	 * in the middle of updating Flash. So I'm now using the processor
 | 
						|
	 * core version register, which is guaranted to be available, and
 | 
						|
	 * non-writable. */
 | 
						|
	return (void __iomem *)CCN_PVR;
 | 
						|
}
 | 
						|
 | 
						|
static void __init mb671_init_irq(void)
 | 
						|
{
 | 
						|
	epld_early_init(&mb671_epld_device);
 | 
						|
 | 
						|
#if defined(CONFIG_SH_ST_STEM)
 | 
						|
	/* The off chip interrupts on the mb671 are a mess. The external
 | 
						|
	 * EPLD priority encodes them, but because they pass through the ILC3
 | 
						|
	 * there is no way to decode them.
 | 
						|
	 *
 | 
						|
	 * So here we bodge it as well. Only enable the STEM INTR0 signal,
 | 
						|
	 * and hope nothing else goes active. This will result in
 | 
						|
	 * SYS_ITRQ[3..0] = 0100.
 | 
						|
	 *
 | 
						|
	 * BTW. According to EPLD code author - "masking" interrupts
 | 
						|
	 * means "enabling" them... Just to let you know... ;-)
 | 
						|
	 */
 | 
						|
	epld_write(0xff, EPLD_INTMASK0CLR);
 | 
						|
	epld_write(0xff, EPLD_INTMASK1CLR);
 | 
						|
	/* IntPriority(4) <= not STEM_notINTR0 */
 | 
						|
	epld_write(1 << 4, EPLD_INTMASK0SET);
 | 
						|
#endif
 | 
						|
}
 | 
						|
 | 
						|
struct sh_machine_vector mv_mb671 __initmv = {
 | 
						|
	.mv_name		= "mb671",
 | 
						|
	.mv_setup		= mb671_setup,
 | 
						|
	.mv_nr_irqs		= NR_IRQS,
 | 
						|
	.mv_init_irq		= mb671_init_irq,
 | 
						|
	.mv_ioport_map		= mb671_ioport_map,
 | 
						|
};
 |