diff --git a/c/src/lib/libbsp/sparc/shared/pci/gr_rasta_tmtc.c b/c/src/lib/libbsp/sparc/shared/pci/gr_rasta_tmtc.c index 823cd9e0ab..47d8061611 100644 --- a/c/src/lib/libbsp/sparc/shared/pci/gr_rasta_tmtc.c +++ b/c/src/lib/libbsp/sparc/shared/pci/gr_rasta_tmtc.c @@ -44,6 +44,12 @@ extern unsigned int _RAM_START; #define GAISLER_GPIO 0x01a #define AHB1_BASE_ADDR 0x80000000 #define AHB1_IOAREA_BASE_ADDR 0x80200000 +#define AHB1_IOAREA_OFS (AHB1_IOAREA_BASE_ADDR - AHB1_BASE_ADDR) + +/* Second revision constants (GRPCI2) */ +#define GRPCI2_BAR0_TO_AHB_MAP 0x04 /* Fixme */ +#define GRPCI2_BAR1_TO_AHB_MAP 0x08 /* Fixme */ +#define GRPCI2_PCI_CONFIG 0x20 /* Fixme */ /* #define DEBUG 1 */ @@ -66,6 +72,28 @@ struct grpci_regs { volatile unsigned int stat_cmd; }; +struct grpci2_regs { + volatile unsigned int ctrl; + volatile unsigned int statcap; + volatile unsigned int pcimstprefetch; + volatile unsigned int ahbtopciiomap; + volatile unsigned int dmactrl; + volatile unsigned int dmadesc; + volatile unsigned int dmachanact; + volatile unsigned int reserved; + volatile unsigned int pcibartoahb[6]; + volatile unsigned int reserved2[2]; + volatile unsigned int ahbtopcimemmap[16]; + volatile unsigned int trcctrl; + volatile unsigned int trccntmode; + volatile unsigned int trcadpat; + volatile unsigned int trcadmask; + volatile unsigned int trcctrlsigpat; + volatile unsigned int trcctrlsigmask; + volatile unsigned int trcadstate; + volatile unsigned int trcctrlsigstate; +}; + struct gr_rasta_tmtc_ver { const unsigned int amba_freq_hz; /* The frequency */ const unsigned int amba_ioarea; /* The address where the PnP IOAREA starts at */ @@ -89,6 +117,7 @@ struct gr_rasta_tmtc_priv { struct gr_rasta_tmtc_ver *version; struct irqmp_regs *irq; struct grpci_regs *grpci; + struct grpci2_regs *grpci2; struct grgpio_regs *gpio; struct drvmgr_map_entry bus_maps_down[3]; struct drvmgr_map_entry bus_maps_up[2]; @@ -215,6 +244,7 @@ void gr_rasta_tmtc_isr (void *arg) DBG("RASTA-TMTC-IRQ: 0x%x\n", tmp); } +/* PCI Hardware (Revision 0) initialization */ int gr_rasta_tmtc_hw_init(struct gr_rasta_tmtc_priv *priv) { unsigned int *page0 = NULL; @@ -383,6 +413,154 @@ int gr_rasta_tmtc_hw_init(struct gr_rasta_tmtc_priv *priv) return 0; } +/* PCI Hardware (Revision 1) initialization */ +int gr_rasta_tmtc1_hw_init(struct gr_rasta_tmtc_priv *priv) +{ + int i; + uint32_t data; + unsigned int ctrl; + uint8_t tmp2; + struct ambapp_dev *tmp; + int status; + struct ambapp_ahb_info *ahb; + uint8_t cap_ptr; + pci_dev_t pcidev = priv->pcidev; + struct pci_dev_info *devinfo = priv->devinfo; + unsigned int pci_freq_hz; + + /* Check capabilities list bit */ + pci_cfg_r8(pcidev, PCI_STATUS, &tmp2); + + if (!((tmp2 >> 4) & 1)) { + /* Capabilities list not available which it should be in the + * GRPCI2 + */ + return -3; + } + + /* Read capabilities pointer */ + pci_cfg_r8(pcidev, PCI_CAP_PTR, &cap_ptr); + + /* Set AHB address mappings for target PCI bars + * BAR0: 16MB : Mapped to I/O at 0x80000000 + * BAR1: 256MB : Mapped to MEM at 0x40000000 + */ + pci_cfg_w32(pcidev, cap_ptr+GRPCI2_BAR0_TO_AHB_MAP, AHB1_BASE_ADDR); + pci_cfg_w32(pcidev, cap_ptr+GRPCI2_BAR1_TO_AHB_MAP, 0x40000000); + + /* Set PCI bus to be same endianess as PCI system */ + pci_cfg_r32(pcidev, cap_ptr+GRPCI2_PCI_CONFIG, &data); + if (pci_endian == PCI_BIG_ENDIAN) + data = data & 0xFFFFFFFE; + else + data = data | 0x00000001; + pci_cfg_w32(pcidev, cap_ptr+GRPCI2_PCI_CONFIG, data); + +#if 0 + /* set parity error response */ + pci_cfg_r32(pcidev, PCI_COMMAND, &data); + pci_cfg_w32(pcidev, PCI_COMMAND, (data|PCI_COMMAND_PARITY)); +#endif + + /* Scan AMBA Plug&Play */ + + /* AMBA MAP bar0 (in PCI) ==> 0x40000000 (remote amba address) */ + priv->amba_maps[0].size = devinfo->resources[0].size; + priv->amba_maps[0].local_adr = devinfo->resources[0].address; + priv->amba_maps[0].remote_adr = AHB1_BASE_ADDR; + + /* AMBA MAP bar0 (in PCI) ==> 0x80000000 (remote amba address) */ + priv->amba_maps[1].size = devinfo->resources[1].size; + priv->amba_maps[1].local_adr = devinfo->resources[1].address; + priv->amba_maps[1].remote_adr = 0x40000000; + + /* Addresses not matching with map be untouched */ + priv->amba_maps[2].size = 0xfffffff0; + priv->amba_maps[2].local_adr = 0; + priv->amba_maps[2].remote_adr = 0; + + /* Mark end of table */ + priv->amba_maps[3].size=0; + + /* Start AMBA PnP scan at first AHB bus */ + ambapp_scan( + &priv->abus, + devinfo->resources[0].address + AHB1_IOAREA_OFS, + NULL, + &priv->amba_maps[0]); + + /* Initialize Frequency of AMBA bus. The AMBA bus runs at same + * frequency as PCI bus + */ + drvmgr_freq_get(priv->dev, 0, &pci_freq_hz); + ambapp_freq_init(&priv->abus, NULL, pci_freq_hz); + + /* Find IRQ controller, Clear all current IRQs */ + tmp = (struct ambapp_dev *)ambapp_for_each(&priv->abus, + (OPTIONS_ALL|OPTIONS_APB_SLVS), + VENDOR_GAISLER, GAISLER_IRQMP, + ambapp_find_by_idx, NULL); + if ( !tmp ) { + return -4; + } + priv->irq = (struct irqmp_regs *)DEV_TO_APB(tmp)->start; + /* Set up GR-RASTA-SPW-ROUTER irq controller */ + priv->irq->mask[0] = 0; + priv->irq->iclear = 0xffff; + priv->irq->ilevel = 0; + + priv->bus_maps_down[0].name = "PCI BAR0 -> AMBA"; + priv->bus_maps_down[0].size = priv->amba_maps[0].size; + priv->bus_maps_down[0].from_adr = (void *)priv->amba_maps[0].local_adr; + priv->bus_maps_down[0].to_adr = (void *)priv->amba_maps[0].remote_adr; + priv->bus_maps_down[1].name = "PCI BAR1 -> AMBA"; + priv->bus_maps_down[1].size = priv->amba_maps[1].size; + priv->bus_maps_down[1].from_adr = (void *)priv->amba_maps[1].local_adr; + priv->bus_maps_down[1].to_adr = (void *)priv->amba_maps[1].remote_adr; + priv->bus_maps_down[2].size = 0; + + /* Find GRPCI2 controller AHB Slave interface */ + tmp = (void *)ambapp_for_each(&priv->abus, + (OPTIONS_ALL|OPTIONS_AHB_SLVS), + VENDOR_GAISLER, GAISLER_GRPCI2, + ambapp_find_by_idx, NULL); + if ( !tmp ) { + return -5; + } + ahb = (struct ambapp_ahb_info *)tmp->devinfo; + priv->bus_maps_up[0].name = "AMBA GRPCI2 Window"; + priv->bus_maps_up[0].size = ahb->mask[0]; /* AMBA->PCI Window on GR-RASTA-SPW-ROUTER board */ + priv->bus_maps_up[0].from_adr = (void *)ahb->start[0]; + priv->bus_maps_up[0].to_adr = (void *) + (priv->ahbmst2pci_map & ~(ahb->mask[0]-1)); + priv->bus_maps_up[1].size = 0; + + /* Find GRPCI2 controller APB Slave interface */ + tmp = (void *)ambapp_for_each(&priv->abus, + (OPTIONS_ALL|OPTIONS_APB_SLVS), + VENDOR_GAISLER, GAISLER_GRPCI2, + ambapp_find_by_idx, NULL); + if ( !tmp ) { + return -6; + } + priv->grpci2 = (struct grpci2_regs *) + ((struct ambapp_apb_info *)tmp->devinfo)->start; + + /* Set AHB to PCI mapping for all AMBA AHB masters */ + for(i = 0; i < 16; i++) { + priv->grpci2->ahbtopcimemmap[i] = priv->ahbmst2pci_map & + ~(ahb->mask[0]-1); + } + + /* Make sure dirq(0) sampling is enabled */ + ctrl = priv->grpci2->ctrl; + ctrl = (ctrl & 0xFFFFFF0F) | (1 << 4); + priv->grpci2->ctrl = ctrl; + + /* Successfully registered the RASTA-SPW-ROUTER board */ + return 0; +} + void gr_rasta_tmtc_hw_init2(struct gr_rasta_tmtc_priv *priv) { /* Enable DMA by enabling PCI target as master */ @@ -455,7 +633,20 @@ int gr_rasta_tmtc_init1(struct drvmgr_dev *dev) if ( priv->genirq == NULL ) return DRVMGR_FAIL; - status = gr_rasta_tmtc_hw_init(priv); + /* Select version of GR-RASTA-IO board */ + switch (devinfo->rev) { + case 0: + puts("GR-RASTA-TMTC: REVISION 0"); + status = gr_rasta_tmtc_hw_init(priv); + break; + case 1: + puts("GR-RASTA-TMTC: REVISION 1"); + status = gr_rasta_tmtc1_hw_init(priv); + break; + default: + return DRVMGR_ENOSYS; /* HW not supported */ + } + if ( status != 0 ) { genirq_destroy(priv->genirq); printf(" Failed to initialize GR-RASTA-TMTC HW: %d\n", status);