📄 pcidrv.c
字号:
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 + -