The MPC8321 has one 32bit PCI BUS. The bus frequency runs up to 66MHz clock. In our design the MPC8321 is operates as a HOST & Arbiter on the BUS. Because the BCM56228 only can run under 50MHz, so the PCI frequency runs under 33MHz.
2.寄存器定义
3.核心数据结构
- typedef struct m83xxPciDrvCtrl
- {
- VXB_DEVICE_ID pInst;
- void * handle;
- UINT32 magicNumber1;
- UINT32 magicNumber2;
- int pciMaxBus; /* Max number of sub-busses */
-
- void * mem32Addr;
- UINT32 mem32Size;
- void * memIo32Addr;
- UINT32 memIo32Size;
- void * io32Addr;
- UINT32 io32Size;
- void * pimmrBase;
- void * mstrMemBus;
- void * lclMemAddr;
- UINT32 lclMemMapSize;
- UINT32 tgtIf;
- UINT32 owAttrMem;
- UINT32 owAttrMemIo;
- UINT32 owAttrIo;
- UINT32 iwAttr;
- UINT32 singleLawBar;
- UINT32 singleLawBarSize;
- UINT32 pciExpressHost;
- UINT32 autoConfig;
- UINT32* lawbar; /* LAWBAR address */
- UINT32* lawar; /* LAWAR address*/
- UINT32 lawarAttr; /* LAWAR attributes */
- BOOL initDone;
- struct vxbPciConfig *pPciConfig;
- struct vxbPciInt *pIntInfo;
- struct hcfDevice * pHcf;
- } M83XXPCI_DRV_CTRL;
4.配置空间寄存器的读写
- 一.读
- LOCAL STATUS m83xxPciMethodCfgRead
- (
- VXB_DEVICE_ID pInst, /* device info */
- UINT8 busNo, /* bus number */
- UINT8 deviceNo, /* device number */
- UINT8 funcNo, /* function number */
- UINT32 offset, /* offset into the configuration space */
- UINT32 width, /* width to be read */
- void * pData /* data buffer read from the offset */
- )
- {
- struct m83xxPciDrvCtrl * pDrvCtrl;
- int key;
- STATUS retStat = OK;
- if ((busNo == 0) && (deviceNo == 12))
- return (ERROR);
- pDrvCtrl = pInst->pDrvCtrl;
- key = intCpuLock ();
- switch (width)
- {
- case 1: /* byte */
- pciOutLong (pInst,M83XXPCI_CONF_ADDR,
- vxbPciConfigBdfPack (busNo, deviceNo, funcNo) |
- (offset & 0xfc) | 0x80000000);
- *(UINT8 *)pData = pciInByte (pInst,
- M83XXPCI_CONF_DATA + (offset & 0x3));
- break;
- case 2: /* word */
- pciOutLong (pInst,M83XXPCI_CONF_ADDR,
- vxbPciConfigBdfPack (busNo, deviceNo, funcNo) |
- (offset & 0xfc) | 0x80000000);
- *(UINT16 *)pData = pciInWord (pInst,
- M83XXPCI_CONF_DATA + (offset & 0x2));
- break;
- case 4: /* long */
- pciOutLong (pInst,M83XXPCI_CONF_ADDR,
- vxbPciConfigBdfPack (busNo, deviceNo, funcNo) |
- (offset & 0xfc) | 0x80000000);
- *(UINT32 *)pData = pciInLong (pInst, M83XXPCI_CONF_DATA);
- break;
- default:
- retStat = ERROR;
- break;
- }
- intCpuUnlock (key);
- return (retStat);
- }
- 二.写
- LOCAL STATUS m83xxPciMethodCfgWrite
- (
- VXB_DEVICE_ID pInst, /* device info */
- UINT8 busNo, /* bus number */
- UINT8 deviceNo, /* device number */
- UINT8 funcNo, /* function number */
- UINT32 offset, /* offset into the configuration space */
- UINT32 width, /* width to be read */
- void * pData /* data buffer write to the offset */
- )
- {
- struct m83xxPciDrvCtrl * pDrvCtrl;
- int key;
- STATUS retStat = OK;
- if ((busNo == 0) && (deviceNo == 12))
- return (ERROR);
- pDrvCtrl = pInst->pDrvCtrl;
- key = intCpuLock ();
- switch (width)
- {
- case 1: /* byte */
- pciOutLong (pInst, M83XXPCI_CONF_ADDR,
- vxbPciConfigBdfPack (busNo, deviceNo, funcNo) |
- (offset & 0xfc) | 0x80000000);
- pciOutByte (pInst, (M83XXPCI_CONF_DATA + (offset & 0x3)),
- *(UINT8*)pData);
- break;
- case 2: /* word */
- pciOutLong (pInst, M83XXPCI_CONF_ADDR,
- vxbPciConfigBdfPack (busNo, deviceNo, funcNo) |
- (offset & 0xfc) | 0x80000000);
- pciOutWord (pInst, (M83XXPCI_CONF_DATA + (offset & 0x2)),
- *(UINT16*)pData);
- break;
- case 4: /* long */
- pciOutLong (pInst,M83XXPCI_CONF_ADDR,
- vxbPciConfigBdfPack (busNo, deviceNo, funcNo) |
- (offset & 0xfc) | 0x80000000);
- pciOutLong (pInst, M83XXPCI_CONF_DATA, *(UINT32*)pData);
- break;
- default:
- retStat = ERROR;
- break;
- }
- intCpuUnlock (key);
- return (retStat);
- }
5.PCI bridge 初始化
- LOCAL STATUS m83xxPciBridgeInit(VXB_DEVICE_ID pInst)
- {
- UINT16 tempWord;
- UINT32 tempLong;
- struct m83xxPciDrvCtrl * pDrvCtrl;
- #ifndef VXB_LEGACY_ACCESS
- PCI_HARDWARE pciDev;
- PCI_HARDWARE * pPciDev = (PCI_HARDWARE *) &pciDev;
- pPciDev->pciBus = 0;
- pPciDev->pciDev = 0;
- pPciDev->pciFunc = 0;
- #endif /* !VXB_LEGACY_ACCESS */
- pDrvCtrl = pInst->pDrvCtrl;
- if(isColdBoot())
- {
- M83XXPCI_REG_WRITE32(M83XXPCI_GCR_REG, 0x1); /* Clear PCI reset */
- /* Allow time for PCI Bus to come out of reset */
- {
- volatile int i;
- for (i = 0 ; i < 0x80000 ; i++)
- WRS_ASM("isync");
- }
-
- M83XXPCI_REG_WRITE32(M83XXPCI_GCR_REG, 0x0); /* PCI reset */
- /* Allow time for PCI Bus to reset */
- {
- volatile int i;
- for (i = 0 ; i < 0x80000 ; i++)
- WRS_ASM("isync");
- }
- M83XXPCI_REG_WRITE32(M83XXPCI_GCR_REG, 0x1); /* Clear PCI reset */
- /* Allow time for PCI Bus to come out of reset */
- {
- volatile int i;
- for (i = 0 ; i < 0x80000 ; i++)
- WRS_ASM("isync");
- }
- }
- M83XXPCI_REG_READ32(M83XXPCI_GCR_REG,tempLong);
- /* Initialize LAWBAR/LAWAR for PCI */
- *pDrvCtrl->lawbar = (UINT32)pDrvCtrl->mem32Addr;
- *pDrvCtrl->lawar = (UINT32)pDrvCtrl->lawarAttr;
- M83XXPCI_REG_WRITE32(M83XXPCI_ECR_REG, 0x0); /* Generate interrupt if PCI error and ESR set*/
- M83XXPCI_REG_WRITE32(M83XXPCI_ESR_REG, 0xffffffff); /* Clear status */
- /* Set outbound translation window addresses */
- /* 设置内存空间基址寄存器 */
- #ifdef VXB_LEGACY_ACCESS
- m83xxPciMethodCfgWrite(pInst, 0,0,0,
- PCI_CFG_BASE_ADDRESS_0,
- 0x4,
- (void *)&pDrvCtrl->pimmrBase);
- #else /* VXB_LEGACY_ACCESS */
- m83xxPciMethodDevCfgWrite(pInst, pPciDev,
- PCI_CFG_BASE_ADDRESS_0,
- 0x4,
- (UINT32)pDrvCtrl->pimmrBase);
- #endif /* VXB_LEGACY_ACCESS */
- /* 设置MPC内部mem基地址 */
- M83XXPCI_REG_WRITE32(M83XXPCI_OB_BASE_ADRS_REG0, pDrvCtrl->mem32Addr >> 12);
- /* 设置PCI总线地址基址 */
- M83XXPCI_REG_WRITE32(M83XXPCI_OB_TRANS_ADRS_REG0, pDrvCtrl->mem32Addr >> 12);
- /* 设置MPC内部memIO基地址 */
- M83XXPCI_REG_WRITE32(M83XXPCI_OB_BASE_ADRS_REG1, pDrvCtrl->memIo32Addr >> 12);
- /* 设置PCI总线memIO地址基址 */
- M83XXPCI_REG_WRITE32(M83XXPCI_OB_TRANS_ADRS_REG1, pDrvCtrl->memIo32Addr >> 12);
- /* 设置MPC内部IO基地址 */
- M83XXPCI_REG_WRITE32(M83XXPCI_OB_BASE_ADRS_REG2, pDrvCtrl->io32Addr >> 12);
- /* 设置PCI总线IO地址基址 */
- M83XXPCI_REG_WRITE32(M83XXPCI_OB_TRANS_ADRS_REG2, pDrvCtrl->io32Addr >> 12);
- /* Switch on the outbound translation windows */
- /* 设置outbound窗口属性 */
- if(pDrvCtrl->owAttrMem == 0)
- M83XXPCI_REG_WRITE32(M83XXPCI_OB_ATTR_REG0, M83XXPCI_OB_WINDOW_ENABLE_BIT |
- M83XXPCI_OB_ATTR_SE_BIT |
- M83XXPCI_OB_ATTR_WS_128M);
- else
- M83XXPCI_REG_WRITE32(M83XXPCI_OB_ATTR_REG0, pDrvCtrl->owAttrMem);
-
- if(pDrvCtrl->owAttrMemIo == 0)
- M83XXPCI_REG_WRITE32(M83XXPCI_OB_ATTR_REG1, M83XXPCI_OB_WINDOW_ENABLE_BIT |
- M83XXPCI_OB_ATTR_SE_BIT |
- M83XXPCI_OB_ATTR_WS_64M);
- else
- M83XXPCI_REG_WRITE32(M83XXPCI_OB_ATTR_REG1, pDrvCtrl->owAttrMemIo);
-
- if (pDrvCtrl->owAttrIo == 0)
- M83XXPCI_REG_WRITE32(M83XXPCI_OB_ATTR_REG2, M83XXPCI_OB_WINDOW_ENABLE_BIT |
- M83XXPCI_OB_ATTR_IO_BIT |
- M83XXPCI_OB_ATTR_WS_64M);
- else
- M83XXPCI_REG_WRITE32(M83XXPCI_OB_ATTR_REG2, pDrvCtrl->owAttrIo);
-
- /* 设置PCI总线基地址 */
- M83XXPCI_REG_WRITE32(M83XXPCI_IB_BASE_ADRS_REG0, ((UINT32)pDrvCtrl->mstrMemBus>>12) & 0xfffff);
-
- /* 设置mpc存储器基地址 */
- M83XXPCI_REG_WRITE32(M83XXPCI_IB_TRANS_ADRS_REG0, ((UINT32)pDrvCtrl->lclMemAddr>>12) & 0xfffff);
-
- /* 设置inbound窗口属性 */
- M83XXPCI_REG_WRITE32(M83XXPCI_IB_ATTR_REG0, M83XXPCI_IB_WINDOW_ENABLE_BIT |
- M83XXPCI_IB_ATTR_PREFETCHABLE |
- M83XXPCI_IB_ATTR_RTT_READ_SNOOP |
- M83XXPCI_IB_ATTR_RTT_WRITE_SNOOP |
- M83XXPCI_IB_ATTR_IWS_256M);
- /* No need to enable inbound memIo */
- M83XXPCI_REG_WRITE32(M83XXPCI_IB_ATTR_REG1, 0);
- /* No need to enable inboune IO */
- M83XXPCI_REG_WRITE32(M83XXPCI_IB_ATTR_REG2, 0);
- /* configure the bridge as bus master */
- tempWord = PCI_CMD_IO_ENABLE | PCI_CMD_MEM_ENABLE | PCI_CMD_MASTER_ENABLE;
- #ifdef VXB_LEGACY_ACCESS
- m83xxPciMethodCfgWrite(pInst, 0,0,0,
- COMMAND_REGISTER_OFFSET,
- COMMAND_REGISTER_WIDTH,
- (void *)&tempWord);
- #else /* VXB_LEGACY_ACCESS */
- m83xxPciMethodDevCfgWrite(pInst, pPciDev,
- COMMAND_REGISTER_OFFSET,
- COMMAND_REGISTER_WIDTH,
- (UINT32)tempWord);
- #endif /* VXB_LEGACY_ACCESS */
- return(OK);
- }
|