source: rtems/c/src/lib/libbsp/powerpc/mpc55xxevb/network/if_smc.c @ 54a4fe5f

4.115
Last change on this file since 54a4fe5f was 54a4fe5f, checked in by Sebastian Huber <sebastian.huber@…>, on 08/30/11 at 13:58:05

2011-08-30 Peter Dufault <dufault@…>

  • 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.
  • Property mode set to 100644
File size: 4.4 KB
Line 
1/*
2 *  $Id$
3 */
4
5#include <mpc55xx/mpc55xx.h>
6#include <mpc55xx/regs.h>
7
8#include <rtems.h>
9
10#include <bsp.h>
11
12#include <bsp/irq.h>
13#include <rtems/bspIo.h>
14#include <libcpu/powerpc-utility.h>
15
16
17#include <stdlib.h>
18#include <stdio.h>
19#include <stdarg.h>
20#include <rtems/error.h>
21#include <rtems/rtems_bsdnet.h>
22#include <rtems/irq-extension.h>
23
24#include <sys/param.h>
25#include <sys/mbuf.h>
26
27#include <sys/socket.h>
28#include <sys/sockio.h>
29#include <net/if.h>
30#include <netinet/in.h>
31#include <netinet/if_ether.h>
32
33#include <libchip/smc91111exp.h>
34
35
36
37/* The SMC91111 on the MPC5554SOM is IRQ2.
38 */
39#define SMC91111_BASE_ADDR (void*)0x22000300
40#define SMC91111_BASE_IRQ  MPC55XX_IRQ_SIU_EXTERNAL_2
41#define SMC91111_BASE_PIO  4
42
43extern rtems_isr lan91cxx_interrupt_handler(rtems_vector_number v);
44
45static const union SIU_EISR_tag clear_eisr_2 = {.B.EIF2 = 1};
46
47static void rtems_smc91111_interrupt_wrapper(rtems_vector_number v, void *arg)
48{
49    /* Clear external interrupt status */
50
51    SIU.EISR = clear_eisr_2;
52
53    lan91cxx_interrupt_handler(v);
54
55}
56
57scmv91111_configuration_t mpc5554_scmv91111_configuration = {
58  SMC91111_BASE_ADDR, /* base address */
59  SMC91111_BASE_IRQ,  /* vector number */
60  SMC91111_BASE_PIO,  /* XXX: What's this? */
61  100,                /* 100b */
62  1,                  /* fulldx */
63  1,                  /* autoneg */
64  "SMC91111",
65  RTEMS_INTERRUPT_UNIQUE,
66  rtems_smc91111_interrupt_wrapper,
67  (void *)0
68};
69
70int _rtems_smc91111_driver_attach(
71  struct rtems_bsdnet_ifconfig *config,
72  scmv91111_configuration_t    *scm_config
73);
74
75/*
76 * Attach an SMC91111 driver to the system
77 */
78int rtems_smc91111_driver_attach_mpc5554(struct rtems_bsdnet_ifconfig *config)
79{
80  /* Configure IRQ2 (GPIO pin 211) is set up properly:
81   * Secondary, Alternate, Input.
82   */
83  static const union SIU_PCR_tag irq_input_pcr = {
84      .B.PA = 2,     /* Alternate function 1 */
85      .B.OBE = 0,
86      .B.IBE = 1,    /* Input Buffer Enable */
87      .B.DSC = 0,
88      .B.ODE = 0,
89      .B.HYS = 1,
90      .B.SRC = 3,    /* Maximum slew rate */
91      .B.WPE = 0,    /* Disable weak pullup/pulldown */
92      .B.WPS = 1     /* Specify weak pullup?  But it isn't enabled! */
93    };
94
95    union SIU_ORER_tag orer = MPC55XX_ZERO_FLAGS;
96    union SIU_DIRER_tag direr = MPC55XX_ZERO_FLAGS;
97    union SIU_IREER_tag ireer = MPC55XX_ZERO_FLAGS;
98    union SIU_IFEER_tag ifeer = MPC55XX_ZERO_FLAGS;
99    union SIU_IDFR_tag idfr = MPC55XX_ZERO_FLAGS;
100    union SIU_DIRSR_tag dirsr = MPC55XX_ZERO_FLAGS;
101    rtems_interrupt_level level;
102
103#define MPC55XX_EBI_CS_2_BR 0x22000003
104#define MPC55XX_EBI_CS_2_OR 0xff000010
105#if MPC55XX_EBI_CS_2_BR
106    static const union SIU_PCR_tag primary_50pf_weak_pullup = {                 /* 0x4c3 */
107        .B.PA = 1,
108        .B.DSC = 3,
109        .B.WPE = 1,
110        .B.WPS = 1
111    };
112    EBI.CS[2].BR.R = MPC55XX_EBI_CS_2_BR;
113    EBI.CS[2].OR.R = MPC55XX_EBI_CS_2_OR;
114    SIU.PCR[2] = primary_50pf_weak_pullup;
115#endif
116
117    SIU.PCR[211] = irq_input_pcr;
118
119    /* XXX These should be using bit set and bit clear instructions */
120
121    /* DMA/Interrupt Request Select */
122    rtems_interrupt_disable(level);
123    dirsr.R = SIU.DIRSR.R;
124    dirsr.B.DIRS2 = 0;                  /* Select interrupt not DMA */
125    SIU.DIRSR.R = dirsr.R;
126    rtems_interrupt_enable(level);
127
128    /* Overrun Request Enable */
129    rtems_interrupt_disable(level);
130    orer.R = SIU.ORER.R;
131    orer.B.ORE2 = 0;                    /* Disable overruns. */
132    SIU.ORER.R = orer.R;
133    rtems_interrupt_enable(level);
134
135    /* IRQ Rising-Edge Enable */
136    rtems_interrupt_disable(level);
137    ireer.R = SIU.IREER.R;
138    ireer.B.IREE2 = 1;              /* Enable rising edge. */
139    SIU.IREER.R = ireer.R;
140    rtems_interrupt_enable(level);
141
142    /* IRQ Falling-Edge Enable */
143    rtems_interrupt_disable(level);
144    ifeer.R = SIU.IFEER.R;
145    ifeer.B.IFEE2 = 0;              /* Disable falling edge. */
146    SIU.IFEER.R = ifeer.R;
147    rtems_interrupt_enable(level);
148
149    /* IRQ Digital Filter */
150    rtems_interrupt_disable(level);
151    idfr.R = SIU.IDFR.R;
152    idfr.B.DFL = 0;                 /* Minimal digital filter. */
153    SIU.IDFR.R = idfr.R;
154    rtems_interrupt_enable(level);
155
156    /* Clear external interrupt status */
157    SIU.EISR = clear_eisr_2;
158
159    /* DMA/Interrupt Request Enable */
160    rtems_interrupt_disable(level);
161    direr.R = SIU.DIRER.R;
162    direr.B.EIRE2 = 1;              /* Enable. */
163    SIU.DIRER.R = direr.R;
164    rtems_interrupt_enable(level);
165
166    return _rtems_smc91111_driver_attach(config,&mpc5554_scmv91111_configuration);
167};
Note: See TracBrowser for help on using the repository browser.