summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/sparc/leon3/leon_smc91111/leon_smc91111.c
blob: a0ffd521868bf32ee60005ca3d9e0d09e40c2115 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
/*
 *  $Id$
 */

#include <bsp.h>
#include <libchip/smc91111exp.h>
#include <stdio.h>


#define SMC91111_BASE_ADDR (void*)0x20000300
#define SMC91111_BASE_IRQ  4
#define SMC91111_BASE_PIO  4

scmv91111_configuration_t leon_scmv91111_configuration = {
  SMC91111_BASE_ADDR,                 /* base address */ 
  LEON_TRAP_TYPE(SMC91111_BASE_IRQ),  /* vector number */ 
  SMC91111_BASE_PIO,                  /* PIO */ 
  10,                                 /* 10b */
  1,                                  /* fulldx */
  1                                   /* autoneg */
};

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_leon3 (
  struct rtems_bsdnet_ifconfig *config,
  int                           attach
)
{
  unsigned int iobar, conf,i;

  {
    unsigned long irq_pio, irq_mctrl, addr_pio = 0;
    unsigned long addr_mctrl = 0, addr_timer = 0;

    i = 0;
    while (i < amba_conf.apbslv.devnr) 
      {
        conf = amba_get_confword(amba_conf.apbslv, i, 0);
        if ((amba_vendor(conf) == VENDOR_GAISLER) &&
            (amba_device(conf) == GAISLER_PIOPORT))
    {
      irq_pio = amba_irq(conf);
      iobar = amba_apb_get_membar(amba_conf.apbslv, i);      
      addr_pio = (unsigned long) amba_iobar_start(amba_conf.apbmst, iobar);
    }
        else if ((amba_vendor(conf) == VENDOR_ESA) &&
                 (amba_device(conf) == ESA_MCTRL))
    {
      irq_mctrl = amba_irq(conf);
      iobar = amba_apb_get_membar(amba_conf.apbslv, i);      
      addr_mctrl = (unsigned long) amba_iobar_start(amba_conf.apbmst, iobar);
    }
        else if ((amba_vendor(conf) == VENDOR_GAISLER) &&
                 (amba_device(conf) == GAISLER_GPTIMER))
    {
      iobar = amba_apb_get_membar(amba_conf.apbslv, i);      
      addr_timer = (unsigned long) amba_iobar_start(amba_conf.apbmst, iobar);
    }
        i++;
      }

    if (addr_timer) {
      LEON3_Timer_Regs_Map *timer = (LEON3_Timer_Regs_Map *)addr_timer;
      if (timer->scaler_reload >= 49)
        leon_scmv91111_configuration.ctl_rspeed = 100;
    }
    
    if (addr_pio && addr_mctrl) {
      
      LEON3_IOPORT_Regs_Map *io = (LEON3_IOPORT_Regs_Map *) addr_pio;
      {
        char buf[1024];
        
        sprintf(buf,
          "Activating Leon3 io port for smsc_lan91cxx (pio:%x mctrl:%x)\n",
          (unsigned int)addr_pio,
          (unsigned int)addr_mctrl);
        DEBUG_puts(buf);
      }
      
      *((volatile unsigned int *)addr_mctrl) |= 0x10f80000;  /*mctrl ctrl 1 */
      io->irqmask |= (1 << leon_scmv91111_configuration.pio);
      io->irqpol |= (1 << leon_scmv91111_configuration.pio);
      io->irqedge |= (1 << leon_scmv91111_configuration.pio);
      io->iodir &= ~(1 << leon_scmv91111_configuration.pio);
    } else {
      return 0;
    }
  }
  
  return _rtems_smc91111_driver_attach(config,&leon_scmv91111_configuration);
};