summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/powerpc/mpc55xxevb/network
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2011-08-30 13:58:05 +0000
committerSebastian Huber <sebastian.huber@embedded-brains.de>2011-08-30 13:58:05 +0000
commit54a4fe5fa936681fd07c8ac6734b53c5ee369f00 (patch)
tree23ed53ba362483535bfeb927ebc21489fda7f4e6 /c/src/lib/libbsp/powerpc/mpc55xxevb/network
parent2011-08-30 Peter Dufault <dufault@hda.com> (diff)
downloadrtems-54a4fe5fa936681fd07c8ac6734b53c5ee369f00.tar.bz2
2011-08-30 Peter Dufault <dufault@hda.com>
* make/custom/phycore_mpc5554.cfg, startup/linkcmds.phycore_mpc5554, network/if_smc.c: New files. * Makefile.am, preinstall.am: Reflect changes above. * configure.ac: Add support for the Phytec PhyCORE MPC5554. Includes: - HAS_SMC91111 to indicate a BSP has that neworking. - SMC91111_ENADDR_IS_SETUP so that it skips code to set up the MAC address. - MPC55XX_CLOCK_EMIOS_CHANNEL to permit one to set which eMIOS channel to use for the clock. - MPC55XX_BOOTFLAGS: Skips two words above the RCHW in the startup for use in skpping over the MMU setup. Required for debugging via a cheap emulator where code is loaded into RAM and then mapped in as flash. - BOARD_PHYCORE_MPC5554 If defined, use custom settings for the Phytec PhyCORE MPC5554 SOM. * clock/clock-config.c: Modify so that the EMIOS channel used for the clock can be selected at configuration time. For MPC5544 only: - Conditionally skip access to a register that faults if accessed on the MPC5554 - Do not set the control register mode as was done for GW_LCFM support, it breaks interrupts. * make/custom/mpc55xx.inc: Make it possible to override the soft-float to set the type of floating point BSP will use. * startup/start.S: Add support for the "boot flags", two long-words that I manipulate with the debugger to skip over MMU setup. Use an external for the start of external SRAM instead of the hardwired number 0x20000000. Disable write access to the internal flash.
Diffstat (limited to 'c/src/lib/libbsp/powerpc/mpc55xxevb/network')
-rw-r--r--c/src/lib/libbsp/powerpc/mpc55xxevb/network/if_smc.c167
1 files changed, 167 insertions, 0 deletions
diff --git a/c/src/lib/libbsp/powerpc/mpc55xxevb/network/if_smc.c b/c/src/lib/libbsp/powerpc/mpc55xxevb/network/if_smc.c
new file mode 100644
index 0000000000..c16dcda022
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/mpc55xxevb/network/if_smc.c
@@ -0,0 +1,167 @@
+/*
+ * $Id$
+ */
+
+#include <mpc55xx/mpc55xx.h>
+#include <mpc55xx/regs.h>
+
+#include <rtems.h>
+
+#include <bsp.h>
+
+#include <bsp/irq.h>
+#include <rtems/bspIo.h>
+#include <libcpu/powerpc-utility.h>
+
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <rtems/error.h>
+#include <rtems/rtems_bsdnet.h>
+#include <rtems/irq-extension.h>
+
+#include <sys/param.h>
+#include <sys/mbuf.h>
+
+#include <sys/socket.h>
+#include <sys/sockio.h>
+#include <net/if.h>
+#include <netinet/in.h>
+#include <netinet/if_ether.h>
+
+#include <libchip/smc91111exp.h>
+
+
+
+/* The SMC91111 on the MPC5554SOM is IRQ2.
+ */
+#define SMC91111_BASE_ADDR (void*)0x22000300
+#define SMC91111_BASE_IRQ MPC55XX_IRQ_SIU_EXTERNAL_2
+#define SMC91111_BASE_PIO 4
+
+extern rtems_isr lan91cxx_interrupt_handler(rtems_vector_number v);
+
+static const union SIU_EISR_tag clear_eisr_2 = {.B.EIF2 = 1};
+
+static void rtems_smc91111_interrupt_wrapper(rtems_vector_number v, void *arg)
+{
+ /* Clear external interrupt status */
+
+ SIU.EISR = clear_eisr_2;
+
+ lan91cxx_interrupt_handler(v);
+
+}
+
+scmv91111_configuration_t mpc5554_scmv91111_configuration = {
+ SMC91111_BASE_ADDR, /* base address */
+ SMC91111_BASE_IRQ, /* vector number */
+ SMC91111_BASE_PIO, /* XXX: What's this? */
+ 100, /* 100b */
+ 1, /* fulldx */
+ 1, /* autoneg */
+ "SMC91111",
+ RTEMS_INTERRUPT_UNIQUE,
+ rtems_smc91111_interrupt_wrapper,
+ (void *)0
+};
+
+int _rtems_smc91111_driver_attach(
+ struct rtems_bsdnet_ifconfig *config,
+ scmv91111_configuration_t *scm_config
+);
+
+/*
+ * Attach an SMC91111 driver to the system
+ */
+int rtems_smc91111_driver_attach_mpc5554(struct rtems_bsdnet_ifconfig *config)
+{
+ /* Configure IRQ2 (GPIO pin 211) is set up properly:
+ * Secondary, Alternate, Input.
+ */
+ static const union SIU_PCR_tag irq_input_pcr = {
+ .B.PA = 2, /* Alternate function 1 */
+ .B.OBE = 0,
+ .B.IBE = 1, /* Input Buffer Enable */
+ .B.DSC = 0,
+ .B.ODE = 0,
+ .B.HYS = 1,
+ .B.SRC = 3, /* Maximum slew rate */
+ .B.WPE = 0, /* Disable weak pullup/pulldown */
+ .B.WPS = 1 /* Specify weak pullup? But it isn't enabled! */
+ };
+
+ union SIU_ORER_tag orer = MPC55XX_ZERO_FLAGS;
+ union SIU_DIRER_tag direr = MPC55XX_ZERO_FLAGS;
+ union SIU_IREER_tag ireer = MPC55XX_ZERO_FLAGS;
+ union SIU_IFEER_tag ifeer = MPC55XX_ZERO_FLAGS;
+ union SIU_IDFR_tag idfr = MPC55XX_ZERO_FLAGS;
+ union SIU_DIRSR_tag dirsr = MPC55XX_ZERO_FLAGS;
+ rtems_interrupt_level level;
+
+#define MPC55XX_EBI_CS_2_BR 0x22000003
+#define MPC55XX_EBI_CS_2_OR 0xff000010
+#if MPC55XX_EBI_CS_2_BR
+ static const union SIU_PCR_tag primary_50pf_weak_pullup = { /* 0x4c3 */
+ .B.PA = 1,
+ .B.DSC = 3,
+ .B.WPE = 1,
+ .B.WPS = 1
+ };
+ EBI.CS[2].BR.R = MPC55XX_EBI_CS_2_BR;
+ EBI.CS[2].OR.R = MPC55XX_EBI_CS_2_OR;
+ SIU.PCR[2] = primary_50pf_weak_pullup;
+#endif
+
+ SIU.PCR[211] = irq_input_pcr;
+
+ /* XXX These should be using bit set and bit clear instructions */
+
+ /* DMA/Interrupt Request Select */
+ rtems_interrupt_disable(level);
+ dirsr.R = SIU.DIRSR.R;
+ dirsr.B.DIRS2 = 0; /* Select interrupt not DMA */
+ SIU.DIRSR.R = dirsr.R;
+ rtems_interrupt_enable(level);
+
+ /* Overrun Request Enable */
+ rtems_interrupt_disable(level);
+ orer.R = SIU.ORER.R;
+ orer.B.ORE2 = 0; /* Disable overruns. */
+ SIU.ORER.R = orer.R;
+ rtems_interrupt_enable(level);
+
+ /* IRQ Rising-Edge Enable */
+ rtems_interrupt_disable(level);
+ ireer.R = SIU.IREER.R;
+ ireer.B.IREE2 = 1; /* Enable rising edge. */
+ SIU.IREER.R = ireer.R;
+ rtems_interrupt_enable(level);
+
+ /* IRQ Falling-Edge Enable */
+ rtems_interrupt_disable(level);
+ ifeer.R = SIU.IFEER.R;
+ ifeer.B.IFEE2 = 0; /* Disable falling edge. */
+ SIU.IFEER.R = ifeer.R;
+ rtems_interrupt_enable(level);
+
+ /* IRQ Digital Filter */
+ rtems_interrupt_disable(level);
+ idfr.R = SIU.IDFR.R;
+ idfr.B.DFL = 0; /* Minimal digital filter. */
+ SIU.IDFR.R = idfr.R;
+ rtems_interrupt_enable(level);
+
+ /* Clear external interrupt status */
+ SIU.EISR = clear_eisr_2;
+
+ /* DMA/Interrupt Request Enable */
+ rtems_interrupt_disable(level);
+ direr.R = SIU.DIRER.R;
+ direr.B.EIRE2 = 1; /* Enable. */
+ SIU.DIRER.R = direr.R;
+ rtems_interrupt_enable(level);
+
+ return _rtems_smc91111_driver_attach(config,&mpc5554_scmv91111_configuration);
+};