[PATCH 053/111] GR-RASTA-TMTC: updated for new version
Daniel Hellstrom
daniel at gaisler.com
Thu Feb 26 16:38:55 UTC 2015
>From this driver's point of view the major new thing is that the
GRPCI peripheral PCI bridge has been updated to GRPCI2, the second
version. This means that both Big and Little Endian systems are now
supported and autodetected on runtime.
The PCI frequency is used as AMBA frequency of the GR-RASTA-TMTC.
---
c/src/lib/libbsp/sparc/shared/pci/gr_rasta_tmtc.c | 193 ++++++++++++++++++++-
1 files changed, 192 insertions(+), 1 deletions(-)
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 823cd9e..47d8061 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);
--
1.7.0.4
More information about the devel
mailing list