Changeset 0da3998 in rtems


Ignore:
Timestamp:
Nov 30, 2007, 4:53:21 PM (12 years ago)
Author:
Joel Sherrill <joel.sherrill@…>
Branches:
4.10, 4.11, 4.9, master
Children:
956286d
Parents:
5b42368a
Message:

2007-11-30 Daniel Hellstrom <daniel@…>

  • shared/include/grspw.h, shared/spw/grspw.c: GRSPW SpaceWire? Driver. Fixes typecast to volatile integer instead of to integer. Added scanning for GRSPW2 Core, The GRSPW2 core is run in legacy mode.
Location:
c/src/lib/libbsp/sparc
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • c/src/lib/libbsp/sparc/ChangeLog

    r5b42368a r0da3998  
     12007-11-30      Daniel Hellstrom <daniel@gaisler.com>
     2
     3        * shared/include/grspw.h, shared/spw/grspw.c: GRSPW SpaceWire Driver.
     4        Fixes typecast to volatile integer instead of to integer. Added
     5        scanning for GRSPW2 Core, The GRSPW2 core is run in legacy mode.
     6
    172007-11-30      Daniel Hellstrom <daniel@gaisler.com>
    28
  • c/src/lib/libbsp/sparc/shared/include/grspw.h

    r5b42368a r0da3998  
    5555   unsigned int nodeaddr;
    5656   unsigned int destkey;
    57    unsigned int clkdiv;
     57   unsigned int clkdiv; /* Note: contain both CLKDIVSTART and CLKDIVRUN, but IOCTL_SET_CLKDIV* commands are split into two */
    5858   unsigned int rxmaxlen;
    5959   unsigned int timer;
     
    7777   unsigned int is_rxunaligned;
    7878   unsigned int is_rmapcrc;
     79   
     80   unsigned int nodemask;
    7981} spw_config;
    8082
     
    104106#define SPACEWIRE_IOCTRL_SET_TXBLOCK_ON_FULL 31
    105107#define SPACEWIRE_IOCTRL_SET_COREFREQ        32
     108#define SPACEWIRE_IOCTRL_SET_CLKDIVSTART     33
     109#define SPACEWIRE_IOCTRL_SET_NODEMASK        34
    106110
    107111#define SPACEWIRE_IOCTRL_START               64
  • c/src/lib/libbsp/sparc/shared/spw/grspw.c

    r5b42368a r0da3998  
    1111 * Changes:
    1212 *
     13 * 2007-09-27, Daniel Hellstrom <daniel@gaisler.com>
     14 *  Added basic support for GRSPW2 core.
     15 *
    1316 * 2007-07-12, Daniel Hellstrom <daniel@gaisler.com>
    1417 *  Fixed bug in TXBLOCK mode (normally called flush).
     
    116119   volatile unsigned int dma0txdesc;
    117120   volatile unsigned int dma0rxdesc;
     121   
     122   /* For GRSPW core 2 and onwards */
     123   volatile unsigned int dma0addr;
     124   
    118125} LEON3_SPACEWIRE_Regs_Map;
    119126
     
    166173   unsigned int irq;
    167174   int minor;
     175   int core_ver;
    168176   int open;
    169177   int running;
     
    189197
    190198static int spw_cores;
     199static int spw_cores2;
    191200static unsigned int sys_freq_khz;
    192201static GRSPW_DEV *grspw_devs;
    193202
    194203#ifdef GRSPW_DONT_BYPASS_CACHE
    195 #define _SPW_READ(address) (*(unsigned int *)(address))
    196 #define _MEM_READ(address) (*(unsigned char *)(address))
     204#define _SPW_READ(address) (*(volatile unsigned int *)(address))
     205#define _MEM_READ(address) (*(volatile unsigned char *)(address))
    197206#else
    198207static unsigned int _SPW_READ(void *addr) {
     
    509518        int minor;
    510519
    511         for(minor = 0; minor < spw_cores; minor++) {
     520        for(minor = 0; minor < spw_cores+spw_cores2; minor++) {
    512521                if (v == (grspw_devs[minor].irq+0x10) ) {
    513522                        grspw_interrupt(&grspw_devs[minor]);
     
    602611        char console_name[20];
    603612                                amba_apb_device dev;
     613                               
    604614        SPACEWIRE_DBG2("spacewire driver initialization\n");       
    605615       
     
    608618       
    609619        /* Get the number of GRSPW cores */
    610         i=0; spw_cores = 0;
     620        i=0; spw_cores = 0; spw_cores2 = 0;
    611621
    612622        /* get number of GRSPW cores */
    613623        spw_cores = amba_get_number_apbslv_devices(amba_bus,VENDOR_GAISLER,GAISLER_SPACEWIRE);
     624        spw_cores2 = amba_get_number_apbslv_devices(amba_bus,VENDOR_GAISLER,GAISLER_GRSPW2);
    614625#if 0
    615626                                if ( spw_cores > SPACEWIRE_MAX_CORENR )
     
    624635#endif
    625636       
    626         if ( spw_cores < 1 ){
     637        if ( (spw_cores+spw_cores2) < 1 ){
    627638                /* No GRSPW cores around... */
    628639                return RTEMS_SUCCESSFUL;
     
    630641       
    631642        /* Allocate memory for all spacewire cores */
    632         grspw_devs = (GRSPW_DEV *)malloc(spw_cores * sizeof(GRSPW_DEV));
     643        grspw_devs = (GRSPW_DEV *)malloc((spw_cores+spw_cores2) * sizeof(GRSPW_DEV));
    633644       
    634645        /* Zero out all memory */
    635         memset(grspw_devs,0,spw_cores * sizeof(GRSPW_DEV));
     646        memset(grspw_devs,0,(spw_cores+spw_cores2) * sizeof(GRSPW_DEV));
    636647       
    637648        /* loop all found spacewire cores */
    638649        i = 0;
    639         for(minor=0; minor<spw_cores; minor++){
     650        for(minor=0; minor<(spw_cores+spw_cores2); minor++){
     651
     652                pDev = &grspw_devs[minor];
     653               
    640654                /* Get device */
    641                 amba_find_next_apbslv(amba_bus,VENDOR_GAISLER,GAISLER_SPACEWIRE,&dev,minor);
    642                
    643                 pDev = &grspw_devs[minor];
     655                if ( spw_cores > minor ) {
     656                        amba_find_next_apbslv(amba_bus,VENDOR_GAISLER,GAISLER_SPACEWIRE,&dev,minor);
     657                        pDev->core_ver = 1;
     658                } else {
     659                        amba_find_next_apbslv(amba_bus,VENDOR_GAISLER,GAISLER_GRSPW2,&dev,minor-spw_cores);
     660                        pDev->core_ver = 2;
     661                }
    644662               
    645663                pDev->regs = (LEON3_SPACEWIRE_Regs_Map *)dev.start;
     
    684702 
    685703        /*  Register Device Names, /dev/grspw0, /dev/grspw1  ... */
    686         for (i = 0; i < spw_cores; i++) {
     704        for (i = 0; i < spw_cores+spw_cores2; i++) {
    687705           GRSPW_DEVNAME_NO(console_name,i);
    688706           SPACEWIRE_DBG("registering minor %i as %s\n", i, console_name);
     
    695713        /* Initialize Hardware and semaphores*/
    696714        c = 'a';
    697         for (i = 0; i < spw_cores; i++) {
     715        for (i = 0; i < spw_cores+spw_cores2; i++) {
    698716                pDev = &grspw_devs[i];
    699717                rtems_semaphore_create(
     
    726744        GRSPW_DEV *pDev;
    727745        SPACEWIRE_DBGC(DBGSPW_IOCALLS, "open [%i,%i]\n", major, minor);
    728         if ( minor >= spw_cores ) {
     746        if ( minor >= (spw_cores+spw_cores2) ) {
    729747                SPACEWIRE_DBG("minor %i too big\n", minor);
    730748                return RTEMS_INVALID_NAME;
     
    883901        spw_ioctl_packetsize *ps;
    884902        int status;
    885         unsigned int tmp;
     903        unsigned int tmp,nodeaddr,nodemask;
    886904        int timeout;
    887905        rtems_device_driver ret;
     
    897915                case SPACEWIRE_IOCTRL_SET_NODEADDR:
    898916                        /*set node address*/
    899                         SPACEWIRE_DBGC(DBGSPW_IOCTRL, "SPACEWIRE_IOCTRL_SET_NODEADDR %i\n", (unsigned int)ioarg->buffer);
     917                        SPACEWIRE_DBGC(DBGSPW_IOCTRL, "SPACEWIRE_IOCTRL_SET_NODEADDR %i\n",(unsigned int)ioarg->buffer);
    900918                        if ((unsigned int)ioarg->buffer > 255) {
    901919                                return RTEMS_INVALID_NAME;
    902920                        }
    903                         SPW_WRITE(&pDev->regs->nodeaddr, (unsigned int)ioarg->buffer); 
    904                         if (SPW_READ(&pDev->regs->nodeaddr) != (unsigned int)ioarg->buffer) {
     921                        nodeaddr = ((unsigned int)ioarg->buffer) & 0xff;
     922                        tmp = SPW_READ(&pDev->regs->nodeaddr);
     923                        tmp &= 0xffffff00; /* Remove old address */
     924                        tmp |= nodeaddr;
     925                        SPW_WRITE(&pDev->regs->nodeaddr, tmp);
     926                        if ((SPW_READ(&pDev->regs->nodeaddr)&0xff) != nodeaddr) {
    905927                                return RTEMS_IO_ERROR;
    906928                        }
    907                         pDev->config.nodeaddr = (unsigned int) ioarg->buffer;
     929                        pDev->config.nodeaddr = nodeaddr;
     930                        break;
     931                case SPACEWIRE_IOCTRL_SET_NODEMASK:
     932                        /*set node address*/
     933                        SPACEWIRE_DBGC(DBGSPW_IOCTRL, "SPACEWIRE_IOCTRL_SET_NODEMASK %i\n",(unsigned int)ioarg->buffer);
     934                        if ( pDev->core_ver > 1 ){
     935                          if ((unsigned int)ioarg->buffer > 255) {
     936                                  return RTEMS_INVALID_NAME;
     937                          }
     938                          nodemask = ((unsigned int)ioarg->buffer) & 0xff;
     939                          tmp = SPW_READ(&pDev->regs->nodeaddr);
     940                          tmp &= 0xffff00ff; /* Remove old mask */
     941                          tmp |= nodemask<<8;
     942                          SPW_WRITE(&pDev->regs->nodeaddr, tmp);
     943                          if (((SPW_READ(&pDev->regs->nodeaddr)>>8)&0xff) != nodemask) {
     944                                  return RTEMS_IO_ERROR;
     945                          }
     946                          pDev->config.nodemask = nodemask;
     947                        }else{
     948                          SPACEWIRE_DBG("SPACEWIRE_IOCTRL_SET_NODEMASK: not implemented in GRSPW1 HW\n");
     949                        }
    908950                        break;
    909951                case SPACEWIRE_IOCTRL_SET_RXBLOCK:
     
    933975                                return RTEMS_INVALID_NAME;
    934976                        }
    935                         SPW_WRITE(&pDev->regs->clkdiv, (unsigned int)ioarg->buffer);
    936                         if (SPW_READ(&pDev->regs->clkdiv) != (unsigned int)ioarg->buffer) {
     977                        tmp = SPW_READ(&pDev->regs->clkdiv);
     978                        tmp &= ~0xff; /* Remove old Clockdiv Setting */
     979                        tmp |= ((unsigned int)ioarg->buffer) & 0xff; /* add new clockdiv setting */
     980                        SPW_WRITE(&pDev->regs->clkdiv, tmp);
     981                        if (SPW_READ(&pDev->regs->clkdiv) != tmp) {
    937982                                return RTEMS_IO_ERROR;
    938983                        }
    939                         pDev->config.clkdiv = (unsigned int)ioarg->buffer;
    940                         break;
     984                        pDev->config.clkdiv = tmp;
     985                        break;
     986                case SPACEWIRE_IOCTRL_SET_CLKDIVSTART:
     987                        SPACEWIRE_DBGC(DBGSPW_IOCTRL,"SPACEWIRE_IOCTRL_SET_CLKDIVSTART %i\n", (unsigned int)ioarg->buffer);
     988                        if ((unsigned int)ioarg->buffer > 255) {
     989                                return RTEMS_INVALID_NAME;
     990                        }
     991                        tmp = SPW_READ(&pDev->regs->clkdiv);
     992                        tmp &= ~0xff00; /* Remove old Clockdiv Start Setting */
     993                        tmp |= (((unsigned int)ioarg->buffer) & 0xff)<<8; /* add new clockdiv start setting */
     994                        SPW_WRITE(&pDev->regs->clkdiv, tmp);
     995                        if (SPW_READ(&pDev->regs->clkdiv) != tmp) {
     996                                return RTEMS_IO_ERROR;
     997                        }
     998                        pDev->config.clkdiv = tmp;
     999                        break;                       
    9411000                case SPACEWIRE_IOCTRL_SET_TIMER:
    9421001                        SPACEWIRE_DBGC(DBGSPW_IOCTRL,"SPACEWIRE_IOCTRL_SET_TIMER %i\n", (unsigned int)ioarg->buffer);
    943                         if ((unsigned int)ioarg->buffer > 4095) {
    944                                 return RTEMS_INVALID_NAME;
    945                         }
    946                         SPW_WRITE(&pDev->regs->timer, (SPW_READ(&pDev->regs->timer) & 0xFFFFF000) | ((unsigned int)ioarg->buffer & 0xFFF));
    947                         if ((SPW_READ(&pDev->regs->timer) & 0xFFF) != (unsigned int)ioarg->buffer) {
    948                                 return RTEMS_IO_ERROR;
    949                         }
    950                         pDev->config.timer = (unsigned int)ioarg->buffer;
     1002                        if ( pDev->core_ver <= 1 ) {
     1003                          if ((unsigned int)ioarg->buffer > 4095) {
     1004                                  return RTEMS_INVALID_NAME;
     1005                          }
     1006                          SPW_WRITE(&pDev->regs->timer, (SPW_READ(&pDev->regs->timer) & 0xFFFFF000) | ((unsigned int)ioarg->buffer & 0xFFF));
     1007                          if ((SPW_READ(&pDev->regs->timer) & 0xFFF) != (unsigned int)ioarg->buffer) {
     1008                                  return RTEMS_IO_ERROR;
     1009                          }
     1010                          pDev->config.timer = (unsigned int)ioarg->buffer;
     1011                        }else{
     1012                          SPACEWIRE_DBG("SPACEWIRE_IOCTRL_SET_TIMER: removed in GRSPW2 HW\n");
     1013                        }
    9511014                        break;
    9521015                case SPACEWIRE_IOCTRL_SET_DISCONNECT:
    9531016                        SPACEWIRE_DBGC(DBGSPW_IOCTRL,"SPACEWIRE_IOCTRL_SET_DISCONNECT %i\n", (unsigned int)ioarg->buffer);
    954                         if ((unsigned int)ioarg->buffer > 1023) {
    955                                 return RTEMS_INVALID_NAME;
    956                         }
    957                         SPW_WRITE(&pDev->regs->timer, (SPW_READ(&pDev->regs->timer) & 0xFFC00FFF) | (((unsigned int)ioarg->buffer & 0x3FF) << 12));
    958                         if (((SPW_READ(&pDev->regs->timer) >> 12) & 0x3FF) != (unsigned int)ioarg->buffer) {
    959                                 return RTEMS_IO_ERROR;
    960                         }
    961                         pDev->config.disconnect = (unsigned int)ioarg->buffer;
     1017                        if ( pDev->core_ver <= 1 ) {
     1018                          if ((unsigned int)ioarg->buffer > 1023) {
     1019                                  return RTEMS_INVALID_NAME;
     1020                          }
     1021                          SPW_WRITE(&pDev->regs->timer, (SPW_READ(&pDev->regs->timer) & 0xFFC00FFF) | (((unsigned int)ioarg->buffer & 0x3FF) << 12));
     1022                          if (((SPW_READ(&pDev->regs->timer) >> 12) & 0x3FF) != (unsigned int)ioarg->buffer) {
     1023                                  return RTEMS_IO_ERROR;
     1024                          }
     1025                          pDev->config.disconnect = (unsigned int)ioarg->buffer;
     1026                        }else{
     1027                          SPACEWIRE_DBG("SPACEWIRE_IOCTRL_SET_DISCONNECT: not implemented for GRSPW2\n");
     1028                        }
    9621029                        break;
    9631030                case SPACEWIRE_IOCTRL_SET_PROMISCUOUS:       
     
    11061173                        SPACEWIRE_DBG2("SPACEWIRE_IOCTRL_GET_CONFIG \n");
    11071174                        (*(spw_config *)ioarg->buffer).nodeaddr = pDev->config.nodeaddr;
     1175                        (*(spw_config *)ioarg->buffer).nodemask = pDev->config.nodemask;
    11081176                        (*(spw_config *)ioarg->buffer).destkey = pDev->config.destkey;
    11091177                        (*(spw_config *)ioarg->buffer).clkdiv = pDev->config.clkdiv;
     
    12321300                        }
    12331301                       
    1234                         /* Calculate Timer64 & Disconnect */
    1235                         pDev->config.timer = grspw_calc_timer64(pDev->core_freq_khz);
    1236                         pDev->config.disconnect = grspw_calc_disconnect(pDev->core_freq_khz);
    1237                        
    1238                         /* Set Timer64 & Disconnect Register */
    1239                         SPW_WRITE(&pDev->regs->timer,
     1302                        /* Only GRSPW1 needs the Timer64 and Disconnect values
     1303                         * GRSPW2 and onwards doesn't have this register.
     1304                         */
     1305                        if ( pDev->core_ver <= 1 ){
     1306                          /* Calculate Timer64 & Disconnect */
     1307                          pDev->config.timer = grspw_calc_timer64(pDev->core_freq_khz);
     1308                          pDev->config.disconnect = grspw_calc_disconnect(pDev->core_freq_khz);
     1309                         
     1310                          /* Set Timer64 & Disconnect Register */
     1311                          SPW_WRITE(&pDev->regs->timer,
    12401312                                 (SPW_READ(&pDev->regs->timer) & 0xFFC00000) |
    12411313                                 ((pDev->config.disconnect & 0x3FF)<<12) |
    12421314                                 (pDev->config.timer & 0xFFF));
    12431315                       
    1244                         /* Check that the registers were written successfully */
    1245                         tmp = SPW_READ(&pDev->regs->timer) & 0x003fffff;
    1246                         if ( ((tmp & 0xFFF) != pDev->config.timer) ||
    1247                              (((tmp >> 12) & 0x3FF) != pDev->config.disconnect) ) {
    1248                                 return RTEMS_IO_ERROR;
     1316                          /* Check that the registers were written successfully */
     1317                          tmp = SPW_READ(&pDev->regs->timer) & 0x003fffff;
     1318                          if ( ((tmp & 0xFFF) != pDev->config.timer) ||
     1319                               (((tmp >> 12) & 0x3FF) != pDev->config.disconnect) ) {
     1320                                  return RTEMS_IO_ERROR;
     1321                          }
    12491322                        }
    12501323                        break;
     
    13581431        unsigned int tmp;
    13591432       
    1360         pDev->config.nodeaddr = 0xFF & SPW_READ(&pDev->regs->nodeaddr);
     1433        tmp = SPW_READ(&pDev->regs->nodeaddr);
     1434        pDev->config.nodeaddr = 0xFF & tmp;
     1435        pDev->config.nodemask = 0xFF & (tmp>>8);
    13611436        pDev->config.destkey = 0xFF & SPW_READ(&pDev->regs->destkey);
    1362         pDev->config.clkdiv = 0xFF & SPW_READ(&pDev->regs->clkdiv);
     1437        pDev->config.clkdiv = 0xFFFF & SPW_READ(&pDev->regs->clkdiv);
    13631438       
    13641439        tmp = SPW_CTRL_READ(pDev);
     
    13721447        pDev->config.linkstart = 1 & (tmp >> 1);
    13731448       
    1374         tmp = SPW_READ(&pDev->regs->timer);
    1375         pDev->config.timer = 0xFFF & tmp;
    1376         pDev->config.disconnect = 0x3FF & (tmp >> 12);
     1449        if ( pDev->core_ver <= 1 ){
     1450          tmp = SPW_READ(&pDev->regs->timer);
     1451          pDev->config.timer = 0xFFF & tmp;
     1452          pDev->config.disconnect = 0x3FF & (tmp >> 12);
     1453        }else{
     1454          pDev->config.timer = 0;
     1455          pDev->config.disconnect = 0;
     1456        }
    13771457       
    13781458        return;
Note: See TracChangeset for help on using the changeset viewer.