//****************************************************************************** // // Function Name: chal_dma_get_int_status // // Description: Returns the DMA controller's interrupt status // //****************************************************************************** void chal_dma_get_int_status(CHAL_HANDLE handle, ChalDmaIntStatus_t *intStatus) { UInt32 rc; ChalDmaDev_t *pDmaDev = (ChalDmaDev_t *)handle; rc = CHAL_REG_READ32(pDmaDev->baseAddr + DMAC_INTTCSTAT_OFFSET); intStatus->tcInt |= (rc & 0xfff); CHAL_REG_WRITE32(pDmaDev->baseAddr + DMAC_INTTCCLEAR_OFFSET, rc); rc = CHAL_REG_READ32(pDmaDev->baseAddr + DMAC_INTERRSTAT_OFFSET); intStatus->errInt |= (rc & 0xfff); CHAL_REG_WRITE32(pDmaDev->baseAddr + DMAC_INTERRCLR_OFFSET, rc); }
/* * ****************************************************************************** * * Function Name: chal_ipc_read_mailbox * * Description: * * ****************************************************************************** */ BCM_ERR_CODE chal_ipc_read_mailbox ( CHAL_IPC_HANDLE handle, IPC_MAILBOX_ID mailboxId, uint32_t *value ) { CHAL_IPC_DEV_T *device; BCM_DBG_ENTER(); /* Check boundry conditions * IPC_MAILBOX_ID is an unsigned value and does not need to check less than zero */ if ( mailboxId >= IPC_MAILBOX_ID_MAX ) { BCM_DBG_EXIT(); return( BCM_ERROR ); } device = (CHAL_IPC_DEV_T*)handle; *value = CHAL_REG_READ32( device->ipc_secure_reg_base + IPCSEC_IPCMAIL0_OFFSET + mailboxId*sizeof(uint32_t) ); BCM_DBG_EXIT(); return( BCM_SUCCESS ); }
//****************************************************************************** // // // Function Name: chal_dma_force_shutdown_chan // // Description: Stop DMA transfer on the specified channel and lose all // data in the FIFO // //****************************************************************************** void chal_dma_force_shutdown_chan(CHAL_HANDLE handle, cUInt32 channel) { // // stop the DMA channel with data loss // You can disable a DMA channel in the following ways: // 1. Write directly to the Channel Enable bit. // You lose any outstanding data in the FIFOs if you use this method. // 2. Use the Active and Halt bits in conjunction with the Channel Enable bit. // 3. Wait until the transfer completes. The channel is then automatically disabled. // // cUInt32 temp; ChalDmaDev_t *pDmaDev = (ChalDmaDev_t *)handle; temp = CHAL_REG_READ32(pDmaDev->baseAddr+DMAC_CH0CONFIG_OFFSET + CHAN_REG_INCREMENT * channel); //chal_dprintf(CDBG_ERRO, "chal_dma_force_shutdown_chan() temp: 0x%x\n", temp); temp &= ~DMAC_CH0CONFIG_E_MASK; CHAL_REG_WRITE32(pDmaDev->baseAddr + DMAC_CH0CONFIG_OFFSET + CHAN_REG_INCREMENT * channel, temp); CHAL_REG_WRITE32(pDmaDev->baseAddr + DMAC_INTTCCLEAR_OFFSET, 0x1<<channel); CHAL_REG_WRITE32(pDmaDev->baseAddr + DMAC_INTERRCLR_OFFSET, 0x1<<channel); chal_dma_mark_channel_inactive(handle, channel); }
//****************************************************************************** // // Function Name: chal_dma_soft_sig_last_request // // Description: Set a device to generate software single DMA request // //****************************************************************************** void chal_dma_soft_sig_last_request(CHAL_HANDLE handle, cUInt32 device) { cUInt32 temp; ChalDmaDev_t *pDmaDev = (ChalDmaDev_t *)handle; temp = CHAL_REG_READ32(pDmaDev->baseAddr + DMAC_SOFTLSREQ_OFFSET); temp |= (0x1 << device); CHAL_REG_WRITE32(pDmaDev->baseAddr + DMAC_SOFTLSREQ_OFFSET, temp); }
//****************************************************************************** // // Function Name: chal_dma_wait_channel // // Description: Wait for a channel // //****************************************************************************** void chal_dma_wait_channel(CHAL_HANDLE handle, cUInt32 channel) { cUInt32 temp; ChalDmaDev_t *pDmaDev = (ChalDmaDev_t *)handle; do { temp = CHAL_REG_READ32(pDmaDev->baseAddr + DMAC_ENBLDCHNS_OFFSET); }while (temp & (0x1 << channel)); }
void chal_audio_enable_aci_auxmic( CHAL_HANDLE handle, int enable ) { cUInt32 regVal; ChalAudioCtrlBlk_t *pCHALCb = (ChalAudioCtrlBlk_t*)handle; if( enable ) { /* Set ACI */ regVal = CHAL_REG_READ32((pCHALCb->aci_base+ACI_ADC_CTRL_OFFSET)); regVal |= ACI_ADC_CTRL_AUDIORX_VREF_PWRUP_MASK; regVal |= ACI_ADC_CTRL_AUDIORX_BIAS_PWRUP_MASK; CHAL_REG_WRITE32((pCHALCb->aci_base+ACI_ADC_CTRL_OFFSET), regVal); /* enable AUXMIC */ regVal = CHAL_REG_READ32((pCHALCb->auxmic_base+AUXMIC_AUXEN_OFFSET)); regVal |= AUXMIC_AUXEN_MICAUX_EN_MASK; CHAL_REG_WRITE32((pCHALCb->auxmic_base+AUXMIC_AUXEN_OFFSET), regVal); /* Set probe cycle to continuous */ regVal = CHAL_REG_READ32((pCHALCb->auxmic_base+AUXMIC_CMC_OFFSET)); regVal |= AUXMIC_CMC_CONT_MSR_CTRL_MASK; CHAL_REG_WRITE32((pCHALCb->auxmic_base+AUXMIC_CMC_OFFSET), regVal); /* disable AUXMIC force power down CHAL_REG_WRITE32(0x3500E028, */ regVal = CHAL_REG_READ32((pCHALCb->auxmic_base+AUXMIC_F_PWRDWN_OFFSET)); regVal &= ~AUXMIC_F_PWRDWN_FORCE_PWR_DWN_MASK; CHAL_REG_WRITE32((pCHALCb->auxmic_base+AUXMIC_F_PWRDWN_OFFSET), regVal); } else { /* Enable AUXMIC force power down */ regVal = CHAL_REG_READ32((pCHALCb->auxmic_base+AUXMIC_F_PWRDWN_OFFSET)); regVal |= AUXMIC_F_PWRDWN_FORCE_PWR_DWN_MASK; CHAL_REG_WRITE32((pCHALCb->auxmic_base+AUXMIC_F_PWRDWN_OFFSET), regVal); /* Set probe cycle to discontinuous */ regVal = CHAL_REG_READ32((pCHALCb->auxmic_base+AUXMIC_CMC_OFFSET)); regVal &= ~AUXMIC_CMC_CONT_MSR_CTRL_MASK; CHAL_REG_WRITE32((pCHALCb->auxmic_base+AUXMIC_CMC_OFFSET), regVal); /* Disable AUXMIC */ regVal = CHAL_REG_READ32((pCHALCb->auxmic_base+AUXMIC_AUXEN_OFFSET)); regVal &= ~AUXMIC_AUXEN_MICAUX_EN_MASK; CHAL_REG_WRITE32((pCHALCb->auxmic_base+AUXMIC_AUXEN_OFFSET), regVal); /* Analog MIC */ regVal = CHAL_REG_READ32((pCHALCb->aci_base+ACI_ADC_CTRL_OFFSET)); regVal &= ~ACI_ADC_CTRL_AUDIORX_VREF_PWRUP_MASK; regVal &= ~ACI_ADC_CTRL_AUDIORX_BIAS_PWRUP_MASK; CHAL_REG_WRITE32((pCHALCb->aci_base+ACI_ADC_CTRL_OFFSET), regVal); } }
void chal_audio_set_aci_auxmic_datab(CHAL_HANDLE handle, _Bool micOutEnable) { cUInt32 regVal; ChalAudioCtrlBlk_t *pCHALCb = (ChalAudioCtrlBlk_t *)handle; regVal = CHAL_REG_READ32((pCHALCb->aci_base+ACI_ACI_CTRL_OFFSET)); if (micOutEnable) regVal |= ACI_ACI_CTRL_SW_MIC_DATAB_MASK; else regVal &= ~ACI_ACI_CTRL_SW_MIC_DATAB_MASK; CHAL_REG_WRITE32((pCHALCb->aci_base+ACI_ACI_CTRL_OFFSET), regVal); }
//****************************************************************************** // // Function Name: chal_dma_shutdown_chan // // Description: Terminate a DMA transfer gracefully without data lose // //****************************************************************************** void chal_dma_shutdown_chan(CHAL_HANDLE handle, cUInt32 channel) { cUInt32 temp; ChalDmaDev_t *pDmaDev = (ChalDmaDev_t *)handle; // // To disable a DMA channel without losing data in the FIFO: // 1. Set the Halt bit in the relevant channel Configuration Register. // This causes any subsequent DMA requests to be ignored. // 2. Poll the Active bit in the relevant channel Configuration Register until // it reaches 0. This bit indicates whether there is any data in the // channel that has to be transferred. // 3. Clear the Channel Enable bit in the relevant channel Configuration Register. // // CHAL_REG_WRITE32(pDmaDev->baseAddr + DMAC_INTTCCLEAR_OFFSET, 0x1<<channel); CHAL_REG_WRITE32(pDmaDev->baseAddr + DMAC_INTERRCLR_OFFSET, 0x1<<channel); temp = CHAL_REG_READ32(pDmaDev->baseAddr+DMAC_CH0CONFIG_OFFSET + CHAN_REG_INCREMENT * channel); temp |= DMAC_CH0CONFIG_H_MASK; CHAL_REG_WRITE32(pDmaDev->baseAddr + DMAC_CH0CONFIG_OFFSET + CHAN_REG_INCREMENT * channel, temp); while (temp & DMAC_CH0CONFIG_A_MASK) { temp = CHAL_REG_READ32(pDmaDev->baseAddr+DMAC_CH0CONFIG_OFFSET + CHAN_REG_INCREMENT * channel); } temp &= ~DMAC_CH0CONFIG_E_MASK; CHAL_REG_WRITE32(pDmaDev->baseAddr + DMAC_CH0CONFIG_OFFSET + CHAN_REG_INCREMENT * channel, temp); chal_dma_mark_channel_inactive(handle, channel); }
//****************************************************************************** // // Function Name: chal_dma_enable_dmac // // Description: enable dma // //****************************************************************************** void chal_dma_enable_dmac(CHAL_HANDLE handle) { cUInt32 temp; ChalDmaDev_t *pDmaDev = (ChalDmaDev_t *)handle; temp = CHAL_REG_READ32(pDmaDev->baseAddr + DMAC_CONFIG_OFFSET); if (temp & DMAC_CONFIG_E_MASK) { //TRACE_Printf_Sio("Already Ensabled"); } else { temp |= DMAC_CONFIG_E_MASK; CHAL_REG_WRITE32(pDmaDev->baseAddr + DMAC_CONFIG_OFFSET, temp); } }
//****************************************************************************** // // Function Name: chal_dma_disable_dmac // // Description: disable dma // //****************************************************************************** void chal_dma_disable_dmac(CHAL_HANDLE handle) { cUInt32 temp; ChalDmaDev_t *pDmaDev = (ChalDmaDev_t *)handle; temp = CHAL_REG_READ32(pDmaDev->baseAddr + DMAC_CONFIG_OFFSET); if (!(temp & DMAC_CONFIG_E_MASK)) { } else { temp &= ~DMAC_CONFIG_E_MASK; CHAL_REG_WRITE32(pDmaDev->baseAddr + DMAC_CONFIG_OFFSET, temp); } }
/* * ****************************************************************************** * * Function Name: chal_ipc_get_error_status * * Description: Get ARM error status * * ****************************************************************************** */ BCM_ERR_CODE chal_ipc_get_error_status ( CHAL_IPC_HANDLE handle, uint32_t *status ) { CHAL_IPC_DEV_T *device; BCM_DBG_ENTER(); device = (CHAL_IPC_DEV_T*)handle; *status = CHAL_REG_READ32(device->ipc_open_reg_base + IPCOPEN_IPCERR_OFFSET ); BCM_DBG_EXIT(); return( BCM_SUCCESS ); }
/* * ****************************************************************************** * * Function Name: chal_ipc_sleep_vc * * Description: VideoCore sleep * * ****************************************************************************** */ BCM_ERR_CODE chal_ipc_sleep_vc ( CHAL_IPC_HANDLE handle ) { CHAL_IPC_DEV_T *device; BCM_DBG_ENTER(); device = (CHAL_IPC_DEV_T*)handle; CHAL_REG_WRITE32( device->ipc_secure_reg_base + IPCSEC_IPCAWAKE_OFFSET, CHAL_REG_READ32( device->ipc_secure_reg_base + IPCSEC_IPCAWAKE_OFFSET ) & ~IPCSEC_IPCAWAKE_WAKEUP_MASK ); return BCM_SUCCESS; }
BCM_ERR_CODE chal_ipc_query_wakeup_vc ( CHAL_IPC_HANDLE handle, uint32_t *result ) { CHAL_IPC_DEV_T *device; BCM_DBG_ENTER(); device = (CHAL_IPC_DEV_T*)handle; *result = CHAL_REG_READ32( device->ipc_secure_reg_base + IPCSEC_IPCAWAKE_OFFSET ); BCM_DBG_EXIT(); return( BCM_SUCCESS ); }
//****************************************************************************** // // Function Name: chal_dma_shutdown_all_channels // // Description: disable all the acitve channel and shutdown DMA controller // //****************************************************************************** void chal_dma_shutdown_all_channels(CHAL_HANDLE handle) { cUInt32 i, temp; ChalDmaDev_t *pDmaDev = (ChalDmaDev_t *)handle; //disable all active channels temp = CHAL_REG_READ32(pDmaDev->baseAddr + DMAC_ENBLDCHNS_OFFSET); for (i=0; i < TOTAL_DMA_CHANNELS; i++) { if (temp & (0x1 << i)) { chal_dma_shutdown_chan(handle,i); chal_dma_reset_channel(handle,i); } } // disable DMA controller chal_dma_disable_dmac(handle); }
//****************************************************************************** // // Function Name: chal_dma_start_transfer // // Description: Start a DMA transfer by reloading DMA registers // //****************************************************************************** void chal_dma_start_transfer( CHAL_HANDLE handle, cUInt32 channel, cUInt32 assocChan ) { cUInt32 temp; ChalDmaLinkNode_t *head; DmaChanConfig_t config; ChalDmaDev_t *pDmaDev = (ChalDmaDev_t *)handle; //chal_dprintf(1, "chal_dma_start_transfer, channel = %d, assocChan = %d\n", channel, assocChan); // // wait the channel to be free // You must fully initialize the channel before you enable it. Additionally, you must set the // Enable bit of the DMAC before you enable any channels. // CHAL_REG_WRITE32(pDmaDev->baseAddr + DMAC_INTTCCLEAR_OFFSET, 0x1<<channel); CHAL_REG_WRITE32(pDmaDev->baseAddr + DMAC_INTERRCLR_OFFSET, 0x1<<channel); do { temp = CHAL_REG_READ32(pDmaDev->baseAddr + DMAC_ENBLDCHNS_OFFSET); }while (temp & (0x1 << channel)); if(assocChan == ASSOC_CHAN_NONE) { // // Mark channel active and enable DMA core // chal_dma_mark_channel_active(handle, channel); // // 1. Clear any pending interrupts on the channel you want to use. // The privious channel operation might have left interrupts active. // 2. Write the source address into the SRC Register. // 3. Write the destination address into the DEST Register. // 4. Write the address of the next SRC into the NEXT Register. If the transfer // consists of a single packet of data, you must write 0 into this register. // 5. Write the control information into the CONTROL Register. // 6. Write the channel configuration information into the CONFIG register. // 7. Set channel enable bit, then the DMA channel is automatically enabled. // head = pDmaDev->chanInfo[channel].headNode; } else { chal_dma_mark_channel_active(handle, TOTAL_DMA_CHANNELS + assocChan); head = pDmaDev->chanInfo[TOTAL_DMA_CHANNELS + assocChan].headNode; } #if 0 chal_dprintf(1, "chal_dma_start_transfer, head->src = 0x%x\n", head->src); chal_dprintf(1, "chal_dma_start_transfer, head->dst = 0x%x\n", head->dst); chal_dprintf(1, "chal_dma_start_transfer, head->control.DWord = 0x%x\n", head->control.DWord); chal_dprintf(1, "chal_dma_start_transfer, head->next = 0x%x\n", head->next); #endif // // set up DMA for transfer // CHAL_REG_WRITE32(pDmaDev->baseAddr + DMAC_CH0CONTROL_OFFSET + CHAN_REG_INCREMENT * channel, head->control.DWord); CHAL_REG_WRITE32(pDmaDev->baseAddr + DMAC_CH0SRCADDR_OFFSET + CHAN_REG_INCREMENT * channel, head->src); CHAL_REG_WRITE32(pDmaDev->baseAddr + DMAC_CH0DESTADDR_OFFSET + CHAN_REG_INCREMENT * channel, head->dst); CHAL_REG_WRITE32(pDmaDev->baseAddr + DMAC_CH0LLI_OFFSET + CHAN_REG_INCREMENT * channel, head->next); config.DWord = CHAL_REG_READ32(pDmaDev->baseAddr+DMAC_CH0CONFIG_OFFSET + CHAN_REG_INCREMENT * channel); config.ChanConfigBitField.chanEnabled = 1; //chal_dprintf(1, "chal_dma_start_transfer, config.DWord = 0x%x\n", config.DWord); CHAL_REG_WRITE32(pDmaDev->baseAddr + DMAC_CH0CONFIG_OFFSET + CHAN_REG_INCREMENT * channel, config.DWord); }
//****************************************************************************** // // Function Name: chal_dma_get_channel_status // // Description: Return DMAC channel status // //****************************************************************************** cUInt32 chal_dma_get_channel_status(CHAL_HANDLE handle) { ChalDmaDev_t *pDmaDev = (ChalDmaDev_t *)handle; return CHAL_REG_READ32(pDmaDev->baseAddr + DMAC_ENBLDCHNS_OFFSET); }
/* * =========================================================================== * * Function Name: chal_memc_ddr3_get_clock_speed * * Description: * Get the current DDR3 clock speed in hz * * =========================================================================== */ MEMC_EXPORT BCM_ERR_CODE chal_memc_ddr3_get_clock_speed ( void* generic_hdl, uint32_t *clock_speed_hz ) { CHAL_MEMC_HANDLE handle = (CHAL_MEMC_HANDLE)generic_hdl; uint32_t ddr3_ctl_base_addr; uint32_t rdvalue; MEMC_MDIV_T mdiv; uint32_t mdiv_val; uint32_t pdiv; uint32_t pdiv_val; uint32_t ndiv_int; uint32_t ndiv_frac; uint32_t xtal_freq; ddr3_ctl_base_addr = handle->memc_open_ddr3_ctl_base; if (handle->operation_mode == MEMC_OP_MODE_ASIC) { switch ( chipregHw_getStrapXtalType() ) { case chipregHw_STRAP_XTAL_TYPE_13MHZ : { xtal_freq = 13*1000*1000; break; } case chipregHw_STRAP_XTAL_TYPE_26MHZ: { xtal_freq = 26*1000*1000; break; } case chipregHw_STRAP_XTAL_TYPE_19p2MHZ: { xtal_freq = 19200000; break; } case chipregHw_STRAP_XTAL_TYPE_38p4MHZ: { xtal_freq = 38400000; break; } default: { BCM_DBG_ERR (("Unsupported XTAL strap\n" )); *clock_speed_hz = 0; return (BCM_ERROR); } } rdvalue = CHAL_REG_READ32( ddr3_ctl_base_addr + DDR3CTL_PLL_CTL6_OFFSET ); ndiv_int = (rdvalue & DDR3CTL_PLL_CTL6_PLL_NDIV_INT_MASK) >> DDR3CTL_PLL_CTL6_PLL_NDIV_INT_SHIFT; ndiv_frac = (rdvalue & DDR3CTL_PLL_CTL6_PLL_NDIV_FRAC_MASK) >> DDR3CTL_PLL_CTL6_PLL_NDIV_FRAC_SHIFT; rdvalue = CHAL_REG_READ32( ddr3_ctl_base_addr + DDR3CTL_PLL_CTL7_OFFSET ); pdiv = (rdvalue & DDR3CTL_PLL_CTL7_PLL_PDIV_MASK) >> DDR3CTL_PLL_CTL7_PLL_PDIV_SHIFT; pdiv_val = ((pdiv == 0) ? 8 : pdiv); rdvalue = CHAL_REG_READ32( ddr3_ctl_base_addr + DDR3CTL_PLL_CTL2_OFFSET ); mdiv = (rdvalue & DDR3CTL_PLL_CTL2_PLL_CH0_MDIV_MASK) >> DDR3CTL_PLL_CTL2_PLL_CH0_MDIV_SHIFT; mdiv_val = ((mdiv == 0) ? 256 : mdiv); /* Store the configured DDR clock speed */ handle->mem_device_ddr3.dev_info.ddr_speed_hz = ((xtal_freq*ndiv_int)/pdiv_val + ((uint32_t)((xtal_freq*(uint64_t)ndiv_frac)>>20))/pdiv_val) / mdiv_val ; } else {
//****************************************************************************** // // Function Name: chal_dma_config_channel // // Description: Config a dma channel, i.e, in this case channel config reg // //****************************************************************************** cUInt32 chal_dma_config_channel( CHAL_HANDLE handle, cUInt32 chan, cUInt32 assocChan, ChalDmaChanConfig_t *pConfig ) { DmaChanConfig_t chanConfig; cUInt32 bandRequested; cUInt32 i, j, k, configChan; ChalDmaDev_t *pDmaDev = (ChalDmaDev_t *)handle; chal_dma_enable_dmac(handle); chal_dma_reset_channel(handle, chan); chanConfig.DWord = CHAL_REG_READ32(pDmaDev->baseAddr+DMAC_CH0CONFIG_OFFSET + CHAN_REG_INCREMENT * chan); chanConfig.ChanConfigBitField.locked = pConfig->locked; chanConfig.ChanConfigBitField.tcIntMask = pConfig->tcIntMask; chanConfig.ChanConfigBitField.errIntMask = pConfig->errIntMask; chanConfig.ChanConfigBitField.flowCtrl = pConfig->flowCtrl; chanConfig.ChanConfigBitField.dstPeripheral = pConfig->dstPeripheral; chanConfig.ChanConfigBitField.srcPeripheral = pConfig->srcPeripheral; CHAL_REG_WRITE32(pDmaDev->baseAddr + DMAC_CH0CONFIG_OFFSET + CHAN_REG_INCREMENT * chan, chanConfig.DWord); // chal_dma_disable_dmac(handle); if(assocChan == ASSOC_CHAN_NONE) { configChan = chan; } else { configChan = TOTAL_DMA_CHANNELS + assocChan; } //allocate pre-allocated node if(pDmaDev->chanInfo[configChan].bUsed == TRUE) { pDmaDev->chanInfo[configChan].bandNum = 0; bandRequested = pConfig->nodeNumRequested/pDmaDev->nodeNumPerBand + 1; //always allocate at least a band for(i=0;i<bandRequested;i++) { for(j=0;j<LLI_NODE_BAND_NUM; j++) { if(pDmaDev->LLIBand[j].bUsed == FALSE) //free band { pDmaDev->chanInfo[configChan].chanNodeBand[i] = &pDmaDev->LLIBand[j]; //reserve the band pDmaDev->chanInfo[configChan].bandNum ++; pDmaDev->LLIBand[j].bUsed = TRUE; //mark it break; } } if(j==LLI_NODE_BAND_NUM) //no more LLI node available { for(k=0;k<pDmaDev->chanInfo[configChan].bandNum;k++) { pDmaDev->chanInfo[configChan].chanNodeBand[k]->bUsed = FALSE; } pDmaDev->chanInfo[configChan].bandNum = 0; //reset count pr_err("%s - exceeded available LLI's\n", __func__); return 0; } } } return 1; }