The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/arm/cavium/cns11xx/econa.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * Copyright (c) 2009 Yohanes Nugroho <yohanes@gmail.com>
    3  * All rights reserved.
    4  *
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions
    7  * are met:
    8  * 1. Redistributions of source code must retain the above copyright
    9  *    notice, this list of conditions and the following disclaimer.
   10  * 2. Redistributions in binary form must reproduce the above copyright
   11  *    notice, this list of conditions and the following disclaimer in the
   12  *    documentation and/or other materials provided with the distribution.
   13  *
   14  * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   17  * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
   18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   24  * SUCH DAMAGE.
   25  */
   26 
   27 #include <sys/cdefs.h>
   28 __FBSDID("$FreeBSD$");
   29 
   30 #include <sys/param.h>
   31 #include <sys/systm.h>
   32 #include <sys/bus.h>
   33 #include <sys/types.h>
   34 #include <sys/kernel.h>
   35 #include <sys/malloc.h>
   36 #include <sys/module.h>
   37 #include <sys/rman.h>
   38 #include <vm/vm.h>
   39 #include <vm/vm_kern.h>
   40 #include <vm/pmap.h>
   41 #include <vm/vm_page.h>
   42 #include <vm/vm_extern.h>
   43 
   44 #define _ARM32_BUS_DMA_PRIVATE
   45 #include <machine/armreg.h>
   46 #include <machine/bus.h>
   47 #include <machine/intr.h>
   48 #include <machine/resource.h>
   49 
   50 #include "econa_reg.h"
   51 #include "econa_var.h"
   52 
   53 static struct econa_softc *econa_softc;
   54 
   55 unsigned int CPU_clock = 200000000;
   56 unsigned int AHB_clock;
   57 unsigned int APB_clock;
   58 
   59 bus_space_tag_t obio_tag;
   60 
   61 static int
   62 econa_probe(device_t dev)
   63 {
   64 
   65         device_set_desc(dev, "ECONA device bus");
   66         return (BUS_PROBE_NOWILDCARD);
   67 }
   68 
   69 static void
   70 econa_identify(driver_t *drv, device_t parent)
   71 {
   72 
   73         BUS_ADD_CHILD(parent, 0, "econaarm", 0);
   74 }
   75 
   76 struct arm32_dma_range *
   77 bus_dma_get_range(void)
   78 {
   79 
   80         return (NULL);
   81 }
   82 
   83 int
   84 bus_dma_get_range_nb(void)
   85 {
   86 
   87         return (0);
   88 }
   89 
   90 extern void irq_entry(void);
   91 
   92 static void
   93 econa_add_child(device_t dev, int prio, const char *name, int unit,
   94     bus_addr_t addr, bus_size_t size,
   95     int irq0, int irq1,
   96     int irq2, int irq3, int irq4)
   97 {
   98         device_t kid;
   99         struct econa_ivar *ivar;
  100 
  101         kid = device_add_child_ordered(dev, prio, name, unit);
  102         if (kid == NULL) {
  103                 printf("Can't add child %s%d ordered\n", name, unit);
  104                 return;
  105         }
  106         ivar = malloc(sizeof(*ivar), M_DEVBUF, M_NOWAIT | M_ZERO);
  107         if (ivar == NULL) {
  108                 device_delete_child(dev, kid);
  109                 return;
  110         }
  111         device_set_ivars(kid, ivar);
  112         resource_list_init(&ivar->resources);
  113         if (irq0 != -1)
  114                 bus_set_resource(kid, SYS_RES_IRQ, 0, irq0, 1);
  115         if (irq1 != 0)
  116                 bus_set_resource(kid, SYS_RES_IRQ, 1, irq1, 1);
  117         if (irq2 != 0)
  118                 bus_set_resource(kid, SYS_RES_IRQ, 2, irq2, 1);
  119         if (irq3 != 0)
  120                 bus_set_resource(kid, SYS_RES_IRQ, 3, irq3, 1);
  121         if (irq4 != 0)
  122                 bus_set_resource(kid, SYS_RES_IRQ, 4, irq4, 1);
  123 
  124         if (addr != 0)
  125                 bus_set_resource(kid, SYS_RES_MEMORY, 0, addr, size);
  126 
  127 }
  128 
  129 struct cpu_devs
  130 {
  131         const char *name;
  132         int unit;
  133         bus_addr_t mem_base;
  134         bus_size_t mem_len;
  135         int irq0;
  136         int irq1;
  137         int irq2;
  138         int irq3;
  139         int irq4;
  140 };
  141 
  142 struct cpu_devs econarm_devs[] =
  143 {
  144         {
  145                 "econa_ic", 0,
  146                 ECONA_IO_BASE + ECONA_PIC_BASE, ECONA_PIC_SIZE,
  147                 0
  148         },
  149         {
  150                 "system", 0,
  151                 ECONA_IO_BASE + ECONA_SYSTEM_BASE, ECONA_SYSTEM_SIZE,
  152                 0
  153         },
  154         {
  155                 "uart", 0,
  156                 ECONA_IO_BASE + ECONA_UART_BASE, ECONA_UART_SIZE,
  157                 ECONA_IRQ_UART
  158         },
  159         {
  160                 "timer", 0,
  161                 ECONA_IO_BASE + ECONA_TIMER_BASE, ECONA_TIMER_SIZE,
  162                 ECONA_IRQ_TIMER_1, ECONA_IRQ_TIMER_2
  163         },
  164         {
  165                 "ohci", 0,
  166                 ECONA_OHCI_VBASE, ECONA_OHCI_SIZE,
  167                 ECONA_IRQ_OHCI
  168                 },
  169         {
  170                 "ehci", 0,
  171                 ECONA_EHCI_VBASE, ECONA_EHCI_SIZE,
  172                 ECONA_IRQ_EHCI
  173         },
  174         {
  175                 "cfi", 0,
  176                 ECONA_CFI_VBASE, ECONA_CFI_SIZE,
  177                 0
  178         },
  179         {
  180                 "ece", 0,
  181                 ECONA_IO_BASE + ECONA_NET_BASE, ECONA_NET_SIZE,
  182                 ECONA_IRQ_STATUS,
  183                 ECONA_IRQ_TSTC, ECONA_IRQ_FSRC,
  184                 ECONA_IRQ_TSQE, ECONA_IRQ_FSQF,
  185         },
  186         {       0, 0, 0, 0, 0, 0, 0, 0, 0 }
  187 };
  188 
  189 static void
  190 econa_cpu_add_builtin_children(device_t dev, struct econa_softc *sc)
  191 {
  192         int i;
  193         struct cpu_devs *walker;
  194 
  195         for (i = 0, walker = econarm_devs; walker->name; i++, walker++) {
  196                 econa_add_child(dev, i, walker->name, walker->unit,
  197                     walker->mem_base, walker->mem_len,
  198                     walker->irq0,walker->irq1, walker->irq2,
  199                     walker->irq3, walker->irq4);
  200         }
  201 
  202 }
  203 
  204 struct intc_trigger_t {
  205         int mode;
  206         int level;
  207 };
  208 
  209 static struct intc_trigger_t intc_trigger_table[] = {
  210         {INTC_EDGE_TRIGGER, INTC_RISING_EDGE},
  211         {INTC_EDGE_TRIGGER, INTC_RISING_EDGE},
  212         {INTC_EDGE_TRIGGER, INTC_FALLING_EDGE},
  213         {INTC_EDGE_TRIGGER, INTC_RISING_EDGE},
  214         {INTC_TRIGGER_UNKNOWN, INTC_TRIGGER_UNKNOWN},
  215         {INTC_LEVEL_TRIGGER, INTC_ACTIVE_LOW},
  216         {INTC_LEVEL_TRIGGER, INTC_ACTIVE_LOW},
  217         {INTC_LEVEL_TRIGGER, INTC_ACTIVE_HIGH},
  218         {INTC_TRIGGER_UNKNOWN, INTC_TRIGGER_UNKNOWN},
  219         {INTC_LEVEL_TRIGGER, INTC_ACTIVE_HIGH},
  220         {INTC_LEVEL_TRIGGER, INTC_ACTIVE_HIGH},
  221         {INTC_LEVEL_TRIGGER, INTC_ACTIVE_HIGH},
  222         {INTC_LEVEL_TRIGGER, INTC_ACTIVE_HIGH},
  223         {INTC_TRIGGER_UNKNOWN, INTC_TRIGGER_UNKNOWN},
  224         {INTC_LEVEL_TRIGGER, INTC_ACTIVE_HIGH},
  225         {INTC_EDGE_TRIGGER, INTC_FALLING_EDGE},
  226         {INTC_TRIGGER_UNKNOWN, INTC_TRIGGER_UNKNOWN},
  227         {INTC_TRIGGER_UNKNOWN, INTC_TRIGGER_UNKNOWN},
  228         {INTC_LEVEL_TRIGGER, INTC_ACTIVE_HIGH},
  229         {INTC_EDGE_TRIGGER, INTC_RISING_EDGE},
  230         {INTC_EDGE_TRIGGER, INTC_RISING_EDGE},
  231         {INTC_EDGE_TRIGGER, INTC_RISING_EDGE},
  232         {INTC_EDGE_TRIGGER, INTC_RISING_EDGE},
  233         {INTC_LEVEL_TRIGGER, INTC_ACTIVE_LOW},
  234         {INTC_LEVEL_TRIGGER, INTC_ACTIVE_LOW},
  235 };
  236 
  237 static inline uint32_t
  238 read_4(struct econa_softc *sc, bus_size_t off)
  239 {
  240 
  241         return bus_space_read_4(sc->ec_st, sc->ec_sys_sh, off);
  242 }
  243 
  244 static inline void
  245 write_4(struct econa_softc *sc, bus_size_t off, uint32_t val)
  246 {
  247 
  248         return bus_space_write_4(sc->ec_st, sc->ec_sys_sh, off, val);
  249 }
  250 
  251 static inline uint32_t
  252 system_read_4(struct econa_softc *sc, bus_size_t off)
  253 {
  254 
  255         return bus_space_read_4(sc->ec_st, sc->ec_system_sh, off);
  256 }
  257 
  258 static inline void
  259 system_write_4(struct econa_softc *sc, bus_size_t off, uint32_t val)
  260 {
  261 
  262         return bus_space_write_4(sc->ec_st, sc->ec_system_sh, off, val);
  263 }
  264 
  265 
  266 
  267 static inline void
  268 econa_set_irq_mode(struct econa_softc * sc, unsigned int irq,
  269                    unsigned int mode)
  270 {
  271         unsigned int val;
  272 
  273         if ((mode != INTC_LEVEL_TRIGGER) && (mode != INTC_EDGE_TRIGGER))
  274                 return;
  275 
  276         val =   read_4(sc, INTC_INTERRUPT_TRIGGER_MODE_REG_OFFSET);
  277 
  278         if (mode == INTC_LEVEL_TRIGGER) {
  279                 if (val & (1UL << irq)) {
  280                         val &= ~(1UL << irq);
  281                         write_4(sc, INTC_INTERRUPT_TRIGGER_MODE_REG_OFFSET,
  282                             val);
  283                 }
  284         } else {
  285                 if (!(val & (1UL << irq))) {
  286                         val |= (1UL << irq);
  287                         write_4(sc, INTC_INTERRUPT_TRIGGER_MODE_REG_OFFSET,
  288                             val);
  289                 }
  290         }
  291 }
  292 
  293 /*
  294  * Configure interrupt trigger level to be Active High/Low
  295  * or Rising/Falling Edge
  296  */
  297 static inline void
  298 econa_set_irq_level(struct econa_softc * sc,
  299     unsigned int irq, unsigned int level)
  300 {
  301         unsigned int val;
  302 
  303         if ((level != INTC_ACTIVE_HIGH) &&
  304             (level != INTC_ACTIVE_LOW) &&
  305             (level != INTC_RISING_EDGE) &&
  306             (level != INTC_FALLING_EDGE)) {
  307                 return;
  308         }
  309 
  310         val = read_4(sc, INTC_INTERRUPT_TRIGGER_LEVEL_REG_OFFSET);
  311 
  312         if ((level == INTC_ACTIVE_HIGH) || (level == INTC_RISING_EDGE)) {
  313                 if (val & (1UL << irq)) {
  314                         val &= ~(1UL << irq);
  315                         write_4(sc, INTC_INTERRUPT_TRIGGER_LEVEL_REG_OFFSET,
  316                             val);
  317                 }
  318         } else {
  319                 if (!(val & (1UL << irq))) {
  320                         val |= (1UL << irq);
  321                         write_4(sc, INTC_INTERRUPT_TRIGGER_LEVEL_REG_OFFSET,
  322                             val);
  323                 }
  324         }
  325 }
  326 
  327 static void
  328 get_system_clock(void)
  329 {
  330         uint32_t sclock = system_read_4(econa_softc, SYSTEM_CLOCK);
  331 
  332         sclock = (sclock >> 6) & 0x03;
  333 
  334         switch (sclock) {
  335         case 0:
  336                 CPU_clock = 175000000;
  337                 break;
  338         case 1:
  339                 CPU_clock = 200000000;
  340                 break;
  341         case 2:
  342                 CPU_clock = 225000000;
  343                 break;
  344         case 3:
  345                 CPU_clock = 250000000;
  346                 break;
  347         }
  348         AHB_clock = CPU_clock >> 1;
  349         APB_clock = AHB_clock >> 1;
  350 }
  351 
  352 static int
  353 econa_attach(device_t dev)
  354 {
  355         struct econa_softc *sc = device_get_softc(dev);
  356         int i;
  357 
  358         obio_tag = arm_base_bs_tag;
  359 
  360         econa_softc = sc;
  361         sc->ec_st = arm_base_bs_tag;
  362         sc->ec_sh = ECONA_IO_BASE;
  363         sc->dev = dev;
  364         if (bus_space_subregion(sc->ec_st, sc->ec_sh, ECONA_PIC_BASE,
  365             ECONA_PIC_SIZE, &sc->ec_sys_sh) != 0)
  366                 panic("Unable to map IRQ registers");
  367 
  368         if (bus_space_subregion(sc->ec_st, sc->ec_sh, ECONA_SYSTEM_BASE,
  369             ECONA_SYSTEM_SIZE, &sc->ec_system_sh) != 0)
  370                 panic("Unable to map IRQ registers");
  371 
  372         sc->ec_irq_rman.rm_type = RMAN_ARRAY;
  373         sc->ec_irq_rman.rm_descr = "ECONA IRQs";
  374         sc->ec_mem_rman.rm_type = RMAN_ARRAY;
  375         sc->ec_mem_rman.rm_descr = "ECONA Memory";
  376         if (rman_init(&sc->ec_irq_rman) != 0 ||
  377             rman_manage_region(&sc->ec_irq_rman, 0, 31) != 0)
  378                 panic("econa_attach: failed to set up IRQ rman");
  379         if (rman_init(&sc->ec_mem_rman) != 0 ||
  380             rman_manage_region(&sc->ec_mem_rman, 0,
  381             ~0) != 0)
  382                 panic("econa_attach: failed to set up memory rman");
  383 
  384         write_4(sc, INTC_INTERRUPT_CLEAR_EDGE_TRIGGER_REG_OFFSET, 0xffffffff);
  385 
  386         write_4(sc, INTC_INTERRUPT_MASK_REG_OFFSET, 0xffffffff);
  387 
  388         write_4(sc, INTC_FIQ_MODE_SELECT_REG_OFFSET, 0);
  389 
  390         /*initialize irq*/
  391         for (i = 0; i < 32; i++) {
  392                 if (intc_trigger_table[i].mode != INTC_TRIGGER_UNKNOWN) {
  393                         econa_set_irq_mode(sc,i, intc_trigger_table[i].mode);
  394                         econa_set_irq_level(sc, i, intc_trigger_table[i].level);
  395                 }
  396         }
  397 
  398         get_system_clock();
  399 
  400         econa_cpu_add_builtin_children(dev, sc);
  401 
  402         bus_generic_probe(dev);
  403         bus_generic_attach(dev);
  404         enable_interrupts(PSR_I | PSR_F);
  405 
  406         return (0);
  407 }
  408 
  409 static struct resource *
  410 econa_alloc_resource(device_t dev, device_t child, int type, int *rid,
  411     u_long start, u_long end, u_long count, u_int flags)
  412 {
  413         struct econa_softc *sc = device_get_softc(dev);
  414         struct resource_list_entry *rle;
  415         struct econa_ivar *ivar = device_get_ivars(child);
  416         struct resource_list *rl = &ivar->resources;
  417 
  418         if (device_get_parent(child) != dev)
  419                 return (BUS_ALLOC_RESOURCE(device_get_parent(dev), child,
  420                            type, rid, start, end, count, flags));
  421 
  422         rle = resource_list_find(rl, type, *rid);
  423         if (rle == NULL) {
  424                 return (NULL);
  425         }
  426         if (rle->res)
  427                 panic("Resource rid %d type %d already in use", *rid, type);
  428         if (start == 0UL && end == ~0UL) {
  429                 start = rle->start;
  430                 count = ulmax(count, rle->count);
  431                 end = ulmax(rle->end, start + count - 1);
  432         }
  433         switch (type)
  434         {
  435         case SYS_RES_IRQ:
  436                 rle->res = rman_reserve_resource(&sc->ec_irq_rman,
  437                     start, end, count, flags, child);
  438                 break;
  439         case SYS_RES_MEMORY:
  440                 rle->res = rman_reserve_resource(&sc->ec_mem_rman,
  441                     start, end, count, flags, child);
  442                 if (rle->res != NULL) {
  443                         rman_set_bustag(rle->res, arm_base_bs_tag);
  444                         rman_set_bushandle(rle->res, start);
  445                 }
  446                 break;
  447         }
  448         if (rle->res) {
  449                 rle->start = rman_get_start(rle->res);
  450                 rle->end = rman_get_end(rle->res);
  451                 rle->count = count;
  452                 rman_set_rid(rle->res, *rid);
  453         }
  454         return (rle->res);
  455 }
  456 
  457 static struct resource_list *
  458 econa_get_resource_list(device_t dev, device_t child)
  459 {
  460         struct econa_ivar *ivar;
  461         ivar = device_get_ivars(child);
  462         return (&(ivar->resources));
  463 }
  464 
  465 static int
  466 econa_release_resource(device_t dev, device_t child, int type,
  467     int rid, struct resource *r)
  468 {
  469         struct resource_list *rl;
  470         struct resource_list_entry *rle;
  471 
  472         rl = econa_get_resource_list(dev, child);
  473         if (rl == NULL)
  474                 return (EINVAL);
  475         rle = resource_list_find(rl, type, rid);
  476         if (rle == NULL)
  477                 return (EINVAL);
  478         rman_release_resource(r);
  479         rle->res = NULL;
  480         return (0);
  481 }
  482 
  483 static int
  484 econa_setup_intr(device_t dev, device_t child,
  485     struct resource *ires, int flags, driver_filter_t *filt,
  486     driver_intr_t *intr, void *arg, void **cookiep)
  487 {
  488         int error;
  489 
  490         if (rman_get_start(ires) == ECONA_IRQ_SYSTEM && filt == NULL)
  491                 panic("All system interrupt ISRs must be FILTER");
  492 
  493         error = BUS_SETUP_INTR(device_get_parent(dev), child, ires, flags,
  494             filt, intr, arg, cookiep);
  495         if (error)
  496                 return (error);
  497 
  498         return (0);
  499 }
  500 
  501 static int
  502 econa_teardown_intr(device_t dev, device_t child, struct resource *res,
  503     void *cookie)
  504 {
  505 
  506         return (BUS_TEARDOWN_INTR(device_get_parent(dev), child, res, cookie));
  507 }
  508 
  509 static int
  510 econa_activate_resource(device_t bus, device_t child, int type, int rid,
  511     struct resource *r)
  512 {
  513 
  514         return (rman_activate_resource(r));
  515 }
  516 
  517 static int
  518 econa_print_child(device_t dev, device_t child)
  519 {
  520         struct econa_ivar *ivars;
  521         struct resource_list *rl;
  522         int retval = 0;
  523 
  524         ivars = device_get_ivars(child);
  525         rl = &ivars->resources;
  526 
  527         retval += bus_print_child_header(dev, child);
  528 
  529         retval += resource_list_print_type(rl, "port", SYS_RES_IOPORT, "%#lx");
  530         retval += resource_list_print_type(rl, "mem", SYS_RES_MEMORY, "%#lx");
  531         retval += resource_list_print_type(rl, "irq", SYS_RES_IRQ, "%ld");
  532         if (device_get_flags(dev))
  533                 retval += printf(" flags %#x", device_get_flags(dev));
  534 
  535         retval += bus_print_child_footer(dev, child);
  536 
  537         return (retval);
  538 }
  539 
  540 void
  541 arm_mask_irq(uintptr_t nb)
  542 {
  543         unsigned int value;
  544 
  545         value = read_4(econa_softc,INTC_INTERRUPT_MASK_REG_OFFSET) | 1<<nb;
  546         write_4(econa_softc, INTC_INTERRUPT_MASK_REG_OFFSET, value);
  547 }
  548 
  549 void
  550 arm_unmask_irq(uintptr_t nb)
  551 {
  552         unsigned int value;
  553 
  554         value = read_4(econa_softc,
  555             INTC_INTERRUPT_CLEAR_EDGE_TRIGGER_REG_OFFSET) | (1 << nb);
  556         write_4(econa_softc,
  557             INTC_INTERRUPT_CLEAR_EDGE_TRIGGER_REG_OFFSET, value);
  558         value = read_4(econa_softc, INTC_INTERRUPT_MASK_REG_OFFSET)& ~(1 << nb);
  559         write_4(econa_softc, INTC_INTERRUPT_MASK_REG_OFFSET, value);
  560 }
  561 
  562 int
  563 arm_get_next_irq(int x)
  564 {
  565         int irq;
  566 
  567         irq = read_4(econa_softc, INTC_INTERRUPT_STATUS_REG_OFFSET) &
  568             ~(read_4(econa_softc, INTC_INTERRUPT_MASK_REG_OFFSET));
  569 
  570         if (irq!=0) {
  571                 return (ffs(irq) - 1);
  572         }
  573 
  574         return (-1);
  575 }
  576 
  577 void
  578 cpu_reset(void)
  579 {
  580         uint32_t control;
  581 
  582         control = system_read_4(econa_softc, RESET_CONTROL);
  583         control |= GLOBAL_RESET;
  584         system_write_4(econa_softc, RESET_CONTROL, control);
  585         control = system_read_4(econa_softc, RESET_CONTROL);
  586         control &= (~(GLOBAL_RESET));
  587         system_write_4(econa_softc, RESET_CONTROL, control);
  588         while (1);
  589 }
  590 
  591 
  592 
  593 void
  594 power_on_network_interface(void)
  595 {
  596         uint32_t cfg_reg;
  597         int ii;
  598 
  599         cfg_reg =  system_read_4(econa_softc, RESET_CONTROL);
  600         cfg_reg |= NET_INTERFACE_RESET;
  601         /* set reset bit to HIGH active; */
  602         system_write_4(econa_softc, RESET_CONTROL, cfg_reg);
  603 
  604         /*pulse delay */
  605         for (ii = 0; ii < 0xFFF; ii++)
  606                 DELAY(100);
  607         /* set reset bit to LOW active; */
  608         cfg_reg =  system_read_4(econa_softc, RESET_CONTROL);
  609         cfg_reg &= ~(NET_INTERFACE_RESET);
  610         system_write_4(econa_softc, RESET_CONTROL, cfg_reg);
  611 
  612         /*pulse delay */
  613         for (ii = 0; ii < 0xFFF; ii++)
  614                 DELAY(100);
  615         cfg_reg = system_read_4(econa_softc, RESET_CONTROL);
  616         cfg_reg |= NET_INTERFACE_RESET;
  617         /* set reset bit to HIGH active; */
  618         system_write_4(econa_softc, RESET_CONTROL, cfg_reg);
  619 }
  620 
  621 unsigned int
  622 get_tclk(void)
  623 {
  624 
  625         return CPU_clock;
  626 }
  627 
  628 static device_method_t econa_methods[] = {
  629         DEVMETHOD(device_probe,         econa_probe),
  630         DEVMETHOD(device_attach,                econa_attach),
  631         DEVMETHOD(device_identify,              econa_identify),
  632         DEVMETHOD(bus_alloc_resource,           econa_alloc_resource),
  633         DEVMETHOD(bus_setup_intr,               econa_setup_intr),
  634         DEVMETHOD(bus_teardown_intr,            econa_teardown_intr),
  635         DEVMETHOD(bus_activate_resource,        econa_activate_resource),
  636         DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
  637         DEVMETHOD(bus_get_resource_list,        econa_get_resource_list),
  638         DEVMETHOD(bus_set_resource,             bus_generic_rl_set_resource),
  639         DEVMETHOD(bus_get_resource,             bus_generic_rl_get_resource),
  640         DEVMETHOD(bus_release_resource, econa_release_resource),
  641         DEVMETHOD(bus_print_child,              econa_print_child),
  642         {0, 0},
  643 };
  644 
  645 static driver_t econa_driver = {
  646         "econaarm",
  647         econa_methods,
  648         sizeof(struct econa_softc),
  649 };
  650 static devclass_t econa_devclass;
  651 
  652 DRIVER_MODULE(econaarm, nexus, econa_driver, econa_devclass, 0, 0);

Cache object: 92642022042075f443b2f016ead4e0eb


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.