⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pcidrv.c

📁 DM6437评估版BIOS下的PCI驱动程序
💻 C
📖 第 1 页 / 共 4 页
字号:
    cmdVal |=   PCI_COMMAND_MEMORY
              | PCI_COMMAND_MASTER
              | PCI_COMMAND_SERR  ;
    /* and clear the interrupt disable bit in command register. */
    cmdVal &=   ~PCI_COMMAND_INTX_DISABLE;
    pci_write_config_word (dev, PCI_COMMAND, cmdVal) ;
}

static Uint8 * wData ;
static Uint8 * rData ;

/* ============================================================================
 *  @func   PCI_dma
 *
 *  @desc   Tests the DMA component.
 *
 *  @modif  None.
 *  ============================================================================
 */
Void PCI_dma (void)
{
    Int32 i ;
    volatile Uint32 addressToWrite = 0x0;
    volatile DM64LCPCI_edmaRegs * ccregs = (DM64LCPCI_edmaRegs *) ((Uint32) regVirt + (DM64LCPCI_EDMAREG_BASE - 0x01C00000)) ;
    volatile DM64LCPCI_pciRegs * pciregs = (DM64LCPCI_pciRegs *) ((Uint32) regVirt + (DM64LCPCI_PCIREG_BASE - 0x01C00000)) ;

    wData = (Uint8 *) kmalloc (0x4000, GFP_DMA) ;
    rData = (Uint8 *) kmalloc (0x4000, GFP_DMA) ;

    for (i = 0 ; i < 0x4000 ; i++) {
         wData [i] = 0x41 ;
    }
    addressToWrite = (Uint32)virt_to_bus(wData);
    printk("Address to write from DSP = 0x%x\n",(int)addressToWrite);
    /* write DMA */
    ccregs->IESR = 0x1 ;
    ccregs->ICR  = 0x1 ;
    ccregs->DCHMAP [0] = 0 ;

    pciregs->PCIADDSUB [0] = ((Uint32) virt_to_bus (wData)) & 0xFF800000 ;

    ccregs->PARAMENTRY [0].OPTION = 0x00100004 ;
    ccregs->PARAMENTRY [0].SRC = 0x30000000 + (((Uint32) virt_to_bus (wData)) & ~0xFF800000) ;
    ccregs->PARAMENTRY [0].A_B_CNT = 0xFF4000 ;
    ccregs->PARAMENTRY [0].SRC_DST_BIDX = 0 ;
    ccregs->PARAMENTRY [0].LINK_BCNTRLD = 0xFFFF ;
    ccregs->PARAMENTRY [0].SRC_DST_CIDX = 0 ;
    ccregs->PARAMENTRY [0].CCNT = 0x1 ;
    ccregs->PARAMENTRY [0].DST = 0x80000000 ;

    ccregs->EESR |= 1 ;
    ccregs->ESR |= 1 ;

    while ((ccregs->IPR & 0x1) == 0) {
        udelay (100) ;
    }

    /* read DMA */
    ccregs->IESR = 0x1 ;
    ccregs->ICR  = 0x1 ;
    ccregs->DCHMAP [0] = 0 ;

    pciregs->PCIADDSUB [0] = ((Uint32) virt_to_bus (rData)) & 0xFF800000 ;

    ccregs->PARAMENTRY [0].OPTION = 0x00100004 ;
    ccregs->PARAMENTRY [0].SRC = 0x80000000 ;
    ccregs->PARAMENTRY [0].A_B_CNT = 0xFF4000 ;
    ccregs->PARAMENTRY [0].SRC_DST_BIDX = 0 ;
    ccregs->PARAMENTRY [0].LINK_BCNTRLD = 0xFFFF ;
    ccregs->PARAMENTRY [0].SRC_DST_CIDX = 0 ;
    ccregs->PARAMENTRY [0].CCNT = 0x1 ;
    ccregs->PARAMENTRY [0].DST = 0x30000000 + (((Uint32) virt_to_bus (rData)) & ~0xFF800000) ;

    ccregs->EESR |= 1 ;
    ccregs->ESR |= 1 ;

    while ((ccregs->IPR & 0x1) == 0) {
        udelay (100) ;
    }

    if (rData [0] == wData [0]) {
        printk ("DMA passed\n") ;
    }
    else {
        printk ("DMA failed\n") ;
    }
}

/* =============================================================================
 *  @func   HAL_CheckPciInterrupt
 *
 *  @desc   This function check whether interrupt is generated by DM642 or not.
 *
 *  @modif  None.
 *  ============================================================================
 */
Bool
HAL_CheckPciInterrupt (void)
{
    volatile DM64LCPCI_pciRegs * pciRegs = (DM64LCPCI_pciRegs *) ((Uint32) regVirt + (DM64LCPCI_PCIREG_BASE - 0x01C00000)) ;
    Bool                 status = 0 ;
    if (   (pciRegs->PCICSRMIR & DM64LCPCI_INTSTATUS_MASK)
        == (DM64LCPCI_INTSTATUS_MASK)) {
        status = 1 ;
    }
    return status ;
}


/** ============================================================================
 *  @func   HAL_PciClearDspInterrupt
 *
 *  @desc   Clear pending interrupt from DSP to Host.
 *
 *  @modif  None.
 *  ============================================================================
 */
Void
HAL_PciClearDspInterrupt (Void)
{
    volatile DM64LCPCI_pciRegs * pciRegs = (DM64LCPCI_pciRegs *) ((Uint32) regVirt + (DM64LCPCI_PCIREG_BASE - 0x01C00000)) ;

    pciRegs->PCISTATCLR |= DM64LCPCI_SOFTINT0_MASK ;
}


/** ============================================================================
 *  @func   HAL_PciEnableDspInterrupt
 *
 *  @desc   Allow the DSP to generate interrupts to the Host.
 *
 *  @modif  None.
 *  ============================================================================
 */
Void
HAL_PciEnableDspInterrupt (Void)
{
    volatile DM64LCPCI_pciRegs * pciRegs = (DM64LCPCI_pciRegs *) ((Uint32) regVirt + (DM64LCPCI_PCIREG_BASE - 0x01C00000)) ;
    printk("PCI host interrupt register vaue = 0x%X\n",(int)pciRegs->PCIHINTSET);

    pciRegs->PCIHINTSET = 0x0;

    printk("PCI host interrupt register value = 0x%X\n", (int)pciRegs->PCIHINTSET);
    pciRegs->PCIHINTSET |= DM64LCPCI_SOFTINT0_MASK ;

    printk("PCI host interrupt register value = 0x%X\n", (int)pciRegs->PCIHINTSET);
}


/** ============================================================================
 *  @func   HAL_PciDisableDspInterrupt
 *
 *  @desc   Disallow the DSP to generate interrupts to the Host.
 *
 *  @modif  None.
 *  ============================================================================
 */
Void
HAL_PciDisableDspInterrupt (Void)
{
    volatile DM64LCPCI_pciRegs * pciRegs = (DM64LCPCI_pciRegs *) ((Uint32) regVirt + (DM64LCPCI_PCIREG_BASE - 0x01C00000)) ;

    pciRegs->PCIHINTCLR |= DM64LCPCI_SOFTINT0_MASK ;
}


static int ISR_handler5 (int irq, void * arg, struct pt_regs * flags)
{
    Uint32 status = HAL_CheckPciInterrupt ()  ;
    volatile DM64LCPCI_pciRegs * pciRegs = (DM64LCPCI_pciRegs *)((Uint32)regVirt+ (DM64LCPCI_PCIREG_BASE - 0x01c00000));
    if (status == 1) {
        HAL_PciClearDspInterrupt () ;
        printk ("Interrupt received from DSP\n") ;
    }
    else
    {
    	return IRQ_NONE;
    }
    printk("Exiting from DSP to Host interrupt ISR\n");
    printk("PCISTAT = 0x%X\n",(int)pciRegs->PCISTATSET);
    pciRegs->PCISTATSET = 0x0f000000;
    printk("PCISTAT = 0x%X\n",(int)pciRegs->PCISTATSET);
    printk("Host to DSP interrupt triggered\n");
    return IRQ_HANDLED;
}

/*  ----------------------------------------------------------------------------
 *  @func   HAL_changeState
 *
 *  @desc   Change power module state to ( ENABLE, DISABLE, SYNCRESET, RESET ).
 *
 *  @modif  None
 *  ----------------------------------------------------------------------------
 */
Void
HAL_changeState (Uint32 lpscNum, Uint16 state)
{
    volatile DM64LCPCI_pscRegs * pscRegs = (DM64LCPCI_pscRegs *) ((Uint32) regVirt + (DM64LCPCI_PSCREG_BASE - 0x01C00000)) ;
    /*  ------------------------------------------------------------------------
     *  Step 1 - Wait for PTSTAT.GOSTAT to clear
     *  ------------------------------------------------------------------------
     */
    while (pscRegs->PTSTAT & 0x1) ;

    /*  ------------------------------------------------------------------------
     *  Step 2 - Set MDCTLx.NEXT to new state
     *  ------------------------------------------------------------------------
     */
    pscRegs->MDCTL [lpscNum] &= 0xFFE0 ;
    pscRegs->MDCTL [lpscNum] |= state  ;

    /*  ------------------------------------------------------------------------
     *  Step 3 - Start power transition ( set PTCMD.GO to 1 )
     *  ------------------------------------------------------------------------
     */
    pscRegs->PTCMD = 0x0001 ;

    /*  ------------------------------------------------------------------------
     *  Step 4 - Wait for PTSTAT.GOSTAT to clear
     *  ------------------------------------------------------------------------
     */
    while (pscRegs->PTSTAT & 0x1) ;

    /*  ------------------------------------------------------------------------
     *  Step 5 - Verify state changed
     *  ------------------------------------------------------------------------
     */
    while ((pscRegs->MDSTAT [lpscNum] & 0x001F) != state) ;
}


/*  ----------------------------------------------------------------------------
 *  @func   HAL_cfgPLL1
 *
 *  @desc   Configures the PLL1.
 *
 *  @modif  None
 *  ----------------------------------------------------------------------------
 */
Void
HAL_cfgPLL1 (Uint32       pllm,
             Uint32       div1,
             Uint32       div2)
{
    volatile DM64LCPCI_pllRegs * pllRegs = (DM64LCPCI_pllRegs *) ((Uint32) regVirt + (DM64LCPCI_PLL1REG_BASE - 0x01C00000)) ;
    /*  ------------------------------------------------------------------------
     *  Step 1 - Set PLL to BYPASS mode and select clock source.
     *  ------------------------------------------------------------------------
     */
    /*  ------------------------------------------------------------------------
     *  Step 1 - Set PLL to BYPASS mode and select clock source.
     *  ------------------------------------------------------------------------
     */
    pllRegs->PLLCTL &= 0xFFFFFEFF ;
    pllRegs->PLLCTL |= 0x0 ;
    pllRegs->PLLCTL &= 0xFFFFFFDF ;
    pllRegs->PLLCTL &= 0xFFFFFFFE ;

    udelay (10000) ;

    pllRegs->PLLCTL &= 0xFFFFFFF7 ;
    pllRegs->PLLCTL |= 0x00000010 ;
    pllRegs->PLLCTL &= 0xFFFFFFFD ;
    pllRegs->PLLCTL &= 0xFFFFFFEF ;
    pllRegs->PLLCTL &= 0xFFFFFEFF ;
    pllRegs->PLLCTL |= 0x0 ;

    /*  ------------------------------------------------------------------------
     *  Step 2 - Load PLL multiplier.
     *  ------------------------------------------------------------------------
     */
    pllRegs->PLLM = pllm ;

    /*  ------------------------------------------------------------------------
     *  Step 3 - Load PLL2 divider - DDR2 and VPBE are programmable.
     *  ------------------------------------------------------------------------
     */
    pllRegs->PLLDIV1  =  div2 ;
    pllRegs->PLLDIV2  =  div1 ;
    pllRegs->PLLDIV1 &= 0xFFFF7FFF ;
    pllRegs->PLLDIV2 &= 0xFFFF7FFF ;
    pllRegs->PLLDIV1 |= 0x00008000 ;
    pllRegs->PLLDIV2 |= 0x00008000 ;

    /*  ------------------------------------------------------------------------
     *  Step 4 - Set phase alignment and Wait for operation to finish.
     *  ------------------------------------------------------------------------
     */
    pllRegs->PLLCMD |= 0x00000001 ;
    while ((pllRegs->PLLSTAT & 0x1) == 0x1) ;
    /*  ------------------------------------------------------------------------
     *  Step 5 - Wait for PLL to re-lock ( 2000 cycles ).
     *  ------------------------------------------------------------------------
     */
    udelay (10000) ;
    pllRegs->PLLCTL |= 0x00000008 ;

    /*  ------------------------------------------------------------------------
     *  Step 6 - Switch out of BYPASS mode.
     *  ------------------------------------------------------------------------
     */
    udelay (10000) ;
    pllRegs->PLLCTL |= 0x00000001 ;
}


/*  ----------------------------------------------------------------------------
 *  @func   HAL_cfgDDR2
 *
 *  @desc   Configures the DDR2 module.
 *
 *  @modif  None
 *  ----------------------------------------------------------------------------
 */
Void
HAL_cfgDDR2 (Uint32  freq)
{
    volatile DM64LCPCI_ddrRegs * ddrRegs = (DM64LCPCI_ddrRegs *) ((Uint32) ddrRegVirt) ;
    Uint32 *             vtpiocr = NULL ;
    Uint32 *             vtpr    = NULL ;
    Uint32 *             dftEnb  = NULL ;

    vtpiocr  = (Uint32 *) ((Uint32) ddrRegVirt  + 0xF0) ;
    vtpr     = (Uint32 *) ((Uint32) regVirt + 0x42038) ;
    dftEnb   = (Uint32 *) ((Uint32) regVirt + 0x4004C) ;

    /* Enable the DDR2 PSC Module */
    HAL_changeState (LPSC_DDR, 0x3) ;
    /*  ------------------------------------------------------------------------
     *  Step 1. Enable DDR2 PHY.
     *  ------------------------------------------------------------------------
     */
    ddrRegs->DDRPHYCR =  0x50006405 ;
    ddrRegs->SDBCR    =  0x00138822 ;
    ddrRegs->SDTIMR   =  0x16492148 ;
    ddrRegs->SDTIMR2  =  0x000CC702 ;
    ddrRegs->SDBCR    =  0x00130822 ;

    /*  ------------------------------------------------------------------------
     *  Step 3. Refresh Control [ 7.8 usec * freq in MHz ].
     *  ------------------------------------------------------------------------
     */
    ddrRegs->SDRCR = 0x4EF ;

    /* Reset the DDR2 PSC Module */
    HAL_changeState (LPSC_DDR, 0x1) ;
    /* Enable the DDR2 PSC Module */
    HAL_changeState (LPSC_DDR, 0x3) ;

    /*  ------------------------------------------------------------------------
     *  Step 4. Enable VTP calibration
     *  ------------------------------------------------------------------------
     */
    *vtpiocr  = 0x201F ;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -