summaryrefslogtreecommitdiffstats
path: root/drivers/pci
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pci')
-rw-r--r--drivers/pci/fsl_pci_init.c148
1 files changed, 148 insertions, 0 deletions
diff --git a/drivers/pci/fsl_pci_init.c b/drivers/pci/fsl_pci_init.c
index 71ab02b88d..d7623369fe 100644
--- a/drivers/pci/fsl_pci_init.c
+++ b/drivers/pci/fsl_pci_init.c
@@ -18,6 +18,8 @@
*/
#include <common.h>
+#include <malloc.h>
+#include <asm/fsl_serdes.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -513,6 +515,152 @@ void fsl_pci_config_unlock(struct pci_controller *hose)
}
}
+#if defined(CONFIG_PCIE1) || defined(CONFIG_PCIE2) || \
+ defined(CONFIG_PCIE3) || defined(CONFIG_PCIE4)
+int fsl_configure_pcie(struct fsl_pci_info *info,
+ struct pci_controller *hose,
+ const char *connected, int busno)
+{
+ int is_endpoint;
+
+ set_next_law(info->mem_phys, law_size_bits(info->mem_size), info->law);
+ set_next_law(info->io_phys, law_size_bits(info->io_size), info->law);
+ is_endpoint = fsl_setup_hose(hose, info->regs);
+ printf("PCIE%u: connected to %s as %s (base addr %lx)\n",
+ info->pci_num, connected,
+ is_endpoint ? "Endpoint" : "Root Complex", info->regs);
+ return fsl_pci_init_port(info, hose, busno);
+}
+
+#if defined(CONFIG_FSL_CORENET)
+ #define _DEVDISR_PCIE1 FSL_CORENET_DEVDISR_PCIE1
+ #define _DEVDISR_PCIE2 FSL_CORENET_DEVDISR_PCIE2
+ #define _DEVDISR_PCIE3 FSL_CORENET_DEVDISR_PCIE3
+ #define _DEVDISR_PCIE4 FSL_CORENET_DEVDISR_PCIE4
+ #define CONFIG_SYS_MPC8xxx_GUTS_ADDR CONFIG_SYS_MPC85xx_GUTS_ADDR
+#elif defined(CONFIG_MPC85xx)
+ #define _DEVDISR_PCIE1 MPC85xx_DEVDISR_PCIE
+ #define _DEVDISR_PCIE2 MPC85xx_DEVDISR_PCIE2
+ #define _DEVDISR_PCIE3 MPC85xx_DEVDISR_PCIE3
+ #define _DEVDISR_PCIE4 0
+ #define CONFIG_SYS_MPC8xxx_GUTS_ADDR CONFIG_SYS_MPC85xx_GUTS_ADDR
+#elif defined(CONFIG_MPC86xx)
+ #define _DEVDISR_PCIE1 MPC86xx_DEVDISR_PCIE1
+ #define _DEVDISR_PCIE2 MPC86xx_DEVDISR_PCIE2
+ #define _DEVDISR_PCIE3 0
+ #define _DEVDISR_PCIE4 0
+ #define CONFIG_SYS_MPC8xxx_GUTS_ADDR \
+ (&((immap_t *)CONFIG_SYS_IMMR)->im_gur)
+#else
+#error "No defines for DEVDISR_PCIE"
+#endif
+
+/* Implement a dummy function for those platforms w/o SERDES */
+static const char *__board_serdes_name(enum srds_prtcl device)
+{
+ switch (device) {
+#ifdef CONFIG_SYS_PCIE1_NAME
+ case PCIE1:
+ return CONFIG_SYS_PCIE1_NAME;
+#endif
+#ifdef CONFIG_SYS_PCIE2_NAME
+ case PCIE2:
+ return CONFIG_SYS_PCIE2_NAME;
+#endif
+#ifdef CONFIG_SYS_PCIE3_NAME
+ case PCIE3:
+ return CONFIG_SYS_PCIE3_NAME;
+#endif
+#ifdef CONFIG_SYS_PCIE4_NAME
+ case PCIE4:
+ return CONFIG_SYS_PCIE4_NAME;
+#endif
+ default:
+ return NULL;
+ }
+
+ return NULL;
+}
+
+__attribute__((weak, alias("__board_serdes_name"))) const char *
+board_serdes_name(enum srds_prtcl device);
+
+static u32 devdisr_mask[] = {
+ _DEVDISR_PCIE1,
+ _DEVDISR_PCIE2,
+ _DEVDISR_PCIE3,
+ _DEVDISR_PCIE4,
+};
+
+int fsl_pcie_init_ctrl(int busno, u32 devdisr, enum srds_prtcl dev,
+ struct fsl_pci_info *pci_info)
+{
+ struct pci_controller *hose;
+ int num = dev - PCIE1;
+
+ hose = calloc(1, sizeof(struct pci_controller));
+ if (!hose)
+ return busno;
+
+ if (is_serdes_configured(dev) && !(devdisr & devdisr_mask[num])) {
+ busno = fsl_configure_pcie(pci_info, hose,
+ board_serdes_name(dev), busno);
+ } else {
+ printf("PCIE%d: disabled\n", num + 1);
+ }
+
+ return busno;
+}
+
+int fsl_pcie_init_board(int busno)
+{
+ struct fsl_pci_info pci_info;
+ ccsr_gur_t *gur = (void *)CONFIG_SYS_MPC8xxx_GUTS_ADDR;
+ u32 devdisr = in_be32(&gur->devdisr);
+
+#ifdef CONFIG_PCIE1
+ SET_STD_PCIE_INFO(pci_info, 1);
+ busno = fsl_pcie_init_ctrl(busno, devdisr, PCIE1, &pci_info);
+#else
+ setbits_be32(&gur->devdisr, _DEVDISR_PCIE1); /* disable */
+#endif
+
+#ifdef CONFIG_PCIE2
+ SET_STD_PCIE_INFO(pci_info, 2);
+ busno = fsl_pcie_init_ctrl(busno, devdisr, PCIE2, &pci_info);
+#else
+ setbits_be32(&gur->devdisr, _DEVDISR_PCIE2); /* disable */
+#endif
+
+#ifdef CONFIG_PCIE3
+ SET_STD_PCIE_INFO(pci_info, 3);
+ busno = fsl_pcie_init_ctrl(busno, devdisr, PCIE3, &pci_info);
+#else
+ setbits_be32(&gur->devdisr, _DEVDISR_PCIE3); /* disable */
+#endif
+
+#ifdef CONFIG_PCIE4
+ SET_STD_PCIE_INFO(pci_info, 4);
+ busno = fsl_pcie_init_ctrl(busno, devdisr, PCIE4, &pci_info);
+#else
+ setbits_be32(&gur->devdisr, _DEVDISR_PCIE4); /* disable */
+#endif
+
+ return busno;
+}
+#else
+int fsl_pcie_init_ctrl(int busno, u32 devdisr, enum srds_prtcl dev,
+ struct fsl_pci_info *pci_info)
+{
+ return busno;
+}
+
+int fsl_pcie_init_board(int busno)
+{
+ return busno;
+}
+#endif
+
#ifdef CONFIG_OF_BOARD_SETUP
#include <libfdt.h>
#include <fdt_support.h>
OpenPOWER on IntegriCloud