static u32 phy_setup_op(struct zynq_gem_priv *priv, u32 phy_addr, u32 regnum, u32 op, u16 *data) { u32 mgtcr; struct zynq_gem_regs *regs = priv->iobase; int err; err = wait_for_bit(__func__, ®s->nwsr, ZYNQ_GEM_NWSR_MDIOIDLE_MASK, true, 20000, true); if (err) return err; /* Construct mgtcr mask for the operation */ mgtcr = ZYNQ_GEM_PHYMNTNC_OP_MASK | op | (phy_addr << ZYNQ_GEM_PHYMNTNC_PHYAD_SHIFT_MASK) | (regnum << ZYNQ_GEM_PHYMNTNC_PHREG_SHIFT_MASK) | *data; /* Write mgtcr and wait for completion */ writel(mgtcr, ®s->phymntnc); err = wait_for_bit(__func__, ®s->nwsr, ZYNQ_GEM_NWSR_MDIOIDLE_MASK, true, 20000, true); if (err) return err; if (op == ZYNQ_GEM_PHYMNTNC_OP_R_MASK) *data = readl(®s->phymntnc); return 0; }
int socfpga_bridges_reset(void) { int ret; /* Disable all the bridges (hps2fpga, lwhps2fpga, fpga2hps, fpga2sdram) */ /* set idle request to all bridges */ writel(ALT_SYSMGR_NOC_H2F_SET_MSK | ALT_SYSMGR_NOC_LWH2F_SET_MSK | ALT_SYSMGR_NOC_F2H_SET_MSK | ALT_SYSMGR_NOC_F2SDR0_SET_MSK | ALT_SYSMGR_NOC_F2SDR1_SET_MSK | ALT_SYSMGR_NOC_F2SDR2_SET_MSK, &sysmgr_regs->noc_idlereq_set); /* Enable the NOC timeout */ writel(ALT_SYSMGR_NOC_TMO_EN_SET_MSK, &sysmgr_regs->noc_timeout); /* Poll until all idleack to 1 */ ret = wait_for_bit(__func__, &sysmgr_regs->noc_idleack, ALT_SYSMGR_NOC_H2F_SET_MSK | ALT_SYSMGR_NOC_LWH2F_SET_MSK | ALT_SYSMGR_NOC_F2H_SET_MSK | ALT_SYSMGR_NOC_F2SDR0_SET_MSK | ALT_SYSMGR_NOC_F2SDR1_SET_MSK | ALT_SYSMGR_NOC_F2SDR2_SET_MSK, true, 10000, false); if (ret) return ret; /* Poll until all idlestatus to 1 */ ret = wait_for_bit(__func__, &sysmgr_regs->noc_idlestatus, ALT_SYSMGR_NOC_H2F_SET_MSK | ALT_SYSMGR_NOC_LWH2F_SET_MSK | ALT_SYSMGR_NOC_F2H_SET_MSK | ALT_SYSMGR_NOC_F2SDR0_SET_MSK | ALT_SYSMGR_NOC_F2SDR1_SET_MSK | ALT_SYSMGR_NOC_F2SDR2_SET_MSK, true, 10000, false); if (ret) return ret; /* Put all bridges (except NOR DDR scheduler) into reset state */ setbits_le32(&reset_manager_base->brgmodrst, (ALT_RSTMGR_BRGMODRST_H2F_SET_MSK | ALT_RSTMGR_BRGMODRST_LWH2F_SET_MSK | ALT_RSTMGR_BRGMODRST_F2H_SET_MSK | ALT_RSTMGR_BRGMODRST_F2SSDRAM0_SET_MSK | ALT_RSTMGR_BRGMODRST_F2SSDRAM1_SET_MSK | ALT_RSTMGR_BRGMODRST_F2SSDRAM2_SET_MSK)); /* Disable NOC timeout */ writel(0, &sysmgr_regs->noc_timeout); return 0; }
int cadence_qspi_apb_indirect_write_execute(struct cadence_spi_platdata *plat, unsigned int n_tx, const u8 *txbuf) { unsigned int page_size = plat->page_size; unsigned int remaining = n_tx; unsigned int write_bytes; int ret; /* Configure the indirect read transfer bytes */ writel(n_tx, plat->regbase + CQSPI_REG_INDIRECTWRBYTES); /* Start the indirect write transfer */ writel(CQSPI_REG_INDIRECTWR_START, plat->regbase + CQSPI_REG_INDIRECTWR); while (remaining > 0) { write_bytes = remaining > page_size ? page_size : remaining; /* Handle non-4-byte aligned access to avoid data abort. */ if (((uintptr_t)txbuf % 4) || (write_bytes % 4)) writesb(plat->ahbbase, txbuf, write_bytes); else writesl(plat->ahbbase, txbuf, write_bytes >> 2); ret = wait_for_bit("QSPI", plat->regbase + CQSPI_REG_SDRAMLEVEL, CQSPI_REG_SDRAMLEVEL_WR_MASK << CQSPI_REG_SDRAMLEVEL_WR_LSB, 0, 10, 0); if (ret) { printf("Indirect write timed out (%i)\n", ret); goto failwr; } txbuf += write_bytes; remaining -= write_bytes; } /* Check indirect done status */ ret = wait_for_bit("QSPI", plat->regbase + CQSPI_REG_INDIRECTWR, CQSPI_REG_INDIRECTWR_DONE, 1, 10, 0); if (ret) { printf("Indirect write completion error (%i)\n", ret); goto failwr; } /* Clear indirect completion status */ writel(CQSPI_REG_INDIRECTWR_DONE, plat->regbase + CQSPI_REG_INDIRECTWR); return 0; failwr: /* Cancel the indirect write */ writel(CQSPI_REG_INDIRECTWR_CANCEL, plat->regbase + CQSPI_REG_INDIRECTWR); return ret; }
/* Initialize mii(MDIO) interface, discover which PHY is * attached to the device, and configure it properly. */ static int pic32_mii_init(struct pic32eth_dev *priv) { struct pic32_ectl_regs *ectl_p = priv->ectl_regs; struct pic32_emac_regs *emac_p = priv->emac_regs; /* board phy reset */ board_netphy_reset(priv); /* disable RX, TX & all transactions */ writel(ETHCON_ON | ETHCON_TXRTS | ETHCON_RXEN, &ectl_p->con1.clr); /* wait till busy */ wait_for_bit(__func__, &ectl_p->stat.raw, ETHSTAT_BUSY, false, CONFIG_SYS_HZ, false); /* turn controller ON to access PHY over MII */ writel(ETHCON_ON, &ectl_p->con1.set); mdelay(10); /* reset MAC */ writel(EMAC_SOFTRESET, &emac_p->cfg1.set); /* reset assert */ mdelay(10); writel(EMAC_SOFTRESET, &emac_p->cfg1.clr); /* reset deassert */ /* initialize MDIO/MII */ if (priv->phyif == PHY_INTERFACE_MODE_RMII) { writel(EMAC_RMII_RESET, &emac_p->supp.set); mdelay(10); writel(EMAC_RMII_RESET, &emac_p->supp.clr); } return pic32_mdio_init(PIC32_MDIO_NAME, (ulong)&emac_p->mii); }
static void pic32_eth_stop(struct udevice *dev) { struct pic32eth_dev *priv = dev_get_priv(dev); struct pic32_ectl_regs *ectl_p = priv->ectl_regs; struct pic32_emac_regs *emac_p = priv->emac_regs; /* Reset the phy if the controller is enabled */ if (readl(&ectl_p->con1.raw) & ETHCON_ON) phy_reset(priv->phydev); /* Shut down the PHY */ phy_shutdown(priv->phydev); /* Stop rx/tx */ writel(ETHCON_TXRTS | ETHCON_RXEN, &ectl_p->con1.clr); mdelay(10); /* reset MAC */ writel(EMAC_SOFTRESET, &emac_p->cfg1.raw); /* clear reset */ writel(0, &emac_p->cfg1.raw); mdelay(10); /* disable controller */ writel(ETHCON_ON, &ectl_p->con1.clr); mdelay(10); /* wait until everything is down */ wait_for_bit(__func__, &ectl_p->stat.raw, ETHSTAT_BUSY, false, 2 * CONFIG_SYS_HZ, false); /* clear any existing interrupt event */ writel(0xffffffff, &ectl_p->irq.clr); }
static int ehci_usb_remove(struct udevice *dev) { struct msm_ehci_priv *p = dev_get_priv(dev); struct usb_ehci *ehci = p->ehci; int ret; ret = ehci_deregister(dev); if (ret) return ret; /* Stop controller. */ clrbits_le32(&ehci->usbcmd, CMD_RUN); reset_usb_phy(p); ret = board_prepare_usb(USB_INIT_DEVICE); /* Board specific hook */ if (ret < 0) return ret; /* Reset controller */ setbits_le32(&ehci->usbcmd, CMD_RESET); /* Wait for reset */ if (wait_for_bit(__func__, &ehci->usbcmd, CMD_RESET, false, 30, false)) { printf("Stuck on USB reset.\n"); return -ETIMEDOUT; } return 0; }
int wait_for_chhltd(uint32_t *sub, int *toggle, bool ignore_ack) { uint32_t hcint_comp_hlt_ack = DWC2_HCINT_XFERCOMP | DWC2_HCINT_CHHLTD; struct dwc2_hc_regs *hc_regs = ®s->hc_regs[DWC2_HC_CHANNEL]; int ret; uint32_t hcint, hctsiz; ret = wait_for_bit(&hc_regs->hcint, DWC2_HCINT_CHHLTD, true); if (ret) return ret; hcint = readl(&hc_regs->hcint); if (hcint & (DWC2_HCINT_NAK | DWC2_HCINT_FRMOVRUN)) return -EAGAIN; if (ignore_ack) hcint &= ~DWC2_HCINT_ACK; else hcint_comp_hlt_ack |= DWC2_HCINT_ACK; if (hcint != hcint_comp_hlt_ack) { debug("%s: Error (HCINT=%08x)\n", __func__, hcint); return -EINVAL; } hctsiz = readl(&hc_regs->hctsiz); *sub = (hctsiz & DWC2_HCTSIZ_XFERSIZE_MASK) >> DWC2_HCTSIZ_XFERSIZE_OFFSET; *toggle = (hctsiz & DWC2_HCTSIZ_PID_MASK) >> DWC2_HCTSIZ_PID_OFFSET; debug("%s: sub=%u toggle=%d\n", __func__, *sub, *toggle); return 0; }
static int flash_wait_till_busy(const char *func, ulong timeout) { int ret = wait_for_bit(__func__, &nvm_regs_p->ctrl.raw, NVM_WR, false, timeout, false); return ret ? ERR_TIMOUT : ERR_OK; }
/* * Initialize the serial port with the given baudrate. * The settings are always 8 data bits, no parity, 1 stop bit, no start bits. */ static int pic32_serial_init(void __iomem *base, ulong clk, u32 baudrate) { u32 div = DIV_ROUND_CLOSEST(clk, baudrate * 16); /* wait for TX FIFO to empty */ wait_for_bit(__func__, base + U_STA, UART_TX_EMPTY, true, CONFIG_SYS_HZ, false); /* send break */ writel(UART_TX_BRK, base + U_STASET); /* disable and clear mode */ writel(0, base + U_MOD); writel(0, base + U_STA); /* set baud rate generator */ writel(div - 1, base + U_BRG); /* enable the UART for TX and RX */ writel(UART_TX_ENABLE | UART_RX_ENABLE, base + U_STASET); /* enable the UART */ writel(UART_ENABLE, base + U_MODSET); return 0; }
int cadence_qspi_apb_indirect_read_execute(struct cadence_spi_platdata *plat, unsigned int n_rx, u8 *rxbuf) { unsigned int remaining = n_rx; unsigned int bytes_to_read = 0; int ret; writel(n_rx, plat->regbase + CQSPI_REG_INDIRECTRDBYTES); /* Start the indirect read transfer */ writel(CQSPI_REG_INDIRECTRD_START, plat->regbase + CQSPI_REG_INDIRECTRD); while (remaining > 0) { ret = cadence_qspi_wait_for_data(plat); if (ret < 0) { printf("Indirect write timed out (%i)\n", ret); goto failrd; } bytes_to_read = ret; while (bytes_to_read != 0) { bytes_to_read *= CQSPI_FIFO_WIDTH; bytes_to_read = bytes_to_read > remaining ? remaining : bytes_to_read; /* Handle non-4-byte aligned access to avoid data abort. */ if (((uintptr_t)rxbuf % 4) || (bytes_to_read % 4)) readsb(plat->ahbbase, rxbuf, bytes_to_read); else readsl(plat->ahbbase, rxbuf, bytes_to_read >> 2); rxbuf += bytes_to_read; remaining -= bytes_to_read; bytes_to_read = cadence_qspi_get_rd_sram_level(plat); } } /* Check indirect done status */ ret = wait_for_bit("QSPI", plat->regbase + CQSPI_REG_INDIRECTRD, CQSPI_REG_INDIRECTRD_DONE, 1, 10, 0); if (ret) { printf("Indirect read completion error (%i)\n", ret); goto failrd; } /* Clear indirect completion status */ writel(CQSPI_REG_INDIRECTRD_DONE, plat->regbase + CQSPI_REG_INDIRECTRD); return 0; failrd: /* Cancel the indirect read */ writel(CQSPI_REG_INDIRECTRD_CANCEL, plat->regbase + CQSPI_REG_INDIRECTRD); return ret; }
/* Return 0 : host node, <>0 : device mode */ static int usb_phy_enable(int index, struct usb_ehci *ehci) { void __iomem *phy_reg; void __iomem *phy_ctrl; void __iomem *usb_cmd; int ret; if (index >= ARRAY_SIZE(phy_bases)) return 0; phy_reg = (void __iomem *)phy_bases[index]; phy_ctrl = (void __iomem *)(phy_reg + USBPHY_CTRL); usb_cmd = (void __iomem *)&ehci->usbcmd; /* Stop then Reset */ clrbits_le32(usb_cmd, UCMD_RUN_STOP); ret = wait_for_bit(__func__, usb_cmd, UCMD_RUN_STOP, false, 10000, false); if (ret) return ret; setbits_le32(usb_cmd, UCMD_RESET); ret = wait_for_bit(__func__, usb_cmd, UCMD_RESET, false, 10000, false); if (ret) return ret; /* Reset USBPHY module */ setbits_le32(phy_ctrl, USBPHY_CTRL_SFTRST); udelay(10); /* Remove CLKGATE and SFTRST */ clrbits_le32(phy_ctrl, USBPHY_CTRL_CLKGATE | USBPHY_CTRL_SFTRST); udelay(10); /* Power up the PHY */ writel(0, phy_reg + USBPHY_PWD); /* enable FS/LS device */ setbits_le32(phy_ctrl, USBPHY_CTRL_ENUTMILEVEL2 | USBPHY_CTRL_ENUTMILEVEL3); return 0; }
/* * Flush Rx FIFO. * * @param regs Programming view of DWC_otg controller. */ static void dwc_otg_flush_rx_fifo(struct dwc2_core_regs *regs) { int ret; writel(DWC2_GRSTCTL_RXFFLSH, ®s->grstctl); ret = wait_for_bit(®s->grstctl, DWC2_GRSTCTL_RXFFLSH, 0); if (ret) printf("%s: Timeout!\n", __func__); /* Wait for 3 PHY Clocks */ udelay(1); }
/* * Flush a Tx FIFO. * * @param regs Programming view of DWC_otg controller. * @param num Tx FIFO to flush. */ static void dwc_otg_flush_tx_fifo(struct dwc2_core_regs *regs, const int num) { int ret; writel(DWC2_GRSTCTL_TXFFLSH | (num << DWC2_GRSTCTL_TXFNUM_OFFSET), ®s->grstctl); ret = wait_for_bit(®s->grstctl, DWC2_GRSTCTL_TXFFLSH, 0); if (ret) printf("%s: Timeout!\n", __func__); /* Wait for 3 PHY Clocks */ udelay(1); }
/* start phy self calibration logic */ static int ddr2_phy_calib_start(void) { struct ddr2_phy_regs *ddr2_phy; ddr2_phy = ioremap(PIC32_DDR2P_BASE, sizeof(*ddr2_phy)); /* DDR Phy SCL Start */ writel(SCL_START | SCL_EN, &ddr2_phy->scl_start); /* Wait for SCL for data byte to pass */ return wait_for_bit(__func__, &ddr2_phy->scl_start, SCL_LUBPASS, true, CONFIG_SYS_HZ, false); }
/* * Do core a soft reset of the core. Be careful with this because it * resets all the internal state machines of the core. */ static void dwc_otg_core_reset(struct dwc2_core_regs *regs) { int ret; /* Wait for AHB master IDLE state. */ ret = wait_for_bit(®s->grstctl, DWC2_GRSTCTL_AHBIDLE, 1); if (ret) printf("%s: Timeout!\n", __func__); /* Core Soft Reset */ writel(DWC2_GRSTCTL_CSFTRST, ®s->grstctl); ret = wait_for_bit(®s->grstctl, DWC2_GRSTCTL_CSFTRST, 0); if (ret) printf("%s: Timeout!\n", __func__); /* * Wait for core to come out of reset. * NOTE: This long sleep is _very_ important, otherwise the core will * not stay in host mode after a connector ID change! */ mdelay(100); }
static int axi_ethernet_init(struct axidma_priv *priv) { struct axi_regs *regs = priv->iobase; int err; /* * Check the status of the MgtRdy bit in the interrupt status * registers. This must be done to allow the MGT clock to become stable * for the Sgmii and 1000BaseX PHY interfaces. No other register reads * will be valid until this bit is valid. * The bit is always a 1 for all other PHY interfaces. * Interrupt status and enable registers are not available in non * processor mode and hence bypass in this mode */ if (!priv->eth_hasnobuf) { err = wait_for_bit(__func__, (const u32 *)®s->is, XAE_INT_MGTRDY_MASK, true, 200, false); if (err) { printf("%s: Timeout\n", __func__); return 1; } /* * Stop the device and reset HW * Disable interrupts */ writel(0, ®s->ie); } /* Disable the receiver */ writel(readl(®s->rcw1) & ~XAE_RCW1_RX_MASK, ®s->rcw1); /* * Stopping the receiver in mid-packet causes a dropped packet * indication from HW. Clear it. */ if (!priv->eth_hasnobuf) { /* Set the interrupt status register to clear the interrupt */ writel(XAE_INT_RXRJECT_MASK, ®s->is); } /* Setup HW */ /* Set default MDIO divisor */ writel(XAE_MDIO_DIV_DFT | XAE_MDIO_MC_MDIOEN_MASK, ®s->mdio_mc); debug("axiemac: InitHw done\n"); return 0; }
static int zynq_gem_send(struct udevice *dev, void *ptr, int len) { u32 addr, size; struct zynq_gem_priv *priv = dev_get_priv(dev); struct zynq_gem_regs *regs = priv->iobase; struct emac_bd *current_bd = &priv->tx_bd[1]; /* Setup Tx BD */ memset(priv->tx_bd, 0, sizeof(struct emac_bd)); priv->tx_bd->addr = (ulong)ptr; priv->tx_bd->status = (len & ZYNQ_GEM_TXBUF_FRMLEN_MASK) | ZYNQ_GEM_TXBUF_LAST_MASK; /* Dummy descriptor to mark it as the last in descriptor chain */ current_bd->addr = 0x0; current_bd->status = ZYNQ_GEM_TXBUF_WRAP_MASK | ZYNQ_GEM_TXBUF_LAST_MASK| ZYNQ_GEM_TXBUF_USED_MASK; /* setup BD */ writel((ulong)priv->tx_bd, ®s->txqbase); addr = (ulong) ptr; addr &= ~(ARCH_DMA_MINALIGN - 1); size = roundup(len, ARCH_DMA_MINALIGN); flush_dcache_range(addr, addr + size); addr = (ulong)priv->rxbuffers; addr &= ~(ARCH_DMA_MINALIGN - 1); size = roundup((RX_BUF * PKTSIZE_ALIGN), ARCH_DMA_MINALIGN); flush_dcache_range(addr, addr + size); barrier(); /* Start transmit */ setbits_le32(®s->nwctrl, ZYNQ_GEM_NWCTRL_STARTTX_MASK); /* Read TX BD status */ if (priv->tx_bd->status & ZYNQ_GEM_TXBUF_EXHAUSTED) printf("TX buffers exhausted in mid frame\n"); return wait_for_bit(__func__, ®s->txsr, ZYNQ_GEM_TSR_DONE, true, 20000); }
/* initializes the MAC and PHY, then establishes a link */ static void pic32_ctrl_reset(struct pic32eth_dev *priv) { struct pic32_ectl_regs *ectl_p = priv->ectl_regs; u32 v; /* disable RX, TX & any other transactions */ writel(ETHCON_ON | ETHCON_TXRTS | ETHCON_RXEN, &ectl_p->con1.clr); /* wait till busy */ wait_for_bit(__func__, &ectl_p->stat.raw, ETHSTAT_BUSY, false, CONFIG_SYS_HZ, false); /* decrement received buffcnt to zero. */ while (readl(&ectl_p->stat.raw) & ETHSTAT_BUFCNT) writel(ETHCON_BUFCDEC, &ectl_p->con1.set); /* clear any existing interrupt event */ writel(0xffffffff, &ectl_p->irq.clr); /* clear RX/TX start address */ writel(0xffffffff, &ectl_p->txst.clr); writel(0xffffffff, &ectl_p->rxst.clr); /* clear the receive filters */ writel(0x00ff, &ectl_p->rxfc.clr); /* set the receive filters * ETH_FILT_CRC_ERR_REJECT * ETH_FILT_RUNT_REJECT * ETH_FILT_UCAST_ACCEPT * ETH_FILT_MCAST_ACCEPT * ETH_FILT_BCAST_ACCEPT */ v = ETHRXFC_BCEN | ETHRXFC_MCEN | ETHRXFC_UCEN | ETHRXFC_RUNTEN | ETHRXFC_CRCOKEN; writel(v, &ectl_p->rxfc.set); /* turn controller ON to access PHY over MII */ writel(ETHCON_ON, &ectl_p->con1.set); }
/* Enable bridges (hps2fpga, lwhps2fpga, fpga2hps, fpga2sdram) per handoff */ int socfpga_reset_deassert_bridges_handoff(void) { u32 mask_noc = 0, mask_rstmgr = 0; int i; for (i = 0; i < ARRAY_SIZE(bridge_cfg_tbl); i++) { if (get_bridge_init_val(gd->fdt_blob, bridge_cfg_tbl[i].compat_id)) { mask_noc |= bridge_cfg_tbl[i].mask_noc; mask_rstmgr |= bridge_cfg_tbl[i].mask_rstmgr; } } /* clear idle request to all bridges */ setbits_le32(&sysmgr_regs->noc_idlereq_clr, mask_noc); /* Release bridges from reset state per handoff value */ clrbits_le32(&reset_manager_base->brgmodrst, mask_rstmgr); /* Poll until all idleack to 0, timeout at 1000ms */ return wait_for_bit(__func__, &sysmgr_regs->noc_idleack, mask_noc, false, 1000, false); }
/* * This function initializes the DWC_otg controller registers for * host mode. * * This function flushes the Tx and Rx FIFOs and it flushes any entries in the * request queues. Host channels are reset to ensure that they are ready for * performing transfers. * * @param regs Programming view of DWC_otg controller * */ static void dwc_otg_core_host_init(struct dwc2_core_regs *regs) { uint32_t nptxfifosize = 0; uint32_t ptxfifosize = 0; uint32_t hprt0 = 0; int i, ret, num_channels; /* Restart the Phy Clock */ writel(0, ®s->pcgcctl); /* Initialize Host Configuration Register */ init_fslspclksel(regs); #ifdef CONFIG_DWC2_DFLT_SPEED_FULL setbits_le32(®s->host_regs.hcfg, DWC2_HCFG_FSLSSUPP); #endif /* Configure data FIFO sizes */ #ifdef CONFIG_DWC2_ENABLE_DYNAMIC_FIFO if (readl(®s->ghwcfg2) & DWC2_HWCFG2_DYNAMIC_FIFO) { /* Rx FIFO */ writel(CONFIG_DWC2_HOST_RX_FIFO_SIZE, ®s->grxfsiz); /* Non-periodic Tx FIFO */ nptxfifosize |= CONFIG_DWC2_HOST_NPERIO_TX_FIFO_SIZE << DWC2_FIFOSIZE_DEPTH_OFFSET; nptxfifosize |= CONFIG_DWC2_HOST_RX_FIFO_SIZE << DWC2_FIFOSIZE_STARTADDR_OFFSET; writel(nptxfifosize, ®s->gnptxfsiz); /* Periodic Tx FIFO */ ptxfifosize |= CONFIG_DWC2_HOST_PERIO_TX_FIFO_SIZE << DWC2_FIFOSIZE_DEPTH_OFFSET; ptxfifosize |= (CONFIG_DWC2_HOST_RX_FIFO_SIZE + CONFIG_DWC2_HOST_NPERIO_TX_FIFO_SIZE) << DWC2_FIFOSIZE_STARTADDR_OFFSET; writel(ptxfifosize, ®s->hptxfsiz); } #endif /* Clear Host Set HNP Enable in the OTG Control Register */ clrbits_le32(®s->gotgctl, DWC2_GOTGCTL_HSTSETHNPEN); /* Make sure the FIFOs are flushed. */ dwc_otg_flush_tx_fifo(regs, 0x10); /* All Tx FIFOs */ dwc_otg_flush_rx_fifo(regs); /* Flush out any leftover queued requests. */ num_channels = readl(®s->ghwcfg2); num_channels &= DWC2_HWCFG2_NUM_HOST_CHAN_MASK; num_channels >>= DWC2_HWCFG2_NUM_HOST_CHAN_OFFSET; num_channels += 1; for (i = 0; i < num_channels; i++) clrsetbits_le32(®s->hc_regs[i].hcchar, DWC2_HCCHAR_CHEN | DWC2_HCCHAR_EPDIR, DWC2_HCCHAR_CHDIS); /* Halt all channels to put them into a known state. */ for (i = 0; i < num_channels; i++) { clrsetbits_le32(®s->hc_regs[i].hcchar, DWC2_HCCHAR_EPDIR, DWC2_HCCHAR_CHEN | DWC2_HCCHAR_CHDIS); ret = wait_for_bit(®s->hc_regs[i].hcchar, DWC2_HCCHAR_CHEN, 0); if (ret) printf("%s: Timeout!\n", __func__); } /* Turn on the vbus power. */ if (readl(®s->gintsts) & DWC2_GINTSTS_CURMODE_HOST) { hprt0 = readl(®s->hprt0); hprt0 &= ~(DWC2_HPRT0_PRTENA | DWC2_HPRT0_PRTCONNDET); hprt0 &= ~(DWC2_HPRT0_PRTENCHNG | DWC2_HPRT0_PRTOVRCURRCHNG); if (!(hprt0 & DWC2_HPRT0_PRTPWR)) { hprt0 |= DWC2_HPRT0_PRTPWR; writel(hprt0, ®s->hprt0); } } }
static int atmel_spi_xfer(struct udevice *dev, unsigned int bitlen, const void *dout, void *din, unsigned long flags) { struct udevice *bus = dev_get_parent(dev); struct atmel_spi_platdata *bus_plat = dev_get_platdata(bus); struct at91_spi *reg_base = bus_plat->regs; u32 len_tx, len_rx, len; u32 status; const u8 *txp = dout; u8 *rxp = din; u8 value; if (bitlen == 0) goto out; /* * The controller can do non-multiple-of-8 bit * transfers, but this driver currently doesn't support it. * * It's also not clear how such transfers are supposed to be * represented as a stream of bytes...this is a limitation of * the current SPI interface. */ if (bitlen % 8) { /* Errors always terminate an ongoing transfer */ flags |= SPI_XFER_END; goto out; } len = bitlen / 8; /* * The controller can do automatic CS control, but it is * somewhat quirky, and it doesn't really buy us much anyway * in the context of U-Boot. */ if (flags & SPI_XFER_BEGIN) { atmel_spi_cs_activate(dev); /* * sometimes the RDR is not empty when we get here, * in theory that should not happen, but it DOES happen. * Read it here to be on the safe side. * That also clears the OVRES flag. Required if the * following loop exits due to OVRES! */ readl(®_base->rdr); } for (len_tx = 0, len_rx = 0; len_rx < len; ) { status = readl(®_base->sr); if (status & ATMEL_SPI_SR_OVRES) return -1; if ((len_tx < len) && (status & ATMEL_SPI_SR_TDRE)) { if (txp) value = *txp++; else value = 0; writel(value, ®_base->tdr); len_tx++; } if (status & ATMEL_SPI_SR_RDRF) { value = readl(®_base->rdr); if (rxp) *rxp++ = value; len_rx++; } } out: if (flags & SPI_XFER_END) { /* * Wait until the transfer is completely done before * we deactivate CS. */ wait_for_bit(__func__, ®_base->sr, ATMEL_SPI_SR_TXEMPTY, true, 1000, false); atmel_spi_cs_deactivate(dev); } return 0; }
void lcd_ctrl_init(void *lcdbase) { unsigned long value; struct lcd_dma_desc *desc; struct atmel_hlcd_regs *regs; int ret; if (!has_lcdc()) return; /* No lcdc */ regs = (struct atmel_hlcd_regs *)panel_info.mmio; /* Disable DISP signal */ writel(LCDC_LCDDIS_DISPDIS, ®s->lcdc_lcddis); ret = wait_for_bit(__func__, ®s->lcdc_lcdsr, LCDC_LCDSR_DISPSTS, false, 1000, false); if (ret) printf("%s: %d: Timeout!\n", __func__, __LINE__); /* Disable synchronization */ writel(LCDC_LCDDIS_SYNCDIS, ®s->lcdc_lcddis); ret = wait_for_bit(__func__, ®s->lcdc_lcdsr, LCDC_LCDSR_LCDSTS, false, 1000, false); if (ret) printf("%s: %d: Timeout!\n", __func__, __LINE__); /* Disable pixel clock */ writel(LCDC_LCDDIS_CLKDIS, ®s->lcdc_lcddis); ret = wait_for_bit(__func__, ®s->lcdc_lcdsr, LCDC_LCDSR_CLKSTS, false, 1000, false); if (ret) printf("%s: %d: Timeout!\n", __func__, __LINE__); /* Disable PWM */ writel(LCDC_LCDDIS_PWMDIS, ®s->lcdc_lcddis); ret = wait_for_bit(__func__, ®s->lcdc_lcdsr, LCDC_LCDSR_PWMSTS, false, 1000, false); if (ret) printf("%s: %d: Timeout!\n", __func__, __LINE__); /* Set pixel clock */ value = get_lcdc_clk_rate(0) / panel_info.vl_clk; if (get_lcdc_clk_rate(0) % panel_info.vl_clk) value++; if (value < 1) { /* Using system clock as pixel clock */ writel(LCDC_LCDCFG0_CLKDIV(0) | LCDC_LCDCFG0_CGDISHCR | LCDC_LCDCFG0_CGDISHEO | LCDC_LCDCFG0_CGDISOVR1 | LCDC_LCDCFG0_CGDISBASE | panel_info.vl_clk_pol | LCDC_LCDCFG0_CLKSEL, ®s->lcdc_lcdcfg0); } else { writel(LCDC_LCDCFG0_CLKDIV(value - 2) | LCDC_LCDCFG0_CGDISHCR | LCDC_LCDCFG0_CGDISHEO | LCDC_LCDCFG0_CGDISOVR1 | LCDC_LCDCFG0_CGDISBASE | panel_info.vl_clk_pol, ®s->lcdc_lcdcfg0); } /* Initialize control register 5 */ value = 0; value |= panel_info.vl_sync; #ifndef LCD_OUTPUT_BPP /* Output is 24bpp */ value |= LCDC_LCDCFG5_MODE_OUTPUT_24BPP; #else switch (LCD_OUTPUT_BPP) { case 12: value |= LCDC_LCDCFG5_MODE_OUTPUT_12BPP; break; case 16: value |= LCDC_LCDCFG5_MODE_OUTPUT_16BPP; break; case 18: value |= LCDC_LCDCFG5_MODE_OUTPUT_18BPP; break; case 24: value |= LCDC_LCDCFG5_MODE_OUTPUT_24BPP; break; default: BUG(); break; } #endif value |= LCDC_LCDCFG5_GUARDTIME(ATMEL_LCDC_GUARD_TIME); value |= (LCDC_LCDCFG5_DISPDLY | LCDC_LCDCFG5_VSPDLYS); writel(value, ®s->lcdc_lcdcfg5); /* Vertical & Horizontal Timing */ value = LCDC_LCDCFG1_VSPW(panel_info.vl_vsync_len - 1); value |= LCDC_LCDCFG1_HSPW(panel_info.vl_hsync_len - 1); writel(value, ®s->lcdc_lcdcfg1); value = LCDC_LCDCFG2_VBPW(panel_info.vl_upper_margin); value |= LCDC_LCDCFG2_VFPW(panel_info.vl_lower_margin - 1); writel(value, ®s->lcdc_lcdcfg2); value = LCDC_LCDCFG3_HBPW(panel_info.vl_left_margin - 1); value |= LCDC_LCDCFG3_HFPW(panel_info.vl_right_margin - 1); writel(value, ®s->lcdc_lcdcfg3); /* Display size */ value = LCDC_LCDCFG4_RPF(panel_info.vl_row - 1); value |= LCDC_LCDCFG4_PPL(panel_info.vl_col - 1); writel(value, ®s->lcdc_lcdcfg4); writel(LCDC_BASECFG0_BLEN_AHB_INCR4 | LCDC_BASECFG0_DLBO, ®s->lcdc_basecfg0); switch (NBITS(panel_info.vl_bpix)) { case 16: writel(LCDC_BASECFG1_RGBMODE_16BPP_RGB_565, ®s->lcdc_basecfg1); break; case 32: writel(LCDC_BASECFG1_RGBMODE_24BPP_RGB_888, ®s->lcdc_basecfg1); break; default: BUG(); break; } writel(LCDC_BASECFG2_XSTRIDE(0), ®s->lcdc_basecfg2); writel(0, ®s->lcdc_basecfg3); writel(LCDC_BASECFG4_DMA, ®s->lcdc_basecfg4); /* Disable all interrupts */ writel(~0UL, ®s->lcdc_lcdidr); writel(~0UL, ®s->lcdc_baseidr); /* Setup the DMA descriptor, this descriptor will loop to itself */ desc = (struct lcd_dma_desc *)(lcdbase - 16); desc->address = (u32)lcdbase; /* Disable DMA transfer interrupt & descriptor loaded interrupt. */ desc->control = LCDC_BASECTRL_ADDIEN | LCDC_BASECTRL_DSCRIEN | LCDC_BASECTRL_DMAIEN | LCDC_BASECTRL_DFETCH; desc->next = (u32)desc; /* Flush the DMA descriptor if we enabled dcache */ flush_dcache_range((u32)desc, (u32)desc + sizeof(*desc)); writel(desc->address, ®s->lcdc_baseaddr); writel(desc->control, ®s->lcdc_basectrl); writel(desc->next, ®s->lcdc_basenext); writel(LCDC_BASECHER_CHEN | LCDC_BASECHER_UPDATEEN, ®s->lcdc_basecher); /* Enable LCD */ value = readl(®s->lcdc_lcden); writel(value | LCDC_LCDEN_CLKEN, ®s->lcdc_lcden); ret = wait_for_bit(__func__, ®s->lcdc_lcdsr, LCDC_LCDSR_CLKSTS, true, 1000, false); if (ret) printf("%s: %d: Timeout!\n", __func__, __LINE__); value = readl(®s->lcdc_lcden); writel(value | LCDC_LCDEN_SYNCEN, ®s->lcdc_lcden); ret = wait_for_bit(__func__, ®s->lcdc_lcdsr, LCDC_LCDSR_LCDSTS, true, 1000, false); if (ret) printf("%s: %d: Timeout!\n", __func__, __LINE__); value = readl(®s->lcdc_lcden); writel(value | LCDC_LCDEN_DISPEN, ®s->lcdc_lcden); ret = wait_for_bit(__func__, ®s->lcdc_lcdsr, LCDC_LCDSR_DISPSTS, true, 1000, false); if (ret) printf("%s: %d: Timeout!\n", __func__, __LINE__); value = readl(®s->lcdc_lcden); writel(value | LCDC_LCDEN_PWMEN, ®s->lcdc_lcden); ret = wait_for_bit(__func__, ®s->lcdc_lcdsr, LCDC_LCDSR_PWMSTS, true, 1000, false); if (ret) printf("%s: %d: Timeout!\n", __func__, __LINE__); /* Enable flushing if we enabled dcache */ lcd_set_flush_dcache(1); }
static int mdio_wait(struct emaclite_regs *regs) { return wait_for_bit(__func__, ®s->mdioctrl, XEL_MDIOCTRL_MDIOSTS_MASK, false, 2000); }
static void atmel_hlcdc_init(struct udevice *dev) { struct video_uc_platdata *uc_plat = dev_get_uclass_platdata(dev); struct atmel_hlcdc_priv *priv = dev_get_priv(dev); struct atmel_hlcd_regs *regs = priv->regs; struct display_timing *timing = &priv->timing; struct lcd_dma_desc *desc; unsigned long value, vl_clk_pol; int ret; /* Disable DISP signal */ writel(LCDC_LCDDIS_DISPDIS, ®s->lcdc_lcddis); ret = wait_for_bit(__func__, ®s->lcdc_lcdsr, LCDC_LCDSR_DISPSTS, false, 1000, false); if (ret) printf("%s: %d: Timeout!\n", __func__, __LINE__); /* Disable synchronization */ writel(LCDC_LCDDIS_SYNCDIS, ®s->lcdc_lcddis); ret = wait_for_bit(__func__, ®s->lcdc_lcdsr, LCDC_LCDSR_LCDSTS, false, 1000, false); if (ret) printf("%s: %d: Timeout!\n", __func__, __LINE__); /* Disable pixel clock */ writel(LCDC_LCDDIS_CLKDIS, ®s->lcdc_lcddis); ret = wait_for_bit(__func__, ®s->lcdc_lcdsr, LCDC_LCDSR_CLKSTS, false, 1000, false); if (ret) printf("%s: %d: Timeout!\n", __func__, __LINE__); /* Disable PWM */ writel(LCDC_LCDDIS_PWMDIS, ®s->lcdc_lcddis); ret = wait_for_bit(__func__, ®s->lcdc_lcdsr, LCDC_LCDSR_PWMSTS, false, 1000, false); if (ret) printf("%s: %d: Timeout!\n", __func__, __LINE__); /* Set pixel clock */ value = priv->clk_rate / timing->pixelclock.typ; if (priv->clk_rate % timing->pixelclock.typ) value++; vl_clk_pol = 0; if (timing->flags & DISPLAY_FLAGS_PIXDATA_NEGEDGE) vl_clk_pol = LCDC_LCDCFG0_CLKPOL; if (value < 1) { /* Using system clock as pixel clock */ writel(LCDC_LCDCFG0_CLKDIV(0) | LCDC_LCDCFG0_CGDISHCR | LCDC_LCDCFG0_CGDISHEO | LCDC_LCDCFG0_CGDISOVR1 | LCDC_LCDCFG0_CGDISBASE | vl_clk_pol | LCDC_LCDCFG0_CLKSEL, ®s->lcdc_lcdcfg0); } else { writel(LCDC_LCDCFG0_CLKDIV(value - 2) | LCDC_LCDCFG0_CGDISHCR | LCDC_LCDCFG0_CGDISHEO | LCDC_LCDCFG0_CGDISOVR1 | LCDC_LCDCFG0_CGDISBASE | vl_clk_pol, ®s->lcdc_lcdcfg0); } /* Initialize control register 5 */ value = 0; if (!(timing->flags & DISPLAY_FLAGS_HSYNC_HIGH)) value |= LCDC_LCDCFG5_HSPOL; if (!(timing->flags & DISPLAY_FLAGS_VSYNC_HIGH)) value |= LCDC_LCDCFG5_VSPOL; switch (priv->output_mode) { case 12: value |= LCDC_LCDCFG5_MODE_OUTPUT_12BPP; break; case 16: value |= LCDC_LCDCFG5_MODE_OUTPUT_16BPP; break; case 18: value |= LCDC_LCDCFG5_MODE_OUTPUT_18BPP; break; case 24: value |= LCDC_LCDCFG5_MODE_OUTPUT_24BPP; break; default: BUG(); break; } value |= LCDC_LCDCFG5_GUARDTIME(priv->guard_time); value |= (LCDC_LCDCFG5_DISPDLY | LCDC_LCDCFG5_VSPDLYS); writel(value, ®s->lcdc_lcdcfg5); /* Vertical & Horizontal Timing */ value = LCDC_LCDCFG1_VSPW(timing->vsync_len.typ - 1); value |= LCDC_LCDCFG1_HSPW(timing->hsync_len.typ - 1); writel(value, ®s->lcdc_lcdcfg1); value = LCDC_LCDCFG2_VBPW(timing->vback_porch.typ); value |= LCDC_LCDCFG2_VFPW(timing->vfront_porch.typ - 1); writel(value, ®s->lcdc_lcdcfg2); value = LCDC_LCDCFG3_HBPW(timing->hback_porch.typ - 1); value |= LCDC_LCDCFG3_HFPW(timing->hfront_porch.typ - 1); writel(value, ®s->lcdc_lcdcfg3); /* Display size */ value = LCDC_LCDCFG4_RPF(timing->vactive.typ - 1); value |= LCDC_LCDCFG4_PPL(timing->hactive.typ - 1); writel(value, ®s->lcdc_lcdcfg4); writel(LCDC_BASECFG0_BLEN_AHB_INCR4 | LCDC_BASECFG0_DLBO, ®s->lcdc_basecfg0); switch (VNBITS(priv->vl_bpix)) { case 16: writel(LCDC_BASECFG1_RGBMODE_16BPP_RGB_565, ®s->lcdc_basecfg1); break; case 32: writel(LCDC_BASECFG1_RGBMODE_24BPP_RGB_888, ®s->lcdc_basecfg1); break; default: BUG(); break; } writel(LCDC_BASECFG2_XSTRIDE(0), ®s->lcdc_basecfg2); writel(0, ®s->lcdc_basecfg3); writel(LCDC_BASECFG4_DMA, ®s->lcdc_basecfg4); /* Disable all interrupts */ writel(~0UL, ®s->lcdc_lcdidr); writel(~0UL, ®s->lcdc_baseidr); /* Setup the DMA descriptor, this descriptor will loop to itself */ desc = memalign(CONFIG_SYS_CACHELINE_SIZE, sizeof(*desc)); if (!desc) return; desc->address = (u32)uc_plat->base; /* Disable DMA transfer interrupt & descriptor loaded interrupt. */ desc->control = LCDC_BASECTRL_ADDIEN | LCDC_BASECTRL_DSCRIEN | LCDC_BASECTRL_DMAIEN | LCDC_BASECTRL_DFETCH; desc->next = (u32)desc; /* Flush the DMA descriptor if we enabled dcache */ flush_dcache_range((u32)desc, ALIGN(((u32)desc + sizeof(*desc)), CONFIG_SYS_CACHELINE_SIZE)); writel(desc->address, ®s->lcdc_baseaddr); writel(desc->control, ®s->lcdc_basectrl); writel(desc->next, ®s->lcdc_basenext); writel(LCDC_BASECHER_CHEN | LCDC_BASECHER_UPDATEEN, ®s->lcdc_basecher); /* Enable LCD */ value = readl(®s->lcdc_lcden); writel(value | LCDC_LCDEN_CLKEN, ®s->lcdc_lcden); ret = wait_for_bit(__func__, ®s->lcdc_lcdsr, LCDC_LCDSR_CLKSTS, true, 1000, false); if (ret) printf("%s: %d: Timeout!\n", __func__, __LINE__); value = readl(®s->lcdc_lcden); writel(value | LCDC_LCDEN_SYNCEN, ®s->lcdc_lcden); ret = wait_for_bit(__func__, ®s->lcdc_lcdsr, LCDC_LCDSR_LCDSTS, true, 1000, false); if (ret) printf("%s: %d: Timeout!\n", __func__, __LINE__); value = readl(®s->lcdc_lcden); writel(value | LCDC_LCDEN_DISPEN, ®s->lcdc_lcden); ret = wait_for_bit(__func__, ®s->lcdc_lcdsr, LCDC_LCDSR_DISPSTS, true, 1000, false); if (ret) printf("%s: %d: Timeout!\n", __func__, __LINE__); value = readl(®s->lcdc_lcden); writel(value | LCDC_LCDEN_PWMEN, ®s->lcdc_lcden); ret = wait_for_bit(__func__, ®s->lcdc_lcdsr, LCDC_LCDSR_PWMSTS, true, 1000, false); if (ret) printf("%s: %d: Timeout!\n", __func__, __LINE__); }