/******************************************************************************* * Function Name : OTGD_FS_EP0Activate * Description : enables EP0 OUT to receive SETUP packets and configures EP0 IN for transmitting packets * Input : None * Output : None * Return : status *******************************************************************************/ USB_OTG_Status OTGD_FS_EP0Activate(void) { USB_OTG_Status status = USB_OTG_OK; USB_OTG_dev_sts_data dsts; USB_OTG_dev_ep_ctl_data diepctl; USB_OTG_dev_ctl_data dctl; dctl.d32 = 0; /* Read the Device Status and Endpoint 0 Control registers */ dsts.d32 = READ_REG32(&core_regs.dev_regs->dev_sts); diepctl.d32 = READ_REG32(&core_regs.inep_regs[0]->dev_in_ep_ctl); /* Set the MPS of the IN EP based on the enumeration speed */ switch (dsts.b.enumspd) { case DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ: case DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ: case DSTS_ENUMSPD_FS_PHY_48MHZ: diepctl.b.mps = DEP0CTL_MPS_64; break; case DSTS_ENUMSPD_LS_PHY_6MHZ: diepctl.b.mps = DEP0CTL_MPS_8; break; } WRITE_REG32(&core_regs.inep_regs[0]->dev_in_ep_ctl, diepctl.d32); dctl.b.cgnpinnak = 1; MODIFY_REG32(&core_regs.dev_regs->dev_ctl, dctl.d32, dctl.d32); return status; }
/******************************************************************************* * Function Name : OTGD_FS_ReadDevOutEP_itr * Description : returns the Device OUT EP Interrupt register * Input : None * Output : None * Return : None *******************************************************************************/ uint32_t OTGD_FS_ReadDevOutEP_itr(USB_OTG_EP *ep) { uint32_t v; v = READ_REG32(&core_regs.outep_regs[ep->num]->dev_out_ep_int); v &= READ_REG32(&core_regs.dev_regs->dev_out_ep_msk); return v; }
/******************************************************************************* * Function Name : OTGD_FS_EPSetStall * Description : Set the EP STALL * Input : None * Output : None * Return : Status *******************************************************************************/ USB_OTG_Status OTGD_FS_EPSetStall(USB_OTG_EP *ep) { USB_OTG_Status status = USB_OTG_OK; USB_OTG_dev_ep_ctl_data depctl; __IO uint32_t *depctl_addr; if (ep->is_in == 1) { depctl_addr = &(core_regs.inep_regs[ep->num]->dev_in_ep_ctl); depctl.d32 = READ_REG32(depctl_addr); /* set the disable and stall bits */ if (depctl.b.epena) { depctl.b.epdis = 1; } depctl.b.stall = 1; WRITE_REG32(depctl_addr, depctl.d32); } else { depctl_addr = &(core_regs.outep_regs[ep->num]->dev_out_ep_ctl); depctl.d32 = READ_REG32(depctl_addr); /* set the stall bit */ depctl.b.stall = 1; WRITE_REG32(depctl_addr, depctl.d32); } return status; }
/******************************************************************************* * Function Name : OTGD_FS_ReadDevAllInEPItr * Description : Get int status register * Input : None * Output : None * Return : None *******************************************************************************/ uint32_t OTGD_FS_ReadDevAllInEPItr(void) { uint32_t v; v = READ_REG32(&core_regs.dev_regs->dev_all_int); v &= READ_REG32(&core_regs.dev_regs->dev_all_int_msk); return (v & 0xffff); }
/******************************************************************************* * Function Name : OTGD_FS_ReadDevAllOutEp_itr * Description : returns the OUT endpoint interrupt bits * Input : None * Output : None * Return : None *******************************************************************************/ uint32_t OTGD_FS_ReadDevAllOutEp_itr(void) { uint32_t v; v = READ_REG32(&core_regs.dev_regs->dev_all_int); v &= READ_REG32(&core_regs.dev_regs->dev_all_int_msk); return ((v & 0xffff0000) >> 16); }
/* * ============================================================================ * * Function Name: void chal_audio_dmic2_pwrctrl(CHAL_HANDLE handle, * _Bool pwronoff) * * Description: power on/off digital microphone path * * Parameters: * handle --- the audio handle * pwronoff --- on or off selection * Return: none * * ============================================================================ */ void chal_audio_dmic2_pwrctrl(CHAL_HANDLE handle, _Bool pwronoff) { cUInt32 regVal; cUInt32 function = 0x0; if (pwronoff == TRUE) function = 0x4; /* Select the function for GPIO33 */ /* For function = 4 (alt_fn5), this will be set * as DMIC2_CLK */ regVal = READ_REG32((KONA_PAD_CTRL_VA + PADCTRLREG_GPIO33_OFFSET)); regVal &= (~PADCTRLREG_GPIO33_PINSEL_GPIO33_MASK); regVal |= (function << PADCTRLREG_GPIO33_PINSEL_GPIO33_SHIFT); WRITE_REG32((KONA_PAD_CTRL_VA + PADCTRLREG_GPIO33_OFFSET), regVal); /* Select the function for GPIO34 */ /* For function = 4 (alt_fn5), this will be set as * DMIC2_DATA */ regVal = READ_REG32((KONA_PAD_CTRL_VA + PADCTRLREG_GPIO34_OFFSET)); regVal &= (~PADCTRLREG_GPIO34_PINSEL_GPIO34_MASK); regVal |= (function << PADCTRLREG_GPIO34_PINSEL_GPIO34_SHIFT); WRITE_REG32((KONA_PAD_CTRL_VA + PADCTRLREG_GPIO34_OFFSET), regVal); /* For FPGA no pads are present */ }
/******************************************************************************* * Function Name : OTGD_FS_ReadCoreItr * Description : returns the Core Interrupt register * Input : None * Output : None * Return : None *******************************************************************************/ uint32_t OTGD_FS_ReadCoreItr(void) { uint32_t v; v = READ_REG32(&core_regs.common_regs->int_sts); v &= READ_REG32(&core_regs.common_regs->int_msk); return v; }
/******************************************************************************* * Function Name : OTGD_FS_CoreInit * Description : Initialize the USB_OTG controller registers and prepares the core for device mode or host mode operation. * Input : None * Output : None * Return : Status *******************************************************************************/ USB_OTG_Status OTGD_FS_CoreInit(void) { USB_OTG_Status status = USB_OTG_OK; USB_OTG_usb_cfg_data usbcfg; usbcfg.d32 = 0; /* Reset the Controller */ OTGD_FS_CoreReset(); usbcfg.d32 = READ_REG32(&core_regs.common_regs->usb_cfg); usbcfg.b.physel = 1; WRITE_REG32 (&core_regs.common_regs->usb_cfg, usbcfg.d32); /* init and configure the phy */ OTGD_FS_PhyInit(); /* Reset after a PHY select and set Host mode */ OTGD_FS_CoreReset(); /* Set Host or Device Mode */ SetID(); return status; }
static unsigned int lba_rd_cfg(struct lba_device *d, u32 tok, u8 reg, u32 size) { u32 data = ~0U; int error = 0; u32 arb_mask = 0; /* used by LBA_CFG_SETUP/RESTORE */ u32 error_config = 0; /* used by LBA_CFG_SETUP/RESTORE */ u32 status_control = 0; /* used by LBA_CFG_SETUP/RESTORE */ LBA_CFG_SETUP(d, tok); LBA_CFG_PROBE(d, tok); LBA_CFG_MASTER_ABORT_CHECK(d, d->hba.base_addr, tok, error); if (!error) { void __iomem *data_reg = d->hba.base_addr + LBA_PCI_CFG_DATA; LBA_CFG_ADDR_SETUP(d, tok | reg); switch (size) { case 1: data = (u32) READ_REG8(data_reg + (reg & 3)); break; case 2: data = (u32) READ_REG16(data_reg+ (reg & 2)); break; case 4: data = READ_REG32(data_reg); break; } } LBA_CFG_RESTORE(d, d->hba.base_addr); return(data); }
/******************************************************************************* * Function Name : OTGD_FS_EPClearStall * Description : Clear the EP STALL * Input : None * Output : None * Return : Status *******************************************************************************/ USB_OTG_Status OTGD_FS_EPClearStall(USB_OTG_EP *ep) { USB_OTG_Status status = USB_OTG_OK; USB_OTG_dev_ep_ctl_data depctl; __IO uint32_t *depctl_addr; if (ep->is_in == 1) { depctl_addr = &(core_regs.inep_regs[ep->num]->dev_in_ep_ctl); } else { depctl_addr = &(core_regs.outep_regs[ep->num]->dev_out_ep_ctl); } depctl.d32 = READ_REG32(depctl_addr); /* clear the stall bits */ depctl.b.stall = 0; if (ep->type == EP_TYPE_INTR || ep->type == EP_TYPE_BULK) { depctl.b.setd0pid = 1; /* DATA0 */ } WRITE_REG32(depctl_addr, depctl.d32); return status; }
/******************************************************************************* * Function Name : OTGD_FS_FlushRxFifo * Description : Flush a Rx FIFO * Input : None * Output : None * Return : status *******************************************************************************/ USB_OTG_Status OTGD_FS_FlushRxFifo( void ) { USB_OTG_Status status = USB_OTG_OK; __IO USB_OTG_rst_ctl_data greset; int count = 0; greset.d32 = 0; greset.b.rxfflsh = 1; WRITE_REG32( &core_regs.common_regs->rst_ctl, greset.d32 ); do { greset.d32 = READ_REG32( &core_regs.common_regs->rst_ctl); if (++count > 200000) { break; } } while (greset.b.rxfflsh == 1); /* Wait for 3 PHY Clocks*/ uDELAY(3); return status; }
static int mercury_cfg_read(struct pci_bus *bus, unsigned int devfn, int pos, int size, u32 *data) { struct lba_device *d = LBA_DEV(parisc_walk_tree(bus->bridge)); u32 local_bus = (bus->parent == NULL) ? 0 : bus->busn_res.start; u32 tok = LBA_CFG_TOK(local_bus, devfn); void __iomem *data_reg = d->hba.base_addr + LBA_PCI_CFG_DATA; if ((pos > 255) || (devfn > 255)) return -EINVAL; LBA_CFG_TR4_ADDR_SETUP(d, tok | pos); switch(size) { case 1: *data = READ_REG8(data_reg + (pos & 3)); break; case 2: *data = READ_REG16(data_reg + (pos & 2)); break; case 4: *data = READ_REG32(data_reg); break; break; } DBG_CFG("mercury_cfg_read(%x+%2x) -> 0x%x\n", tok, pos, *data); return 0; }
/******************************************************************************* * Function Name : InitDevSpeed * Description : Initializes the DevSpd field of the DCFG register depending on the PHY type and the enumeration speed of the device. * Input : None * Output : None * Return : None *******************************************************************************/ static void InitDevSpeed(void) { USB_OTG_dev_cfg_data dcfg; dcfg.d32 = READ_REG32(&core_regs.dev_regs->dev_cfg); dcfg.b.devspd = 0x3; /* Full speed PHY */ WRITE_REG32(&core_regs.dev_regs->dev_cfg, dcfg.d32); }
// Read the FIFO for the endpoint indexed by Endpoint, into the buffer pointed // at by Buffer, whose size is *Size bytes. // // If *Size is less than the number of bytes in the FIFO, return EFI_BUFFER_TOO_SMALL // // Update *Size with the number of bytes of data in the FIFO. STATIC EFI_STATUS ReadEndpointBuffer ( IN UINT8 Endpoint, IN OUT UINTN *Size, IN OUT VOID *Buffer ) { UINT16 NumBytesAvailable; UINT32 Val32; UINTN Index; UINTN NumBytesRead; SelectEndpoint (Endpoint); NumBytesAvailable = READ_REG16 (ISP1761_BUFFER_LENGTH); if (NumBytesAvailable > *Size) { *Size = NumBytesAvailable; return EFI_BUFFER_TOO_SMALL; } *Size = NumBytesAvailable; /* -- NB! -- The datasheet says the Data Port is 16 bits but it actually appears to be 32 bits. */ // Read 32-bit chunks for (Index = 0; Index < NumBytesAvailable / 4; Index++) { ((UINT32 *) Buffer)[Index] = READ_REG32 (ISP1761_DATA_PORT); } // Read remaining bytes // Round NumBytesAvailable down to nearest power of 4 NumBytesRead = NumBytesAvailable & (~0x3); if (NumBytesRead != NumBytesAvailable) { Val32 = READ_REG32 (ISP1761_DATA_PORT); // Copy each required byte of 32-bit word into buffer for (Index = 0; Index < NumBytesAvailable % 4; Index++) { ((UINT8 *) Buffer)[NumBytesRead + Index] = Val32 >> (Index * 8); } }
cVoid chal_audio_mic_input_select(CHAL_HANDLE handle, UInt16 mic_input) { cUInt32 regVal = 0; cUInt32 base = ((ChalAudioCtrlBlk_t *) handle)->audioh_base; cUInt32 reg_val; reg_val = BRCM_READ_REG(base, AUDIOH_ADC_CTL); reg_val &= ~(AUDIOH_ADC_CTL_AMIC_EN_MASK); /* if(mic_input == CHAL_AUDIO_ENABLE) { */ reg_val |= AUDIOH_ADC_CTL_AMIC_EN_MASK; /* Set the required setting */ BRCM_WRITE_REG(base, AUDIOH_ADC_CTL, reg_val); /* ACI control for analog microphone */ /* WRITE_REG32(0x3500E0D4, 0xC0); */ regVal = READ_REG32((ACI_BASE_ADDR + ACI_ADC_CTRL_OFFSET)); regVal |= ACI_ADC_CTRL_AUDIORX_VREF_PWRUP_MASK; regVal |= ACI_ADC_CTRL_AUDIORX_BIAS_PWRUP_MASK; WRITE_REG32((ACI_BASE_ADDR + ACI_ADC_CTRL_OFFSET), regVal); /* enable AUXMIC */ /* WRITE_REG32(0x3500E014, 0x01); */ regVal = READ_REG32((AUXMIC_BASE_ADDR + AUXMIC_AUXEN_OFFSET)); regVal |= AUXMIC_AUXEN_MICAUX_EN_MASK; WRITE_REG32((AUXMIC_BASE_ADDR + AUXMIC_AUXEN_OFFSET), regVal); /* disable AUXMIC force power down */ regVal = READ_REG32((AUXMIC_BASE_ADDR + AUXMIC_F_PWRDWN_OFFSET)); regVal &= ~AUXMIC_F_PWRDWN_FORCE_PWR_DWN_MASK; WRITE_REG32((AUXMIC_BASE_ADDR + AUXMIC_F_PWRDWN_OFFSET), regVal); return; }
void chal_audio_mic_input_select(CHAL_HANDLE handle, cUInt16 mic_input) { cUInt32 base = ((ChalAudioCtrlBlk_t *)handle)->audioh_base; cUInt32 reg_val; reg_val = BRCM_READ_REG(base, AUDIOH_ADC_CTL); reg_val &= ~(AUDIOH_ADC_CTL_AMIC_EN_MASK); reg_val |= AUDIOH_ADC_CTL_AMIC_EN_MASK; /* Set the required setting */ BRCM_WRITE_REG(base, AUDIOH_ADC_CTL, reg_val); /* add the code from Rhea CHAL to be in complaint. Later check, if we can re-use the chal_audio_enable_aci_auxmic() function. Before making use this of this function, chal_aci_auxmic_init needs to be called. */ /* ACI control for analog microphone */ /* WRITE_REG32(0x3500E0D4, 0xC0); */ reg_val = READ_REG32((ACI_BASE_ADDR_VA + ACI_ADC_CTRL_OFFSET)); reg_val |= ACI_ADC_CTRL_AUDIORX_VREF_PWRUP_MASK; reg_val |= ACI_ADC_CTRL_AUDIORX_BIAS_PWRUP_MASK; WRITE_REG32((ACI_BASE_ADDR_VA + ACI_ADC_CTRL_OFFSET), reg_val); /* enable AUXMIC */ /* WRITE_REG32(0x3500E014, 0x01); */ reg_val = READ_REG32((AUXMIC_BASE_ADDR + AUXMIC_AUXEN_OFFSET)); reg_val |= AUXMIC_AUXEN_MICAUX_EN_MASK; WRITE_REG32((AUXMIC_BASE_ADDR + AUXMIC_AUXEN_OFFSET), reg_val); /* disable AUXMIC force power down */ reg_val = READ_REG32((AUXMIC_BASE_ADDR_VA+AUXMIC_F_PWRDWN_OFFSET)); reg_val &= ~AUXMIC_F_PWRDWN_FORCE_PWR_DWN_MASK; WRITE_REG32((AUXMIC_BASE_ADDR_VA + AUXMIC_F_PWRDWN_OFFSET), reg_val); return; }
/* * ============================================================================ * * Function Name: void chal_audio_dmic2_pwrctrl(CHAL_HANDLE handle, * _Bool pwronoff) * * Description: power on/off digital microphone path * * Parameters: * handle --- the audio handle * pwronoff --- on or off selection * Return: none * * ============================================================================ */ void chal_audio_dmic2_pwrctrl(CHAL_HANDLE handle, _Bool pwronoff) { #ifndef CENTRALIZED_PADCTRL cUInt32 regVal; cUInt32 function = 0x0; if (pwronoff == TRUE) function = 0x0; /* For function = 0 (alt_fn1), this will be set as DMIC2_CLK */ regVal = READ_REG32((KONA_PAD_CTRL_VA+PADCTRLREG_DIGMIC2_CLK_OFFSET)); regVal &= (~PADCTRLREG_DIGMIC2_CLK_PINSEL_2_0_MASK); regVal |= (function << PADCTRLREG_DIGMIC2_CLK_PINSEL_2_0_SHIFT); WRITE_REG32((KONA_PAD_CTRL_VA+PADCTRLREG_DIGMIC2_CLK_OFFSET), regVal); /* For function = 0 (alt_fn1), this will be set as DMIC2_DATA */ regVal = READ_REG32((KONA_PAD_CTRL_VA+PADCTRLREG_DIGMIC2_DQ_OFFSET)); regVal &= (~PADCTRLREG_DIGMIC2_DQ_PINSEL_2_0_MASK); regVal |= (function << PADCTRLREG_DIGMIC2_DQ_PINSEL_2_0_SHIFT); WRITE_REG32((KONA_PAD_CTRL_VA+PADCTRLREG_DIGMIC2_DQ_OFFSET), regVal); #endif /* #ifndef CENTRALIZED_PADCTRL */ }
cVoid chal_audio_dmic1_pwrctrl(CHAL_HANDLE handle, Boolean pwronoff) { cUInt32 regVal; cUInt32 function = 0x4; if (pwronoff == TRUE) function = 0x0; /* Select the function for DMIC0_CLK */ /* For function = 0 (alt_fn1), this will be set as DMIC1_CLK */ regVal = READ_REG32((KONA_PAD_CTRL_VA + PADCTRLREG_DMIC0CLK_OFFSET)); regVal &= (~PADCTRLREG_DMIC0CLK_PINSEL_DMIC0CLK_MASK); regVal |= (function << PADCTRLREG_DMIC0CLK_PINSEL_DMIC0CLK_SHIFT); WRITE_REG32((KONA_PAD_CTRL_VA + PADCTRLREG_DMIC0CLK_OFFSET), regVal); /* Select the function for DMIC0_DATA */ /* For function = 0 (alt_fn1), this will be set as DMIC1_DATA */ regVal = READ_REG32((KONA_PAD_CTRL_VA + PADCTRLREG_DMIC0DQ_OFFSET)); regVal &= (~PADCTRLREG_DMIC0DQ_PINSEL_DMIC0DQ_MASK); regVal |= (function << PADCTRLREG_DMIC0DQ_PINSEL_DMIC0DQ_SHIFT); WRITE_REG32((KONA_PAD_CTRL_VA + PADCTRLREG_DMIC0DQ_OFFSET), regVal); }
/******************************************************************************* * Function Name : OTGD_FS_Dev_SetRemoteWakeup * Description : Enable Remote wakeup signaling * Input : None * Output : None * Return : status *******************************************************************************/ void OTGD_FS_Dev_SetRemoteWakeup() { USB_OTG_dev_ctl_data devctl; __IO uint32_t *dctl_addr; dctl_addr = &(core_regs.dev_regs->dev_ctl); devctl.d32 = READ_REG32( dctl_addr); /* Enable the Remote Wakeup signal */ devctl.b.rmtwkupsig = 1; WRITE_REG32(dctl_addr, devctl.d32); }
/******************************************************************************* * Function Name : OTGD_FS_CoreReset * Description : Soft reset of the core * Input : None * Output : None * Return : Status *******************************************************************************/ static USB_OTG_Status OTGD_FS_CoreReset(void) { USB_OTG_Status status = USB_OTG_OK; __IO USB_OTG_rst_ctl_data greset; uint32_t count = 0; greset.d32 = 0; /* Wait for AHB master IDLE state. */ do { uDELAY(3); greset.d32 = READ_REG32(&core_regs.common_regs->rst_ctl); if (++count > 200000) { return USB_OTG_OK; } } while (greset.b.ahbidle == 0); /* Core Soft Reset */ count = 0; greset.b.csftrst = 1; WRITE_REG32(&core_regs.common_regs->rst_ctl, greset.d32 ); do { greset.d32 = READ_REG32(&core_regs.common_regs->rst_ctl); if (++count > 200000) { break; } } while (greset.b.csftrst == 1); /* Wait for 3 PHY Clocks*/ uDELAY(10); return status; }
/******************************************************************************* * Function Name : SetID * Description : Set ID line * Input : None * Output : None * Return : num_in_ep *******************************************************************************/ USB_OTG_Status SetID(void) { USB_OTG_Status status = USB_OTG_OK; USB_OTG_usb_cfg_data usbcfg; usbcfg.d32 = READ_REG32(&core_regs.common_regs->usb_cfg); usbcfg.b.force_dev = 1; WRITE_REG32(&core_regs.common_regs->usb_cfg, usbcfg.d32); mDELAY(50); return status; }
/******************************************************************************* * Function Name : OTGD_FS_ReadPacket * Description : Reads a packet from the Rx FIFO * Input : None * Output : None * Return : status *******************************************************************************/ void* OTGD_FS_ReadPacket(uint8_t *dest, uint16_t bytes) { uint32_t i; uint32_t word_count = (bytes + 3) / 4; __IO uint32_t *fifo = core_regs.data_fifo[0]; uint32_t *data_buff = (uint32_t *)dest; for (i = 0; i < word_count; i++, data_buff++) { *data_buff = READ_REG32(fifo); } /* Return the buffer pointer because if the transfer is composed of several packets, the data of the next packet must be stored following the previous packet's data */ return ((void *)data_buff); }
/******************************************************************************* * Function Name : OTGD_FS_Dev_GetEPStatus * Description : returns the EP Status * Input : - ep: pointer to the EP structure * Output : None * Return : status: DEV_EP_TX_STALL, DEV_EP_TX_VALID, DEV_EP_TX_NAK, * DEV_EP_RX_STALL, DEV_EP_RX_VALID or DEV_EP_RX_NAK, *******************************************************************************/ uint32_t OTGD_FS_Dev_GetEPStatus(USB_OTG_EP *ep) { USB_OTG_dev_ep_ctl_data depctl; __IO uint32_t *depctl_addr; uint32_t Status = 0; if (ep->is_in == 1) { depctl_addr = &(core_regs.inep_regs[ep->num]->dev_in_ep_ctl); } else { depctl_addr = &(core_regs.outep_regs[ep->num]->dev_out_ep_ctl); } depctl.d32 = READ_REG32(depctl_addr); /* Process for IN endpoint */ if (ep->is_in == 1) { if (depctl.b.stall == 1) Status = DEV_EP_TX_STALL; else if (depctl.b.naksts == 1) Status = DEV_EP_TX_NAK; else Status = DEV_EP_TX_VALID; } /* Process for OUT endpoint */ else { if (depctl.b.stall == 1) Status = DEV_EP_RX_STALL; else if (depctl.b.naksts == 1) Status = DEV_EP_RX_NAK; else Status = DEV_EP_RX_VALID; } /* Return the current status */ return Status; }
/******************************************************************************* * Function Name : OTGD_FS_PhyInit * Description : Initialize the phy * Input : None * Output : None * Return : Status *******************************************************************************/ USB_OTG_Status OTGD_FS_PhyInit(void) { USB_OTG_gpio_data gpioctl; USB_OTG_usb_cfg_data usbcfg; USB_OTG_Status status = USB_OTG_OK; /* Enable the I2C interface and deactivate the power down*/ gpioctl.d32 = 0; gpioctl.b.vbussensingB = 1; gpioctl.b.pwdn = 1; gpioctl.b.i2cifen = 0; WRITE_REG32 (&core_regs.common_regs->gpio, gpioctl.d32); mDELAY(200); /* Program GUSBCFG.OtgUtmifsSel to I2C*/ usbcfg.d32 = READ_REG32(&core_regs.common_regs->usb_cfg); usbcfg.b.otgutmifssel = 0; WRITE_REG32 (&core_regs.common_regs->usb_cfg, usbcfg.d32); return status; }
static int elroy_cfg_read(struct pci_bus *bus, unsigned int devfn, int pos, int size, u32 *data) { struct lba_device *d = LBA_DEV(parisc_walk_tree(bus->bridge)); u32 local_bus = (bus->parent == NULL) ? 0 : bus->busn_res.start; u32 tok = LBA_CFG_TOK(local_bus, devfn); void __iomem *data_reg = d->hba.base_addr + LBA_PCI_CFG_DATA; if ((pos > 255) || (devfn > 255)) return -EINVAL; /* FIXME: B2K/C3600 workaround is always use old method... */ /* if (!LBA_SKIP_PROBE(d)) */ { /* original - Generate config cycle on broken elroy with risk we will miss PCI bus errors. */ *data = lba_rd_cfg(d, tok, pos, size); DBG_CFG("%s(%x+%2x) -> 0x%x (a)\n", __func__, tok, pos, *data); return 0; } if (LBA_SKIP_PROBE(d) && !lba_device_present(bus->busn_res.start, devfn, d)) { DBG_CFG("%s(%x+%2x) -> -1 (b)\n", __func__, tok, pos); /* either don't want to look or know device isn't present. */ *data = ~0U; return(0); } /* Basic Algorithm ** Should only get here on fully working LBA rev. ** This is how simple the code should have been. */ LBA_CFG_ADDR_SETUP(d, tok | pos); switch(size) { case 1: *data = READ_REG8 (data_reg + (pos & 3)); break; case 2: *data = READ_REG16(data_reg + (pos & 2)); break; case 4: *data = READ_REG32(data_reg); break; } DBG_CFG("%s(%x+%2x) -> 0x%x (c)\n", __func__, tok, pos, *data); return 0; }
/******************************************************************************* * Function Name : OTGD_FS_EPActivate * Description : Activates an EP * Input : ep * Output : None * Return : num_in_ep *******************************************************************************/ USB_OTG_Status OTGD_FS_EPActivate(USB_OTG_EP *ep) { USB_OTG_Status status = USB_OTG_OK; USB_OTG_dev_ep_ctl_data depctl; __IO uint32_t *addr; USB_OTG_dev_all_int_data daintmsk; daintmsk.d32 = 0; /* Read DEPCTLn register */ if (ep->is_in == 1) { addr = &core_regs.inep_regs[ep->num]->dev_in_ep_ctl; daintmsk.ep.in = 1 << ep->num; } else { addr = &core_regs.outep_regs[ep->num]->dev_out_ep_ctl; daintmsk.ep.out = 1 << ep->num; } /* If the EP is already active don't change the EP Control * register. */ depctl.d32 = READ_REG32(addr); if (!depctl.b.usbactep) { depctl.b.mps = ep->maxpacket; depctl.b.eptype = ep->type; depctl.b.txfnum = ep->tx_fifo_num; depctl.b.setd0pid = 1; depctl.b.usbactep = 1; WRITE_REG32(addr, depctl.d32); } /* Enable the Interrupt for this EP */ MODIFY_REG32(&core_regs.dev_regs->dev_all_int_msk, 0, daintmsk.d32); return status; }
static int elroy_cfg_write(struct pci_bus *bus, unsigned int devfn, int pos, int size, u32 data) { struct lba_device *d = LBA_DEV(parisc_walk_tree(bus->bridge)); u32 local_bus = (bus->parent == NULL) ? 0 : bus->busn_res.start; u32 tok = LBA_CFG_TOK(local_bus,devfn); if ((pos > 255) || (devfn > 255)) return -EINVAL; if (!LBA_SKIP_PROBE(d)) { /* Original Workaround */ lba_wr_cfg(d, tok, pos, (u32) data, size); DBG_CFG("%s(%x+%2x) = 0x%x (a)\n", __func__, tok, pos,data); return 0; } if (LBA_SKIP_PROBE(d) && (!lba_device_present(bus->busn_res.start, devfn, d))) { DBG_CFG("%s(%x+%2x) = 0x%x (b)\n", __func__, tok, pos,data); return 1; /* New Workaround */ } DBG_CFG("%s(%x+%2x) = 0x%x (c)\n", __func__, tok, pos, data); /* Basic Algorithm */ LBA_CFG_ADDR_SETUP(d, tok | pos); switch(size) { case 1: WRITE_REG8 (data, d->hba.base_addr + LBA_PCI_CFG_DATA + (pos & 3)); break; case 2: WRITE_REG16(data, d->hba.base_addr + LBA_PCI_CFG_DATA + (pos & 2)); break; case 4: WRITE_REG32(data, d->hba.base_addr + LBA_PCI_CFG_DATA); break; } /* flush posted write */ lba_t32 = READ_REG32(d->hba.base_addr + LBA_PCI_CFG_ADDR); return 0; }
static int ql_eioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag, struct thread *td) { qla_host_t *ha; int rval = 0; device_t pci_dev; struct ifnet *ifp; int count; q80_offchip_mem_val_t val; qla_rd_pci_ids_t *pci_ids; qla_rd_fw_dump_t *fw_dump; union { qla_reg_val_t *rv; qla_rd_flash_t *rdf; qla_wr_flash_t *wrf; qla_erase_flash_t *erf; qla_offchip_mem_val_t *mem; } u; if ((ha = (qla_host_t *)dev->si_drv1) == NULL) return ENXIO; pci_dev= ha->pci_dev; switch(cmd) { case QLA_RDWR_REG: u.rv = (qla_reg_val_t *)data; if (u.rv->direct) { if (u.rv->rd) { u.rv->val = READ_REG32(ha, u.rv->reg); } else { WRITE_REG32(ha, u.rv->reg, u.rv->val); } } else { if ((rval = ql_rdwr_indreg32(ha, u.rv->reg, &u.rv->val, u.rv->rd))) rval = ENXIO; } break; case QLA_RD_FLASH: if (!ha->hw.flags.fdt_valid) { rval = EIO; break; } u.rdf = (qla_rd_flash_t *)data; if ((rval = ql_rd_flash32(ha, u.rdf->off, &u.rdf->data))) rval = ENXIO; break; case QLA_WR_FLASH: ifp = ha->ifp; if (ifp == NULL) { rval = ENXIO; break; } if (ifp->if_drv_flags & IFF_DRV_RUNNING) { rval = ENXIO; break; } if (!ha->hw.flags.fdt_valid) { rval = EIO; break; } u.wrf = (qla_wr_flash_t *)data; if ((rval = ql_wr_flash_buffer(ha, u.wrf->off, u.wrf->size, u.wrf->buffer))) { printf("flash write failed[%d]\n", rval); rval = ENXIO; } break; case QLA_ERASE_FLASH: ifp = ha->ifp; if (ifp == NULL) { rval = ENXIO; break; } if (ifp->if_drv_flags & IFF_DRV_RUNNING) { rval = ENXIO; break; } if (!ha->hw.flags.fdt_valid) { rval = EIO; break; } u.erf = (qla_erase_flash_t *)data; if ((rval = ql_erase_flash(ha, u.erf->off, u.erf->size))) { printf("flash erase failed[%d]\n", rval); rval = ENXIO; } break; case QLA_RDWR_MS_MEM: u.mem = (qla_offchip_mem_val_t *)data; if ((rval = ql_rdwr_offchip_mem(ha, u.mem->off, &val, u.mem->rd))) rval = ENXIO; else { u.mem->data_lo = val.data_lo; u.mem->data_hi = val.data_hi; u.mem->data_ulo = val.data_ulo; u.mem->data_uhi = val.data_uhi; } break; case QLA_RD_FW_DUMP_SIZE: if (ha->hw.mdump_init == 0) { rval = EINVAL; break; } fw_dump = (qla_rd_fw_dump_t *)data; fw_dump->minidump_size = ha->hw.mdump_buffer_size + ha->hw.mdump_template_size; fw_dump->pci_func = ha->pci_func; break; case QLA_RD_FW_DUMP: if (ha->hw.mdump_init == 0) { device_printf(pci_dev, "%s: minidump not initialized\n", __func__); rval = EINVAL; break; } fw_dump = (qla_rd_fw_dump_t *)data; if ((fw_dump->minidump == NULL) || (fw_dump->minidump_size != (ha->hw.mdump_buffer_size + ha->hw.mdump_template_size))) { device_printf(pci_dev, "%s: minidump buffer [%p] size = [%d, %d] invalid\n", __func__, fw_dump->minidump, fw_dump->minidump_size, (ha->hw.mdump_buffer_size + ha->hw.mdump_template_size)); rval = EINVAL; break; } if ((ha->pci_func & 0x1)) { device_printf(pci_dev, "%s: mindump allowed only on Port0\n", __func__); rval = ENXIO; break; } fw_dump->saved = 1; if (ha->offline) { if (ha->enable_minidump) ql_minidump(ha); fw_dump->saved = 0; fw_dump->usec_ts = ha->hw.mdump_usec_ts; if (!ha->hw.mdump_done) { device_printf(pci_dev, "%s: port offline minidump failed\n", __func__); rval = ENXIO; break; } } else { #define QLA_LOCK_MDUMP_MS_TIMEOUT (QLA_LOCK_DEFAULT_MS_TIMEOUT * 5) if (QLA_LOCK(ha, __func__, QLA_LOCK_MDUMP_MS_TIMEOUT, 0) == 0) { if (!ha->hw.mdump_done) { fw_dump->saved = 0; QL_INITIATE_RECOVERY(ha); device_printf(pci_dev, "%s: recovery initiated " " to trigger minidump\n", __func__); } QLA_UNLOCK(ha, __func__); } else { device_printf(pci_dev, "%s: QLA_LOCK() failed0\n", __func__); rval = ENXIO; break; } #define QLNX_DUMP_WAIT_SECS 30 count = QLNX_DUMP_WAIT_SECS * 1000; while (count) { if (ha->hw.mdump_done) break; qla_mdelay(__func__, 100); count -= 100; } if (!ha->hw.mdump_done) { device_printf(pci_dev, "%s: port not offline minidump failed\n", __func__); rval = ENXIO; break; } fw_dump->usec_ts = ha->hw.mdump_usec_ts; if (QLA_LOCK(ha, __func__, QLA_LOCK_MDUMP_MS_TIMEOUT, 0) == 0) { ha->hw.mdump_done = 0; QLA_UNLOCK(ha, __func__); } else { device_printf(pci_dev, "%s: QLA_LOCK() failed1\n", __func__); rval = ENXIO; break; } } if ((rval = copyout(ha->hw.mdump_template, fw_dump->minidump, ha->hw.mdump_template_size))) { device_printf(pci_dev, "%s: template copyout failed\n", __func__); rval = ENXIO; break; } if ((rval = copyout(ha->hw.mdump_buffer, ((uint8_t *)fw_dump->minidump + ha->hw.mdump_template_size), ha->hw.mdump_buffer_size))) { device_printf(pci_dev, "%s: minidump copyout failed\n", __func__); rval = ENXIO; } break; case QLA_RD_DRVR_STATE: rval = ql_drvr_state(ha, (qla_driver_state_t *)data); break; case QLA_RD_SLOWPATH_LOG: rval = ql_slowpath_log(ha, (qla_sp_log_t *)data); break; case QLA_RD_PCI_IDS: pci_ids = (qla_rd_pci_ids_t *)data; pci_ids->ven_id = pci_get_vendor(pci_dev); pci_ids->dev_id = pci_get_device(pci_dev); pci_ids->subsys_ven_id = pci_get_subvendor(pci_dev); pci_ids->subsys_dev_id = pci_get_subdevice(pci_dev); pci_ids->rev_id = pci_read_config(pci_dev, PCIR_REVID, 1); break; default: break; } return rval; }
static int ql_eioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag, struct thread *td) { qla_host_t *ha; int rval = 0; device_t pci_dev; struct ifnet *ifp; q80_offchip_mem_val_t val; qla_rd_pci_ids_t *pci_ids; qla_rd_fw_dump_t *fw_dump; union { qla_reg_val_t *rv; qla_rd_flash_t *rdf; qla_wr_flash_t *wrf; qla_erase_flash_t *erf; qla_offchip_mem_val_t *mem; } u; if ((ha = (qla_host_t *)dev->si_drv1) == NULL) return ENXIO; pci_dev= ha->pci_dev; switch(cmd) { case QLA_RDWR_REG: u.rv = (qla_reg_val_t *)data; if (u.rv->direct) { if (u.rv->rd) { u.rv->val = READ_REG32(ha, u.rv->reg); } else { WRITE_REG32(ha, u.rv->reg, u.rv->val); } } else { if ((rval = ql_rdwr_indreg32(ha, u.rv->reg, &u.rv->val, u.rv->rd))) rval = ENXIO; } break; case QLA_RD_FLASH: if (!ha->hw.flags.fdt_valid) { rval = EIO; break; } u.rdf = (qla_rd_flash_t *)data; if ((rval = ql_rd_flash32(ha, u.rdf->off, &u.rdf->data))) rval = ENXIO; break; case QLA_WR_FLASH: ifp = ha->ifp; if (ifp == NULL) { rval = ENXIO; break; } if (ifp->if_drv_flags & (IFF_DRV_OACTIVE | IFF_DRV_RUNNING)) { rval = ENXIO; break; } if (!ha->hw.flags.fdt_valid) { rval = EIO; break; } u.wrf = (qla_wr_flash_t *)data; if ((rval = ql_wr_flash_buffer(ha, u.wrf->off, u.wrf->size, u.wrf->buffer))) { printf("flash write failed[%d]\n", rval); rval = ENXIO; } break; case QLA_ERASE_FLASH: ifp = ha->ifp; if (ifp == NULL) { rval = ENXIO; break; } if (ifp->if_drv_flags & (IFF_DRV_OACTIVE | IFF_DRV_RUNNING)) { rval = ENXIO; break; } if (!ha->hw.flags.fdt_valid) { rval = EIO; break; } u.erf = (qla_erase_flash_t *)data; if ((rval = ql_erase_flash(ha, u.erf->off, u.erf->size))) { printf("flash erase failed[%d]\n", rval); rval = ENXIO; } break; case QLA_RDWR_MS_MEM: u.mem = (qla_offchip_mem_val_t *)data; if ((rval = ql_rdwr_offchip_mem(ha, u.mem->off, &val, u.mem->rd))) rval = ENXIO; else { u.mem->data_lo = val.data_lo; u.mem->data_hi = val.data_hi; u.mem->data_ulo = val.data_ulo; u.mem->data_uhi = val.data_uhi; } break; case QLA_RD_FW_DUMP_SIZE: if (ha->hw.mdump_init == 0) { rval = EINVAL; break; } fw_dump = (qla_rd_fw_dump_t *)data; fw_dump->template_size = ha->hw.dma_buf.minidump.size; fw_dump->pci_func = ha->pci_func; break; case QLA_RD_FW_DUMP: if (ha->hw.mdump_init == 0) { rval = EINVAL; break; } fw_dump = (qla_rd_fw_dump_t *)data; if ((fw_dump->md_template == NULL) || (fw_dump->template_size != ha->hw.dma_buf.minidump.size)) { rval = EINVAL; break; } if ((rval = copyout(ha->hw.dma_buf.minidump.dma_b, fw_dump->md_template, fw_dump->template_size))) rval = ENXIO; break; case QLA_RD_PCI_IDS: pci_ids = (qla_rd_pci_ids_t *)data; pci_ids->ven_id = pci_get_vendor(pci_dev); pci_ids->dev_id = pci_get_device(pci_dev); pci_ids->subsys_ven_id = pci_get_subvendor(pci_dev); pci_ids->subsys_dev_id = pci_get_subdevice(pci_dev); pci_ids->rev_id = pci_read_config(pci_dev, PCIR_REVID, 1); break; default: break; } return rval; }
void ql_mbx_isr(void *arg) { qla_host_t *ha; uint32_t data; uint32_t prev_link_state; ha = arg; if (ha == NULL) { device_printf(ha->pci_dev, "%s: arg == NULL\n", __func__); return; } data = READ_REG32(ha, Q8_FW_MBOX_CNTRL); if ((data & 0x3) != 0x1) { WRITE_REG32(ha, ha->hw.mbx_intr_mask_offset, 0); return; } data = READ_REG32(ha, Q8_FW_MBOX0); if ((data & 0xF000) != 0x8000) return; data = data & 0xFFFF; switch (data) { case 0x8001: /* It's an AEN */ ha->hw.cable_oui = READ_REG32(ha, (Q8_FW_MBOX0 + 4)); data = READ_REG32(ha, (Q8_FW_MBOX0 + 8)); ha->hw.cable_length = data & 0xFFFF; data = data >> 16; ha->hw.link_speed = data & 0xFFF; data = READ_REG32(ha, (Q8_FW_MBOX0 + 12)); prev_link_state = ha->hw.link_up; ha->hw.link_up = (((data & 0xFF) == 0) ? 0 : 1); if (prev_link_state != ha->hw.link_up) { if (ha->hw.link_up) if_link_state_change(ha->ifp, LINK_STATE_UP); else if_link_state_change(ha->ifp, LINK_STATE_DOWN); } ha->hw.module_type = ((data >> 8) & 0xFF); ha->hw.flags.fduplex = (((data & 0xFF0000) == 0) ? 0 : 1); ha->hw.flags.autoneg = (((data & 0xFF000000) == 0) ? 0 : 1); data = READ_REG32(ha, (Q8_FW_MBOX0 + 16)); ha->hw.flags.loopback_mode = data & 0x03; ha->hw.link_faults = (data >> 3) & 0xFF; break; case 0x8100: ha->hw.imd_compl=1; break; case 0x8101: ha->async_event = 1; ha->hw.aen_mb0 = 0x8101; ha->hw.aen_mb1 = READ_REG32(ha, (Q8_FW_MBOX0 + 4)); ha->hw.aen_mb2 = READ_REG32(ha, (Q8_FW_MBOX0 + 8)); ha->hw.aen_mb3 = READ_REG32(ha, (Q8_FW_MBOX0 + 12)); ha->hw.aen_mb4 = READ_REG32(ha, (Q8_FW_MBOX0 + 16)); break; case 0x8110: /* for now just dump the registers */ { uint32_t ombx[5]; ombx[0] = READ_REG32(ha, (Q8_FW_MBOX0 + 4)); ombx[1] = READ_REG32(ha, (Q8_FW_MBOX0 + 8)); ombx[2] = READ_REG32(ha, (Q8_FW_MBOX0 + 12)); ombx[3] = READ_REG32(ha, (Q8_FW_MBOX0 + 16)); ombx[4] = READ_REG32(ha, (Q8_FW_MBOX0 + 20)); device_printf(ha->pci_dev, "%s: " "0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n", __func__, data, ombx[0], ombx[1], ombx[2], ombx[3], ombx[4]); } break; case 0x8130: /* sfp insertion aen */ device_printf(ha->pci_dev, "%s: sfp inserted [0x%08x]\n", __func__, READ_REG32(ha, (Q8_FW_MBOX0 + 4))); break; case 0x8131: /* sfp removal aen */ device_printf(ha->pci_dev, "%s: sfp removed]\n", __func__); break; default: device_printf(ha->pci_dev, "%s: AEN[0x%08x]\n", __func__, data); break; } WRITE_REG32(ha, Q8_FW_MBOX_CNTRL, 0x0); WRITE_REG32(ha, ha->hw.mbx_intr_mask_offset, 0x0); return; }